My pipeline setup is as follows.
I need to get it working with adherence to following conditions. Help me defining when blocks and other code to be used and in which stages?
What have I tried & observed? From above conditions defined, 1 and 2 are working as expected but not 3 and 4 with my following attempt.
In C1 and C2, I added catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE')
referring to Continue Jenkins pipeline past failed stage.
But what I have observed is -
This is what you need:
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}")
}
}
}
}
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE')
to mark both the stage and build results as FAILURE but continue pipeline execution.
stageResultMap = [:]
at the top of your Jenkinsfile to capture the results of each stage. Now, for every Bn
stage, use a try-catch
block so that on success a unique key-value pair stageResultsMap.didBnSucceed = true
is added to the map, and on exception the stage result is set to UNSTABLE, build result to FAILURE, and stageResultsMap.didBnSucceed = false
. We use the method unstable
here because none of the other two methods catchError
or warnError
let us add to the map. Then, in the corresponding Cn stage, evaluate the map and execute only if Bn did succeed. Also, if both B1 and B2 fail, i.e., both C1 and C2 do not execute, D wouldn't execute either because when {expression {return stageResultMap.any {it.value}}}
will evaluate to false
. But D will execute if either C1 or C2 executed regardless of failures.
In both the above scenarios, the overall build status will be marked as FAILURE if any of the stages fail.
Of course, a green build on no failures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With