- change selections from the checked-in, "ready" changes, promoting the changes to a "selected" state. At this point we might optionally create a new baseline, or if your CM tool permits, align one and freeze it only after a successful sanity test on the build. We would also create a build record identifying what is going to go into the build.
- For smaller environments, rebuild the entire environment for shared use by the development team. For larger environments, we might do incremental builds, whereby we retrieve only the changed files and files affected by the changed files and perform either a "make" operation or an incremental build operation (i.e. re-compile these specific files). This will depend on your CM tool capabilities. Although you may wish to do builds more than once a day, you may wish to insulate the developer environment a bit more, perhaps making a new build available nightly.
- Repeat the above steps for other promotion levels as necessary. For example, we may be supporting build environments for the latest ready code, the latest integration/sanity tested code and for both verification test environment and the field trial environment. The incremental build environment option works really well when you have multiple promotion levels that you're working with when the builds take a long time or when the promotion level environments are incremental to one another. Especially in this latter case, the cost of distributing four or more promotion level build environments is really not much different than the cost of distributing a single level - most of the time at least.
There are a lot of places where the CM tool is going to be able to help out a lot. From automatic generation of Make/Build files, to promotion violation notices, to support for incremental builds. Some tools (e.g. CM+) will even eliminate the need to build intermediate library archives/dlls in order to do object code sharing.
In the end, we've assumed that changes are flowing through the system, pretty much in the order that they've been made - with a bit of allowance for developer push to the "ready" state to co-advance a set of changes. This has eliminated most of the branching and merging work, especially as the developers realize that, with no reason to hold up a check-in operation, the frequency of parallel check-outs drops dramatically.
Still we have to allow for disruptive changes. There already is a much better chance that unit testing is going to be done against a more up-to-date and sequentially growing build environment, since there are few, if any, merge operations that need to be completed. But what happens when a change "breaks the build"?
Usually, because we are doing frequent integrations, we can simply roll back the change with no impact on other changes. In some cases, we may need to roll back dependent changes as well. But roll-back operations are simple roll-back of the state of the change(s) (i.e. their promotion levels), and a subsequent rebuilding operation.
If we can't afford to roll back some changes, we can fix them through a subsequent change, promote that change and do a rebuild. If we want to allow subsequent changes to the rolled back functionality to continue because the roll back will be for an extended time, we "change" the branch tip to reflect the latest acceptable functionality by creating a "new" change which checks-in older acceptable revision(s) and promoting it. Then new changes may continue against this tip. The rolled back functionality will have to be reconciled forward at a later time.
The big difference here is that we are dealing