Jenkins plugin cannot see variables set using the withEnv workflow step - jenkins

I want the gradle plugin to pick up environment variables that are set in a withEnv step (or other wrapper-types). When I invoke gradle using a sh step the variable is found, but when I use the gradle plugin it is not.
The gradle plugin performs the equivalent of this:
EnvVars env = run.getEnvironment(taskListener);
launcher.launch().cmds(args).envs(env).stdout(gca)
.pwd(rootLauncher).join();
The javadoc for run.getEnvironment() states:
Returns the map that contains environmental variables to be used for
launching processes for this build. BuildSteps that invoke external
processes should use this. This allows BuildWrappers and other project
configurations (such as JDK selection) to take effect.
Unlike earlier getEnvVars(), this map contains the whole environment,
not just the overrides, so one can introspect values to change its
behavior.
If I debug the plugin I see that there are less than a dozen variables in the environment passed to the gradle invocation, none of which are the variables withEnv should be providing. To the best I could tell, the sh step uses a completely different extension point, and is straight up given an instance of EnvVars that appears to be much more complete. I'm fairly certain the problem isn't in withEnv, but I don't see how to fix the gradle plugin.
Am I using the wrong call? Or perhaps the wrong extension point?

Do not call Run.getEnvironment. Rather use the EnvVars passed to SimpleBuildStep.perform.

Related

Unable to determine what the withEnv is doing in Jenkinsfile

I have just started writing Jenkinsfile. I was viewing the following two URLs to learn how to build a Java application, push it to Nexus and then invoke Ansible to deploy.
Redhat Jenkinsfile description
Actual Jenkinsfile
In the second link the following is mentioned several times whose function I am unable to understand:
withEnv(["PATH+MAVEN=${tool 'm3'}/bin"])
What I can find from net is that withEnv is used to create/override a environment variables. But what is ${tool 'm3'}/bin doing? Normally the syntax of withEnv is VARIABLE_NAME=value/expression.
The ${} is substituting a command/variable into the GString. See groovy docs on string Interpolation
From the looks of it, it would be safe to assume tool 'm3' is returning the install path which then gets /bin appended.
So the end result would be
PATH+MAVEN=/my/path/to/m3/etc/bin
Additionally to #metalisticpain's answer, there's some background configuration to the tools directive on the Jenkins server itself that configures the installation paths to be used.
Let's say you have jdk-1.8.0 installed as a tool name on the Jenkins server, then it can be used in the Jenkinsfile as such in your example:
withEnv(["PATH+JDK=${tool 'jdk-1.8.0'}/bin"])
Taken from the documentation linked above:
The tool name must be pre-configured in Jenkins under Manage Jenkins → Global Tool → Configuration.

Use IDE to generate pipline script for jenkins

I need to overload jenkins functions to debug pipeline script in IDE.
I'm new to java/groovy etc. I'm going to write a several hundred lines scripted pipeline. Groovy is based on java. As I'm new I prefer the function name completion/suggestion and a debugging feature would be awesome where I can walk through the lines step by step and see what is in the vars.
I set up a eclipse Luna with the groovy-plugin. Which is actually working =)! (for newest eclipse the plugin is not yet ready). Also debugging is quiet cool!
But special jenkins expressions will still throw errors.
node(MasterName){ ... }
sh
...
Is there a chance to overload those functions?
Just killing the error, not performing any actions. Maybe converting it to a print like "I'm executing script XYZ" or "Switching to node BLUBB"?
The outcome should be a copy paste script, for checking in and running with jenkins without major changes.
Is there any better way?
In the end it turned out, that even if you omit the pipeline specific expressions, you will still have trouble. In some more complex situations e.g. calling a constructor with super in a extended class and executing a function afterwards, it does not behave the same then in my local python interpreter.
So what I did was an error to assume, my Ubuntu system default groovy interpreter would work the same like the jenkins interpreter. It would be nice to run a debugger inside the jenkins environment, or going step by step through the pipeline script and see how it is actually working without a print in every second line.

Environment variable in Jenkins Pipeline

Is there any environment variable available for getting the Jenkins Pipeline Title?
I know we can use $JOB_NAME to get title for a freestyle job,
but is there anything that can be used for getting Pipeline name?
You can access the same environment variables from groovy using the same names (e.g. JOB_NAME or env.JOB_NAME).
From the documentation:
Environment variables are accessible from Groovy code as env.VARNAME or simply as VARNAME. You can write to such properties as well (only using the env. prefix):
env.MYTOOL_VERSION = '1.33'
node {
sh '/usr/local/mytool-$MYTOOL_VERSION/bin/start'
}
These definitions will also be available via the REST API during the build or after its completion, and from upstream Pipeline builds using the build step.
For the rest of the documentation, click the "Pipeline Syntax" link from any Pipeline job
To avoid problems of side effects after changing env, especially using multiple nodes, it is better to set a temporary context.
One safe way to alter the environment is:
withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
sh '$MYTOOL_HOME/bin/start'
}
This approach does not poison the env after the command execution.

Pipeline - Parameterised Trigger Plugin

I have a pipeline type job in my Jenkins. What I am trying to do is to run some pipelines with a parameter like release. For example, I want to run this pipeline for version 1.3.5. I prepared a pipeline code for that and tried to use Parameterized Trigger Plugin to make it parameterised. This plugin was working for normal type tasks but, I couldn't make it works with pipelines.
Here is my definition of the variable;
I can't access the variable I defined with the plugin. Here is the pipeline part which tries to access it;
....
build_tag = "${TAG}"
But, build_tag variable is always null. I tried env.${TAG} and ${env.TAG} but no result.
I defined String param named THIS_IS_TEST and was able to get the value with -
echo "${THIS_IS_TEST}"
Make sure that the plugin is updated

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