这是我的内容Jenkinsfile:
Jenkinsfile
node { // prints only the first element 'a' [ 'a', 'b', 'c' ].each { echo it } }
在Jenkins中使用Pipeline插件执行作业时,仅打印列表中的第一项。
有人可以向我解释这种奇怪的行为吗?是虫子吗?还是只是我不了解Groovy语法?
编辑 :for (i in items)预期的作品:
for (i in items)
node { // prints 'a', 'b' and 'c' for (i in [ 'a', 'b', 'c' ]) { echo i } }
此处接受的答案指出这是一个已知的错误,并且使用了对我不起作用的解决方法,因此,我将提供我最近发现的更新。
尽管有了JENKINS-26481的解决方案(在撰写本文时,它还算是最近的),但许多人仍可能无法使用较旧版本的Jenkins,但该修复程序不可用。在文字列表上进行for循环迭代有时可能会起作用,但诸如JENKINS-46749和JENKINS-46747之类的相关问题似乎继续困扰着许多用户。另外,根据您的Jenkinsfile中的确切上下文,可能echo会工作而sh失败,并且事情可能会静默失败,或者由于序列化失败而使构建崩溃。
echo
sh
如果您不喜欢意外事件(跳过的循环和无声的失败),并且希望让Jenkinsfile在多个版本的Jenkins中具有最大的可移植性,那么主要的想法似乎是您应该始终在for循环中使用经典计数器,而忽略其他常规做法特征。
该要点是我所见过的最好的参考,并阐明了许多您认为应该相同但行为却出奇的情况。这是建立健全性检查和调试设置的良好起点,无论您要查看的是哪种迭代,也不管您是尝试使用@NonCPS,直接在内部进行迭代node{}还是调用单独的函数。
@NonCPS
node{}
再说一次,我对这项工作本身不屑一顾,但是为了后代,我在下面嵌入了迭代测试用例的要点:
abcs = ['a', 'b', 'c'] node('master') { stage('Test 1: loop of echo statements') { echo_all(abcs) } stage('Test 2: loop of sh commands') { loop_of_sh(abcs) } stage('Test 3: loop with preceding SH') { loop_with_preceding_sh(abcs) } stage('Test 4: traditional for loop') { traditional_int_for_loop(abcs) } } @NonCPS // has to be NonCPS or the build breaks on the call to .each def echo_all(list) { list.each { item -> echo "Hello ${item}" } } // outputs all items as expected @NonCPS def loop_of_sh(list) { list.each { item -> sh "echo Hello ${item}" } } // outputs only the first item @NonCPS def loop_with_preceding_sh(list) { sh "echo Going to echo a list" list.each { item -> sh "echo Hello ${item}" } } // outputs only the "Going to echo a list" bit //No NonCPS required def traditional_int_for_loop(list) { sh "echo Going to echo a list" for (int i = 0; i < list.size(); i++) { sh "echo Hello ${list[i]}" } } // echoes everything as expected