This post reviews best practices when we implement Groovy classes and/or static Groovy methods, in src folder as opposed to vars folder, for Jenkins Shared Library.
Examples of shared libraries in src folder
All Groovy files in Jenkins shared library for pipelines have to follow this directory structure:
1 2 3 4 5 6 7 8 9 10 11 12 | |
src folder is intended to set up with groovy files in the standard directory structure, such as “src/org/foo/bar.groovy”.
It will be added to the class path when the Jenkins pipelines are executed.
Any custom function in a Jenkins shared library has to eventually use basic Pipeline steps such as sh or git, made available through various Jenkins plugins.
However, Groovy classes in shared Jenkins library cannot simply call those basic steps directly.
There are a few approaches on how to access those Pipeline steps indirectly.
Method 1: Methods in implicit class
Groovy scripts in src folder can implement methods that invoke Pipeline steps, like this:
1 2 3 4 5 6 | |
The method is stored implicitly in library and can then be invoked from a Scripted Pipeline like this:
1 2 | |
However, the requirement of this approach is that those methods defined in buildUtils.groovy cannot be enclosed in any class.
The “implicit class” mentioned in this approach refers to the fact that any Groovy script, such as buildUtils.groovy, has an implicit class (e.g., org.demo.buildUtils) that contains all the defined functions in it.
This approach has limitations; for example, it prevents the declaration of a superclass.
Method 2: Explicit objects
In the following example, we create an enclosing class that would facilitate things like defining a superclass.
In that case, to access standard DSL steps such as sh or git, we can explicitly pass special global variables env and steps into a constructor or a method of the class.
Global object env contains all current environment variables while steps contains all standard pipeline steps.
Note that the class must also implement Serializable interface to support saving the state if the pipeline is stopped or resumed.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 | |
Method 3: Static methods in explicit class
In the final example, we can also use static method and pass in the script object, which already has access to everything, including environment variables script.env and Pipeline steps such as script.sh.
1 2 3 4 5 6 | |
The above example shows the script being passed in to one static method, invoked from a Scripted Pipeline as follows (note import static):
1 2 3 4 5 | |
Recommended practices
All three approaches shown in three examples above are valid in Scripted Jenkinsfile.
However, per recommended by CloudBees Inc., src folder is best for utility classes that contains a bunch of static Groovy methods.
It is easier to use global variables in the vars directory instead of classes in the src directory, especially when you need to support declarative pipelines in your team.
The reason is that in declarative pipelines, the custom functions in Jenkins shared libraries must be callable in declarative syntax, e.g., “myCustomFunction var1, var2” format.
As you can see in the examples above, only in Method 3 (Static methods in explicit class), where custom functions are defined as static methods, the invocation of custom function is compatible with declarative pipeline syntax.
When using src area’s Groovy codes with library step, you should use a temporary variable to reduce its verbosity, as follows:
1 2 3 4 | |