Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Jenkins build parameters to pipeline nodes

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?

like image 570
Tim Cooper Avatar asked May 06 '16 19:05

Tim Cooper


1 Answers

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.

like image 83
izzekil Avatar answered Sep 17 '22 19:09

izzekil