Groovy interpolation in shell step (Jenkins Pipelines) - jenkins

Just for my curiosity I have a question related to the groovy behavior in the shell step.
I have defined an environment variable REGISTRY_AT in Jenkins and a build parameter VERSION. I know that for Groovy to do substitution on variables they need to be enclosed in double quotes and from experience the following example works.
Example:
dir('metrics/metrics-client'){
sh '''
....
docker build -t "${REGISTRY_AT}"/metrics-client:"${VERSION}" .
'''
}
Question: Why does Groovy engine interpolate the variables if they are inside a triple quoted string which will be passed to the shell step (sh -c " ") as an argument?
Maybe I'm looking at it the wrong way but from the groovy documentation, every string that is defined with single quotes/triple quotes shouldn't support interpolation/substitution
I've searched a lot of answers and documentation but cannot understand fully how the groovy engine works in the case of Jenkinsfiles and it's been bugging me for a while since the inner workings of Jenkins + Groovy + Shell related to variable interpolation (environment, parameters, local defined variables, etc) always cause some confusion, even for those that have worked with the pipelines.

In this case, there is no string interpolation. Because you defined the variables REGISTRY_AT and VERSION as environment variables, they exist in the shell script as environment variables as well.
So there is no string interpolation at the point of the triple-single quotes, but there is string interpolation in the shell script itself.

Related

Workspace variable not printing in Jenkins Pipeline post step

i have configured a Jenkins pipeline job as follows
and env.WORKSPACE works fine
steps {
script
{
echo "${env.WORKSPACE}"
}
}
during build ouput is /home/mach1/workspace
but when i added some lines in post build stage in jenkins pipeline job.
it is returning the following error ${FILE,path="echo "${env.WORKSPACE}"/dir1/file2.html"}
script
{
echo "${env.WORKSPACE}"
}
}
post{
success{
script{
body:'${FILE,path="${env.WORKSPACE}/dir1/file2.html"}'
}
}
}
may i know where its getting wrong, or how do i correct so that in post step it takes /home/mach1/workspace/dir1/file2.html
A shell environment variable is referenced as a key within the env Map within Jenkins Pipeline Groovy, and as a string within the shell step method. In your original example, you referenced the variable as a Groovy variable, and interpolated it within the pipeline with the correct " syntax. However, in your second example, you are still referencing the variable as a Groovy variable, but attempting to interpolate it within the executed shell command from the step method. This will not work, as you will pass a literal string of the env Map variable.
You can fix this either by referencing the environment variable as a shell environment variable by removing the env Map key:
body:'${FILE,path="${WORKSPACE}/dir1/file2.html"}'
or by interpolating the Groovy variable within the pipeline:
body:"\${FILE,path=\"${env.WORKSPACE}/dir1/file2.html\"}"
where characters are properly escaped to denote a shell variable FILE as opposed to a Groovy variable, and for the embedded ".
The first correction is, of course, easier to read, and probably what you will prefer.

How to set multiple environmental variable with Jenkins Groovy Script

I am trying to use Jenkins environmental variable with groovy scripts and assign them to environment variable so I can use those variable through out each Jenkins steps. But I cannot take out Groovy map objects. Is there anything I am doing wrong?
this is simple. In groovy script I have added two keys as "repo" and "version". Environment variables are created from that name and in a shell, I can get those simply by calling their keys.
echo $repo
echo $version

Jenkins Pipeline: use Windows environment variable with '(' in it

In my Jenkins pipeline I want to access the Windows environment variable named "ProgramFiles(x86)". However, I do not know what syntax I have to use to make Jenkins pipeline understand that the '(x86)' is part of the environment variable name. I keep getting an error with for example "echo env.ProgramFiles(x86)
groovy.lang.MissingPropertyException: No such property: x86 for class: groovy.lang.Binding
I also tried
echo "${ProgramFiles(x86)}"
and
echo "${env.ProgramFiles(x86)}"
but no success there either.
you can use single quotes around the variable name see below example:
echo "${env.'ProgramFiles(x86)'}"

Jenkinsfile - write environment variable to a file

In my Jenkinsfile, I'm trying to add a environment variable to a file, however not able to do so - seems like some small syntax thing, however I've tried so many different variations.
So the parameter I want is "${params.Spec}", currently used like:
environment {
SPECTORUN = "${params.Spec}"
}
Then in my script block i'm trying:
sh "echo Run:\"${params.Spec}\" >> allure-results/environment.properties"
Any help would be appreciated.
FOUND THE ANSWER HERE:
How to pass variables from Jenkinsfile to shell command

Jenkins Pipeline accessing environment variables

I'm trying to use DSL pipelines in Jenkins. I thought it'd be nice if I could use the project name as part of my script.
git credentialsId: 'ffffffff-ffff-ffff-ffff-ffffffffffffff',\
url: "${repo_root}/${JOB_NAME}.git"
I get the error:
groovy.lang.MissingPropertyException: \
No such property: JOB_NAME for class: groovy.lang.Binding
I thought I followed these directions, and they mention JOB_NAME as one of the variables.
I decided to try:
sh 'env'
in my DSL, and this prints out:
JOB_NAME = foo-bar
which is what I expect.
Another blog mentions:
Usage of environment variables
We have two ways to get their value. The properties passed by -D= during the startup we could read as System.getProperty("key") thanks to the Groovy's strong relation with Java.
Reading normal environment variables in Java way is the System.getenv("VARIABLE")...
Let's try this:
println "JOB_NAME = " + System.getenv('JOB_NAME');
Now, I get:
java.lang.NullPointerException: Cannot get property 'System' on null object
Null object? But, I can see that JOB_NAME is an environment variable!
How do I read in the $JOB_NAME into a DSL script in a Pipeline job. I am trying a Pipeline job, and when I get that working will make this a Multibranch Pipeline with a Jenkinsfile.
All environment variables are accessible using env, e.g. ${env.JOB_NAME}.
Okay this really vexed me for a while today. Ultimately, I was being done in by a couple of things:
Single-quoted strings in Groovy mean "don't evaluate variables," just like it does in bash
Using $ interpolation is completely unnecessary if you're just referencing the variable, so you can just do env.JOB_NAME.
This SO question proved to be the one that helped me crack the code: Jenkins Workflow Checkout Accessing BRANCH_NAME and GIT_COMMIT
Indeed just use ${env.JOB_NAME} to access a known variable.
However if you need to access environment variable where name is given by another variable (dynamic access), just use env["your-env-variable"].
I had the problem where I configured 3 environment variables (in Jenkins -> Administer -> Configure System -> Environment variables), let's name them ENV_VAR_1, ENV_VAR_2, ENV_VAR_3.
Now I want to dynamically access them, I can do as such :
def envVarName = "ENV_VAR_" + count // Suppose count is initialized in a loop somewhere above...
def value = env[envVarName] // Will be resolved to env["ENV_VAR_1"] depending on count value
My environment variables in Jenkins configuration look like this :
I had an issue with this not working. The globally set properties/environment variables were only available inside a node step. It's a bug in version 2.4 of Pipeline plugin. Upgrade to 2.5 if you face this issue and your global properties will be available anywhere in the script. I've posted this to the Jenkins wiki here with the test script I used.

Resources