跳到主要内容

声明式流水线基础

Jenkins 支持两种流水线语法:声明式(Declarative)和脚本式(Scripted)。声明式结构清晰、适合团队协作和代码评审,是生产首选。脚本式更灵活但难以维护,仅适合高级场景。

本篇目标:能读懂并写出结构完整的声明式 Jenkinsfile,理解 agent、stages、environment、post 等核心块。


1. 声明式 vs 脚本式​

维度声明式脚本式
语法结构化(类似 YAML 的 Groovy DSL)纯 Groovy 脚本
上手难度低高
可读性 / 评审好差
灵活性有约束(利于规范)自由(可任意写代码)
推荐场景生产流水线需要动态逻辑的复杂场景
// 声明式:结构固定
pipeline {
agent any
stages {
stage('Build') { steps { ... } }
}
}

// 脚本式:自由编程
node {
stage('Build') { ... }
}

2. 一个最小可运行模板​

pipeline {
agent any

environment {
APP_NAME = 'backend-service'
REGISTRY = 'registry.company.com'
}

options {
timestamps() // 日志加时间戳
timeout(time: 30, unit: 'MINUTES') // 整条流水线超时
buildDiscarder(logRotator(numToKeepStr: '20')) // 只保留最近 20 次构建
}

stages {
stage('拉取代码') {
steps {
checkout scm
}
}
stage('编译打包') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('归档产物') {
steps {
archiveArtifacts artifacts: 'target/*.jar'
}
}
}

post {
always {
cleanWs() // 清理 Workspace
}
success {
echo "✅ ${APP_NAME} 构建成功"
}
failure {
echo "❌ ${APP_NAME} 构建失败"
}
}
}

2.1 post 区块​

post 按构建结果执行收尾动作:

条件触发时机
always无论结果如何
success构建成功
failure构建失败
unstable构建不稳定(如测试失败但未挂)
aborted被取消
changed结果与上一次不同
post {
always { cleanWs() }
success { notifySuccess() }
failure { notifyFailure() }
}
cleanWs() 会删除整个 Workspace

cleanWs() 清空当前 Agent 的 Workspace,避免磁盘累积,但不要依赖它保存跨构建数据。需要保留的产物用 archiveArtifacts 归档到 Master,或上传到制品仓库。

3. agent:在哪运行​

写法含义
agent any任何可用节点(最简单,不推荐生产)
agent { label 'linux' }指定带该标签的节点
agent { docker { image 'maven:3.9-eclipse-temurin-17' } }在 Docker 容器中运行
agent { kubernetes { ... } }在 K8s 动态 Pod 中运行(见第 10 篇)
agent none顶层不指定,各 stage 单独指定
// 按 stage 指定不同环境
pipeline {
agent none
stages {
stage('Java 编译') {
agent { docker { image 'maven:3.9-eclipse-temurin-17' } }
steps { sh 'mvn package' }
}
stage('部署') {
agent { label 'k8s-deploy' }
steps { sh 'kubectl apply -f deploy/' }
}
}
}

4. environment:环境变量​

pipeline {
environment {
// 静态值
APP_ENV = 'prod'
// 引用 Jenkins 凭证(见第 4 篇)
DOCKER_CREDS = credentials('harbor-registry-auth')
// 引用其他环境变量
IMAGE = "${REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
}
}

内置变量速查:

变量含义
${BUILD_NUMBER}构建序号
${BUILD_URL}本次构建的链接
${JOB_NAME}Job 全名(含文件夹路径)
${WORKSPACE}构建工作目录
${GIT_COMMIT}Git 提交 SHA
${GIT_BRANCH}分支名(部分 SCM)

5. 常见错误与排障​

现象原因与处理
No such DSL method 'sh'steps 块内才能写步骤,sh 用错层级
script not permittedGroovy 沙箱拦截,需在 Manage Jenkins → In-process Script Approval 批准
agent any 一直排队无可用 Executor,检查 Agent 是否离线
变量为空环境变量定义在 steps 之后,或作用域(stage 内)不对
用 echo 和 options 调试

调试流水线时,用 echo 打印关键变量、用 options { timestamps() } 加时间戳定位卡点。先小步验证,再补完整流程。


6. 练习与验收​

练习 A

  1. 新建 Pipeline Job,粘贴本模板,跑通"编译 → 归档 → 清理"全流程
  2. 在 post 中分别写 success / failure,故意让一条命令失败,观察 failure 块执行
  3. 用 options { timestamps() } 确认日志带时间戳

练习 B

  1. 用 environment 定义 IMAGE 变量,在 echo 中输出
  2. 给不同 stage 配不同 agent(用 agent none + 各 stage 指定)
  3. 触发一次沙箱拦截(如在 steps 中定义变量),体验 In-process Script Approval

验收清单

  • 能写出结构完整的声明式 Jenkinsfile
  • 理解 agent 的几种写法与作用域
  • 会用 environment 管理变量,引用凭证
  • 会用 post 的 always/success/failure 做收尾
  • 知道 cleanWs() 与 archiveArtifacts 的分工
  • 能处理常见沙箱 / 变量 / 排队错误

下一篇:声明式流水线进阶。