Capistrano::Unison

Capistrano::Unison is a deployment strategy for Capistrano that uses Unison to syncrhronize the working directory with the filesystem on the remote side. The result is very similar to Capistrano::Deploy::Strategy::Copy, except it is significantly faster and can feasibly used to pull changes on the remote end down.

The main motivation for this is to speed up testing deploys while doing devopsy things with [capistrano]((http://capify.org/), moonshine, puppet, etc, while avoiding having to commit changes that are still being developed. capistrano-cowboy was our first attempt at this workflow, but for sufficiently large repositories and sufficiently slow uplinks, the feedback cycle is enough to kick a developer out of The Zone(tm).

During initial development, capistrano-cowboy deploys took over 2 minutes, and capistrano-unison depoys took 15 seconds. It was pretty shocking

Installation

Add this line to your application's Gemfile:

group :development do
  gem 'capistrano-unison', :require => false
end

And then execute:

$ bundle

Or install it yourself as:

$ gem install capistrano-unison

Usage

Add to config/deploy.rb:

require 'capistrano/unison'

You need to install unison locally first, which most packages managers have:

# on debian/ubuntu
$ sudo apt-get install unison # for
# on macos with homebrew
$ brew install unison

Important note! The major.minor version of unison needs to match on client and server, or it will fail with sads.

You have to do an initial setup to get unison installed on the remote end:

$ cap <stage> unison:setup

Now you can use the unison task to enable unison deploys just for this run:

$ cap <stage> unison deploy

TODO

  • Don't hardcode local directory '.' (borrow from :repository when using scm none?)
  • Support ignores, like .git
  • Test and document using to pulling remote changes back to local directory
  • Write tests with capistrano-spec
  • Reset unison lock files and info, ie that is kept on ~/.unison. Interrupting a unison run can leave these around, and is super annoying to manually remove. unison will spit out what needs to be removed as part of its output, so that could be parsed
  • Test and fix working with conflicting versions of unison on client/server

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request