Doing Continuous Delivery with Hudson and Git

Right now I’m reading the book Continuous Delivery. Excellent reading and even though I’ve only read around 46% percent of it, it’s quite thought provoking.

I’ve written earlier on how we at RemoteX have set up our build environment with a concept I then called The Independent Trunk (terrible name, right?). Continuous Delivery describes a similar approach of handling your source-control and build system, though in greater detail.

Recently we’ve been considering switching build environments to Hudson, since we’ve been quite happy with the results Hudson has been given us when we’ve tried it out for different scenarios.

Hudson however does not have its configuration checked in under source-control. Most people seem to be happy with just doing backups of the configuration with the motivation that it seldom changes. However I firmly believe that the configuration of the build-environment follows the same lifecycle as the software, and it seems the authors of the Continuous Delivery book do as well.

So I set out to do some experiments with Hudson to see if I could model an arbitrary delivery pipeline using Hudson and yet have it checked in.

I wanted the following to hold:

  • All configuration is checked in
  • Developers run the same builds locally as they do on the build-server
  • It’s easy to run the complete pipeline on a developer machine
  • It should be fast to get up and going

I started thinking about this in the middle of December and about a week ago I started to set things up. The idea I got was to simply check the entire Hudson system into source-control. I put the war-file that is executed in source-control along with Hudson’s home directory. I spent quite some time tinkering with the .gitignore file to get things set up how I wanted it.

The result is available on git-hub at: https://github.com/morkeleb/continuous-delivery-with-hudson feedback is highly appreciated. Also if anyone wants to use it as a boilerplate for new projects go right ahead.

The only difference in the pipeline I’ve created and the one that the book describes is that I’ve added a packaging step that is supposed to take all artifacts from the CI builds and add them up into a deliverable package. There are two stub CI builds creating files and shows the intended structure.

To make it easy to start Hudson on a developer machine I created a .bat file that starts the CI engine locally. All a developer has to do is get the latest version and run the script to have Hudson setup locally.

What I’ve found thus far is that this approach seems to work quite well. Sure it takes some disc space but that is affordable.

Upgrading Hudson can be done easily and have the changes replicated across developer machines as the fetch the latest version from the origin.

Now there are some things that differ when you run Hudson locally and on the main build-server. The main build-server will have all its artifacts and fingerprints backed up, as well as following the source-control version.

There are however some things that I’ve yet to try out. Changes to the configuration needs to be updated on the build machine, this can be accomplished by logging on to the machine and the do a git pull. However since this is tiresome a web hook approach could be interesting for automatically restarting Hudson and getting the latest version of the configuration from source-control. This however is yet to be experimented with.

Feel free to check it out on git-hub and any feedback is great. Especially considering that this might seem a bit crazy.