post 与 when:收尾动作与阶段执行条件
May 25, 2024About 2 min
post 与 when:收尾动作与阶段执行条件
post 管「这条 Pipeline / 这个 stage 跑完之后做什么」,when 管「这个 stage 要不要跑」。两个都是声明式 Pipeline 里高频用到的指令。
post:按完成状态执行收尾步骤
post 定义 Pipeline 或 stage 完成后的附加步骤,放哪个层级就对哪个层级生效。它支持一组按完成状态触发的条件块,执行顺序如下:
| 条件 | 何时执行 |
|---|---|
always | 无论结果如何都执行 |
changed | 本次完成状态与上次不同 |
fixed | 上次失败/不稳定,本次成功 |
regression | 上次成功,本次失败/不稳定/中止 |
aborted | 本次被中止(一般是人为) |
failure | 本次失败 |
success | 本次成功 |
unstable | 本次不稳定(测试失败、代码规范问题等) |
unsuccessful | 本次结果不是 success |
cleanup | 在以上所有条件块都求值完之后执行,无视结果 |
pipeline {
agent any
stages {
stage('Example') {
steps { echo 'Hello World' }
// 可以挂在某个 stage 内
post {
always { echo "stage post always" }
}
}
}
// 也可以挂在 stages 外,作用于整条 Pipeline
post {
changed { echo 'pipeline post changed' }
success { echo 'pipeline post success' }
failure { echo 'pipeline post failure' }
}
}
changed、fixed、regression 这几个状态特别适合做通知:只在「构建状态发生翻转」时发邮件,而不是每次构建都骚扰一遍。
when:决定 stage 是否执行
when 让 Pipeline 根据条件决定要不要执行某个 stage,至少要含一个条件。写多个条件时默认是「全部为真才执行」(等价于嵌进 allOf);用 anyOf 时,一旦命中第一个为真的条件就跳过后面的判断。
// branch:仓库分支为指定分支
when { branch 'master' }
// changelog:提交记录匹配正则
when { changelog '.*^\\[DEPENDENCY\\] .+$' }
// changeset:变更文件匹配正则(ANT 风格 glob,默认大小写不敏感)
when { changeset '**/*.js' }
when { changeset pattern: "*/*TEST.java", caseSensitive: true }
// environment:环境变量等于给定值
when { environment name: 'DEPLOY_TO', value: 'production' }
// equals:期望值等于实际值
when { equals expected: 2, actual: currentBuild.number }
// expression:Groovy 表达式返回 true
when { expression { return params.DEBUG_BUILD } }
// buildingTag:本次构建的代码打了 tag
when { buildingTag() }
// tag:打了 tag 且 tag 名匹配规则;tag() 不带参数等价于 buildingTag()
when { tag "release-*" }
// allOf:所有条件都满足
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
// anyOf:任一条件满足
when { anyOf { branch 'master'; branch 'staging' } }
// triggeredBy:由指定触发源触发
when { triggeredBy 'SCMTrigger' }
when { triggeredBy 'TimerTrigger' }
when { triggeredBy 'UpstreamCause' }
when { triggeredBy cause: "UserIdCause", detail: "someuser" }
triggeredBy 有个容易踩的点:若同时存在多种触发方式,每一种实际生效的触发源都会判为 true。比如一次构建既由上游触发又由用户触发,那么 triggeredBy 'UpstreamCause' 和 triggeredBy 'UserIdCause' 都是 true,而没参与的 triggeredBy 'SCMTrigger' 是 false;写成 not { triggeredBy 'UpstreamCause' } 则为 false。
配合 agent 一节提到的 beforeAgent true,可以在判断 when 为真之前不去占用节点,省掉无谓的排队。