When I heard that Capistrano 2 was being released without support for deploying subversion tags, I was a little miffed. I thought it was a major oversight with Capistrano 1, and I was hoping they would rectify it.
After a little hacking, though, I realized there was really no reason to be angry at Capistrano for this oversight. All I needed to do was write a tiny bit of code in the deployment recipe and I was good to go.
The main drawback to this approach is that the directory created on the production server is named with the timestamp of the deployment, rather than the tag name, which would be ideal. However, with the small amount of searching I did, I was unable to find a way to change this naming scheme. I have a hunch it might break the rollback functionality and is probably not worth the trouble.
Note 1: Part of my tagging for release process is to create a ‘latest’ tag in the tags directory that points to the latest tag (duh!) So, the code above asks which tag to deploy, but will deploy ‘latest’ by default if there is no input from the user. This is not strictly necessary for the tagging, but makes the deployment slightly easier (ie. just hit enter when prompted for a tag).
Note 2: This scheme should work with both cap 1 and cap 2, but I only tested it on cap 2.












September 12th, 2007 at 12:05 pm
Ah…Nice and simple just like I was hoping for.
Thanks for the post, guys!
January 30th, 2008 at 7:39 am
[...] is no built in way to deploy a branch from your source code control system. There are a couple ways of accomplishing this. I chose passing in the branch as a parameter to the Capistrano [...]
June 4th, 2008 at 3:22 pm
About note one: instead of manually setting latest tag you can get the last in alphabetical order this way:
require ‘capistrano/recipes/deploy/scm/subversion’
Capistrano::Deploy::SCM::Subversion.class_eval do
def latest_tag
logger.debug “querying latest tag …” unless @latest_revision
tags_dir = configuration.repository + ‘/’ + configuration.svn_tag_dir + ‘/’
@latest_revision = ls(tags_dir).split(”\n”).last.chomp(’/')
end
alias_method :latest_revision, :latest_tag
def ls(path)
`#{scm} ls #{path}`
end
end