3

I have a groovy script that will be common to many jobs - they will all contain an Active Choices Reactive Parameter. Rather than repeat the same script dozens of times I would like to place in a (library | ??) one time, and reference it in each job.

The script works beautifully for any job I paste it in. Just need to know if it is possible to plop it into one place and share across all jobs. Update it once, updates all jobs.

import jenkins.model.Jenkins;

ArrayList<String> res = new ArrayList<String>();
def requiredLabels = [new hudson.model.labels.LabelAtom ("Product")];
requiredLabels.add(new hudson.model.labels.LabelAtom(ClientName));

Jenkins.instance.computers.each {
        if (it.assignedLabels.containsAll(requiredLabels)) {
            res.add(it.displayName);    
        }
}

return res;
John Hennesey
  • 343
  • 1
  • 2
  • 18
  • in Jenkins pipeline, you can use shared libraries to extract out common parts of the pipeline. Please refer this link for more info : https://jenkins.io/doc/book/pipeline/shared-libraries/ – eeedev Sep 12 '19 at 09:57
  • 1
    Works great for pipeline jobs - but I am interested in using a shared function in an Active Choice Parameter before the build kicks off. In the Parameter Groovy script I put '@LIbrary("libname@master")' like I do for pipeline and get 'starup failed: Script1.groovy: 1: unable to resolve class Library , unable to find class for annotation @ line 1, column 1, @Library("libname@master")' – John Hennesey Sep 12 '19 at 12:16
  • If you generate jenkins jobs using Jenkins Job DSL API (https://jenkinsci.github.io/job-dsl-plugin/) it is possible to refer the common methods from the specific jobs – eeedev Sep 12 '19 at 12:24

4 Answers4

3

The option we decide on was to have a common parameters function .groovy we store in git. There is a service hook that pushes the files out to a known network location on check-in. In our Jenkins build step we then have the control dynamically load up the script and invoke the function passing in any parameters.

ArrayList<String> res = new ArrayList<String>();

try {
new GroovyShell().parse( new File( '\\\\server\\share\\folder\\parameterFunctions.groovy' ) ).with {
    res = getEnvironments(ClientName);
}
} catch (Exception ex) {
  res.add(ex.getMessage());
}

return res;

And our parameterFunctions.groovy will respond how we want:

public ArrayList<String> getEnvironments(String p_clientName) {

    ArrayList<String> res = new ArrayList<String>();

    if (!(p_clientName?.trim())){
        res.add("Select a client");
        return res;
    }

    def possibleEnvironments = yyz.getEnvironmentTypeEnum();

    def requiredLabels = [new hudson.model.labels.LabelAtom ("PRODUCT")];
    requiredLabels.add(new hudson.model.labels.LabelAtom(p_clientName.toUpperCase()));


    Jenkins.instance.computers.each { node ->
        if (node.assignedLabels.containsAll(requiredLabels)) {
                // Yes.  Let's get the environment name out of it.
                node.assignedLabels.any { al ->
                    def e = yyz.getEnvironmentFromString(al.getName(), true);
                    if (e != null) {
                        res.add(al.getName());
                        return; // this is a continue
                    }
                }
            }
        }


    return res;
}
John Hennesey
  • 343
  • 1
  • 2
  • 18
2

CAVEAT: This will work only if you have access to your Jenkins box. I haven't tried to do it by adding paths to the jenkins home

You can use this:

  1. Make all your functions into a groovy file. For example will call it: activeChoiceParams.groovy
  2. Convert that file into a jar by: jar cvf <jar filename> <groovy file>. For example: jar cvf activeChoiceParams.jar activeChoiceParams.groovy
  3. Move your jar file to /packages/lib/ext
  4. Restart Jenkins
  5. In your active choices groovy script use (for example>:
import activeChoiceParams

return <function name>()

All functions must return a list or a map

mndrye
  • 489
  • 2
  • 7
  • Unfortunately developing scripts and having to put in a jar / restarting Jenkins / security would be too disruptive to the system. Need something developers can easily change during working hours that doesn't require a restart. Thanks though! – John Hennesey Sep 12 '19 at 13:54
1

Nope, looks like it isn't possible (yet).

https://issues.jenkins-ci.org/browse/JENKINS-46394

John Hennesey
  • 343
  • 1
  • 2
  • 18
1

I found interesting solution by using Job DSL plugin.

usually job definition for Active Choices is look like:

from https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.helpers.BuildParametersContext.activeChoiceParam

  job('example') {
    parameters {
        activeChoiceParam('CHOICE-1') {
            choiceType('SINGLE_SELECT')
            groovyScript {
                script(readFileFromWorkspace('className.groovy') + "\n" + readFileFromWorkspace('executionPart.groovy'))
            }
        }
     }
  }
  1. in className.groovy you can define class as a common part
  2. with executionPart.groovy you can create instance and make your particular part
max.ivanch
  • 339
  • 2
  • 5