Extending¶
Jenkins Job Builder is quite modular. It is easy to add new attributes to existing components, a new module to support a Jenkins plugin, or include locally defined methods to deal with an idiosyncratic build system.
The Builder¶
The Builder
class manages Jenkins jobs. It’s responsible for
creating/deleting/updating jobs and can be called from your application. You
can pass it a filename or an open file-like object that represents your YAML
configuration. See the jenkins_jobs/builder.py
file for more details.
XML Processing¶
Most of the work of building XML from the YAML configuration file is
handled by individual functions that implement a single
characteristic. For example, see the
jenkins_jobs/modules/builders.py
file for the Python module that
implements the standard Jenkins builders. The shell
function at
the top of the file implements the standard Execute a shell build
step. All of the YAML to XML functions in Jenkins Job Builder have
the same signature:
- component(xml_parent, data)
:arg class:xml.etree.ElementTree xml_parent: this attribute’s parent XML element :arg dict data: the YAML data structure for this attribute and below
The function is expected to examine the YAML data structure and create new XML nodes and attach them to the xml_parent element. This general pattern is applied throughout the included modules.
Modules¶
Nearly all of Jenkins Job Builder is implemented in modules. The main program has no concept of builders, publishers, properties, or any other aspects of job definition. Each of those building blocks is defined in a module, and due to the use of setuptools entry points, most modules are easily extensible with new components.
To add a new module, define a class that inherits from
jenkins_jobs.modules.base.Base
, and add it to the
jenkins_jobs.modules
entry point in your setup.py.
- class jenkins_jobs.modules.base.Base(registry)¶
A base class for a Jenkins Job Builder Module.
The module is initialized before any YAML is parsed.
- Parameters:
registry (ModuleRegistry) – the global module registry.
- amend_job_dict(job)¶
This method is called before any XML is generated. By overriding this method, a module may arbitrarily modify a job data structure which will probably be the JJB Job intermediate data dict representation. If it has changed the data structure at all, it must return
True
, otherwise, it must returnFalse
.- Parameters:
job (dict) – the intermediate representation of job data loaded from JJB Yaml files after variables interpolation and other yaml expansions.
- Return type:
bool
- component_list_type = None¶
The component list type will be used to look up possible implementations of the component type via entry points (entry points provide a list of components, so it should be plural). Set both component_type and component_list_type to None if module doesn’t have components.
- component_type = None¶
The component type for components of this module. This will be used to look for macros (they are defined singularly, and should not be plural). Set both component_type and component_list_type to None if module doesn’t have components.
- dispatch_component_list(component_type, component_list, xml_parent, job_data=None)¶
- gen_xml(xml_parent, data)¶
Update the XML element tree based on YAML data. Override this method to add elements to the XML output. Create new Element objects and add them to the xml_parent. The YAML data structure must not be modified.
:arg class:xml.etree.ElementTree xml_parent: the parent XML element :arg dict data: the YAML data structure
- sequence = 10¶
The sequence number for the module. Modules are invoked in the order of their sequence number in order to produce consistently ordered XML output.
Components¶
Most of the standard modules supply a number of components, and it’s easy to provide your own components for use by those modules. For instance, the Builders module provides several builders, such as the shell builder as well as the trigger_builds builder. If you wanted to add a new builder, all you need to do is write a function that conforms to the Component Interface, and then add that function to the appropriate entry point (via a setup.py file).
Module Registry¶
All modules and their associated components are registered in the module registry. It can be accessed either from modules via the registry field, or via the parser parameter of components.
- class jenkins_jobs.registry.ModuleRegistry(jjb_config, plugins_list=None)¶
- dispatch(component_type, xml_parent, component, template_data={}, job_data=None, component_pos=None)¶
This is a method that you can call from your implementation of Base.gen_xml or component. It allows modules to define a type of component, and benefit from extensibility via Python entry points and Jenkins Job Builder Macros.
- Parameters:
component_type (str) – the name of the component (e.g., builder)
xml_parent – the parent XML element
component – component definition
template_data (dict) – values that should be interpolated into the component definition
job_data (dict) – full job definition
See
jenkins_jobs.modules.base.Base
for how to register components of a module.See the Publishers module for a simple example of how to use this method.
- get_plugin_version(plugin_name, alt_plugin_name=None, default=None)¶
Provide plugin version to be used from a module’s impl of Base.gen_xml.
The return value is a plugin version obtained directly from a running Jenkins instance. This allows module authors to differentiate generated XML output based on it.
- Parameters:
plugin_name (str) – Either the shortName or longName of a plugin as seen in a query that looks like:
http://<jenkins-hostname>/pluginManager/api/json?pretty&depth=2
alt_plugin_name (str) – Alternative plugin name. Used if plugin_name is missing in plugin list.
default (str) – Default value. Used if plugin name is missing in plugin list.
During a ‘test’ run, it is possible to override JJB’s query to a live Jenkins instance by passing it a path to a file containing a YAML list of dictionaries that mimics the plugin properties you want your test output to reflect:
jenkins-jobs test -p /path/to/plugins-info.yaml
Below is example YAML that might be included in /path/to/plugins-info.yaml.
- longName: 'Jenkins HipChat Plugin' shortName: 'hipchat' version: "0.1.8"