Refactor and Source-Control Your CI

Refactor and Source-Control Your CI

Dariusz Pasciak
Dariusz Pasciak

August 22, 2016

If you're using Jenkins, then you may have a job that has an "Execute Shell" step to build your project.

The contents of that step may look like:

bundle exec rspec

Or maybe just this:

bundle exec rake teaspoon

Or maybe a little bit of both:

bundle exec rake teaspoon
bundle exec rspec

With a little bit of this:

bundle exec rake teaspoon
bundle exec db:setup db:migrate
bundle exec rspec

And a little bit of:

bundle exec rake teaspoon
bundle exec db:setup db:migrate
bundle exec rspec
curl -X POST -T failures.json https://my.data.com/failures

Maybe it started with a one-liner, but then eventually grew to be a four-or-more-liner.

Instead of using that "Execute Shell" textbox to pile in everything that's relevant to your build, put all of those commands into one file (say, ci/build) and execute that file from the textbox. With this setup, you can check that script in to source control and get all the benefits that come with.

First, because this build script is in source control, all history that goes with it becomes available to you. If the need ever comes up, you can investigate how your project and build script evolved together. Whereas, if your "build script" is just a bunch of text in a box on some Jenkins configuration page, then you don't get any history with that. If someone makes an "improvement" to the build script and ends up breaking everything, you can very easily revert to what you had there previously if it's in source control.

Second, having your entire build process in source control means that the build process is specific to each commit in your repository. With every change to your code you also have the freedom to modify the build script to reflect those changes. What this means is that every developer has the freedom to try different build configurations (i.e. optimizations, experimenation) without affecting anyone else on the project.

Even if your build is very simple right now, and it doesn't do anything more than bundle exec rspec or mvn test, just go ahead and throw that into a ci/build anyway and check that in. There will come a day when you want to change that just a little, and having it in source control will make things just a little simpler.

Jenkins Pipelines

Taking this a little bit further, it would be ideal if we could throw all of our build details into a source-controlled file. If you're using classic Jenkins jobs then that's not really possible because you still have to manually click through the UI, create a job, and set up a bunch of things by hand.

This can get pretty tedious and cumbersome, and that's where the Pipeline plugin comes in. This plugin allows you to specify a lot more of your build configuration in a Jenkinsfile, which is also source-controlled. It may not be trivial to migrate your existing traditional job to the pipeline, but it may certainly be worth the effort. Give it a shot!

Other Solutions

There are a ton of CI solutions out there. I use Jenkins as an example here, but whatever you end up choosing make sure it allows you to source control your build configuration in some manner.

Happy Continuous Integration!