Make deployment visible with Capistrano, Autotagger, Git and Sendgrid
There comes a time in every project when the deployment process comes of age, and that development arrives with its own set of Capistrano recipes and Rake tasks. The project I'm on hit that point recently, and one of the neat outcomes of its nascent puberty was a simple Capistrano recipe to send a git changelog to our project mailing list.
Here's what this looks like:
$ cap staging deploy ... stuff happens here ... * executing `sendgrid:notify' Changelog: 04fc6dd adding capistrano deployment messages
In this post, I'll show you how to set up end-to-end Capistrano testing using Cucumber. I've extracted this from the cucumber features I wrote for a gem I'm building named auto_tagger. To fully test capistrano recipes, your tests will have to:
- Create a local git repository
- Create a local app with a config/deploy.rb file
- Push the app to the local repository
cap deploy:setupfrom the app (which will setup a directory inside your local test directory)
- Run a
cap deployfrom the app (which will deploy to your test directory)
- Assert against the content of the deployed app in the test directory
Background - Capistrano recipes are almost never tested
Looking around online, I couldn't find a single list of capistrano packages that has an automated test suite, even ones from some big hosts. It's no surprise that Capistrano tasks are seldom tested - testing capistrano recipes is hard, and even when you do test them, there are still so many variables in real-life deploys that you can't account for everything.
It's like Rummy said:
There are known knowns. There are things we know that we know. There are known unknowns. That is to say, there are things that we now know we don’t know. But there are also unknown unknowns. There are things we do not know we don’t know.
However, there are some things you can do to stave off the "known unknowns". For example, you know that someone might forget to set an important variable in their cap task and you know they might be using cap-ext-multistage. For these kinds of examples, Capistrano testing can give you much more assurance that a bug in your recipe is less likely to
rm -rf /* on your remote machine.
AutoTagger is a gem that helps you automatically create a date-stamped tag for each stage of your deployment, and deploy from the last tag from the previous environment.
Let's say you have the following workflow:
- Run all test on a Continuous Integration (CI) server
- Deploy to a staging server
- Deploy to a production server
You can use the
autotag command to tag releases on your CI box, then use the capistrano tasks to auto-tag each release.
Moving from Subversion to Git
We recently moved our project from subversion to git, and so far the move has gone very smoothly. The following post will detail what we did to make the move.
For this project there 2 pairs working and we have 6 machines and one hosted service:
- Two Mac OSX workstations with IDEA
- One continuous integration server running Cruise Control
- A staging server running a 2-year old version of Ubuntu
- A subversion server
- A production server hosted on Engine Yard
- A Github account with the ability to create private repositories
The goal was to have one pair continue to work while the migration from svn to git was happening.
What is capistrano multistage?
- A plugin that allows you to store environment-specific variables in different files, and specify a default environment
- It's been on tracker for a while and seems to be stable
- Other options are just specifying your environment-specific variables within separate tasks - keeping everything in one file