问题描述
想要编写一个声明性流水线代码,该代码接受一个映射并创建一个流水线。用户可以实现顺序阶段或并行阶段,但在创建包含并行阶段内部顺序阶段的流水线时遇到问题。
输入数据是一个映射。映射中的每个列表应该并行运行,并且与每个键对应的列表中的项目应该按顺序运行。
示例数据:[1:[11,12], 2:[21,22], 3:[31,32]]
使用的Jenkins版本是2.164.3
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
这个问题在官方博客文章中有详细介绍,当添加了在并行块内嵌套阶段的功能时,这个问题就被解决了。
以下是从博客文章中复制的示例。在这个示例中,Windows和Linux块是并行运行的,但每个块内的阶段是按顺序运行的:
pipeline {
agent none
stages {
stage("build and deploy on Windows and Linux") {
parallel {
stage("windows") {
agent {
label "windows"
}
stages {
stage("build") {
steps {
bat "run-build.bat"
}
}
stage("deploy") {
when {
branch "master"
}
steps {
bat "run-deploy.bat"
}
}
}
}
stage("linux") {
agent {
label "linux"
}
stages {
stage("build") {
steps {
sh "./run-build.sh"
}
}
stage("deploy") {
when {
branch "master"
}
steps {
sh "./run-deploy.sh"
}
}
}
}
}
}
}
}
编辑:我忽略了您是基于任意输入来尝试这样做。如果您想要这样做,您必须使用脚本流水线(或嵌套在声明性流水线中的脚本)。普通的声明性流水线不支持这种类型的运行时定义流水线。
方案2
即使在脚本流水线的情况下,也可以在并行内部嵌套。并行接受Map。我需要的是Map<String, closure\>。是的,这是可能的。我已经做过几次了,这个网站上也有一些关于这个主题的问题。闭包是一段任意的代码块,所以你可以在其中放任何你想要的东西,包括阶段定义。
以下是一个示例代码:
pipeline {
agent any
stages {
stage("parallel stages") {
steps {
script {
def inputMap = [1:[11,12], 2:[21,22], 3:[31,32]]
def parallelStages = [:]
inputMap.each { key, value ->
parallelStages["Stage ${key}"] = {
stage("Sequential stages for ${key}") {
value.each { item ->
stage("Item ${item}") {
// Your steps for each item
}
}
}
}
}
parallel parallelStages
}
}
}
}
}
在这个示例中,我们首先定义了一个输入映射inputMap
,然后创建了一个空的并行阶段parallelStages
。然后,我们使用each
方法遍历输入映射,并为每个键值对创建一个闭包。在闭包中,我们定义了一个顺序阶段,用于遍历值列表,并在每个项目上执行相应的步骤。最后,我们使用parallel
关键字并传入并行阶段的闭包。
请注意,这个示例是基于脚本流水线的,因为它需要在运行时动态定义流水线。