Years of developer experience has produced a lesson the entire industry is paying attention to: leaving integration to the end of a project is a bad idea! It’s been proven a bad idea time and time again. Integrating often keeps errors small and manageable. In fact, many teams (mine included) integrate after every code check-in. The idea of continuous integration is to make integration a normal part of your software construction process. The core of continuous integration (abbreviated “[ci]”), is to feel the pain enough to make it go away. The first pain is that it takes a LOT of time. Solution: automate the process. We find that there are a lot of steps to integrate all the parts of a software system, so we automate all of them. This yields a living artifact called a “build script”. This build script is executable and runs every time someone commits a change to the codebase. If a change to the codebase produces an integration defect, the build will fail, and the team will become aware of a new integration defect immediately (not weeks from now). The build script helps refine the software process by identifying pain points and pushing the team to solve them.
A very popular [ci] combination of tools is [ccnet] for the build server (build reports, stats, and notifications), [nant] (an xml notation for the build script itself), [nunit] (for automated tests that run as part of the build), and the code compiler. (Note, in Java, the parents of all these tools make up the popular combination: [cruisecontrol], [ant], [junit], and the java compiler).
With .Net 2.0, Microsoft has changed the way Visual Studio projects are structured so that they actually form an [msbuild] build file. [msbuild] is Microsoft’s answer to [ant] and [nant]. The basic capabilities are the same (xml declarative build tasks, runnable from the command line). [mstest] is Microsoft’s answer to [nunit]. Unfortunately, [mstest] isn’t available unless you purchase Microsoft’s Team Test IDE. Microsoft doesn’t have an answer for [ccnet].
Before I go on, please take a look at Bil Simser’s experience report setting up CCNet with MSBuild and MSTest.
From reading Bil’s experience report, I am very glad that I saved my team A LOT of wasted time. My team did not dabble with converting from [nant] to [msbuild] or from [nunit] to [mstest]. Here is my thought process:
- Our process works ([ccnet], [nant], [nunit], compiler).
- [ccnet] stays. I don’t see an alternative that is compelling, and [ccnet] is not causing me pain.
- [nant] stays. I see [msbuild] as a comparable alternative but with no compelling advantage over [nant] to force a conversion. [nant] is not causing me pain.
- [nunit] stays. I see [mstest] as a subset of NUnit’s functionality; therefore, there is no compelling reason to switch. [nunit] is not causing me pain.
- compiler: Switched to [msbuild] from the [nant] <solution/> task out of necessity. The [nant] 2005 msbuild task is limited, and it caused me pain. Moving to an <exec /> task calling msbuild.exe gave me exactly what I needed. It’s been working for 6 months without further attention.
To put my decisions in context, let me give you an overview of my department’s software process:
- Mix of [extremeprogramming], [scrum], and [crystal].
- 1-week iterations.
- Story wall of post-it index cards (story cards) for user stories as well as bugs.
- OR mapping with [nhibernate]
- Model-view-controller Winforms UI
- Extensive automated test coverage.
- Automated configuration management.
- Automated database change and upgrades.
In this environment, we don’t have any time to waste. We have to solve problems and move on. We estimate in ideal hours, not days. Anything that causes pain is either fixed or kicked out.
After all this, what does it have to do with Continuous Integration the Microsoft way? I propose that this is the way to do it with .Net. It works well, and teams all across the country do it in a very similar way. From reading Bil’s experience report on attempting a mix of tools in the Team Suite stack, all he experienced was pain. This isn’t the way to make tools.
To Microsoft: you have to do better ( I know you can). If by some odd change, these tools integrate well, and we just don’t know how to do it, please advertise the documentation that shows how to do it seamlessly in an automated, command line environment on a clean build server. We all learn by example, so if teams within Microsoft are doing interesting things with [ci], please let us know because right now, we don’t know how to get it to work.
To the rest of the industry: Do what works and evangelize it. I’ve spelled out what is working well for my team, but there are plenty of other solutions to the [ci] problem. If your team is doing CI with another mix of tools, please tell us about it!