How to perform actions for failed builds in Jenkin

2020-02-27 10:50发布

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 doing a curl at the correct URL).

Basically it would be a post step when build status is set to fail.

Should I use try {} catch ()? If so, what exception type should I catch?

3条回答
放我归山
2楼-- · 2020-02-27 11:34

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

查看更多
SAY GOODBYE
3楼-- · 2020-02-27 11:51

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
            """
        }
    }

}
查看更多
Animai°情兽
4楼-- · 2020-02-27 11:55

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                        
            } 
        }
    }
}
查看更多
登录 后发表回答