How do I skip a stage in a scripted pipeline?

I have found two ways of skipping a stage in the scripted pipeline altough both dont work for me even if the code inside of the conditions is being ran. Obviously i want to skip the stage instead of not creating/failing it to keep a nice visbility in the UI.

No script approvals popup or anything

The problem with these methods is that they skip the stage in the UI but the do not actually skip real execution of the rest of the stage. So for now the workaround is to work with if and else statements

        catchError(catchInterruptions: false, buildResult: null, stageResult: 'NOT_BUILT'){
            error('Skipping this stage');
        }

        if(pipelineParams.run_tests == false)
        {
            print("Skipping Integrity Tests")
            Utils.markStageSkippedForConditional('Integrity Tests')
        }

Jenkins setup: Jenkins 2.492.2

import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
stage('regular stage') {
  echo 'some stage'
}

stage('skippable stage') { // this { defines a Groovy closure
  // get it from params, or based on previous pipeline shenanigans
  boolean shouldSkip = true
  if (shouldSkip) { // this { is a part of "regular {} syntax"
    echo 'skipping stage because reasons'
    // STAGE_NAME is a magical variable that gets injected into closure context by stage() function
    Utils.markStageSkippedForConditional(STAGE_NAME)
    // this exits the current closure
    return
  }
  echo 'continuing stage since no reason'
}

stage('another stage') {
  echo 'same old stage'
}

Works with Blue Ocean:

Works with ol’ silly stage table:

If you are interested how this works under the hood - read up on Closures in Groovy (the particulars of context injection are described under “Delegates” section)

2 Likes

will try this out when i get the chance, thanks

To make that usable everywhere create a pipeline library with following file

# vars/skippableStage.groovy
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils

def call(String name, boolean skip, Closure body) {
  stage(name) {
    if (skip) {
      Utils.markStageSkippedForConditional(STAGE_NAME)
      return
    }
    body()
  }
}

Then use it like this

# this is not skipped
skippableStage("noskip", false) {
  echo "not skipped"
}

# this will be skipped
skippableStage("skip", true) {
  echo "should not be echoed"
}

3 Likes