Reputation:
I created a new Jenkins pipeline. The pipeline is (currently) parametrized with a single boolean option named VAR_A
. My pipeline script is:
node ('windows') {
echo "$VAR_A"
bat 'env'
}
When I manually build the project with VAR_A
checked, "true" is echoed, as expected. The list of environment variables, however, does not show VAR_A=true
.
I am able to get env
to show VAR_A
if I wrap the call in a withEnv
block:
node ('windows') {
echo "$VAR_A"
withEnv(["VAR_A=$VAR_A"]) {
bat 'env'
}
}
I will more parameters than this, so specifying each parameter individually is not desired. Is there a way to transfer all build parameters to a node's environment?
Upvotes: 8
Views: 16313
Reputation: 279
Passing the node dynamically in the build job step is a good feature. It helps to run multiple jobs parallelly on different nodes. The addition of the following script in the Jenkins pipeline script might be helpful.
def build_one()
{
parallel one: {
stage('XYZ') {
catchError(buildResult: 'SUCCESS', stageResult:'FAILURE') {
build job: 'yourDownStreamJob', parameters: [[$class: 'NodeParameterValue', name: 'NodeToRun',labels: ['nodeName'], nodeEligibility: [$class: 'AllNodeEligibility']], string(name: 'ParentBuildName', value: "XX"), string(name: 'Browser', value: 'chrome'), string(name: 'Environment', value: 'envName')]
}
}
},
two : {
stage('SecondArea') {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
build job: 'yourDownStreamJob', parameters: [[$class: 'NodeParameterValue', name: 'NodeToRun',labels: ['Your'], nodeEligibility: [$class: 'AllNodeEligibility']], string(name: 'ParentBuildName', value: "XYX"), string(name: 'Browser', value: 'firefox'), string(name: 'Environment', value: 'envName')]
}
}
}
}
build_one()
Upvotes: 0
Reputation: 6071
The point is that in Pipeline scripts the job parameters are not injected into the environment automatically as for regular jobs. Each parameter becomes a variable of the Pipeline script binding. Therefore you can access them directly by name.
In your example echo "$VAR_A"
variable substitution is performed by groovy in the context of your script (see Groovy doc on strings interpolation). That's why you don't see it in the bat
output.
For each parameter you want to inject you need to add a line like this:
env.VAR_A = VAR_A
in the beginning of your script. It can be outside of node
block because env
is global within the whole script.
Alternatively there is a way to add all the script vars, including parameters and even Pipeline built-in vars i.e. steps
into the environment. Unfortunately it will require some whitelisting to run in a sandbox:
@NonCPS
def populateEnv(){ binding.variables.each{k,v -> env."$k" = "$v"} }
populateEnv()
Example: VAR_A is a parameter. Script body:
def AAAA = 1 // such a definition doesn't put variable in the binding
BBBB = 2 // creates a binding variable. Absolutely the same behavior as for a job parameter.
@NonCPS
def populateEnv(){ binding.variables.each{k,v -> env."$k" = "$v"} }
populateEnv() // at this point injection happens
CCCC = 3 // created after the injection hence it won't appear in env.
node ('windows') {
bat 'env'
}
In the bat
output you will find VAR_A
and BBBB
.
IMO unless your job has tens of parameters defined env.VAR_A = VAR_A
approach is preferred as more simple, straightforward, and requiring no approvals.
Upvotes: 11