基于声明性管道中前一阶段结果的条件执行
Conditional execution based on result of previous stage in declarative pipeline
我的管道设置如下。
我需要让它在遵守以下条件的情况下工作。帮我定义何时使用块和其他代码以及在哪个阶段使用?
- 如果 A 失败,则不会执行其他阶段并且作业 运行 被标记为失败。
- 如果任何一个B阶段失败,则不应调用相应的C阶段。
- 阶段 D 应该在 C1 或 C2 已执行时执行,无论执行失败如何。
- 此外,如果任何阶段失败,则总体作业 运行 状态应为失败。
我尝试并观察到了什么?
从上面定义的条件来看,1 和 2 按预期工作,但在我接下来的尝试中 3 和 4 没有。
在C1和C2中,我添加了catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE')
参考Continue Jenkins pipeline past failed stage。
但是我观察到的是-
- D 在 C1 或 C2 失败时执行,但总的来说 运行 标记为成功。预期失败,因为 C 步骤之一失败。但由于捕获它获得成功状态。
- 当任何 B 阶段失败时,它们对应的 C 也不会执行(预期)但它也不会触发 D。因为我需要触发 D,因为其他一些 C 已被执行。
这就是你需要的:
stageResultMap = [:]
pipeline {
agent any
stages {
stage('A') {
steps {
println("This is stage: ${STAGE_NAME}")
}
}
stage('BC') {
parallel {
stage ('1'){
stages {
stage('B1') {
steps {
script {
// Catch exceptions, set the stage result as unstable,
// build result as failure, and the variable didB1Succeed to false
try {
sh "exit 1"
stageResultMap.didB1Succeed = true
}
catch (Exception e) {
unstable("${STAGE_NAME} failed!")
currentBuild.result = 'FAILURE'
stageResultMap.didB1Succeed = false
}
}
}
}
stage('C1') {
// Execute only if B1 succeeded
when {
expression {
return stageResultMap.find{ it.key == "didB1Succeed" }?.value
}
}
steps {
// Mark the stage and build results as failure on error but continue pipeline execution
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo Hello"
}
}
}
}
}
stage ('2'){
stages {
stage('B2') {
steps {
script {
// Catch exceptions, set the stage result as unstable,
// build result as failure, and the variable didB2Succeed to false
try {
sh "echo Hello"
stageResultMap.didB2Succeed = true
}
catch (Exception e) {
unstable("${STAGE_NAME} failed!")
currentBuild.result = 'FAILURE'
stageResultMap.didB2Succeed = false
}
}
}
}
stage('C2') {
// Execute only if B2 succeeded
when {
expression {
return stageResultMap.find{ it.key == "didB2Succeed" }?.value
}
}
steps {
// Mark the stage and build results as failure on error but continue pipeline execution
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo Hello"
}
}
}
}
}
}
}
stage('D') {
// Execute only when C1 or C2 have executed, that is B1 or B2 have succeeded
when {
expression {
return stageResultMap.any {it.value}
}
}
steps {
println("This is stage: ${STAGE_NAME}")
}
}
}
}
- 对于阶段 C1 和 C2,使用
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE')
将阶段和构建结果都标记为“失败”但继续执行管道。
- 对于阶段 B1 和 B2,首先在 Jenkinsfile 的顶部初始化一个空映射
stageResultMap = [:]
以捕获每个阶段的结果。现在,对于每个 Bn
阶段,使用一个 try-catch
块,以便在成功时将唯一的键值对 stageResultsMap.didBnSucceed = true
添加到映射中,并且在异常情况下阶段结果设置为 UNSTABLE ,构建结果为 FAILURE,并且 stageResultsMap.didBnSucceed = false
。我们在这里使用方法 unstable
因为其他两种方法 catchError
或 warnError
的 none 让我们添加到地图。然后,在相应的 Cn 阶段,评估 map 并仅在 Bn 确实成功时才执行。此外,如果 B1 和 B2 均失败,即 C1 和 C2 均未执行,则 D 也不会执行,因为 when {expression {return stageResultMap.any {it.value}}}
的计算结果为 false
。但是无论失败,如果 C1 或 C2 执行,D 都会执行。
在上述两种情况下,如果任何阶段失败,整体构建状态将被标记为 FAILURE。
当然,在没有失败的情况下构建绿色。
我的管道设置如下。
我需要让它在遵守以下条件的情况下工作。帮我定义何时使用块和其他代码以及在哪个阶段使用?
- 如果 A 失败,则不会执行其他阶段并且作业 运行 被标记为失败。
- 如果任何一个B阶段失败,则不应调用相应的C阶段。
- 阶段 D 应该在 C1 或 C2 已执行时执行,无论执行失败如何。
- 此外,如果任何阶段失败,则总体作业 运行 状态应为失败。
我尝试并观察到了什么? 从上面定义的条件来看,1 和 2 按预期工作,但在我接下来的尝试中 3 和 4 没有。
在C1和C2中,我添加了catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE')
参考Continue Jenkins pipeline past failed stage。
但是我观察到的是-
- D 在 C1 或 C2 失败时执行,但总的来说 运行 标记为成功。预期失败,因为 C 步骤之一失败。但由于捕获它获得成功状态。
- 当任何 B 阶段失败时,它们对应的 C 也不会执行(预期)但它也不会触发 D。因为我需要触发 D,因为其他一些 C 已被执行。
这就是你需要的:
stageResultMap = [:]
pipeline {
agent any
stages {
stage('A') {
steps {
println("This is stage: ${STAGE_NAME}")
}
}
stage('BC') {
parallel {
stage ('1'){
stages {
stage('B1') {
steps {
script {
// Catch exceptions, set the stage result as unstable,
// build result as failure, and the variable didB1Succeed to false
try {
sh "exit 1"
stageResultMap.didB1Succeed = true
}
catch (Exception e) {
unstable("${STAGE_NAME} failed!")
currentBuild.result = 'FAILURE'
stageResultMap.didB1Succeed = false
}
}
}
}
stage('C1') {
// Execute only if B1 succeeded
when {
expression {
return stageResultMap.find{ it.key == "didB1Succeed" }?.value
}
}
steps {
// Mark the stage and build results as failure on error but continue pipeline execution
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo Hello"
}
}
}
}
}
stage ('2'){
stages {
stage('B2') {
steps {
script {
// Catch exceptions, set the stage result as unstable,
// build result as failure, and the variable didB2Succeed to false
try {
sh "echo Hello"
stageResultMap.didB2Succeed = true
}
catch (Exception e) {
unstable("${STAGE_NAME} failed!")
currentBuild.result = 'FAILURE'
stageResultMap.didB2Succeed = false
}
}
}
}
stage('C2') {
// Execute only if B2 succeeded
when {
expression {
return stageResultMap.find{ it.key == "didB2Succeed" }?.value
}
}
steps {
// Mark the stage and build results as failure on error but continue pipeline execution
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo Hello"
}
}
}
}
}
}
}
stage('D') {
// Execute only when C1 or C2 have executed, that is B1 or B2 have succeeded
when {
expression {
return stageResultMap.any {it.value}
}
}
steps {
println("This is stage: ${STAGE_NAME}")
}
}
}
}
- 对于阶段 C1 和 C2,使用
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE')
将阶段和构建结果都标记为“失败”但继续执行管道。
- 对于阶段 B1 和 B2,首先在 Jenkinsfile 的顶部初始化一个空映射
stageResultMap = [:]
以捕获每个阶段的结果。现在,对于每个Bn
阶段,使用一个try-catch
块,以便在成功时将唯一的键值对stageResultsMap.didBnSucceed = true
添加到映射中,并且在异常情况下阶段结果设置为 UNSTABLE ,构建结果为 FAILURE,并且stageResultsMap.didBnSucceed = false
。我们在这里使用方法unstable
因为其他两种方法catchError
或warnError
的 none 让我们添加到地图。然后,在相应的 Cn 阶段,评估 map 并仅在 Bn 确实成功时才执行。此外,如果 B1 和 B2 均失败,即 C1 和 C2 均未执行,则 D 也不会执行,因为when {expression {return stageResultMap.any {it.value}}}
的计算结果为false
。但是无论失败,如果 C1 或 C2 执行,D 都会执行。
在上述两种情况下,如果任何阶段失败,整体构建状态将被标记为 FAILURE。
当然,在没有失败的情况下构建绿色。