我想从此处复制的Jenkins groovy管道寻求帮助:是否可以在循环中创建并行的Jenkins声明性管道阶段?
我想在地图下的一组中传递 几 组var,在并行运行下的 几 阶段中传递。但是,只有最后一组(地图底部的方括号)被注册为我的地图。
当并行阶段运行时,映射成功进行迭代,但仅使用最后一组(当前为install_Stage(it))进行迭代,而忽略其他组。这意味着我得到了一个"stage: install ${product}"并行显示四个阶段的管道,仅此而已。我想按照以下代码获得四个阶段(网络设置,还原和安装)的三个并行部分:
install_Stage(it)
"stage: install ${product}"
#!groovy @Library('ci_builds') def products = ["A", "B", "C", "D"] def parallelStagesMap = products.collectEntries { switch (it) { case "A": static_ip_address = "10.100.100.6"; static_vm_name = "install-vm1"; version = "14.1.60" break case "B": static_ip_address = "10.100.100.7"; static_vm_name = "install-vm2"; version = "15.1" break case "C": static_ip_address = "10.100.100.8"; static_vm_name = "install-vm3"; version = "15.1" break case "D": static_ip_address = "10.100.100.9"; static_vm_name = "install-vm4"; version = "15.2" break default: static_ip_address = "The product name is not on the switch list - please enter an ip address" version = "The product name is not on the switch list - please enter a version" break } ["${it}" : network_reg(it)] ["${it}" : revert_to_snapshot_Stage(it)] ["${it}" : install_Stage(it)] } def network_reg(product) { return { stage("stage: setup network for ${product}") { echo "setting network on ${static_vm_name} with ${static_ip_address}." sh script: "sleep 15" } } } def revert_to_snapshot_Stage(product) { return { stage("stage: revert ${product}") { echo "reverting ${static_vm_name} for ${product} on ${static_ip_address}." sh script: "sleep 15" } } } def install_Stage(product) { return { stage("stage: install ${product}") { echo "installing ${product} on ${static_ip_address}." sh script: "sleep 15" } } } pipeline { agent any stages { stage('non-parallel env check') { steps { echo 'This stage will be executed first.' } } stage('parallel stage') { steps { script { parallel parallelStagesMap } } } } }
network_reg和revert_to_snapshot_Stage将不会运行(除非我将它们放置为最后一组而不是[“ $ {it}”:install_Stage(it)],在这种情况下,同样,仅运行并行阶段之一)
我不介意使用其他方法来运行多个映射定义,但其他方法如:如何在Jenkinsfile中定义和迭代映射不允许使用完整的多变量映射(超过键+值对)
任何帮助将不胜感激,谢谢!
我假设您遇到类似的问题,就像我试图动态构建并行分支以并行执行一样。
有两点非常重要:
复制循环变量(在您的情况下为it),并仅在并行分支内使用该副本;如果您不这样做,那么所有分支(闭包)都将引用相同的变量,而该变量当然具有相同的值。这对于闭包而言尤其如此。另请参阅:http : //groovy-lang.org/closures.html。
it
不要使用collectEntries{}。坚持使用Java风格的循环,因为通常情况下,groovy循环无法正常工作。一些.each{}构造可能已经起作用,但是如果有疑问,请切换到Java循环。
collectEntries{}
.each{}
以下精简示例对我有用。我相信您将能够根据需要进行调整。
def products = ["A", "B", "C", "D"] def parallelStagesMap = [:] // use java-style loop for (def product: products) { // make a copy to ensure that each closure will get it's own variable def copyOfProduct = product parallelStagesMap[product] = {echo "install_Stage($copyOfProduct)"} } echo parallelStagesMap.toString() pipeline { agent any stages { stage('parallel stage') { steps { script { parallel parallelStagesMap } } } } }
Pipeline: Groovy
您可能想检查以下相关问题,其中也包含一个最小的示例: 为并行执行使用groovy CPS闭包