Building For Success

This article addresses detailed scenarios and the associated problems with the build process. We look at the usually activities and work patterns of a developer and relate those to build practices.

Parallel Development and Codeline Merging
Fred works in his Private Workspace and his team is using the Mainline pattern of development. Having created the workspace based on the mainline code from the repository, his standard pattern of working:

    1. Implement desired bug fix or new feature by editing, adding or deleting files
    2. Build locally (Private System Build)
    3. Test locally (Unit Tests)
    4. Commit globally (Task-Level Commit)—if it works, then check-in (commit) changes to the repository, otherwise make some more changes

Any changes made need to be tested before being released (surely you’ve never made a change that was “so small and obvious it doesn’t need testing?!...”), and you can’t test them without building them. If the build fails, then you need to fix it first. Only if the test succeeds does the commit happen.

What the above doesn’t take into account, is what happens when other team members are also making changes. Fred’s lifecycle needs to include the extra step of merging in other people’s changes with his own.

Fred performs a Catchup or Rebase. The problem, as shown by Figure 2—Include Changes From Others, is that this extra step brings with it the need for a sub-cycle of Reconcile/Rebuild/Retest/Resolve. This introduces an extra element of risk since Fred’s code is currently only in his workspace and has not yet been checked in or committed. Possible resolutions [1] include Private Archive, Private Branch and Task Branch.

Using a Task Branch (Private Branch is quite similar) Fred is free to make changes and commit them as often as he likes (note that some tools support the notion of a local commit—something that is saved into the repository but not visible to other users until desired which is the equivalent of a Task Branch). He normally performs a build and test before the commit, but on occasion can still commit something that only partially works since no one else will see it. Fred makes his changes visible to the rest of the project by “publishing” them, or merging them back to the Mainline. The key thing here is that just before publishing, he does a Catchup to bring in other team members changes. This does the more risky merge in his Task Branch which should make the Publish a very simple operation.

To Branch Per Task/Privately or Not?
Using Task Branches isolates the risk but at the cost of extra work required to perform the catchup/publish. Interestingly, working directly on the Mainline can be fine if the risk of developers changing the same modules is low, and it is surprising how often this is the case. Indeed, “collisions” are often restricted to a small subset of modules in the system, and judicious refactoring of these can reduce collisions dramatically. That said, there are often some files that are widely used and shared and frequently updated such as makefiles or some global system definitions.

Team Velocity
In “The Illusion of Control” [2] we talked about how introducing checks to ensure that builds aren’t broken and that bad changes aren’t released into the code base can end by decreasing the velocity of the team. This contrasts with the Continuous Updates pattern described in “Codeline Merging and Locking” [1] where what appears to be more work turns out to give greater velocity.

Checks are enforced by:

    • Build (Private System Build and Integration Builds)
    • Smoke Tests

Each team has to work out the appropriateness of the checks for each stage. Let’s look first at some considerations for improving build velocity.


About the author

About the author

About the author

CMCrossroads is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.