Jenkins 并行构建不同的代理
Jenkins parallel build on different agents
我有一个 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?
}
}
}
以上将return Jenkins 报错:
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
}
}
}
}
}
谁能给我解释一下区别?为什么它适用于 steps
和 script
但没有它们就不行?
编辑 2: 出于文档原因,我想用解决问题的方法来结束我的问题:
SmartToms answer 和 Jenkins 的官方文档 Pipeline Syntax with Docker 明确声明式管道和脚本式管道是两种不同的方法,需要区别对待(注意 "Toggle Scripted Pipeline" link 在每个示例下方)。
解决我的问题的一种方法是使用脚本化管道 - 如果有人对此示例感兴趣,这里有一个 link 到要点,pipeline script 显示了原理。
据此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。
编辑:
Why does does it work with steps
and script
but not without them?
根据这个 documentation,我认为将 parallel
与列表一起使用是 old 方法(声明式管道 1.2 之前的版本),它需要在声明性管道中使用脚本化管道。
新方法parallel
(来自声明式管道 1.2)似乎不能与列表一起使用。所以,要做到这一点,你必须使用 old 脚本化管道方法,因此你需要用 script
封装你的命令 pipeline stage_list
,它本身需要用steps
.
您可以找到有关脚本化管道和声明式管道的更多信息here。
基于 SmartTom 的示例,但是您可以 copy/paste 并且它有效:
// 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
}
}
}
我建议您使用脚本化管道语法,它更强大、更灵活
我有一个 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?
}
}
}
以上将return Jenkins 报错:
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
}
}
}
}
}
谁能给我解释一下区别?为什么它适用于 steps
和 script
但没有它们就不行?
编辑 2: 出于文档原因,我想用解决问题的方法来结束我的问题:
SmartToms answer 和 Jenkins 的官方文档 Pipeline Syntax with Docker 明确声明式管道和脚本式管道是两种不同的方法,需要区别对待(注意 "Toggle Scripted Pipeline" link 在每个示例下方)。
解决我的问题的一种方法是使用脚本化管道 - 如果有人对此示例感兴趣,这里有一个 link 到要点,pipeline script 显示了原理。
据此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。
编辑:
Why does does it work with
steps
andscript
but not without them?
根据这个 documentation,我认为将 parallel
与列表一起使用是 old 方法(声明式管道 1.2 之前的版本),它需要在声明性管道中使用脚本化管道。
新方法parallel
(来自声明式管道 1.2)似乎不能与列表一起使用。所以,要做到这一点,你必须使用 old 脚本化管道方法,因此你需要用 script
封装你的命令 pipeline stage_list
,它本身需要用steps
.
您可以找到有关脚本化管道和声明式管道的更多信息here。
基于 SmartTom 的示例,但是您可以 copy/paste 并且它有效:
// 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
}
}
}
我建议您使用脚本化管道语法,它更强大、更灵活