Search code examples
jenkinsgroovyjenkins-pipelinejenkins-groovyjenkins-declarative-pipeline

How to run outer maps in parallel and inner maps in sequence in jenkins declarative pipeline groovy


I have a scenario which I want to run in a such a way that outer maps should run in parallel whereas inner maps of one of the outer map should run in sequence. I have something similar as mentioned below but it looks to me that outer_map1 and outer_map2 will run in sequence rather running in parallel code excerpts:

stage('test'){
   parallel outer_map1
   outer_map2.each{ key, value ->
      parallel value()
   }
}

Here, outer_map1 contains key as string and value will be the command to be executed and all items of this map should run in parallel, whereas outer_map2 contains key as string and value will be the map and this inner map contains again key as string and value will be the command to be executed. So for each key's value of outer_map2 will be an inner map which should run in parallel whereas each items of outer_map2 should run in sequence.

So, main challenge here is to determine how can outer_map1 and outer_map2 run in parallel.

I am fine to have 2 different stages for outer_map1 and outer_map2 but if I go with this approach then not aware about how to run these 2 stages in parallel.


Solution

  • You can just add the execution section of outer_map2 as an item to outer_map1. This way the entire execution of outer_map2 will be conducted in parallel to all other executions of outer_map1.
    Something like:

    stage('test'){
        outer_map1['outer-map2-branch-name'] = {
            outer_map2.each { key, value ->
                parallel value
            }
        }
        parallel outer_map1
    }
    

    If you are using declarative pipeline and want to separate them into two stages for readability you can use a mixture of declarative and scripted pipeline:

    pipeline {
        agent any
        stages {
            stage('Parallel Stage') {
                parallel {
                    stage('outer map 1') {
                        steps {
                            script{
                                parallel outer_map1
                            }
                        }
                    }
                    stage('outer map 2') {
                        steps {
                            script {
                                outer_map2.each {
                                    echo "executing ${it.key}"
                                    parallel it.value
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Both options should result with the behavior you want.