Search code examples
jenkinsjenkins-pipelinejenkins-groovy

running multiple freestyle jenkins job as downstream - get build status


node {
    stage('Testing') {
        build job: 'Test1', parameters: [string(name: 'Name', value: 'Foo1')], propogate: false, wait: false
        build job: 'Test2', parameters: [string(name: 'Name', value: 'Bar1')], propogate: false, wait: false
        build job: 'Test3', parameters: [string(name: 'Name', value: 'Baz1')], propogate: false, wait: false
        build job: 'Test4', parameters: [string(name: 'Name', value: 'Foo2')], propogate: false, wait: false
        build job: 'Test5', parameters: [string(name: 'Name', value: 'Bar2')], propogate: false, wait: false
        build job: 'Test6', parameters: [string(name: 'Name', value: 'Baz2')], propogate: false, wait: false
    }
}

I have the above job which run multiple freestyle jenkins job in a loop. i have wait false and propogate false so it should not wait for the job to complete and proceed to next job

how can i check the status of the build and if anyone of the job fails i want to make that stage status as unstable

if i try to check the status as below. it says NullPointerException: Cannot get property 'result' on null object may be the build is still running and hence cannot check the status .. is there a way to check the status with wait:false and propogate:false

def downstream = build job: TEST1 , wait: false, propagate: false, parameters: parameters)
   if (downstream.getResult() != 'SUCCESS') {
       unstable(message: "Downstream job result is ${downstream.result}")
     }


Solution

  • What you actually want is to run all the jobs in parallel, and when they all finish check all results and mark the build as unstable if one of the jobs failed.

    To achieve that you can use the parallel keyword to run all you jobs in parallel, for each job set the wait property to true and when it finishes store its result. Once all jobs finished check all the results to see if one of them failed, if so mark the build as unstable.

    Something like:

    node {
        stage('Testing') {
            // Map of all jobs and their parameters
            def jobs = ['Test1' : [string(name: 'Name', value: 'Foo1')],
                        'Test2' : [string(name: 'Name', value: 'Bar1')],
                        'Test3' : [string(name: 'Name', value: 'Baz1')],
                        'Test4' : [string(name: 'Name', value: 'Foo2')],
                        'Test5' : [string(name: 'Name', value: 'Bar2')],
                        'Test6' : [string(name: 'Name', value: 'Baz2')]]
    
            // Map to store all results
            def results = [:]
    
            // Run all jobs in parallel
            parallel jobs.collectEntries { jobName, jobParams->
                ["Running job ${jobName}" : {
                    results[jobName] = build job: jobName, parameters: jobParams, propagate: false, wait: true
                }]
            }
    
            // Check if there are failed jobs
            def failedJobs = results.findAll( it.value.getResult() == 'FAILURE')
            if(failedJobs) { // if there are failed jobs mark build as unstable
                def failedJobNames = failedJobs.collect{ it.key }.join(', ')
                unstable(message: "The following downstream jobs have failed: ${failedJobNames}")
            }
        }
    }