Job Templates

In many enterprise situations, you end up with multiple jobs that differ by only a few aspects, such as where the code is checked out from, or the QA servers that are used. Job templates can be used to represent this model in enterprise development by letting projects only define the minimal variable configuration to apply to the model. Thus, a job template offers a higher level of abstraction, as it templatizes the definition of an entire job.

One typical use case of this is that you have lots of components that are written and built the same way. The open-source Jenkins project, for example, has a large number of plugins that are built precisely in the same way. It makes sense to define a template for this, as we did in the tutorial, to centralize the configuration and make it easier to create a new job for a new plugin.

Another typical use case is that you have multiple branches of the same project, actively developed in parallel. Such jobs tend to only differ in version control configuration, and making a template out of them allows you to rapidly set up CI for new branches.

Another use case of the job template is where there is a gap in Jenkins expertise between the Jenkins experts in your organization and the developers at large. Templates can be useful to “dumb down” the user interface and steer them toward the best practices the experts define, thus gaining overall productivity for them.

A custom job type can be also developed as a plugin, but this is one of the most complex extension points in Jenkins. For this reason, we recommend you start with a job template. Only after you start feeling the constraints of the template plugin should you consider rewriting your template as a custom plugin.

Configuration

Job templates need to produce a full job XML definition as a result of the transformation. As discussed in the tutorial, often the simplest way to get this done is “programming by example”. You manually create a project (or a few), configure it with all the desired options, and then get the config.xml file by adding config.xml to the URL, then insert expressions and statements where you need to reflect actual values from instances.

Tip

When using the Groovy template transformation, you can save time by using the Load Prototype feature to load a named job’s config.xml directly into your transformer input. (Any special characters like $ will automatically be escaped for you.)

Warning

When a job is initially created from template, all of its attributes will be null until the user configures it and clicks Save. This means that your transformer must be prepared to accept null attribute values. Jelly scripts usually have an easy time with this since the JEXL expression language treats attr.prop as null if attr is null. Groovy scripts can use the safe navigation operator (attr?.prop). Or either kind of script can explicitly check for null and conditionally insert an XML block:

Null attribute check in Jelly scripts. 

<j:if test="${attr != null}">
  <somexml>${attr.prop}</somexml>
</j:if>

Null attribute check in Groovy scripts. 

<% if (attr != null) { %>
  <somexml>${attr.prop}</somexml>
<% } %>

Figure 10.14. Job Templates

template job

A job template will also maintain a list of projects that are using the template, so that an administrator can quickly check the project that follows the success of project structure standardization.

Tip

There is no special trick to create job templates whose instances have parameters (i.e., per-build variables chosen by the user initiating the build). You just need to mentally separate parameters from template attributes, since they are expanded at different times. The Load Prototype feature helps ensure that parameter expansions are escaped and not misinterpreted as template attribute expansions. This blog post goes into detail.