How to implement Post-Build stage using Jenkins Pi

2019-01-17 14:16发布

问题:

After reading Jenkins tutorial explaining Pipeline plug-in, it seems that plug-in should make it possible to implement Post-Build steps. However documentation is rather limited in regard to specific instructions.

For example I wonder how to implement:

  • Run only if build succeeds
  • Run only if build succeeds or is unstable
  • Run regardless of build result
  • Run only if build succeeds

    stage 'build'
    ... build
    ... tests
    stage 'post-build'
    ...
    

    (Or add -Dmaven.test.failure.ignore=false to the MAVEN_OPTS)

  • Run only if build succeeds or is unstable

    stage 'build'
    ... build
    try {
        ... tests
    } catch {
        ...
    }
    stage 'post-build'
    ...
    

    (Or add -Dmaven.test.failure.ignore=true to the MAVEN_OPTS)

  • Run regardless of build result - could it be done using try / catch / finally ?

    try {
        stage 'build'
        ...
    } catch {
        ...
    } finally {
        stage 'post-build'
        ...
    }
    

(I've noticed that final build status is set as SUCCESS even though some stages, ie. 'build', have failed as it set based on last stage. Does that mean final build status need to explicitly set, ie.currentBuild.result = 'UNSTABLE'? )

回答1:

The best way is to use post build action in the pipeline script.

Handling Failures
Declarative Pipeline supports robust failure handling by default via its post section which allows declaring a number of different "post conditions" such as: always, unstable, success, failure, and changed. The Pipeline Syntax section provides more detail on how to use the various post conditions.

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'make check'
            }
        }
    }
    post {
        always {
            junit '**/target/*.xml'
        }
        failure {
            mail to: team@example.com, subject: 'The Pipeline failed :('
        }
    }
}

The documentation is below https://jenkins.io/doc/book/pipeline/syntax/#post



回答2:

If you are using try/catch and you want a build to be marked as unstable or failed then you must use currentBuild.result = 'UNSTABLE' etc. I believe some plugins like the JUnit Report plugin will set this for you if it finds failed tests in the junit results. But in most cases you have to set it your self if you are catching errors.

The second option if you don't want to continue is to rethrow the error.

stage 'build'
... build
try {
    ... tests
} catch(err) {
    //do something then re-throw error if needed.
    throw(err)
}
stage 'post-build'
...


回答3:

try-catch blocks can be set up to handle errors like in real application code.

For example:

try {
    node {
        sh 'sleep 20' // <<- can abort here
    }
} catch (Exception e) {
    println 'catch'
} finally {
    println 'finally'
}

node {
    println 'second'
}

try {
    node {
        sh 'sleep 20' // <<- can abort here again
    }
} catch (Exception e) {
    println 'catch'
} finally {
    println 'finally'
}

And here is an example output with two aborts.

Started by user me
Replayed #3
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] sh
[my-job] Running shell script
+ sleep 20

Aborted by me

Sending interrupt signal to process

/var/lib/jenkins-slave/workspace/my-job@tmp/durable-9e1a15e6/script.sh: line 2: 10411 Terminated              sleep 20
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
catch
[Pipeline] echo
finally
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] echo
second
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] sh
[my-job] Running shell script
+ sleep 20

Aborted by me

Sending interrupt signal to process
/var/lib/jenkins-slave/workspace/my-job@tmp/durable-d711100c/script.sh: line 2: 10416 Terminated              sleep 20
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
catch
[Pipeline] echo
finally
[Pipeline] End of Pipeline
Finished: ABORTED

Of course, this works for any exceptions happening during the execution.