Deploying trunk or tags with capistrano

written by paul on October 28th, 2008 @ 08:34 PM

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,  "http://www.example.com/svn/myproject/trunk" 

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 list, we came up with the following solution:


set :repository_root, "http://www.example.com/svn/myproject" 
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 http://www.example.com/svn/myproject/trunk /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 prompting:


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

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.

Comments

  • Joran on 29 Oct 03:26

    I am not really into capistrano, but maybe you could make it that it will deploy to the trunk or tag that you are currently in. I guess you will be deploying from a checked out project, just pick up that repository url and deploy from there.
  • Dan Manges on 30 Oct 01:48

    Nice write up Paul. The lazy attribute evaluation is nice. Here's how I set up Vlad to deploy from a tag: http://www.dcmanges.com/blog/deploying-from-an-svn-tag-using-vlad
  • Paul Gross on 30 Oct 17:54

    Joran, we usually don't check out tags locally. We generally deploy from the trunk or a branch, but then specify the tag we want to deploy.

Post a comment

Options:

Size

Colors