Monday, June 8, 2009

Agile Version Control - another magic bullet

I have previously posted articles about what the magic bullet of agile software development is; to achieve flexible scope. As you may recall, the article talks about the three most important aspects of your Scrum implementation which make up the fundament for being able to achieve this scope flexibility:
  • Strict prioritization (having it and following it)
  • Definition of Done (having one and following it)
  • Story breakdown & formulation skills (understanding its importance, and constantly trying to improve)
In hindsight, I feel I have left out one important success factor when it comes to reaching a truly flexible scope; version control.

Most of us use one form of version control or another, but in my experience it is often (mistakenly so) only a matter of choosing the tool. The options are many, and range from “open source” to “incredibly expensive”. Once you decide on the tool, you use it for version tracking your codebase by checking out, committing and merging files. Perhaps you use branches in order to separate some work from other. But you may be missing an important tool; an Agile Version Control Policy.

If you do Scrum or some other form of Agile Development, you want to be able to actually finish your product increment every iteration, right? The purpose is to be able to achieve a flexible scope so that you can potentially ship on any day, at any given time. And what I am trying to get to here is that it doesn’t matter how well you succeed with your adherence to a Definition of Done if you don’t combine it with applying an Agile Version Control policy (completely regardless of which version control system you’re using). If you don’t have an Agile Version Control policy in place you risk mixing up your “Done-Done” code (code and assets related to User Stories that have been completely done according to the Definition of Done) with code which is in progress.

And guess what: if you mix Done code up with Code in progress, you’re no longer able to release at any given time!

Without Agile Version Control, shipping your software will mean that you first have to perform a series of tasks related to isolating code that is Done-Done from code that is in progress at that moment, and also often tasks related to doing last-minute polishing “while you’re at it”. The result is that shipping code is hard and a “big deal” and something that takes a lot of time. And what else does it cause? Yeah: crunch.

So how do you achieve this separation of Done-Done code from code in progress? Well, there are plenty of good articles out there to read: this one for example, written by Henrik Kniberg.

In short, what you need to do is dedicate a branch for containing that Done-Done code (let’s call this branch “Done Branch”), and define some rules for it. For example "all code on the Done Branch must adhere to the Definition of Done", "no code may be published to Done Branch without being reviewed", "code may only be published there by the branch owner", and so on.

Simplicity ftw! Here is a very simple Agile Version Control policy that I’ve been using;

Live Branch
Description: Create a branch from the trunk when you make a public/final release, that you will maintain for a while (until next release). Maintenance (patching) happens (for sake of simplicity) directly against this branch.

Branch policy:
  • All code in Live Branch must be tested and working.
  • All code in Live Branch must compile & build. In short: all code in Live Branch must follow Definition of Done.
  • Code may only be published to Live Branch by branch owner (who may delegate it).
  • Patches on Live Branch are immediately published to Trunk as the last step, and any conflicts are resolved on Trunk until code adheres to the branch policy. Note that you don’t resolve the conflicts on the Live Branch because it would imply updating Live with whatever is on Trunk (which can be a lot of changes).

Done Branch (which happens to be the Trunk, aka Main)
Description: Use the trunk (aka main branch) as “Done branch”. This will contain only code from stories that are Done-Done.

Branch policy:
  • All code in Done Branch must be tested and working.
  • All code in Done Branch must compile & build. In short: all code in Done Branch must follow Definition of Done.
  • Code may only be published to Done Branch by branch owner (who may delegate it).

Development Branch
Description: Create a branch from the Trunk in which the team works during the sprints. The branch exists across several sprints.

Branch policy:
  • All code in Development Branch must compile & build.
  • The Development Branch should be updated from Trunk often (suggest daily).
  • Conflicts with Trunk are resolved in Development Branch until code adheres to the branch policy.
Remember to update your code often from Development Branch (i.e. spark merges as often as possible!).

This simple policy relies only on three branch types; Live, Done and Development. Your Trunk (aka Main) is your Done Branch. There is a drawback with this policy though; if you have multiple teams who are developing (and finishing) stories which are supposed to be able to release independent of each other, then you will not be able to use the policy above (because Done-Done code from the two teams will be mixed up in the Done Branch). But, do you really have the requirement of teams to be able to release code independent of each other at different dates? Think carefully about this – do you really? If you do, fine: in that case you have to have a slightly more sophisticated setup (with a separate Done Branch + a separate Development Branch per team, and consequently you can’t use the Trunk as your Done Branch). You can read more about such a setup (Agile Version Control in a multi-team environment) in the paper by Kniberg that I referenced above.

As always, I’d be glad to hear about other peoples’ experience in this area. Please leave comments.

4 comments:

  1. Hi!
    Good one. I can picture a situation where you will have teams deliviering on different dates. I can even imagine continous delivery. It depends a lot on the circumstances. Can the rest of the business have a IT that is constantly deliviering?

    ReplyDelete
  2. I have achieved the same result with a branch for each independent release or sprint as applicable and the trunk (ie. no live branch).

    As the trunk which is the production system is updated, all branch(s) are updated. As each branch is ready to go live, it is merged with the trunk and deplyed to production. Release test environments are built from the branch and testing occurs incrementally as the release is built.

    This also affords two other advantages:1) the testing cycle for a new release can begin as soon as the first code is delivered as it is built from the branch. 2) the merge risk is mitigated as all updates to the trunk are added to the branch(s) so testing occurs on a code base representative of the post merge system that will be deployed. In this situation, there should be no merge required. In practice, there may be a minimal set defined by any branch maintenance that did not include all updates to the trunk.

    A PM can run any number of parallel development efforts (ie branches) in this model. There is a practical limit defined by the size of the staff as the dual maintenance between trunk and branches will reach a point of diminishing returns.

    ReplyDelete
  3. Great post. I think this concept has many advantages over working off a single branch; most importantly the ability to release at anytime.

    As far as CI (Continuous Integration) is concerned, you must have that running off of your Development Branch?

    Also, let me know your thoughts on my post on Increasing Agile Visibility using Source Control. http://natereid.com/blog/?p=20

    Nate

    ReplyDelete