Two tenets of Pivotal are continuous integration and coding if you’re in front of a computer. These goals can conflict when you’ve just wrapped up a story and are about to push to a staging environment – while your final tests and deploy are running, you can’t modify your Git working tree. So you grab some coffee or check your email.
In the spirit of eliminating breaks enforced by devops, Dirk Kelly and Mik Freedman paired on a great way to run deploys in the background. In essence, you create a separate Git repository on your development machine, we’ll call it
deployer, that has your original Git code repository as a remote. Your deploy scripts then run in background from the deployer directory while you happily code in your original directory.
If your deployment process is anything more than a push to GitHub, this saves a good amount of time. If your project involves more than 1 pair, continuous integration and automatic deployment of all Git branches can alleviate the pain of long deploys.
Below are the details of our setup. Assume that
~/code/client was our original Git repo and
~/code/client_deployer is our fancy new deployment repo. By keeping these scripts in your development repository and changing directories in the script, you can solve some chicken-egg problems by running the development version of the script against any of your environments.
~/code/client_deployer, add your original repository as a remote:
git remote add local ~/code/client/.git
In the code below, the pushd, popd, and trap commands ensure that your working directory is always left untouched no matter how the script exits. First, we essentially discard all local changes and check out the master branch. We then run our specs and associated rake tasks. Because we include set -e, our deploy will abort if the specs do not pass (or any command exits with a nonzero exit code). Then we push up to GitHub and Heroku (using heroku-san).
#! /bin/bash set -e trap “popd” EXIT pushd ~/code/client_deployer git fetch local git co master git reset local/master --hard git clean -f -d rake db:test:prepare rake rake production:deploy git push origin master
Nothing presented above is particularly revolutionary. Nonetheless, using a second deployment directory is a great way to remain “in the zone” while you code. Deploying doesn’t have to involve a coffee break or a ping-pong match anymore – just run your deploy in a background terminal and check on it when you come to a good stopping point.