Many teams following some flavour of agile use a board (physical or virtual) with columns to track the progress of tasks. When we are working to optimise the flow of items through the development process - as we often do when implementing kanban or similar methods - we concentrate on pulling items towards the right. We want to get features released and into our users’ hands. Often we have the right-most column as “Ready to Release”, with columns to the left for things like “analysis”, “in development”, “QA” etc. Once a feature has passed through these phases then it is “done” and ready to be released - see below for an example from a team I worked with recently. However, I’ve been thinking this is the wrong way around.
Let’s think about the way a scrum or XP team works, within a fixed length iteration or sprint. At the start of the iteration they have a number of tasks in the To Do column, and gradually move them through analysis, development and QA until hopefully they are all done and end up in Ready to Release. Then at the end of the iteration we release them.
If we are working towards continuous delivery then we want to be able to release our code not just at the end of the sprint, but after any green build. Continuous delivery is all about making the process from idea conception to software running in production as smooth as possible. Whenever we agree that there is value to releasing the current feature set, we should be able to do so, without any technical bottlenecks or necessarily waiting until the end of an artificial timebox. As soon as a feature is ready, we want to be able to release it.
But what if some things aren’t ready? In a team with more than a couple of developers, it’s likely that we’ll be working on a couple of features in parallel. How can we release one feature when others are still being worked on? I’ve often heard people make the argument “we can’t release something if it isn’t done” - but I don’t think that’s right.
To get to a state of continuous delivery, we have to be able to release any good build, which may contain any number of incomplete features - but in a form such that they do not negatively impact the user experience. I might have added some code and tests for a feature, where the tests pass, but the code isn’t actually called from the rest of the application yet. That’s safe to deploy - the new code isn’t called - but the feature certainly isn’t complete. Or we may have a feature that we’re still working on and testing internally, but in the live system it is hidden in the UI, perhaps using a feature toggle.
Practising continuous integration and continuous delivery means that every commit that we make is potentially releasable, but it doesn’t mean that we have to wait until our feature is complete before committing - quite the opposite in fact. It does however mean that we need to change the way that we think about adding code to the system so that we can add things iteratively and incrementally, without breaking any current behaviour. Once we can do this, we can release any time we want. The code should always be releasable, regardless of whether or not any particular feature is done.
If you are interested in finding out more about these issues, don’t forget about Continuous Delivery Kickstart a two-day workshop on Continuous Delivery that we’re running in London at the end of September.