Jenkins Pipeline 声明式语法

FreeGuideOnline 最新 2026-07-10

groovy pipeline { agent any stages { stage('Build') { steps { echo 'Building..' } } } }


以上代码定义了一个最简单的 Pipeline:在任何可用代理(agent)上执行一个名为 “Build” 的阶段,其中只包含一个打印文本的步骤。

## 顶级指令详解

声明式 Pipeline 允许在 `pipeline` 块中使用一系列指令来控制整体行为。

### agent

`agent` 指定整个 Pipeline 或特定阶段在哪个节点上执行。它必须位于 `pipeline` 块内的顶层,或者在 `stage` 内部。常用参数包括:

- `any`:在任何可用的代理上执行。
- `none`:不在全局指定代理,后续各 `stage` 必须各自定义自己的 `agent`。
- `label`:在指定标签的节点上执行,如 `agent { label 'linux' }`。
- `docker`:在 Docker 容器中执行,例如:
  ```groovy
  agent {
      docker {
          image 'node:16-alpine'
          args '-v /tmp:/tmp'
      }
  }

stages 与 stage

stages 块包含一个或多个 stage,每个 stage 代表流程中的一个阶段,比如“构建”、“测试”、“部署”。stage 的名称(如 stage('Build'))会在 Jenkins 界面上清晰显示,方便追踪进度。

stages {
    stage('Stage 1') {
        steps { ... }
    }
    stage('Stage 2') {
        steps { ... }
    }
}

steps

steps 是每个 stage 内部必须包含的块,它定义该阶段要执行的实际操作。可以使用 Jenkins 内置步骤,如 echoshgit 等。

steps {
    echo '开始编译'
    sh 'mvn clean compile'
}

post

post 块定义了在整个 Pipeline 或某个 stage 执行完毕后需要运行的操作,通常用于清理、通知等。它支持多种条件分支:

  • always:无论结果如何都会执行。
  • success:只有当前构建成功时执行。
  • failure:只有构建失败时执行。
  • unstable:构建结果不稳定时执行。
  • changed:当前构建状态与上一次不同时执行。
post {
    always {
        junit '**/target/surefire-reports/*.xml'
    }
    failure {
        mail to: 'team@example.com', subject: 'Pipeline Failed'
    }
}

environment

environment 指令用于定义环境变量,这些变量可以在所有步骤中通过 env.VAR_NAME${VAR_NAME} 访问。它可以放在 pipeline 顶层(全局有效)或某个 stage 内部(仅该阶段有效)。

pipeline {
    environment {
        APP_NAME = 'my-app'
        DEPLOY_DIR = '/var/www'
    }
    stages {
        stage('Deploy') {
            environment {
                TARGET_ENV = 'production'
            }
            steps {
                sh 'echo "Deploying $APP_NAME to $TARGET_ENV in $DEPLOY_DIR"'
            }
        }
    }
}

options

options 用于设置 Pipeline 级别的选项,如超时时间、保持构建天数、禁止并发构建等。

options {
    timeout(time: 1, unit: 'HOURS')
    buildDiscarder(logRotator(numToKeepStr: '10'))
    disableConcurrentBuilds()
}

parameters

parameters 指令可定义参数化构建中的参数,用户在触发构建时可以输入自定义值。支持类型包括 stringbooleanParamchoice 等。

parameters {
    string(name: 'VERSION', defaultValue: '1.0', description: '版本号')
    booleanParam(name: 'RUN_TESTS', defaultValue: true, description: '是否运行测试')
    choice(name: 'ENV', choices: ['dev', 'staging', 'prod'], description: '部署环境')
}

triggers

triggers 定义了 Pipeline 的自动触发方式,例如定时构建、轮询 SCM 或由上游项目触发。

triggers {
    cron('H 4 * * 1-5')   // 周一到周五凌晨4点左右构建
    pollSCM('* * * * *')  // 每分钟检查版本库变化
}

tools

tools 用于自动安装并配置构建工具,要求 Jenkins 已安装对应工具的配置。它可在 pipeline 顶层或 stage 内使用。

tools {
    maven 'Maven-3.8.6'    // 引用的工具名称需在 Jenkins 全局工具配置中定义
    jdk 'JDK11'
}

when

when 指令允许阶段在特定条件满足时才执行,这是实现智能流程控制的重要手段。它必须放在 stage 块内部,steps 之前。常用条件包括 branchenvironmentexpression 等。

stage('Deploy to Production') {
    when {
        branch 'main'
        environment name: 'DEPLOY_TO_PROD', value: 'true'
    }
    steps {
        sh 'ansible-playbook deploy.yml'
    }
}

进阶功能与内置步骤

并行执行

声明式 Pipeline 支持在同一个阶段内并行运行多个子阶段,只需在 stage 下使用 parallel 块。

stage('Run Tests') {
    parallel {
        stage('Unit Tests') {
            steps { sh 'npm run test:unit' }
        }
        stage('Integration Tests') {
            steps { sh 'npm run test:integration' }
        }
    }
}

凭据与敏感信息处理

通过 credentials() 助手方法可以安全地引用 Jenkins 中存储的凭据,避免在脚本中硬编码密码。

environment {
    DB_PWD = credentials('database-password')
}
steps {
    sh 'echo "Connecting with password $DB_PWD"'
}

代码拉取

最常用的步骤是 git,它会根据 SCM 配置拉取源代码。通常放在第一个阶段:

stage('Checkout') {
    steps {
        git url: 'https://github.com/user/repo.git', branch: 'main'
    }
}

共享库

当多个 Pipeline 存在重复逻辑时,可以将 Groovy 函数封装为“共享库”,并在声明式 Pipeline 中通过 @Library 注解引入,或直接在 libraries 指令中配置。

@Library('my-shared-library@v1.0') _
pipeline {
    // ...
    steps {
        myCustomStep(arg1: 'value')
    }
}

编写最佳实践

  • 保持 Jenkinsfile 精简:将复杂逻辑封装到 Shell 脚本或工具中,避免 Groovy 代码过度膨胀。
  • 遵循阶段语义:一个阶段只做一件事,如“编译”、“测试”、“构建镜像”、“部署”,便于快速定位问题。
  • 使用 when 条件而非硬编码分支判断:让流程根据分支、标签、参数自动调整行为。
  • 善用 post 处理资源清理和通知:确保无论成功失败都能归档报告或发送通知。
  • 对耗时的步骤设置超时:通过 stageoptions 或在步骤中使用 timeout 包装,避免构建挂起。

完整示例:一个典型的 CI/CD Pipeline

下面展示一个使用声明式语法构建 Java 应用的完整 Pipeline,涵盖代码拉取、编译、测试、镜像构建和部署通知。

pipeline {
    agent any

    environment {
        REGISTRY = 'docker.io'
        IMAGE = "$REGISTRY/myorg/myapp"
    }

    tools {
        maven 'Maven-3.8.6'
        jdk 'JDK11'
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/myorg/myapp.git'
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }

        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }

        stage('Containerize') {
            when {
                branch 'main'
            }
            steps {
                sh "docker build -t $IMAGE:${env.BUILD_ID} ."
                sh "docker push $IMAGE:${env.BUILD_ID}"
            }
        }

        stage('Deploy to Staging') {
            when {
                branch 'main'
            }
            steps {
                sh "kubectl set image deployment/myapp myapp=$IMAGE:${env.BUILD_ID}"
            }
        }
    }

    post {
        success {
            emailext body: '构建成功!', subject: 'CI Pipeline Passed', to: 'devs@example.com'
        }
        failure {
            emailext body: '构建失败,请检查日志。', subject: 'CI Pipeline Failed', to: 'devops@example.com'
        }
    }
}