Check out my new blog at

Tuesday, March 25, 2008

Continuous Integration Part I

While I don't subscribe part and parcel to a single development approach or philosophy, I do like the agile philosophy for its focus on customer satisfaction by rapid, continuous delivery of useful software.  Of course, rapid and continuous are not free, so interesting support systems such as automated builds, staging and deployment tools, and other continuous integration (CI) systems are required to support speed and rapidity.

I am not specifying CI requirements for all organizations or even for my entire organization.  I have a very real, practical set of problems I need to solve for a specific project I am working on.  With my scope nicely tuned, I can think about what needs to be done to get some CI up and running.  I have the following needs and requirements:

  1. Source Control Integration - We are a Subversion shop.  I need to be able to kick-off a CI run with a get from the SVN repository (or at least check that the current bits on the CI server are the latest bits in SVN).

  2. Automated Build with Test - NAnt is our build system.  I need a set of NAnt scripts that will build and smoke test the build.  I need further build verification tests (BVT) to verify the quality of the build.

  3. Integration with Test - Once the project's components are built and verified, I need to integrate the components into major build units and run additional BVT's.

  4. Automated Staging with Test - After Build and Integration run, I need to automatically stage the different systems and do habitat testing (test the systems in a simulation of their natural habitat--the production environment)

  5. Testing - Once the automatons have run and systems pass all automated tests, the human testers come into play.  We are a Mantis shop (can't beat the price).  Bug reports are fed back to developers and the process continues

  6. Deployment - Once quality/calendar/feature bar is reached commensurate with the stated goals of the release, the systems are ready for deployment.  In my case, deployment means pushing out a database, a web site, two Windows services, Microsoft SQL Server Reporting Services reports, and a Windows client application.

Let's take a closer look at two components of our development environment:  Subversion and NAnt. 

  • Subversion is a version control system similar to CVS in that it is non-locking (versus SourceSafe which is locking).   For a crash-course in Subversion, go here.   We use TortoiseSVN, a Windows Explorer shell extension, as our primary graphical interface for Subversion

  • NAnt logo (link to home page)NAnt is a .Net build tool modeled after Apache Ant.  Instead of a model which is extended with shell-based commands, NAnt is extended using task classes. Instead of writing shell commands, the configuration files are XML-based, calling out a target tree where various tasks get executed. Each task is run by an object that implements a particular Task interface. For an overview of NAnt, go here.

Server-side we target .Net 2.0-3.5 on Windows 2003 Server with IIS 6.0 and Microsoft SQL Server 2005.  We support modern browsers such as Firefox, Internet Explorer, and Opera.   When we do have a Windows client application, we target .Net 2.0 with WinForms (we are not using Windows Presentation Framework in production as of yet).  We are a C# shop.

I want to touch on a tool before I get into the specifics of using NAnt and Subversion to implement a minimal CI system.  Last week when I started really digging into this, I went looking for a NAnt tool to assist in creating, managing, and executing NAnt scripts.  Like any good developer, I am always looking for new tools...and like most developers, I sometimes get an itch to write a tool myself, even if one exists. 

In this case, I got about two hours into creating my NAnt Build Runner tool before I started googling for something already baked.  The following images show what little progress I made with my Build Runner application and the tool called NantPad that I decided to spent some time evaluating.



At first glance, NantPad seems to be a nice tool.  Check out the site here.  The fact that following the Purchase link on the home page fails is a bit worrisome...

The Development Loop

The project that I am working on is managed through SDLC phases (I use a modified Microsoft Solutions Framework known as MSF4ASD for agile software development--I learned this stuff while I worked at Microsoft):

  • Envisioning
  • Planning
  • Developing
  • Stabilizing
  • Deploying

These phases shouldn't require too much explanation.  The key with respect to CI is the bits moving from phase to phase:  Developing-->Stabilizing-->Deploying.  In the agile model, these three phases are compacted into what I call the Development Loop.  The Development Loop is where the agile and continuous integration practices live. 

I have operated in a variety of environments with different engineering, regulatory, cultural, and economic realities.  Going from Microsoft with its relatively mature (no religious debates about SDLC correctness please, I am pragmatist) to a startup with a vastly different development necessity (RAD), to a government program management consulting firm, and then back to a startup environment has really yanked my brain from waterfall to rapid development and back again, several times over.

The net effect of my experience is that I try to look at each project as an opportunity to improve my methods, and possibly recycle my efforts back into the SDLC community when appropriate but at the same time avoid getting tied down a single way of doing things.

I have attempted to visualize The Development Loop below.  The development team takes feeds from product and program management (again, Microsoft terms--essentially those responsible for the feature set and schedule for a product) and does incremental and iterative work with frequent releases to test and eventually release to a limited group of customers.  The process repeats.  The key is that developers, testers, and customers (plus internal planning groups) are always circling in on a feature set and quality bar good (and valuable enough) to be considered for a general release.


Deployment is used in the above diagram to name the point at which development and test have agreed a build is of sufficient quality and value to be released to the customer.  Other systems call this Release Management, which I put further down the pipeline to indicate the difference between being ready with the software and being ready to go to market.   Release Management is coupled to marketing, sales support, launch, and a host of other extra-development activities (work that is done in parallel with the Development Loop but is separate).  Release Management can be thought of as the ultimate integration gate in that the technical deliverables such as software and the non-technical deliverables such as marketing plans and materials must finally coalesce.   

CI Goal #1: Get It From The Source

imageI got off on a tangent a little bit with discussing SDLC but it is important to recognize that I need to is grease the little wheel in the center of the Development Loop. 

I made it clear that source control integration needs to be present in our CI strategy.  What does that mean?  Put simply, it means getting the latest source from Subversion... First thing that I need to do is a checkout from Subversion using NAnt.

<a few minutes pass>

NAnt is open source.  There is a separate SourceForge project for those NAnt tasks that haven't made it into the mainline build.  This project is called NantContrib.  Included is a NAnt task called svn-checkout, which after some fiddling does the job nicely.  Here are the steps:

  1. Make sure you are a Subversion shop ;-)

  2. Get familiarized with the basic NAnt feature set and script syntax

  3. Install the Subversion client (svn-checkout requires svn.exe)

  4. In your NAnt script, add a task that looks like the following:image

  5. If you run svn-checkout and get an error to the effect of "svn.exe not found":

    1. Make sure NantContrib is installed correctly (read the readme file!)

    2. Create an environment PATH that points to svn.exe or use svnpath.exe to do it for you("C:\Program Files\Subversion\helpers\svnpath.exe" add "C:\Program Files\Subversion\bin\svn.exe")

Note that #4 runs only if the ".svn" directory does not exist beneath the directory specified by the build.configuration.sourceroot property (for information about NAnt properties, go here).  This is great but what if the source root already exists?  In this case, I don't want to do a full checkout, I want to do an update:


Note that a handy attribute to attach to both svn-checkout and svn-update is the failonerror attribute, which will halt the build process if CI Goal #1 (Get It From The Source) can't be satisfied...

Of course, none of this matters if sourceroot does not exist... I simply create the sourceroot and do a full check-checkout.

By the way, NantPad is good.  Here is a partial screen shot that shows the tasks in a graphical form:


The only issue I have found with it so far is that you can't edit the XML directly.  If find myself opening the build file in Visual Studio where I can edit it directly, then open it in NantPad to add tasks and run the build.

CI Goal #2 - Build It and They Will Come

Tomorrow I start the automated build...


zack said...

Godspeed! You'll find NAnt + NAntcontrib has the vanilla stuff covered pretty nicely. Of course there are those wacky tasks you'll need to do by writing auxiliary command line tools that can be called from NAnt. (Office automation, etc) Yikes. Don't forget to keep your build scripts in SVN too ;-)

Colby Africa said...

Roger that good buddy ;-)


Content on this site is provided "AS IS" with no warranties and confers no rights. Additionally, all content on this site is my own personal opinion and does not represent my employer's view in any way.