问题描述
在Jenkins的声明性流水线中,是否有一种方式可以通过共享库编写阶段,以便可以将其添加到流水线中?
背景
对于许多项目,我需要在多个不同的服务器上运行测试。我的解决方案是创建一系列并行阶段,每个阶段对应我想要运行的每个服务器。我已经创建了下面这个流水线(以在2个服务器上运行为例):
pipeline {
agent any
stages {
stage('Test') {
parallel {
stage('San Jose') {
agent {
label "test && san-jose"
}
steps {
sh 'run-tests'
}
}
stage('Dallas') {
agent {
label 'test dallas'
}
steps {
sh 'run-tests'
}
}
}
}
}
}
这很不错,但我真的想保持我的代码DRY(不重复冗余),不想在每个项目中复制和粘贴这个测试阶段(特别是因为这必须在大约10台服务器上运行,只有标签每次更改)。
我可以将整个流水线放入我的共享库中(就像Jenkins文档中的示例那样),但那样我就无法自定义其他阶段(例如,添加一个发布阶段)。
我真正想做的是这样的:
pipeline {
agent any
stages {
runOnServers {
sh 'run-tests'
}
stage('Release') {
echo 'release'
}
}
}
解决方案
请注意以下操作注意版本差异及修改前做好备份。
最佳解决方案
是的,但(据我所知)您将不得不在共享库中使用脚本化流水线。这意味着您将传递给共享库的闭包(在下面的示例中,闭包是 sh 'run-tests'
)也必须是脚本化的。
在您的Jenkinsfile
中:
pipeline {
agent any
stages {
stage('Test') {
steps {
runOnServers {
sh 'run-tests'
}
}
}
stage('Release') {
echo 'release'
}
}
}
然后在您的共享库中,创建一个名为 vars/runOnServers.groovy
的文件:
def call(Closure closure) {
parallel({
SanJose: {
node("test && san-jose") {
stage('SanJose') {
closure()
}
}
},
Dallas: {
node('test dallas') {
stage('Dallas') {
closure()
}
}
}
})
}
在这个示例中,我们在流水线的Test
阶段内调用了名为runOnServers
的闭包。在共享库中的runOnServers.groovy
文件中,我们使用parallel
来并行运行不同服务器的测试,并在每个服务器上运行指定的闭包。这样,您可以通过在流水线中调用runOnServers
来实现在多个服务器上运行测试的需求。
请注意,如果您需要在共享库中进一步自定义其他阶段,您可以按照类似的方式进行操作。
方案2
使用脚本或工具来管理流水线的构建顺序可能会增加复杂性,并且需要确保共享库的正确使用。
另一种方法是编写脚本或使用工具来控制流水线的构建顺序。您可以通过手动使用node
和stage
来控制不同服务器上的测试执行顺序。然而,这可能会增加流水线定义的复杂性,需要确保流水线中的各个部分正确地协同工作。这个方法可能不如使用共享库那样优雅和易于维护。
无论您选择哪种方法,都应该根据您的需求和团队的实际情况做出决定。
请注意:以上解决方案是基于我对Jenkins和共享库的理解,如果您的环境有特定的配置或需求,请确保在实施前做好备份并进行适当的测试。
请在实际操作前仔细阅读文档和示例,并在测试环境中进行尝试,以确保解决方案的适用性和正确性。