Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mark Jenkins build as success, in case of timeout on input? (declarative pipeline)

I'm creating a declarative Jenkins pipeline, that looks like this:

pipeline {
    agent {
        label 'mylabel'
    }
    stages {
        stage('Install dependencies') {
            milestone()
            steps {
                sh "yarn install"
            }
        }
        stage('Lint files') {
            steps {
                sh "eslint src"
            }
        }
        stage('Create bundle') {
            steps {
                sh "yarn run build:server"
                sh "yarn run build:client"
            }
        }
        stage('Publish') {
            steps {
                timeout(time: 15, unit: 'SECONDS') {
                    input(message: 'Deploy this build to QA?')
                }
                // deployment steps
            }
        }

    }
}

It works great, however, if the timeout step fails (because we don't want to deploy this build, or nobody is there to push the button, and so on), the build is marked with status "aborted". Unfortunately this means that for example Github marks our pull requests as "checks failing".

Is there a way to declare the build with the status that it had before the timeout() step? Eg. if the build was a success up until the timeout step, it should be marked as success, even if the timeout happens.

like image 536
K. Norbert Avatar asked Jun 12 '17 07:06

K. Norbert


3 Answers

Since all you want is to let the build abort without marking it as failed, you can just add a simple try/catch to your code.

        stage('Publish') {
            steps {
                script {
                    def proceed = true
                    try {
                        timeout(time: 15, unit: 'SECONDS') {
                            input(message: 'Deploy this build to QA?')
                        }
                    } catch (err) {
                        proceed = false
                    }
                    if(proceed) {
                        // deployment steps
                    }
                }
            }
        }

If a user aborts the build or it times out, the error is suppressed, the build is still a success, and the deployment steps won't execute.

like image 149
jpyams Avatar answered Nov 13 '22 01:11

jpyams


We have a situation where we don't want to start a build if there are no user commits. Because of a bug in the scm trigger prevention on message or user. What we then do is fail the build with a NOT_BUILT result.

Maybe this will also work for your situation

Try the following in your script

try {
    stage ('wait') {
        timeout(time: 15, unit: 'SECONDS') {
            input(message: 'Deploy this build to QA?')
        } 
    }
} catch (err) {
    def user = err.getCauses()[0].getUser()
    if('SYSTEM' == user.toString()) { //timeout
        currentBuild.result = "SUCCESS"
    }
}
like image 7
Wim Ederveen Avatar answered Nov 12 '22 23:11

Wim Ederveen


If you don't want the job to be marked as "aborted" or "failed":

For a Declarative pipeline (not a scripted) you would do something like this

    stage('Foo') {
          steps {
                script {
                    env.PROCEED_TO_DEPLOY = 1
                    try {
                        timeout(time: 2, unit: 'MINUTES') {
                            // ...
                        }
                    } catch (err) {
                        env.PROCEED_TO_DEPLOY = 0
                    }
                }
          }
      }
      stage('Bar') {
        when {
            expression {
                env.PROCEED_TO_DEPLOY == 1
            }
        }
        //rest of your pipeline

stage "Bar" would be skipped but as for the rest of the stages the job will be marked as passed (assuming nothing wrong happened before)

like image 2
Guillermo Mansilla Avatar answered Nov 12 '22 23:11

Guillermo Mansilla