Deploying trunk or tags with capistrano

On my current project, we use capistrano for all of our deployments. In
the simplest case, you tell capistrano the URL
of your repository, and then you deploy by performing a checkout from
this repository:

set :repository,  ""

However, putting this line in the capistrano recipe only lets you deploy
from trunk. We needed the ability to deploy either the trunk or a tag of
our choice. We generally deploy the trunk to development servers and the
latest tag to staging and production servers.

We started out with something more complicated, but with the help of
Jamis Buck on the capistrano mailing
, we came up with
the following solution:

set :repository_root, ""
set(:tag) { Capistrano::CLI.ui.ask("Tag to deploy (or type 'trunk' to deploy from trunk): ") }
set(:repository) { (tag == "trunk") ? "#{repository_root}/trunk" : "#{repository_root}/tags/#{tag}" }

This deploy script will prompt the user to enter either a tag name or
the word trunk. It will then use that variable to set the repository to
the correct path. The output of a deploy will look like:

% cap deploy
  * executing `deploy'
  * executing `deploy:update'
 ** transaction: start
  * executing `deploy:update_code'
Tag to deploy (or type 'trunk' to deploy from trunk): trunk
  * executing "svn checkout -q  -r2210 /var/www/myproject/releases/20081029012754 && (echo 2210 > /var/www/myproject/releases/20081029012754/REVISION)"

Capistrano evaluates variables lazily. It will only fetch the repository
variable if it needs it, which will then fetch the tag variable, which
will then prompt the user. Therefore, if you run a command that does not
require the repository, it will not prompt. For example, running the
following command will not prompt the user:

cap deploy:restart

Next, we created a convenience rake task to deploy the trunk without

namespace :deploy do
  task :trunk do
    sh "cap -s tag=trunk deploy"

This rake task sets the tag variable on the command line. Therefore,
capistrano will not need to evaluate the set(:tag) command and will
deploy the trunk without prompting.

Paul Gross

Paul Gross

I'm a lead software developer in Seattle working for Braintree Payments.

Read More