Several times recently I’ve been bitten by “code-freeze”. Granted, I’ve been bitten because I wasn’t tracking the “freeze” closely enough, my bad. But there are alternatives to this (in my mind) counter productive process. Developers need to be free to check in changes. They fix bugs, or add new features, and need to get those things checked in. Their dev machine could collapse catastrophically, they could forget to check them in, or the fixes could become irrelevant if they wait too long. Plus, the farther you get away from the point where you made the changes, the more likely you are to get merge conflicts. If the “freeze” lasts too long, multiple people may make changes to the same files, so that when the freeze is lifted, merge conflicts ensue, and that’s not fun for anyone. Not good for continuous integration. Code freezes pretty much take the continuous right out of it.
The solution, you ask? Labels. I think most people don’t realize how many groovy things you can do with good labeling policy. Part of this stems from the widespread use of Visual SourceSafe. If you are still using VSS, stop. VSS and continuous integration just don’t belong in the same sentence. Labeling doesn’t work right, branches are hard and have lasting consequences, etc. The common excuse is “it comes for ‘free’ with my development environment”. Of course, it’s not really “free” but that’s another issue. Even if it were, there are several (much better) free alternatives. CVS and Subversion top the list. Much better choices, since they do labeling and branching right, and they discourage the exclusive check-out, which is pure evil anyway. (Can you tell I have an opinion or two on this topic?)
What I have done (quite successfully) in the past is to use labels to “freeze” the tree rather than actually preventing people from making check-ins. It runs something like this… Every developer is responsible for checking in changes, and for deciding when those changes are stable. It’s a common mistake to assume that the tip or HEAD of your source tree must always be pristine. That keeps people from checking things in when they should. So, decide on a label (like “BUILDABLE”) that represents that stable state. That way developers can continue to check in changes, even potentially destabilizing ones, on the tip without causing havoc. When the developer decides that his/her changes are stable, he or she can move the label out to encompass those changes.
How does this work with continuous integration? Your build server always builds from the label you’ve chosen to represent stability. Not from the tip. That way you should always get the latest stable build, even if that doesn’t represent the latest changes. When it’s done successfully building, the build server should label whatever it just built with something like “BUILT” and the time/date (in another label). Remember, each revision can have as many labels as you need, so extras don’t hurt.
Another big benefit of this process is that if someone is just joining the team, or needs to build the software for the first time, they can pull from the BUILT label, and be assured that they are getting the most recent version that is known to be build-able.
The end result is that you have two labels that move, leapfrogging each other as new things get marked as stable and then built, and some that don’t move indicating what was successfully built for each date/time/version. That’s good information to have. It’s also good for developers to be able to freely check in changes without having to worry about “freezes” or breaking the build.
Give it a shot. It’s work up front, and requires a little training and discipline, but you’ll be glad you made the effort.