Is there a way to perform cleanup (or rollback) if the build in Jenkinsfile failed?
I would like to inform our Atlassian Stash instance that the build failed (by doi
I manage to solve it by using try:finally. In case of this stage raises an error the stage will be red and finally run the code but if the stage is okay, the stage will be green and finally will run too.
stage('Tests'){
script{
try{
sh """#!/bin/bash -ex
docker stop \$(docker ps -a -q)
docker rm \$(docker ps -a -q)
export DOCKER_TAG=${DOCKER_TAG}
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} build test
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} up --abort-on-container-exit --exit-code-from test
"""
}
finally{
sh """#!/bin/bash -ex
export DOCKER_TAG=${DOCKER_TAG}
docker-compose -p ${VISUAL_TESTING_PROJECT_TAG} down
"""
}
}
}
I'm currently also searching for a solution to this problem. So far the best I could come up with is to create a wrapper function that runs the pipeline code in a try catch block. If you also want to notify on success you can store the Exception in a variable and move the notification code to a finally block. Also note that you have to rethrow the exception so Jenkins considers the build as failed. Maybe some reader finds a more elegant approach to this problem.
pipeline('linux') {
stage 'Pull'
stage 'Deploy'
echo "Deploying"
throw new FileNotFoundException("Nothing to pull")
// ...
}
def pipeline(String label, Closure body) {
node(label) {
wrap([$class: 'TimestamperBuildWrapper']) {
try {
body.call()
} catch (Exception e) {
emailext subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - FAILURE (${e.message})!", to: "me@me.com",body: "..."
throw e; // rethrow so the build is considered failed
}
}
}
}
Since 2017-02-03, Declarative Pipeline Syntax 1.0 can be used to achieve this post build step functionality.
It is a new syntax for constructing Pipelines, that extends Pipeline with a pre-defined structure and some new steps that enable users to define agents, post actions, environment settings, credentials and stages.
Here is a sample Jenkinsfile with declarative syntax:
pipeline {
agent label:'has-docker', dockerfile: true
environment {
GIT_COMMITTER_NAME = "jenkins"
GIT_COMMITTER_EMAIL = "jenkins@jenkins.io"
}
stages {
stage("Build") {
steps {
sh 'mvn clean install -Dmaven.test.failure.ignore=true'
}
}
stage("Archive"){
steps {
archive "*/target/**/*"
junit '*/target/surefire-reports/*.xml'
}
}
}
post {
always {
deleteDir()
}
success {
mail to:"me@example.com", subject:"SUCCESS: ${currentBuild.fullDisplayName}", body: "Yay, we passed."
}
failure {
mail to:"me@example.com", subject:"FAILURE: ${currentBuild.fullDisplayName}", body: "Boo, we failed."
}
}
}
The post code block is what handles that post step action
Declarative Pipeline Syntax reference is here