我们在一些工作中动态创建并行步骤。感谢this thread我找到了如何动态创建带有参数的地图,以便在并行步骤中使用。
但是现在我想重用部分用于创建这些并行步骤的代码。为此,我觉得我需要为闭包做好准备。
然而,currying似乎无法正常工作。在闭包内引用循环变量(valueCopy)会做正确的事情(as mentioned here),但是currying不能达到我的预期。
我做错了什么,这是不是(还)支持,是否有任何解决方法?这可能是Jenkins管道中的一个错误吗?
希望任何人都知道为什么这不起作用和/或如何使其正常工作。
Jenkins:LTS(2.32.1)&最新的插件更新截至2017/01/19。
升级到Pipeline后:Groovy插件版本2.40 eveything正在按预期工作。
执行管道脚本:
def echoSome(val) {
echo val
}
def buildClosures() {
def someList = ["1", "2", "3"]
def closures = [:]
for (value in someList) {
final valueCopy = value
closures[value] = {val ->
echo valueCopy.toString()
echo val.toString()
}.curry(value)
}
closures
}
parallel buildClosures()
输出:
[Pipeline] parallel
[Pipeline] [1] { (Branch: 1)
[Pipeline] [2] { (Branch: 2)
[Pipeline] [3] { (Branch: 3)
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] echo
[1] 3
[Pipeline] [1] }
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] echo
[2] 3
[Pipeline] [2] }
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
预期产出:
[Pipeline] parallel
[Pipeline] [1] { (Branch: 1)
[Pipeline] [2] { (Branch: 2)
[Pipeline] [3] { (Branch: 3)
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] }
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] }
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
答案 0 :(得分:4)
我不确定它是currying还是for循环,但是这个函数需要标记为NonCPS,如下所述:https://github.com/jenkinsci/pipeline-examples/blob/master/docs/BEST_PRACTICES.md#groovy-gotchas
基本上,这样做:
@NonCPS
def buildClosures() {
def someList = ["1", "2", "3"]
def closures = [:]
for (value in someList) {
final valueCopy = value
closures[value] = {val ->
echo valueCopy.toString()
echo val.toString()
}.curry(value)
}
closures
}
我认为这是你的for循环,但无论如何,只要你不使用经典的“C Style”循环,你就需要将你的功能标记为NonCPS。
答案 1 :(得分:0)
这似乎是对Groovy语言或Jenkins groovy运行时的限制,我不确定是哪一个,但值得注意的是他们的示例完全按照您的方式执行,为循环的每次迭代声明一个新变量
他们评论了他们的例子
每次迭代//新变量;我会被改变
我不认为使用C风格的循环会消除这种限制并且currying(这个用例需要)也不能解决问题。笨拙,但很容易解决。
https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md#creating-multiple-threads
答案 2 :(得分:0)
发现最新的Pipeline: Groovy插件(2.40)与至少Jenkins版本2.60.3相结合(尽管插件主页表明你至少需要Jenkins 2.73.3)但一切都按预期工作。