Deploying SVN tags and branches with Capistrano

Posted by Jason King over 2 years ago

Something which I came up against fairly early on in my Capistrano use was the problem of releasing from tags or branches in SVN. My normal development process for a large release is to tag the trunk, and then release from the tag. Then there are other times when I have a long-running branch that I want released as well. These posed some problems for Capistrano because the repository location was baked right into the deployment scripts.

A great little trick that I do now for all my projects, lets Capistrano automatically release the right thing. Whether that’s a tag, a branch or the trunk.

What we need is to be able to set the :repository dynamically based on where a given rails project is in SVN. Thankfully, SVN has the perfect feature for just such a purpose.

For those unaware, SVN keywords allow you to enter a special string in any file, and SVN will replace the string with some dynamic value. You can put strings for the revision number, the date, or user-set strings. One which we’ll use is $HeadURL$ (you can also use $URL$) which is replaced with the URL of the file in the SVN repository.

So the steps are this:

1. Update deploy.rb

After you’ve capified your rails project, you need to edit deploy.rb in order to add in the repository URL (ie. you have to do this whether implementing this tip or not), usually you set it to a hard-coded value which would be something like this:

set :repository, "http://foo.com/proj/trunk"

But here we’re going to set it to our special $HeadURL$ string. Thing is though, that this will be replaced with the URL of the deploy.rb file itself, whereas we want the root of the project, so we just need some munging:

set :repository, "$HeadURL$".split[1].
   gsub(%r{(trunk|(?:branches/|tags/)[^/]+).*},'\1')

Seems a bit weird right now, but remember that by the time we finish, $HeadURL$ will be replaced with a full URL.

Note also that we’re assuming that your SVN structure is in keeping with the standard SVN convention, ie. you have the following structure:

proj/
  trunk/
     app/
     Capfile
     components/
     ...etc.
  branches/
     eg1/
        app/
        Capfile
        components/
        ...etc.
  tags/
     eg2/
        app/
        Capfile
        components/
        ...etc.

2. Set the keywords property on deploy.rb

You can configure SVN to do this automatically when you add deploy.rb into SVN (it only works at the time you’re adding a new file into SVN, not on every commit) by editing your ~/.subversion/config file and adding this line:

deploy.rb = svn:keywords=HeadURL

Or, you can do it manually like this:

svn ps svn:keywords HeadURL path/to/deploy.rb

3. You’re done.

Now when you commit that deploy.rb file SVN will update $HeadURL$ to be the full URL, and Capistrano will use that URL to set the project root for any deployment. So your deploy.rb file will end up with something like this:

set :repository, "$HeadURL: http://foo.com/proj/tags/x1/config/deploy.rb $".
  split[1].gsub(%r{(trunk|(?:branches/|tags/)[^/]+).*},'\1')

Which, after the substitution will end up (for the above example) with the :repository set to http://foo.com/proj/tags/x1

Comments

There are 0 comments on this post. Post yours →

Post a comment

Required fields look like this.

Markdown enabled. See the syntax rules for help.