从 Jenkins 2.0 管道中的并行执行访问构建
Access builds from Parallel execution in Jenkins 2.0 Pipeline
我目前正在使用 Build Flow 插件,它似乎已被 Jenkins 2.0 中的 Pipelines 所取代。
运行 使用新管道重建我们现有工作的一些问题。
目前,我有类似这样的代码:
ignore(FAILURE) {
join = parallel([
job1: {build('job1')},
job2: {build('job2')},
job3: {build('job3')}
])
}
results = [join.job1.result.toString(), join.job2.result.toString(), join.job2.result.toString()]
if(join.job1.result.toString() == 'SUCCESS') {
buildList << join.job1.lastBuild.getDisplayName()
}
此处的目标是 运行 并行执行多个现有作业,然后访问有关已完成构建的信息。这在 Build Flow 插件中一直没有问题。
我一直找不到使用新管道访问此数据的方法。
echo 'Checking streams for latest builds'
join = [:]
join['Job1'] = { build job: 'Job1', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
join['Job2'] = { build job: 'Job2', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
join['Job3'] = { build job: 'Job3', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
parallel join
join['Job1'] 的转储无法像 Build Flow 插件那样提供对 AbstractBuild 或类似内容的访问权限。相反,它显示:
<org.jenkinsci.plugins.workflow.cps.CpsClosure2@2eac6ed9
def=com.cloudbees.groovy.cps.impl.CpsClosureDef@59647704
delegate=WorkflowScript@3aa1807f
owner=WorkflowScript@3aa1807f
thisObject=WorkflowScript@3aa1807f
resolveStrategy=0
directive=0
parameterTypes=null
maximumNumberOfParameters=0
bcw=null>
使用新的管道,有没有办法访问像 job1.result、job1.lastBuild、job1.lastBuild.getDisplayName() 这样的数据?
您可以在 parallel
步骤后使用 Jenkins API 访问该数据:
Jenkins.instance.getItemByFullName('Job1').lastBuild
有点晚了,但您也可以在闭包中定义 build
命令返回的 runWrapper
对象,并将其放置在 parallel
命令之外定义的映射中。
这是一个例子。 注意: 我正在使用 propagate: false
以便不会抛出异常(JUnit 测试失败等)。您必须决定如何处理异常,try/catch/finally,等等
要执行的示例管道作业(需要使用字符串参数 commandStr
进行参数化):
env.PASSED_CMD="${params.commandStr}"
stage('command-exec') {
node {
sh "${commandStr}"
}
}
正在执行作业(配置):
buildRuns = [:]
buildResults = [:]
def buildClosure(String jobKey, String paramAValue) {
return {
def runWrapper = build(
job: 'command-test-job',
propagate: false,
parameters: [[$class: 'StringParameterValue', name: 'commandStr', value: paramAValue]]
)
buildResults."$jobKey" = runWrapper
}
}
buildRuns."job1" = buildClosure("job1", "echo 'HI' && exit 0")
buildRuns."job2" = buildClosure("job2", "echo 'HO' && exit 0")
parallel buildRuns
for(k in buildRuns.keySet()) {
def runResult = buildResults."$k"
echo "$k -> ${runResult.result}"
echo "$k -> ${runResult.buildVariables.PASSED_CMD}"
}
构建日志显示:
[Pipeline] parallel
[Pipeline] [job1] { (Branch: job1)
[Pipeline] [job2] { (Branch: job2)
[Pipeline] [job1] build (Building command-test-job)
[job1] Scheduling project: command-test-job
[Pipeline] [job2] build (Building command-test-job)
[job2] Scheduling project: command-test-job
[job1] Starting building: command-test-job #7
[job2] Starting building: command-test-job #8
[Pipeline] [job2] }
[Pipeline] [job1] }
[Pipeline] // parallel
[Pipeline] echo
job1 -> SUCCESS
[Pipeline] echo
job1 -> echo 'HI' && exit 0
[Pipeline] echo
job2 -> SUCCESS
[Pipeline] echo
job2 -> echo 'HO' && exit 0
[Pipeline] End of Pipeline
Finished: SUCCESS
这与 非常相似,但您实际上不需要明确定义 runwrapper 或事先将其放置在附加地图中。
tl;dr 您可以将并行构建存储到 hashMap 并通过直接遍历它的 keySet 来访问该映射
对这个答案持保留态度,我使用的是旧版本的管道(Jenkins 2.7.2 和管道 2.2)。
您可以将并行构建结果存储到 hashMap 并遍历映射的 keySet 以获取有关构建的一些信息。
def create_build_job(job_name, pool_label="master", propagate=false) {
build job: job_name, parameters: [[$class: 'LabelParameterValue', name: "node_label", label: "${pool_label}"]], propagate: propagate, wait:true
}
def buildmap = [:]
def build_results
stage 'Perform Build'
//test1 is set to fail, test2 is set to succeed
buildmap['test1'] = {create_build_job('test1', "your_node_label")}
buildmap['test2'] = {create_build_job('test2', "your_node_label")}
build_results = parallel buildmap
for(k in build_results.keySet()){
println build_results["${k}"].getProperties()
}
对于这个管道,我只是转储存储在地图中的项目中的 RunWrapper 的所有属性,但是您可以直接访问每个 属性,所以如果您想要构建的结果,您可以只是做:
build_results["${k}"].result
此管道产生的控制台输出(已编辑任何可能的识别信息是:
Started by user <user>
[Pipeline] stage (Perform Build)
Entering stage Perform Build
Proceeding
[Pipeline] parallel
[Pipeline] [test1] { (Branch: test1)
[Pipeline] [test2] { (Branch: test2)
[Pipeline] [test1] build (Building test1)
[test1] Scheduling project: test1
[test1] Starting building: test1 #11
[Pipeline] [test2] build (Building test2)
[test2] Scheduling project: test2
[test2] Starting building: test2 #11
[Pipeline] }
[Pipeline] }
[Pipeline] // parallel
[Pipeline] echo
{rawBuild=test1 #11, class=class org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper, absoluteUrl=<jenkins_url>/job/test1/11/, buildVariables={}, previousBuild=org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@1480013a, id=11, nextBuild=null, changeSets=[], result=FAILURE, description=null, startTimeInMillis=1509667550519, timeInMillis=1509667550510, duration=956, number=11, displayName=#11}
[Pipeline] echo
{rawBuild=test2 #11, class=class org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper, absoluteUrl=<jenkins_url>/job/test2/11/, buildVariables={}, previousBuild=org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@2d9c7128, id=11, nextBuild=null, changeSets=[], result=SUCCESS, description=null, startTimeInMillis=1509667550546, timeInMillis=1509667550539, duration=992, number=11, displayName=#11}
[Pipeline] End of Pipeline
Finished: SUCCESS
我目前正在使用 Build Flow 插件,它似乎已被 Jenkins 2.0 中的 Pipelines 所取代。
运行 使用新管道重建我们现有工作的一些问题。
目前,我有类似这样的代码:
ignore(FAILURE) {
join = parallel([
job1: {build('job1')},
job2: {build('job2')},
job3: {build('job3')}
])
}
results = [join.job1.result.toString(), join.job2.result.toString(), join.job2.result.toString()]
if(join.job1.result.toString() == 'SUCCESS') {
buildList << join.job1.lastBuild.getDisplayName()
}
此处的目标是 运行 并行执行多个现有作业,然后访问有关已完成构建的信息。这在 Build Flow 插件中一直没有问题。
我一直找不到使用新管道访问此数据的方法。
echo 'Checking streams for latest builds'
join = [:]
join['Job1'] = { build job: 'Job1', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
join['Job2'] = { build job: 'Job2', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
join['Job3'] = { build job: 'Job3', parameters: [[$class: 'StringParameterValue', name: 'TimeWindow', value: '1200']], propagate: false}
parallel join
join['Job1'] 的转储无法像 Build Flow 插件那样提供对 AbstractBuild 或类似内容的访问权限。相反,它显示:
<org.jenkinsci.plugins.workflow.cps.CpsClosure2@2eac6ed9
def=com.cloudbees.groovy.cps.impl.CpsClosureDef@59647704
delegate=WorkflowScript@3aa1807f
owner=WorkflowScript@3aa1807f
thisObject=WorkflowScript@3aa1807f
resolveStrategy=0
directive=0
parameterTypes=null
maximumNumberOfParameters=0
bcw=null>
使用新的管道,有没有办法访问像 job1.result、job1.lastBuild、job1.lastBuild.getDisplayName() 这样的数据?
您可以在 parallel
步骤后使用 Jenkins API 访问该数据:
Jenkins.instance.getItemByFullName('Job1').lastBuild
有点晚了,但您也可以在闭包中定义 build
命令返回的 runWrapper
对象,并将其放置在 parallel
命令之外定义的映射中。
这是一个例子。 注意: 我正在使用 propagate: false
以便不会抛出异常(JUnit 测试失败等)。您必须决定如何处理异常,try/catch/finally,等等
要执行的示例管道作业(需要使用字符串参数 commandStr
进行参数化):
env.PASSED_CMD="${params.commandStr}"
stage('command-exec') {
node {
sh "${commandStr}"
}
}
正在执行作业(配置):
buildRuns = [:]
buildResults = [:]
def buildClosure(String jobKey, String paramAValue) {
return {
def runWrapper = build(
job: 'command-test-job',
propagate: false,
parameters: [[$class: 'StringParameterValue', name: 'commandStr', value: paramAValue]]
)
buildResults."$jobKey" = runWrapper
}
}
buildRuns."job1" = buildClosure("job1", "echo 'HI' && exit 0")
buildRuns."job2" = buildClosure("job2", "echo 'HO' && exit 0")
parallel buildRuns
for(k in buildRuns.keySet()) {
def runResult = buildResults."$k"
echo "$k -> ${runResult.result}"
echo "$k -> ${runResult.buildVariables.PASSED_CMD}"
}
构建日志显示:
[Pipeline] parallel
[Pipeline] [job1] { (Branch: job1)
[Pipeline] [job2] { (Branch: job2)
[Pipeline] [job1] build (Building command-test-job)
[job1] Scheduling project: command-test-job
[Pipeline] [job2] build (Building command-test-job)
[job2] Scheduling project: command-test-job
[job1] Starting building: command-test-job #7
[job2] Starting building: command-test-job #8
[Pipeline] [job2] }
[Pipeline] [job1] }
[Pipeline] // parallel
[Pipeline] echo
job1 -> SUCCESS
[Pipeline] echo
job1 -> echo 'HI' && exit 0
[Pipeline] echo
job2 -> SUCCESS
[Pipeline] echo
job2 -> echo 'HO' && exit 0
[Pipeline] End of Pipeline
Finished: SUCCESS
这与
tl;dr 您可以将并行构建存储到 hashMap 并通过直接遍历它的 keySet 来访问该映射
对这个答案持保留态度,我使用的是旧版本的管道(Jenkins 2.7.2 和管道 2.2)。
您可以将并行构建结果存储到 hashMap 并遍历映射的 keySet 以获取有关构建的一些信息。
def create_build_job(job_name, pool_label="master", propagate=false) {
build job: job_name, parameters: [[$class: 'LabelParameterValue', name: "node_label", label: "${pool_label}"]], propagate: propagate, wait:true
}
def buildmap = [:]
def build_results
stage 'Perform Build'
//test1 is set to fail, test2 is set to succeed
buildmap['test1'] = {create_build_job('test1', "your_node_label")}
buildmap['test2'] = {create_build_job('test2', "your_node_label")}
build_results = parallel buildmap
for(k in build_results.keySet()){
println build_results["${k}"].getProperties()
}
对于这个管道,我只是转储存储在地图中的项目中的 RunWrapper 的所有属性,但是您可以直接访问每个 属性,所以如果您想要构建的结果,您可以只是做:
build_results["${k}"].result
此管道产生的控制台输出(已编辑任何可能的识别信息是:
Started by user <user>
[Pipeline] stage (Perform Build)
Entering stage Perform Build
Proceeding
[Pipeline] parallel
[Pipeline] [test1] { (Branch: test1)
[Pipeline] [test2] { (Branch: test2)
[Pipeline] [test1] build (Building test1)
[test1] Scheduling project: test1
[test1] Starting building: test1 #11
[Pipeline] [test2] build (Building test2)
[test2] Scheduling project: test2
[test2] Starting building: test2 #11
[Pipeline] }
[Pipeline] }
[Pipeline] // parallel
[Pipeline] echo
{rawBuild=test1 #11, class=class org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper, absoluteUrl=<jenkins_url>/job/test1/11/, buildVariables={}, previousBuild=org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@1480013a, id=11, nextBuild=null, changeSets=[], result=FAILURE, description=null, startTimeInMillis=1509667550519, timeInMillis=1509667550510, duration=956, number=11, displayName=#11}
[Pipeline] echo
{rawBuild=test2 #11, class=class org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper, absoluteUrl=<jenkins_url>/job/test2/11/, buildVariables={}, previousBuild=org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@2d9c7128, id=11, nextBuild=null, changeSets=[], result=SUCCESS, description=null, startTimeInMillis=1509667550546, timeInMillis=1509667550539, duration=992, number=11, displayName=#11}
[Pipeline] End of Pipeline
Finished: SUCCESS