So you’re making the move to install a Continuous Integration process on your project. Most of your early attention is going to be spent on getting the CI server up and the build scripts put together and functioning. That part of the process in the .Net world is getting easier as the tools have matured and the accumulated knowledge available online has multiplied. My company is moving to full blown CI and TDD on our main systems soon. Other than getting migrated off of VSS, I’m not too worried about the infrastructure setup. What I am worried about are the developer practices.
One of the key practices in agile processes is Collective Code Ownership. Collective ownership can make a project team much stronger, but there are some inconvenient side effects in coding construction. Because agile iteration work is mostly scheduled by business need and not by what is convenient for us the developers, it’s not unusual for two or more active coding threads to be simultaneously changing some subset of the code. The idea of continuous design* implies that even big architectural changes can be happening on an ongoing process. The key point is that things are changing and that can be risky. CI is one of the enabling processes that supports both continuous design and collective ownership, but you’ve got to take advantage of it. The CI build process is a mechanism to find and eliminate problems from code changes as early as possible. The key for developers to get the most out of CI without being burned is to be disciplined about their “Check In Dance.”
- Check in as often as you can. Try to reach stopping points as often as you can. This goes back to the basic agile philosophy of making small changes and immediately verifying the small change. When you’re doing Test Driven Development you strive to keep “Red Bar” periods as short as possible. The same kind of thinking applies to code check-ins. Make small changes and see the impact on the rest of the code immediately. Merging code will be less painful the more frequently a team integrates their code.
- Avoid stale code. If you have to keep code out for any length of time, make sure you are getting everyone else’s changes. Try really hard not to keep code out overnight. If you’re using shared developer workstations, put some sort of sign on the workstation that there is outstanding code on the box. I’ve seen several XP zealots swear that they’ll throw away any code left overnight. Personally, I think that’s just a silly case of “I’m more agile than thou,” but it’s still a bad idea to leave code out overnight if you can help it.
- Don’t ever check into or out of a busted build. Checking in might make it harder to fix the build because it will cloud the underlying reason for the build, and you can’t really know if your changes are valid.
- Communicate and negotiate check in’s to the rest of the team. Frequently the complexity of a merge can be dependent upon who goes first. Some teams will use some kind of toy as a “check in token” to ensure that there is never more than one set of updates in any CI build. Pay attention to what the rest of the team is doing too.
- If you’re working on fixing the build, let the rest of the team know.
- DON’T LEAVE THE BUILD BROKEN OVERNIGHT. That’s also an occasional excuse to your wife on why you’re home late from work. Use with caution though.
- Not every member of the team needs to be a full-fledged “BuildMaster,” but every developer needs to know how to execute a build locally and troubleshoot a broken build. If you’re suckered into being the technical lead, make sure every team member is up to speed on the build.
The “Check In Dance”
The best practice for effective CI is to perform the integration on a developer workstation before that code escapes into the build server wild. It’s okay to break the build once in awhile. One of my former colleagues used to say that the CI build *should* break occasionally just to know it’s actually working. What’s not okay is to leave the build in a broken state. That slows down the rest of the team by preventing them from checking in or out. Even worse, somebody might accidentally update their workstation with the broken build and get into an unknown state. If you follow these dance steps, you can minimize build breaks and run more smoothly. Besides, it’s embarassing to have the “Shame Card” on your desk.
- Let the rest of the team know a change is coming if it’s a significant update.
- Get the latest code from source control.
- Do a merge on any conflicts.
- Run the build locally and fix any problems found.
- Commit the changes to source control.
- Stop coding until the build passes.
- If the build breaks, drop everything else and fix the build.
Here’s a tip on annoying the crap out of your teammates. I found a MIDI file of the “Chicken Dance” song one time and commenced playing that out loud everytime I checked in. It was funny for about a day or two.
* I detest the term “Emergent Design.” That term makes it sound like you just spit out a bunch of code like a new age painter randomly splattering paint on a canvass and voila — a coherent design will spontaneously create itself. When I worked with the High Priests of Agile, I used to frequently get chewed out and told to “just let the design emerge.” To this day I have no earthly idea what that means. I think it means just write lots of “it/then/else” statements until the code practically screams for restructuring, then have a big, heated hullabaloo meeting to agonize about the proposed refactoring. Agile processes can be just as stupid as any CMM-driven waterfall if you’re not thinking straight.