Continuous integration with git, Capistrano, and Integrity

What is continuous integration (CI)?

When working in an environment with multiple developers, the practice of continous integration can be tremendous for catching integration errors quickly. This means, as soon as code is checked in to your central repository, integration will be verified by an automated build / test suite. This requires that you have a single source repository and are writing proper tests for your application.

Automated builds / tests with Integrity

Integrity will build your code, then run tests to make sure everything works as expected. Installation instructions can be found on their homepage, but once you do have it setup, it is quite easy to add extremely useful functionality. What I have used, is the email on completion functionality. To get this up and running, you simply need the following line in your init.rb file:

require "integrity/notifier/email"

Once you have added a new project, the repository URI, branch, and name should be straight forward to fill out. Your build script is what will be evaluated for a return value of 0, indicating everything went well and good. You can use this section to do some really cool things, what I've done is take a rails app and run some tasks using rake. Then using &&, on success of the tests, it will launch a deploy using capistrano.

rake RAILS_ENV=test gems:build db:migrate \
&& spec ./spec --format specdoc && cap -f /srv/app/capfile deploy

I heavily advise against using this straight to your production web server, in this example I'm having cap deploy to my staging servers. This is a great way to go from successful tests to deployment on your staging or QA servers. Now, to complete the full automated build to deploy, you need a way for your code check-ins to perform an action.

Using git hooks to initiate a build

Inside every git repository, there is a subdirectory called hooks. This directory contains a series of specially named scripts that will get executed at various points whne interacting with git. For a full explanation of the scripts, check out the githooks(5) man page.

#!/bin/bash
echo "Received commit to branch: $1"
if [[ "$1" =~ ^(.*)/master$ ]]; then
  echo "Starting Integrity build..."
  curl -F 'build=build' http://ci.example.com/project/builds 2>/dev/null
else
  echo "Current branch is not master, Integrity will not be started."
fi

Sending a simple POST request to your integrity server at the /:project/builds URI will cause integrity to do its thing. This script checks the branch that was commited to, and only kicks off the POST request if it was master.

There you have it, a full commit, test, and deployment all automated. This forces your developers to use version control and write good tests, because as soon as you commit something, it will be tested and if it passes it's going straight to your servers. As a sysadmin, I've learned a lot about rails applications by setting something like this up.

Tags: