詹金斯并行建立在不同的代理上

时间:2019-02-28 13:04:05

标签: jenkins jenkins-pipeline jenkins-plugins

我有一个Jenkins声明性管道的小例子,该管道应同时在“ Windows”和“ Linux”代理上运行。目标是动态构建配置矩阵(例如,发布/调试配置;不同的CMake参数;等等),并使所有组合并行运行。但是,我被困在建立从预备变量执行并行步骤的管道中。

这是脚本的一个版本,其中在parallel{}块中显式指定了并行阶段:

pipeline {
    agent any
    stages {
        stage ("Parallel Build") {
            parallel {
                stage ("Windows") {
                    steps {
                        echo "TEST Windows"
                    }
                }
                stage ("Linux") {
                    steps {
                        echo "TEST Linux"
                    }
                }
            }
        }
    }
}

我的计划是在parallel{}块中动态创建阶段(取决于所需的配置),但是我不确定语法或是否完全可能。

类似这样的东西:

def stage_list = {
    stage ("Windows") {          <=== How to correctly create the stage_list?
        steps {
            echo "TEST Windows"
        }
    }
    stage ("Linux") {
        steps {
            echo "TEST Linux"
        }
    }
}

pipeline { 
    agent any
    stages {    
        stage ("Parallel Build") {
                parallel stage_list <== How to replace a block with variable?
        }
    }
}

以上内容将在詹金斯中返回错误:

WorkflowScript: 17: Expected a block for parallel @ line 17, column 9.
           stage ("Parallel Build") {
           ^

WorkflowScript: 17: Expected one of "steps", "stages", or "parallel" for stage "Parallel Build" @ line 17, column 9.
           stage ("Parallel Build") {
           ^

有人知道怎么做吗?


编辑:在前两个答案之后,我想稍作更新。

我测试了创建stage_list变量的建议方法。但是,如果我将对parallel stage_list的调用放入原始结构中,则会得到与以前相同的错误。与script一起使用时,它运行良好

pipeline { 
    agent any
    stages {    
        stage ("Parallel Build") {
            steps {
                script {
                    parallel stepsForParallel
                }
            }            
        }
    }
}

有人可以向我解释差异吗?为什么它不能与stepsscript一起使用,而不能没有它们呢?


编辑2:出于文档方面的原因,我想用解决问题的方法来结束问题:

SmartToms的答案和Jenkins在Pipeline Syntax with Docker上的官方文档明确指出,声明性管道和脚本管道是需要分开处理的两种单独方法(请注意每个示例下方的“ Toggle Scripted Pipeline”链接)。

解决我的问题的一种方法是使用脚本化管道-如果有人对此示例感兴趣,下面是指向pipeline script的概要的链接,该链接说明了原理。

2 个答案:

答案 0 :(得分:1)

通过此documentation,可以这样做:

// Creation of the stage_list
def stage_list = ["Windows", "Linux"]

// Creation of a map of stages
def stepsForParallel = stage_list.collectEntries {
    ["echoing ${it}" : transformIntoStage(it)]
}

// Run the stages in parallel
parallel stepsForParallel

// Creation of the stage
def transformIntoStage(inputString) {
    return {
        stage (inputString) {
            steps {
                echo "TEST "+inputString
            }
        }
    }
}

您可以找到有关并行Jenkins声明式管道here的更多信息。


修改

  

为什么它不能与stepsscript一起使用,却不能没有它们呢?

根据此documentation,我认为将parallel与列表一起使用是 old 方法(声明式管道1.2之前的方法),该方法要求在声明性管道。

似乎新方法parallel(来自Declarative Pipeline 1.2)不能与列表一起使用。因此,要执行此操作,必须使用 old 脚本化管道方法,因此,您需要将命令pipeline stage_listscript封装在一起,而该命令本身必须与{{1 }}。

您可以找到有关脚本化管道和声明性管道here的更多信息。

答案 1 :(得分:0)

基于SmartTom的示例,但是您可以复制/粘贴该示例,并且可以正常工作:

// Creation of the stage_list
def node_list = ["win7", "linux"]

// Creation of a map of stages
def stepsForParallel = node_list.collectEntries {
    ["echoing ${it}" : transformIntoStage(it)]
}

// Run the stages in parallel
parallel stepsForParallel

// Creation of the stage
def transformIntoStage(inputString) {
    return {
        node (inputString) {
          echo "TEST "+inputString
        }
    }
}

我建议您使用脚本化管道语法,该语法更强大,更灵活