For all its benefits, Continuous Integration (CI) does have its share of flaws. For one, CI is somewhat reactionary when integration builds break because the code has already been committed to the mainline of the version control system.

Broken Builds
The main problem of reactionary CI is that you don’t learn that your full integration build has failed until the code is committed to the version control system and other developers are affected by it, which can decrease team velocity.

Current workarounds
In Software Configuration Management Patterns, Berczuk and Appleton describe the Private System Build as a pattern for preventing a broken build from occurring on the integration build machine. The private system build includes integrating changes from other developers on your project and running a successful integration build before you commit changes to your version control system. However, there are certain errors such as those that may be configuration-related or you may have simply forgotten to commit new files to the repository. Another workaround to preventing broken builds is performing Manual Integration Builds as James Shore covers in his blog. In this workaround, developers are put into a queue where only one person (or pair) integrates at a time. This was the original concept of CI with XP teams. This technique should be coupled with the private system build. While this approach can take some discipline and can be a little more difficult for distributed teams, it can prevent builds from being broken too long. However, you still have the same problem of having broken code (compile, test or otherwise) in the repository — even if it isn’t as long as an asynchronous build when using a CI server.

Possible Solutions
There is a new breed of tools entering the marketplace that hold some promise. While they probably don’t yet solve all the “problems” of CI, they are addressing some of CI’s flaws. There are servers that provide CI capabilities and can prevent “bad” code from entering the version control system. Borland’s Gauntlet (full disclosure: my company is a partner of Borland) and JetBrains’ TeamCity. Gauntlet uses a feature called “sandboxing” which creates a temporary repository branch for each integration build and promotes the code to the mainline of the repository only if the integration build is successful (including compilation, tests, inspections and so on).

What’s Next?
Don’t get me wrong, I use and evangelize CI regularly (even wrote a book on it) and I think its practices provide significant benefits…especially when compared to “big-bang” integration when teams wait until the end of a significant milestone (e.g. the day before they were supposed to release) to integrate all of their changes. However, like anything, things can be improved and we are continuing to see improvements in the evolution of the practice and I expect to see more in the future. As I eluded, there are other issues with CI and I will cover these in another blog entry…