Jenkins 并行管道:参数块中的所有子例程调用都从最后一个块传递参数

Jenkins parallel pipeline: All subroutine calls in parameter blocks pass arguments from last block

我寻求帮助以了解 Groovy 闭包的情况以及 "right" 做某事的方式。我有一个 Jenkins 管道,我在其中调用 5 个并行分支中的子例程;它采用一个参数,其实际值为字符串常量 - 来自并行分支的每次调用都不同。我看到的是所有 5 次执行都接收到在最后一个并行分支中命名的字符串常量:

片段:

def build_if_needed = { project ->
  println "build_if_needed: $project"
  // ultimately this will kick off a build job...
}

parallel (
  aaa : { build_if_needed('aaa')},
  bbb : { build_if_needed('bbb')},
  ccc : { build_if_needed('ccc')},
  ddd : { build_if_needed('ddd')},
  eee : { build_if_needed('eee')},
)

输出:

[Pipeline] parallel
[Pipeline] [aaa] { (Branch: aaa)
[Pipeline] [bbb] { (Branch: bbb)
[Pipeline] [ccc] { (Branch: ccc)
[Pipeline] [ddd] { (Branch: ddd)
[Pipeline] [eee] { (Branch: eee)
[Pipeline] [aaa] echo
[aaa] build_if_needed: eee
[Pipeline] [aaa] }
[Pipeline] [bbb] echo
[bbb] build_if_needed: eee
[Pipeline] [bbb] }
[Pipeline] [ccc] echo
[ccc] build_if_needed: eee
[Pipeline] [ccc] }
[Pipeline] [ddd] echo
[ddd] build_if_needed: eee
[Pipeline] [ddd] }
[Pipeline] [eee] echo
[eee] build_if_needed: eee
[Pipeline] [eee] }
[Pipeline] // parallel
[Pipeline] End of Pipeline

我希望在 [aaa] 中转储的参数值是 'aaa',而不是 'eee'。它是作为参数传递的固定字符串常量。为什么 'build_if_needed' 的所有 5 次执行都从最终的并行调用中接收到字符串常量?我错过了什么?

有没有办法做我想做的事?

在我的案例中(Jenkins 2.7.4)使用方法而不是闭包效果很好:

def build_if_needed(project) {
  println "build_if_needed: $project"
  // ultimately this will kick off a build job...
}

parallel (
  aaa : { build_if_needed('aaa')},
  bbb : { build_if_needed('bbb')},
  ccc : { build_if_needed('ccc')},
  ddd : { build_if_needed('ddd')},
  eee : { build_if_needed('eee')}
)

根据我的经验,您应该尽可能避免在管道脚本中使用闭包。 Jenkins 似乎无法处理像 https://issues.jenkins-ci.org/browse/JENKINS-26481.

这样的闭包

这基本上是 中的一个错误。它已从 Groovy 管道 2.35 开始修复。