问题
I'm experiencing some confusing behavior trying to execute code in a Jenkins pipeline script. Values inside a closure take on some unexpected values. I've seen references to a local variable trick that supposedly fixes this, but it is not working for me.
Simplified example: Create 3 jobs 'a', 'b', 'c' that print their argument - as passed in and as copied to a local. First execute the jobs in parallel; then execute outside parallel to compare the result. "say" is defined because println gives access exceptions in my Jenkins (I am not admin).
def say(s) {println(s)} // println gives exception inside create_jobs
def create_jobs() {
def map = [:] // needed for parallel
def jobrunfn = { jobid -> // return a closure that prints hello from job
def pid = "$jobid"
return {
def xsay = { s -> say("[$pid] $s") }
xsay "HELLO from $pid"
}
}
map['a'] = jobrunfn('a')
map['b'] = jobrunfn('b')
map['c'] = jobrunfn('c')
return map
}
def jobs = create_jobs()
parallel(jobs) // for Jenkins pipeline only - not groovy interp
for (j in jobs) { jobs[j.key]() } // groovy interp - parallel not available
The output - inside parallel, 'pid' is sometimes 'c', when it should be 'a' or 'b':
[Pipeline] parallel
[Pipeline] [a] { (Branch: a)
[Pipeline] [b] { (Branch: b)
[Pipeline] [c] { (Branch: c)
[Pipeline] [a] echo
[a] [a] HELLO from c
[Pipeline] [a] }
[Pipeline] [b] echo
[b] [b] HELLO from c
[Pipeline] [b] }
[Pipeline] [c] echo
[c] [c] HELLO from c
[Pipeline] [c] }
[Pipeline] // parallel
[Pipeline] echo
[a] HELLO from a
[Pipeline] echo
[b] HELLO from b
[Pipeline] echo
[c] HELLO from c
[Pipeline] End of Pipeline
Finished: SUCCESS
The argument is ALWAYS the last value passed in (not sure why, but it is consistent and I understand that you need the local variable trick.)
But, the local variable trick doesn't work consistently inside of parallel: even the local is sometimes 'c' (to the nested 'say' it gets it right, but the main body gets it wrong); outside of parallel it gets 'a' and 'b' as expected.
Am I misunderstanding?
Jenkins 2.32.2 on Linux, Pipeline:Grooby 2.27
回答1:
It is a pipeline's bug. See the ticket.
来源:https://stackoverflow.com/questions/42416854/jenkins-pipeline-shouldnt-closures-resolve-variables-the-same-inside-parallel