How to exit from the Jenkins pipeline if a stage sets build fail/unstable status?
Solution 1
The easiest way to skip remaining pipeline stages is to set up a variable which will control if following stages should be skipped or not. Something like this:
def skipRemainingStages = false
pipeline {
agent any
stages {
stage("Stage 1") {
steps {
script {
skipRemainingStages = true
println "skipRemainingStages = ${skipRemainingStages}"
}
}
}
stage("Stage 2") {
when {
expression {
!skipRemainingStages
}
}
steps {
script {
println "This text wont show up...."
}
}
}
stage("Stage 3") {
when {
expression {
!skipRemainingStages
}
}
steps {
script {
println "This text wont show up...."
}
}
}
}
}
This is very simple example that sets skipRemainingStages
to true at Stage 1
and Stage 2
and Stage 3
get skipped because expression in the when
block does not evaluates to true.
Alternatively you can call error(String message)
step to stop the pipeline and set its status to FAILED
. For example, if your stage 1 calls error(msg)
step like:
stage("Stage 1") {
steps {
script {
error "This pipeline stops here!"
}
}
}
In this case pipeline stops whenever error(msg)
step is found and all remaining stages are ignored (when
blocks are not even checked).
Of course you can call error(msg)
depending on some condition to make it FAILED
only if specific conditions are met.
Solution 2
You can use post in a stage to exit as follows:
pipeline {
stages {
stage('stage 1') {
steps {
//step 1
}
}
stage('stage 2') {
steps {
script{
//step 2
}
}
post{
success {
}
failure {
script{
sh "exit 1"
//or
error "Failed, exiting now..."
}
}
aborted {
}
unstable {
script{
sh "exit 1"
//or
error "Unstable, exiting now..."
}
}
}
}
}
}
This will abort the build and job wouldn't run further.
Solution 3
You can also simply throw an Exception. That will abort the build. In fact simply setting the build status in a catch clause works pretty well. You can also then add custom logic in the finally block for sending notifications for build status changes (email, Slack message etc)
So perhaps something like the following. NOTE: I have copied some of this from an existing Jenkinsfile. So not 100% sure this is the same syntax as you were using:
pipeline {
try {
stages {
stage("stage1") {
if (something) {
throw new RuntimeException("Something went wrong")
}
}
stage("stage2") {
}
}
} catch (e) {
currentBuild.result = "FAILED"
throw e
}
}
user6348718
Updated on July 21, 2020Comments
-
user6348718 almost 4 years
I have a declarative Jenkins pipeline with
stage1
,stage2
,stage3
and so on. I want to stopstage2
from running ifstage1
sets the build unstable/fail.I know I can stop the steps in
stage1
from running usingreturn
when the build is not success but couldn't find a way where I can just exit the pipeline without running the stages belowstage1
Here is what I have:
stage('stage1') { steps { script{ //somesteps if ("${stdout}" == "1"){ currentBuild.result = 'UNSTABLE' return } //if //somesteps } //script } //steps } //stage // run only when stage1 is success stage('stage2'){ when { expression { params.name ==~ /x|y/ } } steps { script{ //stage2 steps } } }
If
params.name ==~ /z/
stage 3 will be executed skippping stage2Note: I cannot include the steps in stage2/3/.. in stage1. It should be that way. Based on the build paramters stage2/3/4... will be called after stage1