It’s hard enough for software developers to write code that works on their machine. But even when that’s done, there’s a long journey from there to software that’s producing value – since software only produces value when it’s in production.
Continuous delivery is an approach to delivering software that reduces the cost, time, and risk of delivering incremental changes to users. You’re doing continuous delivery when:
- Your software is deployable throughout its lifecycle;
- Your team prioritizes keeping the software deployable over working on new features;
- Anybody can get fast, automated feedback on the production readiness of their systems any time somebody makes a change to them;
- You can perform push-button deployments of any version of the software on demand.
Why Should you Care About Continuous Delivery?
Continuous delivery enables teams to deliver software in small batches. As described in an article by Damon Edwards, and at more length in Donald Reinertsen’s magisterial The Principles of Product Development Flow, there are many important advantages to using small batches.
The top three benefits of continuous delivery are:
- Reduce the risk and cost of releases. Continuous delivery makes deployments boring, so you can perform them whenever you want, as often as you like.
- Innovate faster and build the right thing. Because your software is always releasable, it’s cheap to experiment with new ideas. As described in The Lean Startup, build the smallest possible amount of code to validate your experiment, push it out to a small set of users, and get real feedback.
- Get real project progress. The only real measure of being “done” with a task is having code live in production.
How to Implement Continuous Delivery
Continuous delivery rests on three foundations:
- Comprehensive configuration management. Everything required to create a production environment, or production-like test environments – along with the applications that run in them – should be managed using version control. That includes source code, automated tests, manual test scripts, database schema changes, build and deployment scripts, infrastructure configuration, and provisioning scripts. It should be possible for a developer to check out from version control everything she needs to build and test any application, and run a single command to deploy it to any environment she has access to. Martin Fowler even has a certification program for your configuration management strategy.
- Continuous integration. CI is a set of practices designed to ensures that the team prioritizes keeping the software in a known good state over doing new work. As traditionally practiced, everybody on the team checks regularly into trunk or mainline, triggering a build of the software and the running of a suite of some automated tests (as many as you can do in a few minutes). If this process fails, the team stops what they are doing and either fixes the problem or reverts the change that broke the build.
- Build quality in. Teams should be continuously testing the software throughout the development lifecycle using a combination of automated and manual tests to make sure it is always releasable.
The best place to start is with continuous integration. Every change to the state of the system should trigger the build and “commit” test suite. The team makes sure that if this fails it gets fixed. The CI process can then be extended all the way to release using a pattern called the deployment pipeline.
The deployment pipeline models your current process for taking changes from check-in to release, which may include both automated and manual tasks. It then allows you to take every change you make to your system through that process as quickly as possible, so you can get:
- Visibility into the production-readiness of your applications, as well as which versions of your systems are in which environments, and who authorized their deployment.
- Feedback on every change you make to your system as rapidly as possible.
- Control over the delivery process, including the ability to perform push-button deployments of any version of your system into any environment you have access to, so that (for example) testers can self-service the build of their choice into a testing environment at the push of a button.
In the deployment pipeline pattern, every change to your system results in running the CI process and creating application packages that can be deployed to every environment (in other words, the packages don’t contain environment-specific configuration). Every build creates a release candidate. The job of the deployment pipeline is to try and find a problem with the latest release candidate as quickly as possible so that the team can take action.
Ultimately you are aiming to optimize your delivery process for lead time – the time it takes to get a change from check-in to release. This is how you maximize feedback on whether the work you are doing is actually valuable. Thus you want to make sure your deployment pipeline is as short as possible. You can achieve this by simplifying, automating, and parallelizing as much of this work as possible.
Continuous Delivery by Jez Humble and David Farley, Addison-Wesley 2010.
The Lean Startup by Eric Ries, Crown Publishing, 2011.
The Principles of Product Development Flow by Donald Reinertsen, Celeritas Publishing, 2009.