Jenkins循环创建并行流水线仅触发最后一个作业问题排查
Jenkins上游流水线仅触发单个作业问题解决
问题根源
这是Groovy闭包的变量捕获特性导致的。你用for循环时,jobName是一个共享变量,闭包并不会立即执行,而是在parallel调用时才会读取jobName的值——此时循环已经执行完毕,jobName已经指向列表的最后一个元素(比如pipeline2),所以所有并行任务都会触发同一个作业。
解决方案
有几种简单的修复方式:
方式1:使用each遍历数组(推荐)
Groovy的each循环会为每个迭代创建独立的变量作用域,闭包能正确捕获当前迭代的jobName值:
def testJobs = [ 'pipeline1', 'pipeline2' ] def buildList = [:] testJobs.each { jobName -> buildList[jobName] = { build job: jobName, propagate: false } } def buildResults = parallel(buildList)
方式2:在for循环内创建局部变量
手动在循环体内创建局部变量,让闭包捕获这个变量的当前值:
def testJobs = [ 'pipeline1', 'pipeline2' ] def buildList = [:] for (jobName in testJobs){ def currentJob = jobName // 用局部变量保存当前迭代的作业名 buildList[jobName] = { build job: currentJob, propagate: false } } def buildResults = parallel(buildList)
方式3:使用闭包参数绑定
通过闭包的call方法绑定参数,确保每个闭包拿到独立的作业名:
def testJobs = [ 'pipeline1', 'pipeline2' ] def buildList = [:] for (jobName in testJobs){ buildList[jobName] = { String currentJob -> build job: currentJob, propagate: false }.call(jobName) } def buildResults = parallel(buildList)
验证效果
修复后执行,日志会正确显示每个并行任务触发对应的作业:
[pipeline1] Starting building: pipeline1 #3 [pipeline2] Starting building: pipeline2 #6
内容的提问来源于stack exchange,提问作者Abhishek Parmar
相关产品推荐
相关产品推荐

