58

I'm using Scriptler plugin, so I can run a groovy script as a build step. My Jenkins slaves are running on windows in service mode. With scriptler, I don't need to use windows batch scripts.

But I have trouble to get the environment variables in a build step... This is working:

System.getenv("BASE")

Where BASE is part of the env-vars on jenkins startup. However, I would like to get

%JOB_NAME%

If I'm adding an "Execute Windows batch command" build step:

echo %JOB_NAME%

It works. If I'm adding a scriptler script as a build step with the same settings:

println "JOB_NAME: " + System.getenv("JOB_NAME")

I'm getting:

JOB_NAME: null

So how can I reach the injected environment variables from a groovy script as a build step?

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
Adam Ocsvari
  • 8,056
  • 2
  • 17
  • 30

8 Answers8

63

build and listener objects are presenting during system groovy execution. You can do this:

def myVar = build.getEnvironment(listener).get('myVar')
  • 2
    Thanks! This seems to be the only way to get access to the env vars in a "Execute System Groovy Script" build step. – Torben Knerr Dec 18 '14 at 22:56
  • doesn't work for me, get "Problems occurs on injecting env vars as a build wrap: null". No additional error details, how to debug this situation? – Mando Nov 17 '15 at 14:52
  • 1
    The question states "I'm using Scriptler plugin..." and this requires system groovy execution so doesn't answer the question. – christutty Nov 24 '15 at 04:04
  • Scriptler is a script storage with possibility to use it in any way you want. So statement that "scriptler" requires only "system groovy execution" is wrong. – Kanstantsin Shautsou Nov 28 '15 at 18:16
  • 8
    what is `listener` in this case? – dokaspar Nov 16 '16 at 09:35
  • listener is an object passed to perform() that available during build execution. – Kanstantsin Shautsou Jan 06 '17 at 17:10
  • There is no perform() call here. `listener` is an instance of [TaskListener](http://javadoc.jenkins-ci.org/hudson/model/TaskListener.html). In a simple case like this, you can just use [`TaskListener.NULL`](http://javadoc.jenkins-ci.org/hudson/model/TaskListener.html#NULL) instead of `listener` in the above snippet. – darrenp Feb 27 '18 at 12:10
  • 6
    I get `groovy.lang.MissingPropertyException: No such property: build for class: WorkflowScript` when trying this from within a function. – micseydel Jan 30 '20 at 16:18
  • @micseydel try the alternative I provided in the edit. – kayleeFrye_onDeck Mar 04 '20 at 00:05
20

You might be able to get them like this:

def thr = Thread.currentThread()
def build = thr?.executable
def envVarsMap = build.parent.builds[0].properties.get("envVars")
Alf
  • 1,518
  • 3
  • 17
  • 21
17

On jenkins 2.x, with groovy plugin 2.0, running SystemGroovyScript I managed to get to build variables, as below:

def build = this.getProperty('binding').getVariable('build')
def listener = this.getProperty('binding').getVariable('listener')
def env = build.getEnvironment(listener)
println env.MY_VARIABLE

If you are using goovy from file, simple System.getenv('MY_VARIABLE') is sufficient

Augustin Ghauratto
  • 1,420
  • 1
  • 19
  • 21
  • 5
    I found that this also works in Jenkins 2.89: `def env = binding.build.environment; println env.FOO` – Allan Lewis May 22 '18 at 10:10
  • @AllanLewis I'm getting `groovy.lang.MissingPropertyException: No such property: build for class: groovy.lang.Binding`... Any suggestion? – Marcello DeSales Aug 06 '18 at 22:22
  • @MarcellodeSales in what context? – Allan Lewis Aug 07 '18 at 14:46
  • @AllanLewis on a Global Shared Library... I was only able to use the global property as in https://build.intuit.com/services-config/pipeline-syntax/globals#env. See my answer – Marcello DeSales Aug 08 '18 at 00:10
  • @MarcellodeSales You're right, my solution won't work in a shared library, only in a Groovy script executed directly in the context of a build. I guess your library function could take the build as a parameter. – Allan Lewis Aug 08 '18 at 07:08
  • I found the JavaDoc to be helpful: https://javadoc.jenkins-ci.org/hudson/model/Build.html. – jaco0646 Jan 24 '20 at 19:56
11

The Scriptler Groovy script doesn't seem to get all the environment variables of the build. But what you can do is force them in as parameters to the script:

  1. When you add the Scriptler build step into your job, select the option "Define script parameters"

  2. Add a parameter for each environment variable you want to pass in. For example "Name: JOB_NAME", "Value: $JOB_NAME". The value will get expanded from the Jenkins build environment using '$envName' type variables, most fields in the job configuration settings support this sort of expansion from my experience.

  3. In your script, you should have a variable with the same name as the parameter, so you can access the parameters with something like:

    println "JOB_NAME = $JOB_NAME"

I haven't used Sciptler myself apart from some experimentation, but your question posed an interesting problem. I hope this helps!

macg33zr
  • 1,725
  • 15
  • 13
  • One problem with this approach (assuming the variable is set as MYVAR) is that groovy will "blow up" if the value is not provided as a parameter. To see what WAS passed you can try this: ``` println "--> The following values were provided: " this.binding.variables.each {k,v -> println "$k = '$v'"} ``` – Steven the Easily Amused Jun 22 '17 at 00:08
6

The only way I could get this to work (on Linux) was to follow this advice:

https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+System+Groovy+script

import hudson.model.*

// get current thread / Executor and current build
def thr = Thread.currentThread()
def build = thr?.executable

// if you want the parameter by name ...
def hardcoded_param = "FOOBAR"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)

println "param ${hardcoded_param} value : ${hardcoded_param_value}"

This is on Jenkins 1.624 running on CentOS 6.7

dayer4b
  • 978
  • 14
  • 26
6

Jenkins 2.x has the global variables. env is one of them from any script...

println env.JOB_NAME

More at https://build.intuit.com/services-config/pipeline-syntax/globals#env

Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
3

One thing to note, if you are using a freestyle job, you won't be able to access build parameters or the Jenkins JVM's environment UNLESS you are using System Groovy Script build steps. I spent hours googling and researching before gathering enough clues to figure that out.

John Czukkermann
  • 539
  • 1
  • 4
  • 13
0

In System Groovy Script (Jenkins 2.89), I was able to use the environmental variable to disable another Jenkins job

import jenkins.*
import jenkins.model.*
def env = binding.build.environment
Jenkins.instance.getItemByFullName(env.job_name).setDisabled(false) 

I also added a conditional step so as to either enable or disable another Jenkins job.

enter image description here

Thanks @Allan Lewis, your comment was helpful.

Ashwaq
  • 431
  • 7
  • 17