Jenkins Pipeline Get Current Stage Status After Using catchError

前端 未结 4 1619
孤独总比滥情好
孤独总比滥情好 2021-01-19 05:39

This is a follow-up to my earlier question:

Set a stage status in Jenkins Pipelines

It turns out I can keep a pipeline as SUCCESS but can mark an individual

相关标签:
4条回答
  • 2021-01-19 06:05

    As for me the most elegant way to do it, it's a post section. In your example, you mark the stage as UNSTABLE so after that you can catch it using post->unstable.

    stage("1") {
        steps {
            catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
                error 'Something goes wrong'
            }
        }
        post {
            always { echo 'Executed on every build'}
            unstable { echo 'Executed only if build is unstable (marked by catchError)'}
        }
    }
    
    0 讨论(0)
  • 2021-01-19 06:10

    Though there is no direct method for accessing the result of a stage in a pipeline as of now, you can work around it. This is considering you are only interested in either SUCCESS or UNSTABLE stage results as per the question and not in FAILURE.

    The workaround is to initialize an empty map at the top of your pipeline to store the result of each stage. Now, instead of the catchError() method, use the unstable() method in combination with a try-catch block. This is because the latter not only lets you set the result as unstable but also perform other operations such as add the result to the map in the except block. Then you can read this stored result from the map in your if statement.

    Example

    stageResults = [:]
    ...
    stage("1") {
        try {
            // do stuff
            // Add to map as SUCCESS on successful execution 
            stageResults."{STAGE_NAME}" = "SUCCESS"
        } catch (Exception e) {
            // Set the result and add to map as UNSTABLE on failure
            unstable("[ERROR]: ${STAGE_NAME} failed!")
            currentBuild.result = "SUCCESS"
            stageResult."{STAGE_NAME}" = "UNSTABLE"
        }
        if(stageResults.find{ it.key == "{STAGE_NAME}" }?.value == "UNSTABLE") {
            // do something special if we're unstable
        }
    }
    
    0 讨论(0)
  • 2021-01-19 06:20

    I did it like this (to keep the catchError):

    def boolean test_results = false
    
    pipeline {
        ...
        stage( 'x' ) {
            steps{
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    
                    <Do some dangerous stuff here>
                    
                    //
                    // If we reached here the above step hasn't failed
                    //
                    script { test_results = true }
                }
            }
        }
        stage( 'y' ) {
            steps{
                script{
                    if( test_results == true ) {
                    } else {
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-19 06:20

    As an alternative to add to Dibakar Aditya's answer, it is possible to wrap everything in a function which resembles regular steps. I.e.:

    stage("1") {
        def localSuccess = catchLocalError {
            // do stuff
        }
        if(!localSuccess) {
            // do something special if we're unstable
        }
    }
    
    boolean catchLocalError(Closure c) {
        try {
            c()
            return true
        } catch (Exception e) {
            return false
        }
    }
    
    0 讨论(0)
提交回复
热议问题