迭代 Jenkins Groovy 映射,具有多个集合

Nah*_*paz 1 groovy jenkins jenkins-groovy jenkins-pipeline

我想寻求有关 Jenkins Groovy 管道的帮助,从这里复制: Is it possible to createparallel Jenkins Declarative Pipeline stages in a loop?

我希望在并行运行的几个阶段中在地图下传递几组变量但是,只有最后一组(地图底部的方括号)会在我的地图中注册。

当并行阶段运行时,映射会成功迭代,但仅限于最后一组(当前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
            }
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

network_reg 和 revert_to_snapshot_Stage 将不会运行(除非我将它们作为最后一组而不是 ["${it}" : install_Stage(it)] ,在这种情况下,同样,仅运行其中一个并行阶段)

我不介意使用不同的方法来运行多个映射定义,但其他方法例如:如何在 Jenkinsfile 中定义和迭代映射不允许完整的多变量映射(超过键+值对)

任何帮助将不胜感激,谢谢!

Joe*_*g S 6

我假设您有类似的问题,就像我尝试动态构建并行分支以进行并行执行一样。

有两件事非常重要:

  1. 制作循环变量的副本(在您的情况下:)it并仅在并行分支内使用该副本;如果您不这样做,所有分支(闭包)都会引用完全相同的变量,当然该变量将具有相同的值。这是闭包所特有的。另请参阅: http: //groovy-lang.org/closures.html

  2. 不要使用collectEntries{}. 坚持使用 java 风格的循环,因为 groovy 循环大多数时候都不能正常工作。某些.each{}构造可能已经可以工作,但如果有疑问,请切换到 java 循环。另请参阅:无法在 Jenkins Pipeline 中使用 Groovy 迭代 Map

以下精简示例对我有用。我相信您能够根据自己的需要进行调整。

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
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果仍然不起作用:检查是否有并升级您的Pipeline: Groovy插件,因为它们通常会修复许多通常在 groovy 中工作但在管道中不起作用的问题。

您可能想检查以下相关问题,其中也包含一个最小的示例: Currying groovy CPSclosure forparallelexecution