Friday, October 08, 2010

My Continuous Integration Build is too fast

We all know of Continuous Integration and the importance of having really fast builds, especially on a central build server. If not read up on http://martinfowler.com/articles/continuousIntegration.html. You may have also heard that a good build time to shoot for is ~10-15 minutes for each regular build (not accounting for nightly builds)  at least for small-medium sized projects. If you are interested there are numerous discussions and posts on this. So like any good build engineer striving for efficiency and speed I attempted to reduce build times for the project I work on, at least till now.

Some details on the project build:

  • Our projects are currently in Visual Studio 2005 (we are in the process of upgrading to 2010 but that is another story).
  • Almost all our projects are native C++ (i.e. Unmanaged code) with a sprinkling of C# (i.e. Managed code)
  • We use CruiseControl.NET but use the Visual Studio Task (which internally executes devenv.com to rebuild the Visual Studio 2005 projects).
  • Monitor every minute for a developer's commit to the repository
  • Run Unit tests
  • Run Functional tests
  • Run Integrated tests (nightly builds only)
  • Notify developers of build status
  • Licensing and Unlocking
  • Package (ZIP, installer)
  • Deploy (for download by our modelers/testers)
This entire process takes about 12-15 minutes on our build server which is not the newest piece of hardware (in fact was purchased somewhere around 2001/2002). The nightly builds could take more than an hour since we run Integrated tests too, on the same build server. Not too shabby but we could definitely do better. 

The simplest way to speed up the build would be to purchase a new build server and cannibalize the old one or simply re-purpose it. 

Licensing and what now?
But here's the catch. In case you missed it, I highlighted "Licensing and Unlocking" in the steps above for that reason. What is that step you wonder? Well I work with Pro/Toolkit applications, the API for Pro/Engineer. If you want to deliver programs that use Pro/Tookit to your customers (who most likely will not have a license for Pro/Toolkit) then PTC provides a little executable called protk_unlock.exe that simply "unlocks" your Pro/Toolkit application to enable it to run on PC that don't have the license for Pro/Toolkit. If you were not aware of it, "unlocking" your Pro/Toolkit application will cause the PTC License Server to hold your Pro/Toolkit license for 15 minutes (yes, you read that right - FIFTEEN minutes). Of course all this is common knowledge.

'14' is the wrong answer
So what if my average build completes in less than 14 minutes? Well CruiseControl.NET uses a "update before you build" style to build your projects regularly. Which means that if two developers commit to the repository within a minute then there is a good chance that the two commits would be rolled into a single build (this is different from the process that some Continuous Integration tools use where a commit triggers a build - must be nice to own these nicer tools). But the worst case scenario is that "if for some reason the average build time is less than, say, 14 minutes AND the next build starts within the minute, THEN there is a good chance that the second build will not be able to 'unlock' its Pro/Toolkit application, since protk_unlock holds the license for 15 minutes and our build has finished in less than that time."

Now what?
So what is the solution to this problem? Well, if you have the money, you could always add a 2nd Pro/Toolkit license to that single build server, so that you always have one license available every 15 minutes.

Or you could do what I did - YOUR BUILD IS TOO FAST, SLOW IT DOWN.

Almost makes me want to cry. Oh well. What other idiocracies have you encountered in your build scenarios?

Note: I linked to a cached page from Google's server for the following link http://openmakesoftware.com/mavericks/2009/02/17/check-out-code-post-commit-not-pre-build/ since the original didn't show when I posted this article.