Reputation: 811
In my declarative Jenkinsfile, I am trying to compute some values and then pass them to maven. As easy as it seems, I can't make it work.
Here's the relevant part of my Jenkinsfile :
def port = 1000 as Integer
def mocksport = 0 as Integer
def safebranch='unknown'
pipeline {
stages {
stage('Compile'){
steps {
script {
safebranch=env.BRANCH_NAME.toLowerCase().replaceAll("[-_/]", "");
for (int i=0; i<safebranch.length(); i++) {
port = (port as Integer) + (Character.getNumericValue(safebranch.charAt(i)) as Integer);
}
port = (port as Integer) % 99 + 9000;
mocksport = (port as Integer) + 1;
echo "Application will be deployed on port ${port}"
echo "Mocks will be deployed on port ${mocksport}"
}
sh "mvn clean install -Dmaven.test.failure.ignore=true -T 1C -Drancher.port=${port} -Drancher.mocks.port=${mocksport} -Drancher.tag=${safebranch}"
}
}
} // stages
} // pipeline
This version is the closest I could get to a working solution. At least the script block is executed and the echoed values are correct : in the log I see :
[Pipeline] [Compile] echo
[Compile] Application will be deployed on port 9065
[Pipeline] [Compile] echo
[Compile] Mocks will be deployed on port 9066
I am now getting this exception, probably related to groovy being unable to find the variables outside of the script block context :
java.lang.NullPointerException: Cannot get property '' on null object
at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:60)
at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:284)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:286)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
I tried declaring the variables in a global environment section right under pipeline, and access them using the "env." prefix, but in this case it seems the script block is not allowed to update the values (= I get 1000 and 0 as result of the echo).
How can I make this work ?
Bonus question : strangely, the variables seem to always be handled as Strings. If I don't add the cast to Integer at every variable usage, it doesn't work (the port variable expands at each iteration : 1000, 10001012, 100010122343, etc...). Can I declare and use the variable as integer ?
Upvotes: 0
Views: 4253
Reputation: 5319
I don't see a scope issue with your variables as you have set them up. They should be available outside of the script{}
block. The error message doesn't really point to a scope issue, either.
I took your exact code you pasted, added an agent declaration, and made up a value for "safebranch" and it run exactly as I would expect (with the mvn command not being found, of course).
Running shell script
+ mvn clean install -Dmaven.test.failure.ignore=true -T 1C -Drancher.port=9011 -Drancher.mocks.port=9012 -Drancher.tag=BRANCH
/home/jenkins/jenkins/workspace/morepipe@tmp/durable-6849aecb/script.sh: 2: /home/jenkins/jenkins/workspace/morepipe@tmp/durable-6849aecb/script.sh: mvn: not found
I even got rid of all of the to Integer
type coercion and it works fine. Maybe the problem is actually in part of your script you didn't post. Here is my exact script. Try plugging it in and see if it runs:
def port = 1000
def mocksport = 0
def safebranch='unknown'
pipeline {
agent any
stages {
stage('Compile'){
steps {
script {
safebranch="BRANCH"
for (int i=0; i<safebranch.length(); i++) {
port = (port) + (Character.getNumericValue(safebranch.charAt(i)));
}
port = (port) % 99 + 9000;
mocksport = (port) + 1;
echo "Application will be deployed on port ${port}"
echo "Mocks will be deployed on port ${mocksport}"
}
sh "mvn clean install -Dmaven.test.failure.ignore=true -T 1C -Drancher.port=${port} -Drancher.mocks.port=${mocksport} -Drancher.tag=${safebranch}"
}
}
} // stages
} // pipeline
Upvotes: 2