Reputation: 137
I'm trying to set a variable on a switch statement. I created a simple function to do this, but it won't actually update the value. here is the function I created:
def VAR1 = 'this is not the real value';
stage('Set Variables') {
steps {
script{
SetVariables()
}
}
}
def SetVariables() {
sh 'echo $BRANCH_NAME'
switch(BRANCH_NAME){
case 'BranchA':
sh 'echo We are in the right branch'
VAR1 = "This is the correct String"
sh 'echo $VAR1 is the variable's value'
break
}
}
Both of the echos are showing, but the value of VAR1
remains 'this is not the real value'
If I move this code into a steps/script block it works perfectly fine.
stage('Set Variables') {
steps {
script{
switch(BRANCH_NAME){
case 'BranchA':
sh 'echo We are in the right branch'
VAR1 = "This is the correct String"
sh 'echo $VAR1 is the variable's value'
break
}
}
}
}
This bit of code will expand as I add more variables and cases and I'd like to have it stored at the bottom in a function to keep things clean and readable. What am I missing here that is preventing the variable from being updated properly in a function?
Upvotes: 1
Views: 1594
Reputation: 6869
One of Groovy quirks is that if you want a global, you have to define it without def
:
VAR1 = 'this is not the real value';
// the rest unchanged
I believe your code will work as expected then.
Upvotes: 2
Reputation: 2270
I believe this issue is about scoping.
Let's understand the behaviour. Taking into account this pipeline:
def MY_VAR = 'hello world'
fun()
pipeline {
agent any
stages {
stage('Hello') {
steps {
script {
println("Pipeline Before: ${MY_VAR}")
fun()
println("Pipeline After : ${MY_VAR}")
}
}
}
}
}
def fun() {
println("Fun before: ${MY_VAR}")
VAR1 = 'hello world, in fun'
println("Fun after : ${MY_VAR}")
}
If we run this we get the following error:
groovy.lang.MissingPropertyException: No such property: MY_VAR for class: groovy.lang.Binding
Let's delete the fun()
call in the second line. We get the following output
Pipeline Before: hello world
groovy.lang.MissingPropertyException: No such property: MY_VAR for class: groovy.lang.Binding
Let's delete the first println("Fun before: ${MY_VAR}")
from the function. We get:
Pipeline Before: hello world
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline After : hello world
We can see the value is unaltered. To combat these issue, we can use the attach our variable to the env object as env.MY_VAR
The pipeline will look as follows
env.MY_VAR = 'hello world'
fun()
pipeline {
agent any
stages {
stage('Hello') {
steps {
script {
println("Pipeline Before: ${env.MY_VAR}")
fun()
println("Pipeline After : ${env.MY_VAR}")
}
}
}
}
}
def fun() {
println("Fun before: ${env.MY_VAR}")
env.VAR1 = 'hello world, in fun'
println("Fun after : ${env.MY_VAR}")
}
We will get:
[Pipeline] echo
Fun before: hello world
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline Before: hello world, in fun
[Pipeline] echo
Fun before: hello world, in fun
[Pipeline] echo
Fun after : hello world, in fun
[Pipeline] echo
Pipeline After : hello world, in fun
Which is the desired output. You could argue about the use of the env
object, maybe you could parameterize your function. I would do it like this since if I would need the variable in a bash/powershell/etc script, I could access it via the environment variables.
Upvotes: 3