Search code examples
jenkinsjenkins-pipelinedevopsjenkins-groovyjenkins-job-dsl

How to run pipeline irrespective of stage failure and capture errors and report the failed stages at end


First of all, Thanks for looking into my concern.

I have below pipeline.

pipeline {
  agent any
  stages {
    stage(‘one’) {
        steps {
            catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
            bat '''
            echo “stage one”;
            exit 1;
            '''
            echo "RESULT: ${currentBuild.result}"
            //echo "RESULT2 ${currentBuild.stageResult}"
        } //catch
        }//steps
    }//stage 1
        stage('RunParallel') {
            parallel { 
                stage(‘two’) {
                    steps {
                    bat '''
                    echo “stage two”;
                    exit 0;
                    '''
                    echo "RESULT: ${currentBuild.result}"
                    }
                }
                
                stage(‘three’) {
                    steps {
                    bat '''
                    echo “stage three”;
                    exit 0;
                    '''
                    echo "RESULT: ${currentBuild.result}"
                    }
                }
                
                stage(‘four’) {
                    steps {
                    bat '''
                    echo “stage four”;
                    exit 0;
                    '''
                    echo "RESULT: ${currentBuild.result}"
                    }
                }
            }//parallel
        }//runParallel

    stage(‘validate’) {
      steps {
        echo "RESULT: ${currentBuild.result}"
        bat 'echo validation stage'
      }

    }
    stage(‘five’) {
      steps {
        bat '''
        echo “stag e 5”;
        exit 0;
        '''
      }
    }

  }
  post {
    always {
    bat '''
      echo ‘I will always execute this!’
      '''
    }
  }
}

And pipeline looks like his. enter image description here

My goal is:

  1. even if stage1 fails, I need to run stages 2,3,4
  2. a. if stage 1,2,3,4 fails, I have to report it in validation stage and fail the build b. if stage 1,2,3,4 succeeds, I need to pass validation and proceed towards stage5 and later stages

Right now I am able to do first step with catch block. And, stuck at step2. Can you guide on how to capture stage result and report failed stages.


Solution

  • Finally, I have managed to capture all the stage results and filter failed stages. Now I can write conditions around it. Here's what I have got.

    #!/usr/bin/env groovy
    rstages=[:]
    
    pipeline {
      agent any
      stages {
        stage(‘one’) {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                bat '''
                echo “stage one”;
                exit 1;
                '''
                script{
                echo "stage name is: ${env.STAGE_NAME}"
                echo "RESULT: ${currentBuild.result}"
                }
            } //catch
            }//steps
            post {
                    always {
                        script{
                        println "RESULT: ${currentBuild.result}"
                        println "current stage name is: ${env.STAGE_NAME}"
                        rstages."${env.STAGE_NAME}" = "${currentBuild.result}"
                        }
                    }
                } 
        }//stage 1
        
            stage('RunParallel') {
                parallel { 
                    stage(‘two’) {
                        steps {
                        bat '''
                        echo “stage two”;
                        exit 0;
                        '''
                        echo "RESULT: ${currentBuild.result}"
                        }
                        post {
                            always {
                            script{
                            println "current stage name is: ${env.STAGE_NAME}"
                            rstages."${env.STAGE_NAME}" = "${currentBuild.result}"
                        }
                            }
                        }
                    }
                    
                    stage(‘three’) {
                        steps {
                        bat '''
                        echo “stage three”;
                        exit 0;
                        '''
                        echo "RESULT: ${currentBuild.result}"
                        }
                        post {
                            always {
                            script{
                            println "current stage name is: ${env.STAGE_NAME}"
                            rstages."${env.STAGE_NAME}" = "${currentBuild.result}"
                        }
                            }
                        }
                    }
                    
                    stage(‘four’) {
                        steps {
                        bat '''
                        echo “stage four”;
                        exit 0;
                        '''
                        echo "RESULT: ${currentBuild.result}"
                        }
                        post {
                            always {
                            script{
                            println "current stage name is: ${env.STAGE_NAME}"
                            rstages."${env.STAGE_NAME}" = "${currentBuild.result}"
                        }
                            }
                        }
                    }
                }//parallel
            }//runParallel
    
        stage(‘validate’) {
          steps {
            script{
            //println RESULT: "${currentBuild.result}"
            //println "stage name is: ${env.STAGE_NAME}"
            println "Printing all stage results"
            rstages.each{entry -> println "$entry.key=$entry.value"}  // to print all elements in map object rstages
            }
            script{
            //help: https://www.baeldung.com/groovy-maps
            println "printing failed stages"
            def fstages=rstages.findAll{ key, value -> value.contains('FAIL') } //to print all keys matching a value FAILURE
            println fstages 
            }
          }
          post {
                            always {
                            script{
                            println "current stage name is: ${env.STAGE_NAME}"
                            rstages."${env.STAGE_NAME}" = "${currentBuild.result}"
                        }
                            }
                        }
    
        }
        stage(‘five’) {
          steps {
            bat '''
            echo “stage 5”;
            exit 0;
            '''
          }
        }
    
      }
      post {
        always {
        bat '''
          echo ‘I will always execute this!’
          '''
        }
      }
    }