2
votes

I am executing 3 parallel jobs, each that run tests, from my job as follows:

def run_job(job) {
   output = build(job:job, parameters:parameters)
   def buildNumber = output.getNumber().toString()
   test_results[job] = '/job/'+ job +'/' + buildNumber + '/artifact/test_result.xml'

}


def test_func_array = [:]
def test_results = [:]

test_func_array['Python_Tests'] = {run_job('Run_Python_Tests', test_results)}

test_func_array['JS_Tests'] = {run_job('Run_JS_Tests', test_results)}

test_func_array['Selenium_Tests'] = {run_job('Run_Selenium_Tests', test_results)}

parallel(test_func_array)

I am able to get the build number using the output.getNumber() call when each job succeeds. However, when a job fails, build() function call throws an exception so I cannot get the build number.

However, failed builds can still have build numbers and have archived artifacts. How do I get the build number of a failed build?

3

3 Answers

3
votes

Use propagate: false. See Snippet Generator for details.

2
votes

if you use propagate: false, you can't use try-catch block because build job don't throw exception when the job failed so you need to handle the result by getResult() method like this:

stage('build something'){
    def job_info = build job: build_something, propagate: false,
    println "Build number: ${job_info.getNumber()}"
    currentBuild.result = job_info.getResult()
}

see also: https://jenkins.io/doc/pipeline/steps/pipeline-build-step/

0
votes

I think Jesse's answer is valid when you want to complete all the parallel jobs, even when one of more jobs have failed. So basically, it will disable the failFast feature.

Does anyone know how to catch the failed job's number while still have failFast feature working to short-circuit the builds in the event of a job failure? For example, below is my code and i want the value of variable achild_job_info inside the catch block as well.

build_jobs = [“Build_A”, “ Build_B”, “ Build_C”]

// in this hashmap we'll place the jobs that we wish to run
def branches = [:] 
def achild_job_info = ""
def abuild_number = ""
for (x in build_jobs) {
    def abuild = x 
    branches[abuild] = { 
        stage(abuild){
            def allow_retry = true
            retry(2) {
                try {
                    achild_job_info = build job: abuild
                    echo “ achild_job_info”  // —>  this gives: org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@232601dc
                    abuild_number = achild_job_info.getId()
                    build_job_to_number_mappings[abuild] = achild_job_info.getNumber()
                } catch (err) {
                    echo “ achild_job_info: ${achild_job_info } “  // —> This comes empty. I want the runwrapper here as well, just like in the try block. 
                    abuild_job_number = abuild_job_info.getId()
                    build_job_to_number_mappings[abuild] = achild_job_info.getNumber()
                } // try-catch
        } // stage
   } // branches
} // for
branches.failFast = true
parallel branches