Search code examples
jenkins-pipelinejenkins-declarative-pipeline

Jenkins declarative pipeline. Stage post action goes to failure block if previous stage failed and current stage is successful


I have pipeline runs 3 stages. success, fail, success. Yes I want the pipeline continue to run even one stage fails.
This screenshot looks right.
My problem is, the last stage green2 is successful but the post action went to failure block instead of success. Here is output

green success
red failure
green2 failure

My goal is catch every stage status and send to slack. With catchError(), if the stage fail I cannot assign a global variable to indicates that stage failed.
Thank you in advance for your help!
enter image description here

pipeline {
    stages {    
        stage("green"){            
            steps{
                catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                    sh 'exit 0'
                }               
            }
            post{
                success {
                    echo 'green success'
                }
                failure{
                    echo 'green fail'
                }               
            }
        }       
        stage("red"){
           
            steps{
                catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                    sh 'exit 1'
                }
            }
            post{
                success {
                    echo 'red success'
                }
                failure{
                    echo 'red failure'
                }           
            }
        }
        
        stage("green2"){
            steps{
                catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                    sh 'exit 0'
                }
            }
            post{
                success {
                    echo 'green2 success'
                }
                failure{
                    echo 'green2 failure'
                }
            }
        }
    }
}

Jenkins 2.401.3


Solution

  • A slight variation of the @m-b 's answer, accumulating stage results in a map

    def stageResults = [:]
    pipeline {
      agent any
      stages {
        stage("green"){
          steps{
            script { stageResults[STAGE_NAME] = 'failure' }
            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
              sh 'exit 0'
              script { stageResults[STAGE_NAME] = 'success' }
            }
          }
        }
        stage("red"){
          steps{
            script { stageResults[STAGE_NAME] = 'failure' }
            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
              sh 'exit 1'
              script { stageResults[STAGE_NAME] = 'success' }
            }
          }
        }
        stage("green2"){
          steps{
            script { stageResults[STAGE_NAME] = 'failure' }
            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
              sh 'exit 0'
              script { stageResults[STAGE_NAME] = 'success' }
            }
          }
        }
      }
      post{
        always {
          echo "Stage results: ${stageResults}"
        }
      }
    }