运行 管道的一部分作为单独的作业
Run Parts of a Pipeline as Separate Job
我们正在考虑将 Jenkins Pipeline 插件用于一个相当复杂的项目,该项目由多个交付组成,在合并之前需要使用不同的工具(在不同的机器上)构建这些交付。不过,使用单个 Jenkinsfile
完成完整构建似乎很容易,而且我喜欢自动发现管道附带的 git 个分支。
但是,在这一点上,我们为每个交付都有作业,并使用基于构建流程的 "meta" 作业来编排各个作业。这样做的好处是,如果只进行了一些小的更改,它还允许只启动一个单独的作业,只是为了看看这个交付是否仍然可以编译。
为了效仿这一点,我想到了一些想法:
- 对交付使用不同的
Jenkinsfile
,并在顶级 Jenkinsfile
中使用 load
;似乎 Multibranch Pipeline 作业还不允许配置 Jenkinsfile
使用 (https://issues.jenkins-ci.org/browse/JENKINS-35415),但是,因此为单个交付创建作业仍然是开放的。
- 为 "top-level" 作业提供一个配置选项,并为
Jenkinsfile
中的所有交付提供 if
s,以便能够 select 构建。但是,这会在一个管道中混合不同的构建类型,并且至少会扰乱构建时间的估计。
这些是可行的选择,还是有更好的选择?
你可以做的是编写一个流水线脚本,在单个阶段周围有 "if"-guards,如下所示:
stage "s1"
if (theStage in ["s1","all"]) {
sleep 2
}
stage "s2"
if (theStage in ["s2", "all"]) {
sleep 2
}
stage "s3"
if (theStage in ["s3", "all"]) {
sleep 2
}
然后您可以通过将参数 "theStage" 设置为 "all" 来制作使用此脚本的 "main" 作业和 运行 所有阶段。此作业将在所有阶段一次 运行 时收集统计信息,并为您提供有用的估计时间。
此外,您可以创建一个 "partial run" 使用此脚本的作业,并使用您想要 运行 的阶段进行参数化。不过,估计不会很有用。
请注意,按照 Martin Ba 的建议,我将舞台本身放到主脚本中,只将执行代码放入条件中。这确保作业的可视化更加可靠
作为对先前答案的扩展,我会提出类似的建议:
def stageIf(String name, Closure body) {
if (params.firstStage <= name && params.lastStage >= name) {
stage(name, body)
} else {
stage(name) {
echo "Stage skipped: $name"
}
}
}
node('linux') {
properties([
parameters([
choiceParam(
name: 'firstStage',
choices: '1.Build\n' +
'2.Docker\n' +
'3.Deploy',
description: 'First stage to start',
defaultValue: '1.Build',
),
choiceParam(
name: 'lastStage',
choices: '3.Deploy\n' +
'2.Docker\n' +
'1.Build',
description: 'Last stage to start',
defaultValue: '3.Deploy',
),
])
])
stageIf('1.Build') {
// ...
}
stageIf('3.Deploy') {
// ...
}
}
虽然没有我希望的那么完美,但至少可以用。
我们正在考虑将 Jenkins Pipeline 插件用于一个相当复杂的项目,该项目由多个交付组成,在合并之前需要使用不同的工具(在不同的机器上)构建这些交付。不过,使用单个 Jenkinsfile
完成完整构建似乎很容易,而且我喜欢自动发现管道附带的 git 个分支。
但是,在这一点上,我们为每个交付都有作业,并使用基于构建流程的 "meta" 作业来编排各个作业。这样做的好处是,如果只进行了一些小的更改,它还允许只启动一个单独的作业,只是为了看看这个交付是否仍然可以编译。
为了效仿这一点,我想到了一些想法:
- 对交付使用不同的
Jenkinsfile
,并在顶级Jenkinsfile
中使用load
;似乎 Multibranch Pipeline 作业还不允许配置Jenkinsfile
使用 (https://issues.jenkins-ci.org/browse/JENKINS-35415),但是,因此为单个交付创建作业仍然是开放的。 - 为 "top-level" 作业提供一个配置选项,并为
Jenkinsfile
中的所有交付提供if
s,以便能够 select 构建。但是,这会在一个管道中混合不同的构建类型,并且至少会扰乱构建时间的估计。
这些是可行的选择,还是有更好的选择?
你可以做的是编写一个流水线脚本,在单个阶段周围有 "if"-guards,如下所示:
stage "s1"
if (theStage in ["s1","all"]) {
sleep 2
}
stage "s2"
if (theStage in ["s2", "all"]) {
sleep 2
}
stage "s3"
if (theStage in ["s3", "all"]) {
sleep 2
}
然后您可以通过将参数 "theStage" 设置为 "all" 来制作使用此脚本的 "main" 作业和 运行 所有阶段。此作业将在所有阶段一次 运行 时收集统计信息,并为您提供有用的估计时间。
此外,您可以创建一个 "partial run" 使用此脚本的作业,并使用您想要 运行 的阶段进行参数化。不过,估计不会很有用。
请注意,按照 Martin Ba 的建议,我将舞台本身放到主脚本中,只将执行代码放入条件中。这确保作业的可视化更加可靠
作为对先前答案的扩展,我会提出类似的建议:
def stageIf(String name, Closure body) {
if (params.firstStage <= name && params.lastStage >= name) {
stage(name, body)
} else {
stage(name) {
echo "Stage skipped: $name"
}
}
}
node('linux') {
properties([
parameters([
choiceParam(
name: 'firstStage',
choices: '1.Build\n' +
'2.Docker\n' +
'3.Deploy',
description: 'First stage to start',
defaultValue: '1.Build',
),
choiceParam(
name: 'lastStage',
choices: '3.Deploy\n' +
'2.Docker\n' +
'1.Build',
description: 'Last stage to start',
defaultValue: '3.Deploy',
),
])
])
stageIf('1.Build') {
// ...
}
stageIf('3.Deploy') {
// ...
}
}
虽然没有我希望的那么完美,但至少可以用。