Previously, we’ve discussed the vision of Continuous Deployment. When people start implementing Continuous Deployment, I’ve noticed that they confuse it with Continuous Delivery.
I’ll try to redefine these from another point of view – the product’s point of view:
Continuous Delivery: The ability to deliver features to production whenever we want.
Continuous Deployment: The ability to deploy our current code without ANY manual intervention.
The way I think about it is that Continuous Delivery defines the requirement, while Continuous Deployment is an implementation. Delivery is a more abstract term.
Another type of implementation for Continuous Delivery is Releasable Trunk. In this implementation our trunk/master branch is always in a state in which it is verified and valid for production deployment, but the deployment it-self is triggered manually while someone is “overseeing” the deployment.
The decision to use one implementation or another is a product decision.
Remember that whatever you do, before you deploy the version you want to deploy needs to be validated and verified (site down == no money).
Why should we have someone behind the wheel?
Manual processes are slow! Manual processes are error prone.
When someone asks you the annoying question “Why do you need to automate?” recite the above statements.
Besides these, automation has positive side effects on our process:
Improves the process
Automation requires us to take a deep look into the process and its components, which usually results in finding the weak spots. This in turn makes us fix and improve them.
Improves code quality
Automatic build of our code leads to less mistakes heading to everyone’s work space (you’ll kick someone for committing code that breaks compilation).
Continuous Integration of our features leads us to fix integration errors sooner in the development process, forces us to change design and code (and sometimes spec) very early on in the process.
Continuous Deployment causes us to deal with backward compatibility on a granular level – feature level, instead of version level. This in turn makes us create “safer” code (feature switches, silent deployments/gradual rollout).
Improves testing quality
Since we don’t have a man in the middle, validation of a version is done using automated testing.
When we start to automate the validations we need to do for each version, we are actually making sure they will happen in each version before deployment (repetitive testing).
If we fix a bug and don’t want it to happen again, we write a test for it, and that’s that. It won’t happen again.
If one test runs wild – causes missed validation (aka flakiness) and the whole automated process stops because of that – you’ll have to improve the test if you want your feature in production.
Sense of ownership
We feel safe if the ownership of the deployment is in someone's (usually someone else's) hands. It create a sense of virtual safety – “He's responsible for what is going to happen with the version. If there’s a bug, he is responsible to find it.”.
This is called the bystander effect.
As you can understand, this is not the culture you want. Collective ownership means everyone is responsible for production and the codebase. If we remove that someone who deploys the version, imagine how it will make the developers feel. We want to create a sense of “No one is there – so I’ll need to be there.” This in turn makes the ownership of a version become collective – among many people (or a blamefest).
The need for speed
Imagine you had 200 testers and 1,000 test cases. How long would it take you to validate a version? What if you had 10 servers you need to remove from the Load Balancer, stop, copy-paste (at best) your new code, restart the site, add back to the LB? How long would it take you? What if you had 20 servers?
A developer wants to automate because, well, we are a lazy bunch “first time do it manually, second time write a script, third time write a framework.”
We want to do our job – which is to code features. Everything else is waste. This is why we love Continuous Integration – it reduces the waste of integration. While Continuous Delivery equals "Give us product power", Continuous Deployment equals removing waste from the process.
Continuous Deployment: From commit to production automatically. (In other words – all you need is to code.)