Git – Using capistrano to deploy from different git branches

capistranogit

I am using capistrano to deploy a RoR application. The codebase is in a git repository, and branching is widely used in development. Capistrano uses deploy.rb file for it's settings, one of them being the branch to deploy from.

My problem is this: let's say I create a new branch A from master. The deploy file will reference master branch. I edit that, so A can be deployed to test environment. I finish working on the feature, and merge branch A into master. Since the deploy.rb file from A is fresher, it gets merged in and now the deploy.rb in master branch references A. Time to edit again.

That's a lot of seemingly unnecessary manual editing – the parameter should always match current branch name. On top of that, it is easy to forget to edit the settings each and every time.

What would be the best way to automate this process?

Edit: Turns out someone already had done exactly what I needed:

This morning I had occasion to deploy a branch of a git repository to
a staging server but hadn’t the foggiest idea how. A quick search
through the capistrano source code revealed that I could use set
:branch "branch_name" in my deploy script. I tried it and it worked.
I then figured I would need to make a similar change across all my
branches. Of course, I’m a lazy sod and wondered if there wasn’t a
better way.

If you’re not familiar with git, the output of the git branch command
is a list of branches with an asterisk marking the one currently
checked out on your local machine. For example:

> git branch
* drupal_authentication
fragment_caching
master

So, I figured, what if I just parsed the output and searched for the
branch marked as current:

set :branch, $1 if `git branch` =~ /\* (\S+)\s/m

Now I’m able to deploy whatever branch is current on my local machine
from a single, shared, deploy script.

Best Answer

This works with Capistrano >= 3.1:

add this line to config/deploy.rb:

set :branch, ENV['BRANCH'] if ENV['BRANCH']

and then call capistrano with:

cap production deploy BRANCH=master

This solution works with Capistrano < 3.1:

# call with cap -s env="<env>" branch="<branchname>" deploy

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")