Continuous deployment sounds terrifying. It means that with each commit you make to your version control, your code is pulled down, all tests are run, and, if everything passes, that code is then pushed to production. We can all see the risks here. One slightly screwy checkin could create a bug that’s not covered by unit tests. That code then goes live to your production environment, where customers see it and get angry.
First, continuous deployment makes deployment a non-event
You do have to plan some specific event for deployment. CI makes it “Little drop of water,little grain sand make the mighty ocean and the pleasant sand.” Testing and commit and deploying drop by drop instead of flooding them on day makes life much easier.
Second, continuous deployment forces you to build great tests.
There’s simply no way around this. As developers, we all know that we should be religiously writing tests for our code, but it’s incredibly easy to cheat and say, “I’ll catch up on my tests later,” or “This test can fail for right now.” The problem is that we never, ever clean that up. With continuous deployment, you absolutely can’t operate in that manner. Without repeatable and thorough testing, continuous deployment is continuous nightmare.Will you encounter production bugs that you didn’t catch with a test? Of course, you will. At that point, you write a test that covers the bug, you watch the test fail, you fix the bug, you watch the test pass, and then you commit. Like magic, the fix goes out to production and you have a little more confidence in your code.
Third, continuous deployment encourages good source control practices.
You know what would be hilarious? Someone trying to continuously deploy with 50 developers all checking into the trunk all the time.All non-idiotic source control systems have branches; use them! If you’re building something great, you’re going to have to make breaking changes to your code. I’m a big fan of branching for these breaking changes/big features/huge refactors, and then merging that back into the trunk once you’ve stabilized the code. Not only does that keep the build happy, that keeps your teammates happy because they don’t have to suffer through you sending out emails to everybody saying, “I know I broke the trunk, it’ll be fixed in 2 days or I’ll come to work dressed as a leprechaun.” So far, this branching strategy has been crucial to scaling the deployment process to larger teams.Another good source control practice that’s enforced through continuous deployment is tagging. It’s trivial to script your deployment out so that it tags each release you push to production. That is very helpful in the event you need to rollback.
Fourth, and most importantly, continuous deployment is fun.
You know what I love about making software? It’s when someone tells me about a major problem that I can fix simply. I am inundated with warm, fuzzy feelings when I see that simple, but important change go live just a few minutes after I commit. It makes me feel like I’m making a difference.
How do you set up continuous deployments?
It’s simpler than you might think. First, download a continuous integration service; I really like Hudson, which is free and easy to administer. Once you have your continuous integration service installed, create a job inside of it that polls your source control repository every few minutes for changes. When changes are found, you want to build your code (if necessary) and run your unit tests. So far, this is straight up continuous integration.
The deployment angle comes in after the tests have been run. Here, I just wrote a simple shell script that my Hudson job calls before it completes. The script zips up the current production code and moves it to an archive directory, then it copies the files over from my continuous integration environment to our production environment. We do multiple projects in a couple of seconds this way. It took me an hour or two to figure out this shell script, so allow time for experimentation here.
Continuous deployment is an ideal solution in any environment where you must me able to iterate very quickly.