How to iterate through the done build and rerun only steps that failed in Workflow?

Article ID:207127338
1 minute readKnowledge base

Issue

How to rerun only the failed steps in a completed build.

Environment

CloudBees Jenkins Platform

Resolution

This can be accomplished by doing the following in your Pipeline Script:

passed = []
def part(name, closure) {
  if (passed.contains(name)) {
    return
  }
  stage name
  try {
    closure.call()
    passed.add(name)
  } catch (e) {
    echo "===> part ${name} failed with ${e} <==="
    currentBuild.result = 'FAILURE'
  }
}
def go() {
  part('one') {echo 'first part passes'}
  part('two') {
    // Example of a flaky build step:
    if (env.BUILD_NUMBER == '2') {
      echo 'second part passes'
    } else {
      error 'second part fails'
    }
  }
  part('three') {echo 'third part passes'}
}
go()
def origBuildNumber = env.BUILD_NUMBER // CJP-1620 workaround
checkpoint 'performed parts'
if (origBuildNumber != env.BUILD_NUMBER) {
  go()
}

Here we are keeping track of which stages have passed already. When the build is first run, we try them all, recording successes, and just setting the build status to failed in case any fail (but proceeding). The last if-block is skipped. If you resume from the checkpoint, the whole sequence is run again (from the last if-block), but skips over anything which passed earlier.

This works around CJP-1621 for a single resumption. If something fails again the second time around, and you resume from checkpoint again, the third build will retry the same stages, even ones that did pass in the second build. I am not currently seeing a way to fix that.