14

I'm going to use Jenkins pipeline plugin to test several binaries A B C on several nodes 1 2 3. In the end of my test I would like to have every single result of all possible combinations. So my Pipe may not abort when a single stage fails. It should proceed.

eg: A1 green, A2 green, A3 red, B1 green, B2 red, ..., C3 green

But when the first binary returns with an value unequal zero ("Binary not working on the system") it's stage is marked as FAILURE and any other stages are skipped.

Is there a possibility in Jenkins Pipeline to mark a stage as "UNSTABLE" but proceed with running the other tests?

According to Continue Jenkins job after failed stage while marking stage as failed can't mark this step as failed. The solution of this in running tasks in parallel is not working for my setup. So is it possible to safely mark it as something else? Is it possible to manipulate the result of a stage?

This question How to continue past a failing stage in Jenkins declarative pipeline syntax intents to use a scripted pipeline. I would like to avoid that if it is possible to do it in an other way.

pipeline {
    agent {label 'master'}     
     stages {            
        stage('A1') { 
            agent {label 'Node1'} 
            steps {
                sh 'binA'
            }
        }
        stage('A2') {
            agent {label 'Node1'}
            steps {
                sh 'binB' // If this bin fails, all following stages are skipped
            }
        }
// ...        
        stage('C3'){
            agent {label 'Node3'}
            steps {
                sh 'binC'
            }
        }
    }
}

Panup Pong
  • 1,871
  • 2
  • 22
  • 44
Cutton Eye
  • 3,207
  • 3
  • 20
  • 39

3 Answers3

23

Declarative Pipeline: Though using currentBuild.result = 'UNSTABLE' works in declarative pipelines too, Blue Ocean displays all stages as unstable irrespective of which stage fails.

enter image description here

To mark only specific stages as unstable, use the step unstable(message: String) as described here within your stage and install/update the following plugins:

  • Pipeline: Basic Steps to 2.16 or newer
  • Pipeline: API Plugin to 2.34 or newer
  • Pipeline: Groovy to 2.70 or newer
  • Pipeline Graph Analysis to 1.10 or newer

Sample pipeline stage:

stage('Sign Code') {
    steps {
        script {
            try {
                pwd()
                sh "<YOUR SCRIPT HERE>"
            }
            catch (err) {                                        
                unstable(message: "${STAGE_NAME} is unstable")
            }
        }
    }
}

enter image description here

Note: This also marks the overall build status as unstable.

Dibakar Aditya
  • 3,893
  • 1
  • 14
  • 25
  • thank you! does the whole thing work for scripted pipeline too? Is there any difference? – Cutton Eye Jul 10 '19 at 10:55
  • 2
    Yes, it works in scripted pipelines too except that you don't need to use the `script{}` block as a wrapper around the try-catch blocks. – Dibakar Aditya Jul 11 '19 at 06:57
  • this is marking the entire build as unstable in a scripted pipeline, but does not mark the stage itself as unstable in the UI. – CoryDorning Jul 26 '22 at 14:03
20

There is now a more elegant solution, that not only allows you to set a stage and the job result to unstable. Using catchError, you can set any combination of stage and build result:

pipeline {
    agent any
    stages {
        stage('1') {
            steps {
                sh 'exit 0'
            }
        }
        stage('2') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    sh "exit 1"
                }
            }
        }
        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}

In the example above, all stages will execute, the pipeline will be successful, but stage 2 will show as failed:

Pipeline Example

As mentioned above, you can freely choose the buildResult and stageResult. You can even fail the build and continue the execution of the pipeline.

Just make sure your Jenkins is up to date, since this is a fairly new feature. (Pipeline: Basic Steps needs to be 2.18 or newer)

Erik B
  • 40,889
  • 25
  • 119
  • 135
  • uiiiiii this is blue ocean then? So I need to get grid of the traditional view. This thing makes me happy! thx – Cutton Eye Jul 12 '19 at 08:12
  • @CuttonEye It works just as well with the traditional view. I just prefer the visualisation of blue ocean. Also, there's no reason you can't use both, depending on your mood. :) – Erik B Jul 12 '19 at 10:32
  • @ErikB How can we execute custom error-handling code (ex. send mail to sys admins) if code inside `catchError` fails? – Sam Carlson Jul 27 '22 at 12:01
  • @Mark I think you will have to simply add a try catch inside and rethrow the error after you've sent the email. Just keep in mind that try catch needs to be inside a script block if you are using a declarative pipeline. – Erik B Aug 04 '22 at 12:23
  • @Mark I created a question for this to be able to give you a code example: https://stackoverflow.com/questions/73236129/how-to-add-error-handling-code-to-catcherror-in-jenkins/73236130#73236130 – Erik B Aug 04 '22 at 12:42
3

For scripted pipeline, you can use try .. catch blocks inside the stages and then set currentBuild.result = 'UNSTABLE'

in the exception handler.

Poorna Senani Gamage
  • 1,246
  • 2
  • 19
  • 30