Issue
Background
I have a written a Groovy DSL declarative pipeline script in Jenkins. The script is executes on a slave agent which runs on Windows Server 2012. On this agent machine there is a command line executable called kitchen
. I execute the kitchen
program using Groovy's bat()
method, and I pipe in a parameter that is passed into the pipeline when it's built.
The script is simple and does the following in a series of two stages
- Takes in an
AWARD_YEAR
parameter - Checkout a project from SVN
- Executes the
kitchen
program through abat()
function
I am using Jenkins 2.235.3
Issue
The kitchen
executable returns an exit code in the range from 0 - 9. When the exit code is anything other than 0 this indicates the executable has failed. However, as it stands currently the pipeline execution always succeeds regardless of the exit code. To fix this, I need to store the exit code in a variable and then check its value.
However, when I attempt to store the result into a variable I get the error shown below.
Code and Error
Below is the code that causes the error
pipeline {
agent { label 'pentaho-test' }
parameters {
string(name: 'AWARD_YEAR', defaultValue: "${Calendar.getInstance().get(Calendar.YEAR)}", description: 'Award Year Parameter')
}
stages {
stage('Checkout') {
steps {
checkout changelog: false, poll: false, scm: [
$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[cancelProcessOnExternalsFail: true,
credentialsId: 'hudson',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: 'https://svn.int.domain.edu/project/trunk']],
quietOperation: true,
workspaceUpdater: [$class: 'UpdateUpdater']
]
}
}
stage('Run Kitchen') {
steps {
def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%' )
echo result
}
}
}
}
Below is the error shown in the Jenkins Console
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 35: Expected a step @ line 35, column 5.
result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%' )
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:142)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:561)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:522)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:337)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:428)
Finished: FAILURE
When I modify the step as follows the script executes without error, but the exit code is not stored and therefore even when the binary executable fails the pipeline shows as if it succeeds.
steps {
result = bat label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'
}
Post Script
There are two other StackOverflow questions that ask this specific question, but the solution causes the error I am recieving.
Solution
If you want to capture the result from the sh
step and assign it to a variable, you need to do it in the script
block.
Change
stage('Run Kitchen') {
steps {
def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%' )
echo result
}
}
to
stage('Run Kitchen') {
steps {
script {
def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%' )
echo result
}
}
}
and you should fix the problem you see at the moment.
Answered By - Szymon Stepniak
Answer Checked By - David Marino (JavaFixing Volunteer)