【问题标题】:Can Jenkins pipelines have variable stages?Jenkins 管道可以有可变阶段吗?
【发布时间】:2023-01-21 02:11:11
【问题描述】:

根据我使用 Jenkins 声明式语法管道的经验,我知道您可以使用 when 子句有条件地跳过一个阶段。例如。:

run_one = true
run_two = false
run_three = true

pipeline {
    agent any

    stages {
        stage('one') {
            when {
                expression { run_one }
            }
            steps {
                echo 'one'
            }
        }
        stage('two') {
            when {
                expression { run_two }
            }
            steps {
                echo 'two'
            }
        }
        stage('three') {
            when {
                expression { run_three }
            }
            steps {
                echo 'three'
            }
        }
    }
}

...在上面的代码块中,有三个阶段,onetwothree,每个阶段的执行都以布尔变量为条件。

IE。范例是存在已知阶段的固定超集,可以有条件地跳过其中的各个阶段。

Jenkins 管道脚本是否支持没有已知阶段的固定超集的模型,并且可以“查找”阶段以进行条件执行?

将其表述为伪代码,可能类似于以下内容:

my_list = list populated _somehow_, maybe reading a file, maybe Jenkins build params, etc.

pipeline {
    agent any

    stages {
        if (stage(my_list[0]) exists) {
            run(stage(my_list[0]))
        }
        if (stage(my_list[1]) exists) {
            run(stage(my_list[1]))
        }
        if (stage(my_list[2]) exists) {
            run(stage(my_list[2]))
        }
    }
}

我认为另一种思考我所问问题的方法是:是否有一种方法可以从一些动态的阶段组合动态构建管道?

【问题讨论】:

  • 有关示例,请参见this answer
  • 您需要在 Groovy 中执行此操作,因此需要在脚本管道或共享库的全局变量方法中对其进行编码。
  • @MaratC - 我想知道您是否可以扩展您的链接答案(在这里作为答案或扩展您的链接答案)?到目前为止,我在过去的在线研究中还没有看到创建管道的“风格”,因此我不完全理解您演示的代码示例如何工作的机制,并且想学习。也有相关的出现,例如:您的链接示例似乎并行运行所有阶段;是否可以扩展该示例以显示阶段是否也可以串行运行?

标签: jenkins jenkins-pipeline


【解决方案1】:

对于动态阶段,您可以编写完全脚本化的管道或使用带有脚本部分的声明性管道(例如,通过使用 script {…} 步骤或调用您自己的函数)。有关概述,请参阅Declarative versus Scripted Pipeline syntaxPipeline syntax overview

Blue Ocean 更好地支持声明式管道,因此我个人会以此为起点。缺点可能是您需要有一个固定的根阶段,但我通常将其命名为“start”或“init”,这样看起来不会太尴尬。

在脚本部分,您可以调用 stage 作为功能, 所以它可以完全动态地使用。

pipeline {
    agent any

    stages {
        stage('start') {
            steps {
                createDynamicStages()
            }
        }
    }
}

void createDynamicStages() {
    // Stage list could be read from a file or whatever
    def stageList = ['foo', 'bar']
    
    for( stageName in stageList ) {
        stage( stageName ) {
            echo "Hello from stage $stageName"
        }
    }
}

这在 Blue Ocean 中显示如下:

【讨论】:

    最近更新 更多