詹金斯管道 - 阶段级别的迭代

时间:2018-03-22 22:24:32

标签: jenkins jenkins-pipeline

在构建多平台时,我一直希望使用迭代来在舞台上保存冗余代码。 下面是展示我正在尝试做的事情:

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

pipeline {
    agent none
    stages {
        map.each { entry ->
            stage ($entry.key) {
                steps{
                    timestamps{
                        echo "$entry.value"
                    }
                }
            }
        }
    }
}

我认为这里的概念很简单,但是通过告诉我,构建失败了:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 13: Expected a stage @ line 13, column 9.
           map.each { entry ->
           ^

WorkflowScript: 12: No stages specified @ line 12, column 5.
       stages {
       ^

2 errors

这是否意味着jenkins尚未支持用户在舞台上进行迭代?如果我做的有什么问题,请告诉我。谢谢!

----- ------ EDIT

顺便说一下,@ NonCPS也尝试了,我不认为这是管道脚本中的each问题......

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

pipeline {
    agent none
    stages {
        iter_stages map
    }
}

@NonCPS
def iter_stages(dd) {
    dd.each { entry ->
        stage ($entry.key) {
            steps{
                timestamps{
                    echo "$entry.value"
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我认为这可以帮到你。我真的不知道你为什么要在阶段上进行迭代,而不是只是在一个阶段的步骤中迭代你的函数:

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

pipeline {
    agent any

    stages {
        stage('loop') {
            steps {
                loopNames(map)
            }
        }
    }
}

def loopNames(map){
    map.each { 
        key, value -> println "Age of " + key + " is " + value + ".";
    }
}

调用管道中的groovy function并传递map作为参数。 在管道下面我定义了函数的内容。

Output of this run:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (loop)
[Pipeline] echo
Age of Bob is 42.
[Pipeline] echo
Age of Alice is 54.
[Pipeline] echo
Age of Max is 33.
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

答案 1 :(得分:0)

OP朝着正确的方向发展,但是代码存在一些问题:

  • 创建动态阶段的代码必须在script块中。
  • 您至少需要一个带有步骤的阶段,以便您可以运用以上逻辑
  • 您不需要在动态阶段中使用steps(可能是因为它位于script块中,这意味着它不再是声明性的)。
  • 传递给阶段名称的值存在语法错误,可能是拼写错误

以下是符合OP要求的代码:

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

pipeline {
    agent any

    stages {
        stage('Initialize') {
            steps {
                script {
                    map.each { entry ->
                        stage (entry.key) {
                            timestamps{
                                echo "$entry.value"
                            }
                        }
                    }
                }
            }
        }
    }
}

以下是管道的外观:

Pipeline view

由于无论如何这都是动态的,因此它可能应该使用脚本化的管道语法而不是上面的(声明性管道),这也可以避免进入Initialize阶段。

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

node {
    map.each { entry ->
        stage (entry.key) {
            timestamps{
                echo "$entry.value"
            }
        }
    }
}