I have a Jenkins pipeline which has multiple stages, for example:
node("nodename") { stage("Checkout") { git .... } stage("Check Preconditions") { ... if(!continueBuild) { // What do I put here? currentBuild.xxx ? } } stage("Do a lot of work") { .... } }
I want to be able to cancel (not fail) the build if certain preconditions are not met and there is no actual work to be done. How can I do this? I know the currentBuild
variable is available, but I can't find the documentation for it.
Pipeline jobs can be stopped by sending an HTTP POST request to URL endpoints of a build. BUILD ID URL/stop - aborts a Pipeline. BUILD ID URL/term - forcibly terminates a build (should only be used if stop does not work).
While build #1 is running, if build #2 is started, it will create milestone1 and milestone2 in the project. Build #2 will immediately pass milestone1 and will therefore cause Build #1 to abort.
You can mark the build as ABORTED, and then use the error step to cause the build to stop: if (! continueBuild) { currentBuild. result = 'ABORTED' error('Stopping early…') }
You can mark the build as ABORTED, and then use the error
step to cause the build to stop:
if (!continueBuild) { currentBuild.result = 'ABORTED' error('Stopping early…') }
In the Stage View, this will show that the build stopped at this stage, but the build overall will be marked as aborted, rather than failed (see the grey icon for build #9):
After some testing I came up with the following solution:
def autoCancelled = false try { stage('checkout') { ... if (your condition) { autoCancelled = true error('Aborting the build to prevent a loop.') } } } catch (e) { if (autoCancelled) { currentBuild.result = 'ABORTED' echo('Skipping mail notification') // return here instead of throwing error to keep the build "green" return } // normal error handling throw e }
This will result into following stage view:
If you don't like the failed stage, you have to use return. But be aware you have to skip each stage or wrapper.
def autoCancelled = false try { stage('checkout') { ... if (your condition) { autoCancelled = true return } } if (autoCancelled) { error('Aborting the build to prevent a loop.') // return would be also possible but you have to be sure to quit all stages and wrapper properly // return } } catch (e) { if (autoCancelled) { currentBuild.result = 'ABORTED' echo('Skipping mail notification') // return here instead of throwing error to keep the build "green" return } // normal error handling throw e }
The result:
You can also use a custom message instead of a local variable:
final autoCancelledError = 'autoCancelled' try { stage('checkout') { ... if (your condition) { echo('Aborting the build to prevent a loop.') error(autoCancelledError) } } } catch (e) { if (e.message == autoCancelledError) { currentBuild.result = 'ABORTED' echo('Skipping mail notification') // return here instead of throwing error to keep the build "green" return } // normal error handling throw e }
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