I have the following build pipeline set up as a job:

Stage 1 - verify all dependencies exist
Stage 2 - build the new jar
Stage 3 - Run integration tests
Stage 4 - Deploy to staging environment (manual step)
Stage 5 - Deploy to production environment (manual step)

I am looking for a way to start the build pipeline from a particular stage in case of a transient failure. For example, let's say there was a network issue when the user clicked to deploy to production. I don't think it makes sense to start the pipeline from stage 1... I'd like to try that step again and continue on from there in the pipeline. I don't see any functionality like this in the Build Pipeline Plugin.



checkpoint is what you are looking for. Unfortunately it is only available in the CloudBees Jenkins Enterprise suite, not in the free version.

Let's hope it makes it into the open-source version as it seems to be a very common use case.


Meanwhile, many other answers are obsolete, as Jenkins provides a built-in solution that allows you to restart a job from any stage: https://jenkins.io/doc/book/pipeline/running-pipelines/ It is applicable to declarative pipeline only through.

  • 5
    this is nice but does not appear to be enabled for scripted pipelines, declarative only Jun 18 '19 at 21:49

A better solution is a solution similar to what I suggested in this question:

Write a pipelining script that has has "if"-guards around the single stages, like this:

stage "s1"
if (theStage in ["s1"]) {
    sleep 2

stage "s2"
if (theStage in ["s1", "s2"]) {
    sleep 2

stage "s3"
if (theStage in ["s1", "s2", "s3"]) {
    sleep 2

Then you can make a "main" job that uses this script and runs all stages at once by setting the parameter "theStage" to "s1". This job will collect the statistics when all stages are run at once and give you useful estimation times.

Furthermore, you can make a "partial run" job that uses this script and that is parametrized with the stage that you want to start with. The estimation will not be very useful, though.

  • 1
    This is essentially what I've done, although somewhat different. I created if blocks by checking to see if the jar version was already built, if so I go to the integration test step and check if it's already passed for that jar version (by creating touchfiles in the workspace).
    – threejeez
    Jul 5 '16 at 18:42
  • 1
    I've just done this too - my stages are 'Build', 'Push to dev', 'Push to QA' and 'Release'. As I have dockerised the output in the build stage, I've stored the build number to a variable at the top of my script, so the 'push' stages can reconstitute the container name from the build step using a manually entered number when replaying the script. In this manner, I am able to redeploy as I can't think of a good reason for not rebuilding/retesting after fixing a broken build (or test). It's messy, but it works. It is so disappointing that the Jenkins guys won't make an OSS version of 'Checkpoint'
    – Jay
    Apr 13 '17 at 15:19

You can wrap your code in a retry step:

stage "Deployment"
retry(3) {
  sh "deploy.."

EDIT: This might help in the free version of Jenkins. Users of CloudBees Enterprise, please see @tarantoga's answer.

  • Doesn't that mean that Jenkins will retry that step 3 times automatically?
    – threejeez
    Jun 30 '16 at 20:31
  • You mean that you manually want to try that yourself again? Then this doesn't work. I'm not aware of anything like that in combination with the Pipeline plugin. Jun 30 '16 at 20:32
  • Yeah, manually. Let's say, for example, the integration tests fail because one of the tests was wrong instead of the application logic... there's no need to rebuild the application from scratch... you'd just want to update the integration test and resume the pipeline from that point. Make sense?
    – threejeez
    Jun 30 '16 at 22:42
  • You could wrap it only around the flaky parts that should be retried, not the complete pipeline. Jul 1 '16 at 11:45
  • Right, that totally makes sense for parts that could be flaky (eg a push to production where network issues could be intermittent). That said, a failing integration test because of a bad test isn't flaky and wouldn't be fixed in the time it takes to retry 3 times.
    – threejeez
    Jul 1 '16 at 15:59

Here's another sketch to run stages conditionally without breaking the Stage View Plugin history.

As they say:

Dynamic stages: in general, if you want to visualize dynamically changing stages, make it conditional to execute the stage contents, not conditional to include the stage

Here's what I've come up with so far. Seems to work mostly: (Just ignore the other dummy steps)

We define a little conditionalStage helper function that neatly wraps up the stage name checking from the JP_STAGE Jenkins Job parameter.

Notice how conditionalStage first opens the stage and then checks stageIsActive within the stage, just skipping all steps. This way, the Stage View Plugin sees all stages and soesn't mess up, but the stages' steps are still skipped.

def stageSelect = JP_STAGE.toLowerCase()

// test if stage or any of sub-stages is active
def stageIsActive(theStage, theStages) { 
    // echo "pass: $theStages"
    // ARGL: https://issues.jenkins-ci.org/browse/JENKINS-26481
    // def lcStages = theStages.collect {it.toLowerCase()}
    def lcStages = []
    for (def s : theStages) { lcStages += s.toLowerCase() }
    def lcAllStages = lcStages + ['all']
    // echo "check: $lcAllStages"
    // echo JP_STAGE.toLowerCase()
    if (JP_STAGE.toLowerCase() in lcAllStages) {
        echo "Run: Stage '$theStage' is active through '$JP_STAGE'."
        return true
    } else {
        echo "Skip: Stage '$theStage' is NOT active through '$JP_STAGE'."
        return false

// 1st element should be the stage, optionally followed by all sub-stages
def conditionalStage(names, stageBody) {
  stage(names[0]) { if (stageIsActive(names[0], names)) {

timestamps {
// --S--

conditionalStage(['Intro']) { 
    echo 'Outside Node'

    build job: 'FreeX', wait: true
    sleep 3

// --S--
conditionalStage(['AtNode', 'Hello', 'Done']) {
    node {
        // Cloudbees Enterprise Only: checkpoint 'Now'
        conditionalStage(['Hello']) {
            echo 'Hello World @ Node'
            sleep 4
        conditionalStage(['Done']) {
            dir('C:/local') {
                echo pwd()


A bit old topic but since Jenkins still (!) doesn't support this I'm sending another solution for scripted pipeline implementations. It's based on building stages list dynamically when running pipeline.

  1. step - stages definition enum
enum Steps {
  PREPARE(0, "prepare"), 
    BUILD(1, "build"), 
    ANALYSE(2, "analyse"), 
    CHECKQG(3, "checkQG"), 
    PROVISION(4, "provision"), 
    DEPLOY(5, "deploy"), 
    ACTIVATE(6, "activate"), 
    VERIFY(7, "verify"), 
    CLEANUP(8, "cleanup")

  Steps(int id, String name) {
      this.id = id
          this.name = name

  private final int id
    private final String name

  int getId() {

      String getName() {

    public static Steps getByName(String name) {
        println "getting by name " + name
        for(Steps step : Steps.values()) {
          if(step.name.equalsIgnoreCase(name)) { 
              return step 
        throw new IllegalArgumentException()
  1. method creating the final steps list
  def prepareStages(def startPoint){
        println "preparing build steps starting from " + startPoint
        Set steps = new LinkedHashSet()
        List finalSteps = new ArrayList()
            step ->
                if (step.id >= startPoint.id) {
        return finalSteps
  1. and u can use it like this

def stages = prepareStages(Steps.getByName("${startStage}"))

node {
    try {
        //pipelineTriggers([pollSCM('${settings.scmPoolInterval}')])  //this can be used in future to get rid build hooks 

        sh "echo building " + buildVersionNumber(${settings.isTagDriven})
        tool name: 'mvn_339_jenkins', type: 'maven'

        script {             
            println "running: " + stages

        stage('Prepare') {
            if (stages.contains(Steps.PREPARE)) {
                script { currentStage = 'Prepare' }
        } //...

the "startStage" is a build parameter defined as follows

parameters { choiceParam('startStage', [ 'prepare', 'build', 'analyse', 'checkQG', 'provision', 'deploy', 'activate', 'verify', 'cleanup' ], 'Pick up the stage you want to start from') }

This allows me to pick up the stage I want to start the pipeline from (prepare stage is set by default)


What you could do is to put the single steps into groovy scripts. Then you can make a "runAll"-job that loads all of the scripts in the correct order, and single jobs for the different steps.

Although this is a way that should work, I do not think that this is the ideal solution, as it means that you have to take care how the different steps exchange information, so that the steps can run independently.

A built-in solution would be much better.

  • 1
    Yes and no. I would give up part of its flexibility, but I would retain the ability to version control the jobs.
    – olenz
    Jul 1 '16 at 13:23
  • In my case, I have a job pipeline of 4 jobs where each job takes ~4 hours to complete. In particular while developing the jobs, it would be very helpful if I could restart a later stage.
    – olenz
    Jul 1 '16 at 13:25

Your Answer

