问题描述
希望将其定制的Jenkins集成方案转换为流水线。然而,他无法弄清楚如何做到以下操作。是否有人可以提供帮助,并提供一个可以实现以下需求的Jenkins脚本?
1---2---3-----------9---10
| | |---4-------| | |
| |---5---6---| | | |---7---|
其中:
– 1: 启动流水线
– 10: 结束流水线
– 5: 构建一些文件,供6和7使用,并作为最终的构件
– 2, 3, 4, 6, 7: 具有jUnit结果文件,应在测试结束时可用,即使有一个失败也应该可用
用户还提出了一种可能的简化方案,即在3, 4, 5之后合并。如下所示:
1---2---3-------6-------9---10
| | | | |---4---|
7---| | | |---5---|
解决方案
请注意以下操作可能涉及版本差异,备份前做好准备。
最佳解决方案
根据用户提供的需求,使用嵌套的并行语句是一种解决方案。需要注意的是,当前的Jenkins Blue Ocean对这种结构的可视化显示存在问题,但可以通过其他插件如Groovy Postbuild来展示结果。以下是一种实现方法:
- 首先,在主要的触发任务的Jenkinsfile中,使用
script
块来启动嵌套的并行任务:
pipeline {
agent any
stages {
stage('Build Nested Parallel') {
steps {
script {
def builds = [
"subJob1": performTriggerJob('subJob1'),
"subJob2": performTriggerJob('subJob2'),
"subJob3": {
script {
performTriggerJob('subJob3').call()
parallel (
'nestedJob1': performTriggerJob('nestedJob1'),
'nestedJob2': performTriggerJob('nestedJob2')
)
}
}
]
parallel builds
}
}
}
// 其他阶段
}
}
- 为了在并行任务之间共享结果,可以使用
buildResults
变量来存储每个任务的结果,然后在流水线的后续阶段中对这些结果进行处理:
stage("Post steps") {
steps {
script {
for (finishedBuildObj in buildResults) {
buildObj = finishedBuildObj
projectName = buildObj.getFullProjectName()
if (buildObj.getResult() != "SUCCESS") {
buildObj = buildObj.getPreviousSuccessfulBuild()
}
copyArtifacts(
projectName: projectName,
optional: true,
flatten: true,
target: 'allArtifacts',
fingerprintArtifacts: true,
selector: specific(buildObj.getNumber().toString())
)
}
}
}
}
以上解决方案使用了嵌套的并行语句来实现复杂的流水线结构。每个任务都被定义为一个performTriggerJob
函数,并且结果被存储在buildResults
列表中,以便在后续阶段中进行处理。请确保为并行任务分配足够的执行器以充分发挥并行运行的优势。
其他方案
另一种可能的方法是通过嵌套的parallel
命令来实现并行运行,这要求脚本在scripted pipeline中编写。以下是一个示例脚本:
def performDeploymentStages(String node, String app) {
stage("build") {
echo "Building the app [${app}] on node [${node}]"
}
stage("deploy") {
echo "Deploying the app ${app}] on node [${node}]"
}
stage("test") {
echo "Testing the app [${app}] on node [${node}]"
}
}
pipeline {
agent {
label 'master'
}
parameters {
string(name: 'NODES', defaultValue: '1,2,3', description: 'Nodes to build, deploy and test')
choice(name: 'ENV', choices: 'qa', description: 'Environment')
string(name: 'APPS', defaultValue: 'app01,app02', description: 'App names')
}
stages {
stage('parallel stage') {
steps {
script {
def nodes = [:]
for (node in params.NODES.tokenize(',')) {
def apps = [:]
for (app in params.APPS.tokenize(',')) {
performDeploymentStages(node, app)
}
parallel apps
}
parallel nodes
}
}
}
}
}
以上脚本中,我们定义了一个performDeploymentStages
函数来表示构建、部署和测试阶段。在主pipeline的parallel stage
中,我们使用script
块来定义并行任务,使用嵌套的parallel
命令来实现并行运行。
请注意,这两种方案都需要根据实际需求进行修改和调整。其中最佳解决方案使用了Groovy的Closure来处理并行任务的结果,而另一种方案则使用了函数来表示各个阶段,用户可以根据自己的喜好和需求来选择适合的方法。同时,根据Jenkins版本的不同,一些细节可能需要进行调整以适应最新的特性和插件。