Motivation
I just recently changed jobs: my new development team is larger, it’s a very dynamic environment with multiple branches being created in git repositories all the time, and people are creating Jenkins build jobs in order to run automated builds and tests for these branches on a daily basis.
At some point the manual copy-pasting of Jenkins jobs that was the general practice was beginning to annoy me and I decided to give a try to Jenkins’ HTTP API. The goal was to be able to script the creation of jobs, from consistent updateable descriptions. The result has been the creation of the autojenkins package written in Python, that will allow us to query the status of Jenkins jobs, trigger manual builds, create new ones, and cleanup by removing old jobs.
Using Autojenkins
Autojenkins is published on PyPI, you install it simply with:
pip install autojenkins
Once installed, it provides an easy to use Python client for the Jenkins HTTP API. Here’s a taste of the API with some sample usage:
from autojenkins import Jenkins
j = Jenkins('http://jenkins.pe.local')
# trigger a manual build and check results
j.build('my-job')
j.last_result('my-job')
# get only the result string (one of 'SUCCESS', 'UNSTABLE', 'FAILURE'):
j.last_result('my-job')['result']
# get the configuration file for a job:
j.get_config_xml('template')
# Create a new job from a job named 'template', replacing variables
j.create_copy('my-new-job', 'template',
repo='my-repo',
branch='my-branch')
# build
j.build('my-new-job')
# check result and delete if successful:
result = j.last_result('my-new-job')['result']
if result == 'SUCCESS':
j.delete('my-new-job')
Creating New Jobs
I wanted to make the creation of jobs scriptable, where jobs could be created from template definitions. The API for creating a job in Jenkins consists of posting a full config.xml file with the complete job description, which is kind of annoying. Building these job configurations from scratch was not something I found useful at this point, so I thought of using Jinja2 templates for Jenkins jobs. This way I can include replacement variables in the template using the Jinja2/Django syntax {{ variable }}.
Instead of writing these XML files, what we will do is something nicer, which is to create the template jobs as jobs within Jenkins itself, but we will use the {{ variable }} syntax at will within the job configuration page (e.g. use {{ repo }} for the repository name, {{ branch }} for the branch name, etc.). We can disable build for these template jobs so that Jenkins doesn’t try to build them and fail miserably.
What our Jenkins.create_copy method will do is download the config.xml file for one such template job, liberally perform variable substitutions (using arbitrary kwargs), mark the job as enabled again, and upload the replaced template as a new job:
from autojenkins import Jenkins
j = Jenkins('http://jenkins.pe.local')
j.create_copy('my-new-job', 'template',
repo='my-repo',
branch='my-branch')
What this sample call does is:
- Download the
config.xmlof a job namedtemplate - Replace occurrences of
{{ repo }}with the valuemy-repo - Similarly with
{{ branch }}andmy-branch - Upload the new template for the creation of a new job named
my-new-job
Give autojenkins a spin, and tell me what you think!

#1 by mgiaco on 2012/05/09 - 09:37
Hi,
Today i tried autojenkins it is realy great!
But one function is missing i think.
I think it is very usefull to have a
update_job function
j.update_copy('my-running-job', 'template', repo='my-repo', branch='my-branch')or is your recommended way to
j.delete('my-running-job')and then use creat_copy
thx
#2 by Carles Barrobés on 2012/05/17 - 09:39
Aha, I see the point in keeping a job definition in sync with the template. Feel free to raise an issue in our github repo: https://github.com/txels/autojenkins/issues
Patches (Pull Requests) are also welcome.