If like me, you use the Capistrano Multistage extensions in the capistrano-ext plugin, you’d have noticed to your horror at some point that if you deploy to an environment other than production, your migrations will still run against the production database.
As the extension has no native support for this change in behaviour, the following method override will do the trick:
namespace :deploy do desc "Invoke the db migration using the correct stage" task :migrate, :roles => :app do send(run_method, "cd #{release_path} && rake db:migrate RAILS_ENV=#{stage} ") end end
While I’m here, here’s a simple trick I came up with: at work we use SVN branches heavily, some for each Sprint and then for Releases. As each release has its own branch, we need to change the Capistrano repository URL for each release, which is tedious and easy to forget.
Instead of the manual change, why not just ask SVN to tell you the current URL for the current path, which is in our case the root of the app? If, during the cap deploy, we run some ruby code to call ‘svn info’, like so (the first line is not necessary – it’s just there for context):
set :scm, :subversion lines = %x[svn info]
The ‘svn info’ command obviously relies on the svn executable being in your path, but it is required for the rest of deployment so I’ll assume that’s already taken care of. The output of the command is something like:
Path: . URL: https://svn.example.com/svn/project/branches/release_12345 Repository Root: https://svn.example.com/svn Repository UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Revision: 1359 Node Kind: directory Schedule: normal Last Changed Author: dan Last Changed Rev: 13582 Last Changed Date: 2009-03-17 22:34:44 +0000 (Thu, 19 Feb 2009)
the %x[] command takes this output and puts it in a long string with line breaks. Then, because this output is well formed, we can use a little regex-fu to get out the parh of the repository, like so (full commands):
lines = %x[svn info] set :repository, /URL\: (.*)\n/.match(lines)[1]
The regular expression we use here is looking for a string that is between “URL: ” and “\n”, which as you would see from the output above, is:
https://svn.example.com/svn/project/branches/release_12345
Just what we were after!