koxta
koxta

Reputation: 916

Jenkins Pipeline - how to execute sequential sub-jobs and propagate the error while keeping the sequence

I am trying to have a pipeline that executes multiple sequential jobs.

The problem is that if I have the "propagate false" flag, the jobs are executed but the pipeline build always returns 'Success' regardless the sub-jobs status.

If I want the pipeline reflects the 'Fail' status when a sub-job fails, and remove the propagate flag, the sequence is broken at that failure point, and no more jobs are executed.

Can you help me getting the best way to achieve this? I hope I was clear. Thank you very much.

pipeline{
    stages{
        stage('Tests'){
            steps{
                parallel(
                    'TestSet':{
                            build wait: true, job: 'Test A'
                            build wait: true, job: 'Test B'
                            build wait: true, job: 'Test C'
                     }
                )
            }
        }
    }
}

Upvotes: 0

Views: 1044

Answers (1)

Noam Helmer
Noam Helmer

Reputation: 6824

When you run the build step it actually returns an RunWrapper object (see Java Docs).
The RunWrapper has a getResult() function which enables you to get the result of the build that was executed, along side many other proproteins of the executed build, like the build number.
You can then run your jobs with the propagate false option, save the results, examine them after all builds are finished and then run your required logic.
For example:

pipeline{
    stages{
        stage('Tests'){
            steps{
                script {
                    parallel(
                        'TestSet': {
                            // Collect all results of build execution into a map
                            def results = [:]
                            results['Test A'] = build(wait: true, job: 'Test A').getResult()
                            results['Test B'] = build(wait: true, job: 'Test B').getResult()
                            results['Test C'] = build(wait: true, job: 'Test C').getResult()

                            // Analyze the result
                            failedJobs = results.findAll(it.value != 'SUCCESS') // you can also use Result.SUCCESS instead of the string
                            if (failedJobs){
                                error "The following jobs have failed: ${failedJobs.collect{it.key}.join(',')}"
                            }
                        }
                    )
                }
            }
        }
    }
}

Upvotes: 1

Related Questions