iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Jenkins

Jenkins is the venerable open-source CI server. Pipelines as code via Jenkinsfile, agents, credentials, and the patterns that age well.

CI/CD — Jenkins

EXAMPLE
# ===== The model =====
# - Master / Controller: runs the UI, schedules builds
# - Agents (workers): execute jobs; pinned by label
# - Jobs / Pipelines: scripted or declarative; live in the repo as Jenkinsfile

# ===== Declarative Jenkinsfile (recommended) =====
# Jenkinsfile (root of repo)
pipeline {
  agent any
  options {
    timeout(time: 30, unit: 'MINUTES')
    timestamps()
    buildDiscarder(logRotator(numToKeepStr: '20'))
  }
  environment {
    NODE_VERSION = '20'
  }
  stages {
    stage('Setup') {
      steps {
        sh 'corepack enable && npm ci'
      }
    }
    stage('Test') {
      parallel {
        stage('Lint')      { steps { sh 'npm run lint' } }
        stage('Typecheck') { steps { sh 'npm run typecheck' } }
        stage('Unit')      { steps { sh 'npm test -- --coverage' } }
      }
    }
    stage('Build') {
      steps { sh 'npm run build' }
    }
    stage('Deploy') {
      when { branch 'main' }
      steps {
        withCredentials([string(credentialsId: 'deploy-token', variable: 'TOKEN')]) {
          sh './scripts/deploy.sh $TOKEN'
        }
      }
    }
  }
  post {
    always { junit 'reports/**/*.xml' }
    failure { mail to: 'oncall@example.com', subject: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}" }
  }
}

# ===== Scripted Jenkinsfile (fallback) =====
node('linux') {
  stage('Test') {
    checkout scm
    sh 'npm ci'
    sh 'npm test'
  }
}

# ===== Agents =====
# Configure agents on Manage Jenkins -> Nodes
# Pin a job to a label:
agent { label 'linux && docker' }

# Docker as the agent (ephemeral):
agent {
  docker { image 'node:20-alpine' }
}

# ===== Credentials =====
# Manage Jenkins -> Credentials -> Global -> Add
# Types: secret text, username/password, SSH key, certificate, file
# Use them in pipelines via withCredentials([...]) { ... }.

# ===== Shared libraries =====
# Code shared across many pipelines lives in a Git repo configured under
# Manage Jenkins -> Configure System -> Global Pipeline Libraries.
@Library('my-shared-lib') _
mySharedFunction()

# ===== Triggers =====
triggers {
  cron('H 4 * * 1-5')           // nightly weekdays
  pollSCM('H/15 * * * *')       // poll repo every 15 minutes (prefer webhooks)
  upstream(upstreamProjects: 'shared-libs', threshold: hudson.model.Result.SUCCESS)
}

# Or: GitHub / GitLab webhooks (Manage Jenkins -> Configure System).

# ===== Plugin essentials =====
# - Pipeline + Pipeline: Stage View
# - Git + GitHub Branch Source (multi-branch jobs)
# - Credentials + Credentials Binding
# - Blue Ocean (modern UI)
# - JUnit (test result reporting)
# - Docker / Kubernetes (ephemeral agents)

# ===== Multi-branch pipelines =====
# Auto-discover branches + PRs; build each on its own Jenkinsfile.
# 'GitHub Organization' job scans an entire org.

# ===== When Jenkins wins =====
# - You self-host CI and need flexibility
# - Complex matrices, agents on diverse OS / hardware
# - On-prem secrets that should not leave your network
# - Heavy plugin ecosystem

# ===== When Jenkins hurts =====
# - Tiny team without Jenkins ops experience
# - Public OSS projects (use GitHub Actions / GitLab CI; cheaper + less admin)
# - Plugin churn / upgrades (manage them deliberately)

# ===== Patterns to internalise =====
# - Pipeline as code (Jenkinsfile in the repo)
# - Multi-branch pipelines + GitHub webhooks
# - Ephemeral agents (Docker / Kubernetes)
# - JUnit + coverage reports as first-class outputs

# ===== Pitfalls =====
# - Click-ops in the UI -> not versioned, drifts from repo
# - Long-running agent VMs with leftover state
# - Plugin sprawl + skipped upgrades -> security debt
# - Secrets in env vars logged accidentally (use withCredentials masking)

Why it matters

Jenkins repays the operational tax with flexibility nothing else matches. Declarative Jenkinsfile in the repo, multi-branch pipelines, ephemeral agents, credentials in the vault — keep these as the floor and Jenkins ages gracefully across team and project change.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Jenkinsfile
pipeline {
    agent any
    stages {
        stage('Test')   { steps { sh 'npm ci && npm test' } }
        stage('Build')  { steps { sh 'npm run build' } }
        stage('Deploy') { steps { sh './deploy.sh' } }
    }
}
Try it Yourself »

Discussion

Loading…