Jenkinsfile 是 CI/CD 流水线的“代码化配置文件”。 把构建、测试、发布流程写进仓库后,流水线就可以版本化、可复用、可审计。
1. Jenkinsfile 基本语法
1.1. Pipeline 的定义方式
Pipeline 通常有 3 种维护方式:
- 在 Blue Ocean 中可视化创建。
- 在 Jenkins 经典 UI 中直接配置脚本。
- 在代码仓库中维护
Jenkinsfile(推荐)。
最常见的是第 3 种:和代码一起评审、一起发布。
1.2. 一个最小可运行的声明式 Pipeline
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| pipeline { agent any
environment { APP_NAME = "demo-app" }
parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '部署环境') booleanParam(name: 'RUN_TEST', defaultValue: true, description: '是否执行测试') choice(name: 'REGION', choices: ['cn', 'eu', 'us'], description: '部署区域') }
stages { stage('Build') { steps { sh 'echo "building ${APP_NAME}"' } } stage('Test') { when { expression { return params.RUN_TEST } } steps { sh 'echo "running test..."' } } } }
|
2. 常用指令说明
2.1. agent
用于指定在哪个执行节点运行任务。
常见写法:
或按标签指定:
1
| agent { label 'linux-docker' }
|
2.2. environment
可全局定义,也可在某个 stage 内定义(仅该阶段生效):
1 2 3
| environment { BUILD_TS = "${new Date().format('yyyyMMddHHmmss')}" }
|
2.3. parameters
参数通过 params 对象读取,适合控制分支行为,例如“是否发布”“发布环境”等。
3. 触发器(以 Gerrit 为例)
如果你使用 Gerrit,可以通过 Gerrit Trigger 插件触发 Jenkins 构建。
常见事件包括:Patchset Created、Change Merged、Comment Added。
你原文中的触发器示意图仍可保留:

在 Jenkinsfile 中也可以声明触发器配置(会覆盖部分 Job UI 配置):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| triggers { gerrit( gerritProjects: [[ compareType: 'PLAIN', pattern: 'repo-name', branches: [[compareType: 'PLAIN', pattern: 'master']] ]], serverName: 'gerrit-server', triggerOnEvents: [ patchsetCreated(excludeDrafts: true), changeMerged() ] ) }
|
4. 共享库与模块化
复杂流水线建议用 Shared Library,避免把所有逻辑都堆进一个 Jenkinsfile。
1
| @Library(['ci-lib@main']) _
|
典型做法:
- Jenkinsfile 只负责“流程编排”。
- 业务构建、测试、部署逻辑沉淀到共享库方法。
- 通过参数或配置 Map 做差异化。
5. 参数化构建实践(Map/List)
对于多镜像构建、多测试用例场景,常用 List/Map 组织配置:
1 2 3 4 5 6 7 8 9
| def builds = [ [name: 'backend', agent: 'docker', command: 'ci/build-backend.sh'], [name: 'frontend', agent: 'docker', command: 'ci/build-frontend.sh'] ]
def tests = [ [name: 'unit-test', command: 'ci/test-unit.sh', timeout: 20], [name: 'e2e-test', command: 'ci/test-e2e.sh', timeout: 30] ]
|
这样可以通过循环统一执行,减少重复代码。
6. 通知与失败处理
通知建议做成独立配置,按事件触发:
- 主分支失败通知。
- 主分支成功通知(可选)。
- Tag 发布成功/失败通知。
通知通道通常是:
- 邮件。
- Teams/Yammer/Slack Webhook。
同时建议在 post 块统一做收尾(日志采集、清理资源):
1 2 3 4 5 6 7 8 9
| post { always { sh 'ci/collect-logs.sh || true' sh 'ci/cleanup.sh || true' } failure { echo 'Build failed, send notification...' } }
|
7. 环境变量落盘与脚本解耦
实践中常把关键变量输出到 env_vars 文件,再由部署/测试脚本 source 使用。
这样脚本与 Jenkins DSL 之间更解耦,也更便于本地排查。
例如:
1 2 3 4
| HELM_NAME="demo-123-main" NAMESPACE="staging" BUILD_ID="123" BRANCH_NAME="main"
|
8. 一份更完整的 Jenkinsfile 模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @Library(['ci-lib@main']) _
pipeline { agent { label 'linux-docker' }
parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '部署环境') booleanParam(name: 'PUBLISH_IMAGE', defaultValue: false, description: '是否发布镜像') }
stages { stage('Build') { steps { sh 'ci/build.sh' } } stage('Test') { steps { sh 'ci/test.sh' } } stage('Deploy') { when { expression { return params.DEPLOY_ENV == 'prod' } } steps { sh 'ci/deploy.sh' } } }
post { always { sh 'ci/collect-logs.sh || true' sh 'ci/cleanup.sh || true' } } }
|
9. 小结
写 Jenkinsfile 的核心思路是:
- 用声明式语法把流程分层(参数、环境、阶段、收尾)。
- 用共享库和配置化数据(Map/List)减少重复。
- 把触发器、通知、日志清理纳入统一治理。
做到这三点,流水线会更稳定,也更容易被团队协作维护。