Jenkins

Last update: 2023-09-13 18:46:33 +0800 +0800
tags: Ci-Cd | Jenkins
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Jenkins coordinates delivery work as jobs and Pipelines. Store a Pipeline in a versioned Jenkinsfile because build logic, application code, and tool versions must change under the same review process.

Controller, Agents, and Workspaces #

The controller stores configuration and build records, evaluates scheduling decisions, serves the user interface, and coordinates agents. Builds should not run on the controller. An agent supplies one or more executors; each executor can occupy one Pipeline task at a time. Labels describe capabilities such as linux, arm64, or docker, and a Pipeline’s agent selection constrains where its workspace is allocated.

A workspace is mutable checkout and build state, not an artifact repository. Concurrent builds can receive distinct workspace paths, and an ephemeral agent can disappear after a stage. Publish outputs with archiveArtifacts, transfer small files between stages with stash and unstash, or upload release artifacts to a dedicated repository. Do not rely on files left by a previous build.

Agents should have only the tools, network paths, and credentials required by their labels. Ephemeral agents reduce cross-build contamination, but reproducible builds still require pinned container images, toolchains, plugins, and dependency inputs.

Declarative and Scripted Pipelines #

Declarative Pipeline provides a validated structure around pipeline, agent, stages, steps, environment, options, and post. Scripted Pipeline uses Groovy control flow inside node and other Pipeline steps. Declarative script { ... } can contain an imperative section, but large scripted regions discard declarative validation and stage semantics. Put reusable policy in a versioned Shared Library rather than copying Groovy between repositories.

groovy
pipeline {
  agent { label 'linux && container' }
  options {
    timeout(time: 20, unit: 'MINUTES')
    disableConcurrentBuilds()
  }
  stages {
    stage('Test') {
      steps {
        retry(2) {
          sh './mvnw --batch-mode verify'
        }
      }
      post {
        always { junit 'target/surefire-reports/*.xml' }
      }
    }
    stage('Package') {
      steps {
        sh './mvnw --batch-mode package -DskipTests'
        archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
      }
    }
  }
  post {
    always { deleteDir() }
  }
}

Pipeline steps persist execution state so a durable task can survive controller restarts, but external commands must remain restart-safe. Use timeout to bound stalled work and retry only for operations known to be idempotent. Deployment retries can duplicate side effects. parallel reduces latency when branches do not mutate the same workspace or external resource; use separate workspaces or agents when isolation is required.

Credentials and Least Privilege #

Store secrets in Jenkins credentials and bind them for the smallest possible scope:

groovy
withCredentials([file(credentialsId: 'registry-token-file',
                      variable: 'REGISTRY_TOKEN_FILE')]) {
  sh 'registry-client --token-file "$REGISTRY_TOKEN_FILE"'
}

Masking reduces accidental log disclosure; it cannot protect a secret from untrusted build code running in the same scope. Avoid Groovy interpolation of string secrets because the value can enter process arguments or Jenkins-generated scripts before masking. File credentials supply a temporary protected file, but untrusted code in the same build context can still read it. Restrict credential IDs by folder, isolate untrusted pull requests from deployment jobs, and grant agents short-lived credentials for one environment.

Operating the Pipeline #

Use multibranch jobs or trusted webhooks to associate execution with an exact commit. Preserve test reports and immutable artifacts according to a retention policy. Configure post actions for cleanup and notifications even when a stage fails. Protect the controller with authentication and authorization, review plugin updates as controller code, back up JENKINS_HOME, and keep build agents outside the controller’s trust boundary.

Comments

Read or comment on GitHub (sign-in required to comment)