38

The website for the plugin says that you can create a groovy script to run to determine the parameter list.

how is this resolved though? The instructions don't say anything.

  1. In what context is the script run?
  2. What am i supposed to return from the script?
  3. What directory is the cwd of the script? is it the environment variable WORKSPACE?
  4. there is an extra field called variable bindings. How is this used?
coderatchet
  • 8,120
  • 17
  • 69
  • 125
  • 6
    simplest Groovy one-liner: `return ["item1", "item2", "etc."]` – MarkHu Mar 19 '16 at 02:48
  • 1
    tried with the suggestion above but always got an empty field. actually when using a "groovy script" in the text area, I always have empty results. – dawez Apr 13 '16 at 09:55
  • 1
    Had the same issue. Go to 'http://:/scriptApproval/' and approve Classpath entry '/' – vehovmar Apr 25 '16 at 14:51
  • 1
    In my case ```return ["item1", "item2", "etc."]``` results in JS error ```Uncaught TypeError: Cannot read property '$ref' of undefined``` – Ilia Shakitko Jan 06 '17 at 12:40

2 Answers2

36

I had to dig into the source code to find the answer to these questions so i hope this helps everyone else.

1. In what context is the script run?

The script is run inside a groovy.lang.GroovyShell. This class is currently from the Groovy 1.8.5 library. here is an excerpt from the code:

// line 419 - 443 of the ExtendedChoiceParamaterDefinition
else if(!StringUtils.isBlank(groovyScript)) {
    try {
        GroovyShell groovyShell = new GroovyShell();
        setBindings(groovyShell, bindings);
        Object groovyValue = groovyShell.evaluate(groovyScript);
        String processedGroovyValue = processGroovyValue(isDefault, groovyValue);
        return processedGroovyValue;
    }
    catch(Exception e) {

    }
}
else if(!StringUtils.isBlank(groovyScriptFile)) {
    try {
        GroovyShell groovyShell = new GroovyShell();
        setBindings(groovyShell, bindings);
        groovyScript = Util.loadFile(new File(groovyScriptFile));
        Object groovyValue = groovyShell.evaluate(groovyScript);
        String processedGroovyValue = processGroovyValue(isDefault, groovyValue);
        return processedGroovyValue;
    }
    catch(Exception e) {

    }
}

2. What am i supposed to return from the script?

As the above code demonstrates, the script should return a string with whatever delimiter you have specified in the paramater or a String[] array. here is a snippet of the function that processes the value returned from the script:

// line 450 - 465 of ExtendedChoiceParameterDefinition
private String processGroovyValue(boolean isDefault, Object groovyValue) {
    String value = null;
    if(groovyValue instanceof String[]) {
        String[] groovyValues = (String[])groovyValue;
        if(!isDefault) {
            value = StringUtils.join((String[])groovyValue, multiSelectDelimiter);
        }
        else if(groovyValues.length > 0) {
            value = groovyValues[0];
        }
    }
    else if(groovyValue instanceof String) {
        value = (String)groovyValue;
    }
    return value;
}

3. What directory is the cwd of the script? is it the environment variable WORKSPACE?

Does it matter? You can access the environment variable WORKSPACE from within the script using

Map<String, String> props = System.getenv();
def currentDir = props.get('WORKSPACE');

4. there is an extra field called variable bindings. How is this used?

This is a property file formatted key=value file. these names are then resolvable in the groovy script.

    e.g.
    key1=foo
    prop2=bar
coderatchet
  • 8,120
  • 17
  • 69
  • 125
  • 9
    Sorry but where is the script supposed to be placed? I'm trying to make this work from a Pipeline Jenkinsfile and so far I to it to work by placing the text of the script inline, as a variable in the Jenkinsfile. It doesn't seem to work when I try to load the definition of the parameter from an external script. – Mig82 Jun 28 '17 at 12:30
  • 9
    Please add an example of a pipeline that uses this plugin with scripts – AFP_555 Oct 23 '17 at 20:41
  • 1
    Simple example: Jenkins > Job > Configure > This project is parameterized > Extended Choice Parameter > Basic Parameter Types > Single Select > Groovy Script > `return [1,2,3]` – mellow-yellow Nov 08 '19 at 22:28
  • 4
    As this thread appears to be the official documentation for how a JSON Parameter Groovy Script type of Extended Choice Parameter works, I would like to see a single, simple, functioning example of this parameter type. https://plugins.jenkins.io/extended-choice-parameter/ – timblaktu Apr 01 '20 at 16:38
  • 5
    This looks like the plugin i want to use but there is literally zero documentation on how. I agree that i would like to see example(s) using declarative syntax. Update: I forgot I had this in my bookmarks: https://support.cloudbees.com/hc/en-us/articles/115003895271-How-to-do-a-multiselect-input-in-a-pipeline . It's still not clear, but maybe it'll help someone. – Max Cascone Nov 12 '20 at 19:34
  • I finally found out where to place the script. You can basically put it anywhere but you need to know the path to it and specify it. If you run Jenkins on a machine that you operate, you can manually put the file somewhere and then refer to the path. In my case I use a docker image and also rely on shared libraries so it was easier to put the script in my lib and then use the path to the lib (it is in the job's workspace). For example I used ```groovyScriptFile: '/var/lib/jenkins/jobs/sandbox/jobs/springboot/branches/feature.qjmq9u/workspace@libs/jenkins-lib/vars/myScript.groovy'``` – ssc327 Mar 19 '21 at 17:10
  • @ssc327 : can you give us an example of your script? – Bobax Dec 05 '21 at 15:49
  • @bobax do you want to the script, or how I call it, or both? – ssc327 Dec 05 '21 at 15:55
  • @ssc327 thanks for your help but I succeed by my own by using `...JSONObject.fromObject(...` in place of using `...Boon.fromJson(...` – Bobax Dec 06 '21 at 09:58
  • I cannot obtain the workspace directory as described in section 3. * props.get('WORKSPACE') returns null * System.getProperty("user.dir") returns the Jenkins install path Maybe something has changed since this description. I'm running Extended Choice Parameter 0.82 on Jenkins 2.303.2 – Daniel Ellis Dec 07 '21 at 09:01
1

For parse json object (from parametres) to groovy object - Parsing and producing JSON

import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText('{ "myList": [4, 8, 15, 16, 23, 42] }')
println(object.myList)
Kirill K
  • 335
  • 1
  • 6
  • 21