# BlogStream

### Jenkins CI + DSL

By Sterling Heibeck on December 28, 2015

We work on a lot of projects at BizStream, which means that when we change something about our process we need to find a way to retroactively update all our projects (or at least many of them) to use the new process. One of our core technologies is our continuous integration system - Jenkins CI.

Jenkins is a great tool that has a very active community and many, many great plugins one of which is the Job DSL plugin. Normally with Jenkins you define jobs by using the UI and creating a new job and then configuring the job with various bits of information, like the repository location and the location of your development server. You can also add post-build actions that can do things like monitor the success of the job and copy files out to your development environment.

This is great when you have just a handful of jobs, but when you have upwards of 30 active jobs then one little change to the CI process means hand-editing 30 jobs. Enter Job DSL plugin.

DSL (or Domain Specific Language) is a way to encapsulate your CI Jobs in code, which means you can put these job descriptions in a code repository and best of all, update them in bulk using simple Search and Replace functionality found in virtually every text editor out there.

Our CI process is pretty simple: Pull the project files from BitBucket, Copy files to the proper folder on the development server, send some emails if something goes wrong. Here’s what our DSL file would look like for this process (written in Groovy):

//************************************************
//********  Create a Job  *************
//************************************************
job('my-job-name') {
displayName 'My Job Name'
description 'the description of my job'

// pull files from a repository into the current workspace
scm {
hg(“https://bitbucket.org/my-job-name/repository/url”, "default") { node ->
node / installation('Mercurial')
}
}

steps {
// This tells jenkins to copy files from this jobs workspace to a folder location appended by the Job Name
// %WORKSPACE% tells Jenkins to use the projects Workspace
batchFile("xcopy \"%WORKSPACE%\" \"c:\\path\\to\\folder\\%JOB_NAME%\\\" /s /e /y /d /r")
}
}


I trimmed the fat, but you get the gist of what this file can look like. There’s an exhaustive list of commands for the Job DSL Plugin, and they support many of the plugins as well.

We keep one file per project and store them in a repository. Then we have a Seed Job that we’ve created in Jenkins that pulls all the files from this repository and runs each file, creating a job for each file it finds. If the job already exists, it updates the job. If a job created from this process no longer exists, the job is removed from the Jenkins job list. Self maintaining, nice!

To configure the seed job simply create a new Job and specify the repository location of your DSL files. Add one build step of type Process Job DSLs. Specify that this step look in the file system for all *.groovy files. We chose to disable removed jobs instead of deleting them, however, since the DSL files are all under revision control you can safely choose to remove jobs because it’s in your repository history.

Now, if we ever want to add a build step (for example, building a solution file), we can add the step to our DSL file and do a search and replace across all our DSL files to add the step in each one. Save and push the change to our repository and run the seed job and Jenkins will update all of the existing jobs automatically.

This is a huge time saver, and just plain awesome.