Deliberating On Software Development

March 6, 2010

Why should I continuously integrate? (or … how I learned to love claps and cheers)

One of the practices I consider essential for any development team is to continuously integrate their code.  There is a good discussion of continuous integration out there already but in short continuous integration means that every time you commit to your version control repository a fully-fledged build of your project occurs.  These builds should have various features:

  • Have a meaningful version number.  For example where revision is the revision of your version control repository.
  • Build a clean copy of the source code each time (delete + svn checkout as opposed to svn update)
  • Perform unit and/or integration tests to determine the quality of the build
  • Gather the various deployable pieces of your application into an archive (or set of archives) that the anyone can retrieve with little trouble

While it is not necessary, some other nice things you can do as part of a continuous integration process are

  • Perform static analysis of your code and produce reports on this for every build
  • Perform code coverage analysis of your code and produce reports on every build
  • Run integration tests using tools like Cucumber, SpecFlow or Fitnesse.
  • Link build numbers back to your activity management tool (Bugzilla, Trac, Jira, TFS Work Items)
  • Track who breaks builds, etc.

Real Life Continuous Integration

On my team we have been doing full-fledged continuous integration on all projects for over a year now.  We use a combination of tools to support the trinity of activities involved in configuration management.

I have tried a few different continuous integration tools (VisualBuildPro, IBM Rational BuildForge and JetBrains’ TeamCity) and found Hudson to be the best among them.  There is a plethora of plug-ins available, an active user and developer support group and its open source!  Does a tool get any better?  TeamCity comes a close second but its lack of support for trend charts and plugins was a real downer.  It does have pre-flight builds but this feature wasn’t enough to win me over.  IBM Rational Build Forge was ridiculously over priced for the functionality, required a lot of manual configuration and had a confusing set of terminology (as is common with IBM Rational products).  Avoid it at all costs.  All that being said, in the end we chose Hudson and every build in Hudson has some key ingredients:

  • We monitor the Subversion repositories for change every 5 minutes.
  • When a change is detected Hudson deletes the old working copy and gets a fresh copy from Subversion (no svn update!!)
  • The actual build is done with an NAnt script
    • You could use MSBuild, Rake or PSake instead.
    • The NAnt script builds the solution with MSBuild, runs any unit tests, calls FxCop to produce a report for some static analysis and then packages the results of the build.  For some projects we use ILMerge to reduce the number of assemblies we need to deploy as I am a heavy user of open source tools.
    • Hudson creates environment variables BUILD_NUMBER and SVN_REVISION that we use in our build script to generate the version numbers.  These get put into the AssemblyInfo.cs files and cause the Version property of the assembly to reflect the 
  • NUnit plugin to read the NUnit results report and produce a trend chart on
  • Violations plugin to read the FxCop results and produce a trend chart on possible code violations
  • Warnings plugin to parse the MSBuild log file and produce a trend chart on compiler violations
  • Task Scanner plugin parses the class files (*.cs) looking for those //TODO and // HACK (or whatever else you tell it) comments and then makes a nice report on them
  • The Jira plugin is probably the nicest feature.  It parses the commit comments from Subversion for each build for tags in Jira format (i.e. PROJECT-19) and if it finds one it puts a comment in the relevant Jira issue with a link back to the Hudson build.  This is an awesome way for our users to be notified when an issue that they created has been worked on!
  • A zip archive is produced with all of the materials for using the product (the executable, configuration files, etc.)

When used in conjunction with “Commit early, commit often” Hudson becomes the heartbeat of our team.  Anytime someone performs a commit we get a pile of useful trend charts and reports indicating the health of the project.  With the Jira plugin we get connection to the activity management tool so users know what build their issue has been worked on and Hudson keeps track of the source code changes for every build … in other words complete traceability!  If a user encounters a problem we can tell immediately what the version is that they’re using and whether they are up to date or not.  We can tell what has changed since the last build to determine if merely upgrading will resolve their problem.  We can point a user to a Hudson build and they can get everything they need from a single page since everything is archived in one place.

One important thing that I have found out is that it is important to have a way to build your project exactly like Hudson would, but do it locally.  This was the main reason I chose NAnt as the build script.  In my source control repository there is a .build file containing the NAnt script, a copy of the NAnt executable and

Good for you smarty-pants … but how long does it take to get all that setup if I know nothing about continuous integration?

To get my setup running it took me a solid week (spread out over time).  I started off very small, with no plug-ins and Hudson simply building the solution file.  I would add a plugin, get it working and then expand.  I think this is a good way for a newbie to start because even if you are only building the project it can catch a lot of errors.  one of the most common mistakes I find on my team is when someone adds a file to the solution file in Visual Studio but forgets to add the file to Subversion.  When they commit the change set MSBuild barfs when it cannot find the file that is not in Subversion.  This is an easy and effective way of ensuring that the source control tree is always in a buildable state.  I love this because one of my pet peeves is checking out a project only to discover it doesn’t actually build.  It’s little mistakes like these that upset the rhythm of a team and affect productivity.

In terms of tools for newcomers I would highly recommended Hudson because it is such a simple point-and-click Web 2.0 interface and has great help built right in where you need it.  Hudson is ridiculously easy to install and use, even installing it as a Windows service is built right into the package now, and installing plug-ins, etc. is downright simple.

If you’re still unconvinced you will see some payback from continuous integration (despite the evidence to the contrary) then look at the relatively minimal investment of a few days to a week as something that you can bring to every project in the future.

The Future

I would like to expand our setup to include code coverage metrics and possibly use a tool like StyleCop to measure how well the source code is formatted.  I have in the past attempted to integrate trend charts for a Fitnesse wiki but gave up because the restriction of having a wiki server up and running to perform the tests was tedious and error-prone.  We’re moving our specification tests to SpecFlow anyway and this should be considerably easier to use since its just NUnit under the hood.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at

%d bloggers like this: