以下是我Jenkinsfile
的内容:
node {
// prints only the first element 'a'
[ 'a', 'b', 'c' ].each {
echo it
}
}
在Jenkins中执行作业时(使用Pipeline plugin),只打印列表中的第一项。
有人能解释我这种奇怪的行为吗?这是一个错误吗?或者只是我不理解Groovy语法?
修改:for (i in items)
按预期工作:
node {
// prints 'a', 'b' and 'c'
for (i in [ 'a', 'b', 'c' ]) {
echo i
}
}
答案 0 :(得分:17)
这里接受的答案表明这是一个已知的错误,并使用了对我不起作用的解决方法,因此我将提供最近我发现的更新。
尽管解决了JENKINS-26481(最近,截至撰写本文时),很多人可能会遇到Jenkins的旧版本,但修复程序不可用。文字列表上的for循环迭代有时可能有效,但JENKINS-46749和JENKINS-46747等相关问题似乎仍然困扰着许多用户。此外,根据Jenkinsfile中的确切上下文,可能echo
将起作用,而sh
失败,并且事情可能会无声地失败,或者它们可能会因序列化失败而导致构建崩溃。
如果你不喜欢惊喜(跳过循环和无声失败),如果你希望你的Jenkinsfiles在Jenkins的多个版本中最便携,那么主要的想法似乎是你应该总是在你的for中使用经典的计数器-loops并忽略其他常规功能。
This gist是我见过的最佳参考,并列出了许多你认为应该相同但行为却出奇的不同的案例。无论您正在查看何种迭代,无论您是否尝试使用@NonCPS
,都可以在{{1}内直接进行迭代,这是建立健全性检查和调试设置的良好起点。 },或调用一个单独的函数。
同样,我不赞成这项工作本身,但我将下面的迭代测试用例的要点嵌入后代:
node{}
答案 1 :(得分:5)
感谢@batmat #jenkins IRC channel回答此问题!
这实际上是一个已知错误:JENKINS-26481。
答案 2 :(得分:2)
此问题的解决方法是将所有命令扩展为平面文本文件,作为groovy脚本。然后使用加载步骤加载文件并执行。
例如:
@NonCPS
def createScript(){
def cmd=""
for (i in [ 'a', 'b', 'c' ]) {
cmd = cmd+ "echo $i"
}
writeFile file: 'steps.groovy', text: cmd
}
然后调用函数
createScript()
load 'steps.groovy'
答案 3 :(得分:0)
这里是curl
不带NonCPS
的循环示例:
#!/usr/bin/env groovy
node('master') {
stagesWithTry([
'https://google.com/',
'https://github.com',
'https://releases.hashicorp.com/',
'https://kubernetes-charts.storage.googleapis.com',
'https://gcsweb.istio.io/gcs/istio-release/releases'
])
stage ('ALlinOneStage'){
stepsWithTry([
'https://google.com/',
'https://github.com',
'https://releases.hashicorp.com/',
'https://kubernetes-charts.storage.googleapis.com',
'https://gcsweb.istio.io/gcs/istio-release/releases'
])
}
}
//loop in one stage
def stepsWithTry(list){
for (int i = 0; i < list.size(); i++) {
try {
sh "curl --connect-timeout 15 -v -L ${list[i]}"
} catch (Exception e) {
echo "Stage failed, but we continue"
}
}
}
//loop in multiple stage
def stagesWithTry(list){
for (int i = 0; i < list.size(); i++) {
try {
stage(list[i]){
sh "curl --connect-timeout 15 -v -L ${list[i]}"
}
} catch (Exception e) {
echo "Stage failed, but we continue"
}
}
}