我正在尝试使用工作流插件同时执行一项作业5次。这是代码段:
def concurrent=[:] for (int i = 0; i < 5; i++) { concurrent["concurrent${i}"] = { build job: 'test_job', parameters: [[$class: 'StringParameterValue', name:'queue', value: 'automation_prod.q'],[$class: 'StringParameterValue', name:'dummy', value: "${i}"]] } } parallel concurrent
此代码段导致test_job仅运行一次。我需要同时运行5次。
谢谢!
除了缺乏对脚本错误的诊断之外,这里的工作流中没有错误。在Groovy中,循环计数器i是在封闭范围内定义的,并且已被更改,因此在每次关闭运行时,它具有相同的值:5.在Jenkins之外,您可以看到此值以及该修复程序的概念:
i
$ groovy -e 'def cs = []; for (int i = 0; i < 5; i++) {def j = i; cs += {println "${i} vs. ${j}"}}; for (c in cs) {c()}' 5 vs. 0 5 vs. 1 5 vs. 2 5 vs. 3 5 vs. 4
在您的情况下,Jenkins进行了五次尝试来调度具有相同参数的同一下游项目,并将它们全部合并为一个队列项,从而构建了一个构建。(取决于时间,它可能已经开始了一个下游构建,然后再执行其他build步骤,在这种情况下,它将运行第二个下游构建,但通常少于五个总构建。)
build
这项新测试表明,您确实想做点什么;您只需要在闭包外部的新的词法范围变量中捕获循环变量的 当前 值即可。
顺便说说
def cs = []; (0..4).each {i -> cs += {println i}}; cs*.call()
确实可以从命令行Groovy正常工作,因为没有突变的循环变量。不幸的是,该语法在工作流中尚不可用:JENKINS-26481
要注意的是,你应该 不 使用一个“虚拟”的参数值来区分队列项。尽管今天可能会发生这种情况,但是希望可以解决该问题,以便所指定的参数值build与下游项目中实际定义的任何参数都不对应,将被警告跳过或导致错误。如果您认为需要一个虚拟参数,则可能是在做其他错误,但是如果没有解释为什么您希望下游项目多次运行而其输入中没有任何内容可以区分版本,那么就不可能给出建议。