Wednesday, August 29, 2007

Hoorah for Hudson

Introduction

If you haven't heard yet, there's a neat little build tool (server) called Hudson that is available for free to a good home. I read about Hudson on Glen Smith's blog, and when competent people rave about something I usually sit up and take notice. I believe Hudson was started by Kohsuke Kawaguchi though there are others now involved in development with him. You can read about Hudson here, and download the latest version here.

At my company, we'd gotten by doing manual builds at the appropriate time for whatever the purpose. Sounds horrid, but the fact of the matter was that everything was checked into CVS, so if you needed a build, it was there to be checked out and built. However, as our product suite grew and our developer numbers grew, it was never going to be an ideal situation. Thing is, what to do about it? Cue Hudson.

I installed Hudson and played around with it and found it to be a very competent build server, so I talked my boss into letting me stick it on a dedicated machine, so that we could use it as an interim tool. The idea at that time was to get something more robust, like TeamCity, from Jetbrains. Well that was a few months ago, and we currently have 29 jobs setup on Hudson.

What's so great about Hudson?

Glad you asked. Well a number of things actually. I could go on and on so I'm just going to mention some of the main things:
  1. It's 1 WAR file.
    In case you missed what I just said, I said it's ... one... WAR file. So you drop that into your (in our case) Tomcat webapps root, and you're done. I like that Hudson defaults to creating a .hudson folder in your user home folder. This makes it easy-peasy to upgrade Hudson: simply download a new WAR, nuke the old one and its folder and restart Tomcat. Done. Hudson even comes with a 'Shutdown' feature that will gracefully end any currently executing builds, and prevent new builds from starting until after the restart.

  2. AJAXification.
    Other than the pointless fact that it has buzzword gravity, the AJAX behaviour of Hudson is quite useful. If you're on the home page, builds that are scheduled or busy executing will automatically show up in the sidebar, without the whole page reloading every few minutes. There's AJAX behaviour when you fill in textfields etc. Hudson will prompt you with values for that textfields from existing data in Hudson. That kind of thing. Very useful.

  3. Smart touches.
    You can see that the people who are developing Hudson, also use Hudson, and have an understanding for the needs of a build server. An example is that Hudson exports an environment variable for the build number, while executing a job. So you can tap into that value and use it in marking your deliverables. That way you can track bugs back to a particular build, and do better forensic detective work. We use that build number when closing a bug in Bugzilla.

    Hudson also does its CVS checkout using a datetime limiter i.e. check out this module as at this time. At first this was a bit frustrating. If I checked something into CVS and triggered a Hudson build manually, and the change wasn't in the resulting build because the build servers time was off by a few minutes, so I wondered why on earth Hudson didn't simply take the latest HEAD snapshot. Well, as it turns out, there's a good reason. Thing is, most build servers operate in a team environment and it is quite possible that while Hudson is busy checking stuff out of CVS, somebody else is busy checking stuff in. So using a specific time ensures that it checks out everything as it was at that moment, even if it takes Hudson 5 minutes to check it all out. Of course somebody could also be doing a long check-in that crosses that time moment, but that's a lot less likely since CVS commits are usually quick use cases. Ok, truth be told, Hudsons main purpose is, I think, to run scheduled build jobs, at a time when it is unlikely that developers will be actively committing to CVS.

  4. Master slave functionality.
    Our dedicated build server is actually a bit on the puny side. So I thought to myself "Self, wouldn't it be useful if we could use some of our steroid-taking servers to do some of the build work for us?" And lo and behold, Hudson has the ability to create slave nodes, so your master Hudson build server can farm work off to your slave nodes. We haven't actually set this up yet, mainly because of time constraints, but pretty soon I see that as being a very useful feature for us.

  5. Email notification.
    Hudson lets you know when a build fails. It did bother me that it doesn't let you know when a build succeeds, but then it occurred to me that the idea behind Hudson is to schedule builds, or have them trigger from CVS commits, so really, you only want to know when something goes wrong. Also, if a build has failed, then succeeds, it emails you once to let you know that all is back to normal.

  6. RSS Feeds.
    You can pull RSS feeds for all the projects, so to check the latest build and result of a build you simply use your RSS browser. Click on that link and you go straight there. Neat!
So far the only real downside that has impacted us is that you have to checkout modules on a branch, not a tag. For some reason it can't handle tags. After some research I found that this is actually a bug, and that prior to build 1.65 it could handle tags. It's already logged as a bug here though there's no fix estimate at the time of writing this post.

Conclusion
There are many other useful touches to Hudson that make it quite an impressive tool for something that is free, as in beer. We have all of our products now configured to build on Hudson and we have dependencies defined between projects, so that if we make a change to a core component, dependent components build immediately after the core component builds, and that way we detect API breakages very quickly. It should be very easy to hookup Ant test scripts to also run, since they'll be part of the overall build, so hopefully in the near future we have that configured too. I certainly know that our QA guys are much happier having a website they can go to for the latest stuff, and one that has us all on the same page when cross-referencing bugs with bug fixes, and their purported fix build number.

Give it a try and drop me a comment with your comments, good or bad.