JenkinsPipelineUnit
JenkinsPipelineUnit copied to clipboard
callstack indentation wrong when overriding sh with vars/sh.groovy
I used the strategy described here: https://brokenco.de/2017/08/03/overriding-builtin-steps-pipeline.html to override the default sh
steps. I thus have quite exactly the proposed vars/sh.groovy file in my jenkins library:
def call(Map params = [:]) {
String script = params.script
Boolean returnStatus = params.get('returnStatus', false)
Boolean returnStdout = params.get('returnStdout', false)
String encoding = params.get('encoding', null)
timeout(time: 2, unit: 'HOURS') {
ansiColor('xterm') {
timestamps {
return labelledShell(script: "hostname; " + script,
label: script,
returnStatus: returnStatus,
returnStdout: returnStdout,
encoding: encoding)
}
}
}
}
/* Convenience overload */
def call(String script) {
return call(script: script)
}
I am using the BaseRegressionTest class to avoid regressions. However my automatic build fails because the indentation of the underlying steps inside sh.groovy don't have exactly the same depth as on my pc. Example: on my pc I get this callstack:
myPipelineTestAndPublish.sh(./gradlew test)
sh.timeout({time=2, unit=HOURS}, groovy.lang.Closure)
sh.ansiColor(xterm, groovy.lang.Closure)
sh.timestamps(groovy.lang.Closure)
sh.labelledShell({script=hostname; ./gradlew test, label=./gradlew test, returnStatus=false, returnStdout=false, encoding=null})
and on the jenkins node I would get:
myPipelineTestAndPublish.sh(./gradlew test)
sh.timeout({time=2, unit=HOURS}, groovy.lang.Closure)
sh.ansiColor(xterm, groovy.lang.Closure)
sh.timestamps(groovy.lang.Closure)
sh.labelledShell({script=hostname; ./gradlew test, label=./gradlew test, returnStatus=false, returnStdout=false, encoding=null})
or something similar. Note also that none of both outputs are correct, since all steps are enclosed in one another, so the right output would be:
myPipelineTestAndPublish.sh(./gradlew test)
sh.timeout({time=2, unit=HOURS}, groovy.lang.Closure)
sh.ansiColor(xterm, groovy.lang.Closure)
sh.timestamps(groovy.lang.Closure)
sh.labelledShell({script=hostname; ./gradlew test, label=./gradlew test, returnStatus=false, returnStdout=false, encoding=null})
I have been trying for hours to get this right, but am quite out of ideas. Trouble is the library and sh.groovy work just fine, I'm just having a lot of trouble getting the unit-tests reproducible (and correct).
maybe an important note: all other commands are prefixed with my library name, only this one is prefixed with the name of the JenkinsFile that I loaded with loadScript
MyPipeline.steps(groovy.lang.Closure)
MyPipeline.withEnv([CHANGE_TARGET=merge-base], groovy.lang.Closure)
MyPipeline.script(groovy.lang.Closure)
myPipelineTestAndPublish.sh(./gradlew test)
sh.timeout({time=2, unit=HOURS}, groovy.lang.Closure)
sh.ansiColor(xterm, groovy.lang.Closure)
sh.timestamps(groovy.lang.Closure)
sh.labelledShell({script=hostname; ./gradlew test, label=./gradlew test, returnStatus=false, returnStdout=false, encoding=null})
@chrismaes87, hi may I ask you to submit a PR with test case to reproduce the issue
This will be rather complicated to give a simple reproducible case... the indentation changed several times on my pc and also between my pc and jenkins build nodes; but it seemed rather arbitrary.
For the moment I am thinking about changing my whole code to scripted pipeline instead of DSL for more advanced behavior, so I'm not even sure I will keep using the JenkinsPipelineUnit.
Are intendants on the same host have the same formatting no matter how many times you run it? Any information about the difference between hosts (os, jdk) would be helpful.
I have since left that company so I can no longer reproduce this. The indendation was the same each time on the same host. One host was an opensuse15.0, the other might have been centos7, but I'm not sure about that anymore.