Often, developers create build steps as shell scripts to address enterprise requirements, for custom deployments, packaging, notification, QA integration, etc. The same script is used across a large set of jobs and only differ by few attributes. Maintaining such scripts and avoiding copy/paste mistakes can be a nightmare on large Jenkins installations. The builder template creates a new type of builder, thereby eliminating the need of copying a script, and highlighting the things that need to be filled in by users.
A similar goal can be achieved by a custom plugin development. A builder template, compared to a custom plugin, has the following trade-offs:
- Writing a plugin requires a significant one-time learning cost, whereas a simple template can be developed rapidly. So for simple things, templates tend to get the job done more quickly.
- A template can be created, modified, or removed without restarting Jenkins.
- You get a lot more tool assistance for plugin development, thanks to the great IDEs available for Java. So for complex things, plugins tend to get the job done more quickly and elegantly.
Compared to job templates, builder templates tend to be more flexible, as the person configuring jobs still has substantial freedom to control how it works. A builder template is also the easiest kind of template to create, especially in combination with the specialized transformers that generate shell scripts. This makes builder templates the best entry point to the template plugin.
The new item wizard offers a few options, including that of creating a new Builder Template. The template configuration allows the administrator to define the execution details of any custom tool, which will be exposed to users as a new build step.
The transformer controls how your builder template maps to the actual builder that carries out the build.
One way to define a transformer is to use one of the standard transformers that takes an instance and produces XML. (In this case, the XML should match that saved for a build step in a job configuration.) As we discussed in the tutorial, a good way to do this is programming by example, where you manually create a freestyle project and configure it, then observe what XML it is producing.
The other way to do this, which is often preferable, is to use one of the specialized transformers that only work with builder templates, which we’ll discuss below.
For shell scripts, a simpler way to define a builder template is to generate the script using Jelly or Groovy instrumentation to process the attributes and generate the adequate script. These specialized transformers eliminate the need of “programming by example” by focusing on the shell scripts.
See the transformer reference section for more details about the general syntax of Jelly/Groovy template, as well as available variable bindings.
The following screenshot demonstrates a Groovy-generated shell script to run the du
command on an arbitrary user home directory. The \${… }
in the text should not be mistaken for a shell variable reference. These Groovy expressions are expanded during the transformation before it gets passed to the shell.
Such templates are easily created by a Unix administrator to automate maintenance processes, and can be used to give users the ability to run tools without the risk of allowing arbitrary commands to be executed.
An alternate transformer option, Sets some variables using Groovy then runs a shell/batch script, is also available. Unlike the previous transformer, the shell (or Windows batch) script section is not processed using any template language. Instead, your template attributes are directly available as shell variables, and you can optionally run a Groovy program to define other shell variables (typically based on the Jenkins build object, as in the section called “Template evaluation timing”).
For example, suppose you have defined an auxiliary template for compiler options (the section called “Auxiliary Template” has more).
Now if you want to collect a number of options in a builder template, and produce an options variable suitable for interpolation in a shell script, you can use a brief Groovy snippet to process the options into a flat string.
When this builder template is used in a job definition, compiler options may be defined structurally.
The resulting build will run: cc -O3 -g --sysroot=/usr/local *.c
Another key difference of these specialized transformers is the difference in the timing of the template evaluation. The general purpose transformers perform transformation asynchronously from the execution of builds (roughly speaking, think of it as transforming right after the job is configured), whereas these shell script transformers run during the build.
This allows you to perform contextual transformations that depend on the parameters and conditions of the in-progress build (such as the changes in the source code, or what started it).
To do so, use the build
variable from within your template to access the AbstractBuild object that represents the current build in progress.
Tip
One special use for a builder template is to use Groovy to compute some variables, and then make them available to subsequent build steps—without actually running anything itself. The Sets some variables using Groovy then runs a shell/batch script transformer can be used for that purpose. Just leave Shell/Batch Script empty, and use something like the following in Groovy Script:
e = new hudson.EnvVars() e.put('VAR1', 'val1') e.put('VAR2', 'val2') build.environments.add(hudson.model.Environment.create(e))
These variables can now be used like any others in subsequent build steps, e.g. $VAR1
from Execute shell.