如何在 Jenkins 声明式管道的阶段中对同一函数进行并行调用

How to make parallel calls to the same function in stage in Jenkins Declarative Pipeline

在声明性管道中并行执行函数的正确方法是什么?

这个论坛上的几个 post 建议你建立一个数组,然后将数组传递给 'parallel' 或者传递一个函数给 'parallel'

Is it possible to create parallel Jenkins Declarative Pipeline stages in a loop?

我已经多次尝试让它工作,但它总是串行运行

我认为问题是在构建数组时正在评估函数,甚至在我到达阶段中的 'parallel' 步骤之前。

我无法从官方文档中得出解决方案。

https://jenkins.io/blog/2017/09/25/declarative-1/

这是我希望它的工作方式,但这可能吗?

    pipeline {

        agent {
            label "l1" && "l2"
        }

        stages {

            stage ('Prepare Data') {
                // Some code that creates that data object
                // data is an array of maps
                data
            }

            stage ('Build') {
                script {
                    def stepsForParallel = [:]
                    data.each { d ->
                        // name is a key in the data map
                        stepsForParallel["${d['name']}"] = {
                            node {
                                stage("${d['name']}") {
                                    stepsForParallel[execDownStreamJob("DownStreamJobName", d)] = {
                                        println("Executing DownstreamJob")
                                    }
                                }
                            }
                        }
                    }
                    parallel stepsForParallel
                }
            }

        }
    }
}

下面的函数实际上不在这个问题的范围内,但我添加了它以防它提供一些价值。在这个 post 中得到了最好的解释:

// job is a string
// jobParameters is a hashmap
def execDownStreamJob(job, jobParameters) {

    // Some parsing takes place on hashMap and creates the p object 
    // 'p' is passed to the 'build job' function as a parameter

    def downStreamJobResult = build job: job, parameters: p, propagate: false

    // Some try/catch logic

}

下面这段代码真的很奇怪

因为您正在尝试分配 stepsForParallel 两次

    stepsForParallel["${d['name']}"] = {
        node {
            stage("${d['name']}") {
                stepsForParallel[execDownStreamJob("DownStreamJobName", d)] = {
                    println("Executing DownstreamJob")
                }
            }
        }
    }

我认为它应该是这样的(现在无法测试):

    script {
        def stepsForParallel = data.collectEntries{ d ->
            ["${d.name}", 
                {
                    stage("${d.name}") {
                        println "DownstreamJob ${d.name} start")
                        execDownStreamJob("DownStreamJobName", d)
                        println "DownstreamJob ${d.name} end")
                    }
                }
            ]
        }
        parallel stepsForParallel
    }