如何编写包含并行作业内部顺序作业的动态声明性流水线

68次阅读
没有评论

问题描述

想要编写一个声明性流水线代码,该代码接受一个映射并创建一个流水线。用户可以实现顺序阶段或并行阶段,但在创建包含并行阶段内部顺序阶段的流水线时遇到问题。
输入数据是一个映射。映射中的每个列表应该并行运行,并且与每个键对应的列表中的项目应该按顺序运行。
示例数据:[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关键字并传入并行阶段的闭包。
请注意,这个示例是基于脚本流水线的,因为它需要在运行时动态定义流水线。

正文完