Topic: How do I use transactions within custom capistrano tasks?

(Originally posted on stackoverflow with no replies)

I'm writing a custom capistrano task to minify my javascripts and want to handle the case where the minification fails by rolling back the deploy.

I've been through the documentation and thought I'd figured out how to do it, but it's not working for me.

Here's what I have:

desc 'Minify all javascript files'
task :bundle, :roles => :app, :except => { :no_release => true } do
  on_rollback do
    run "rm #{current_path}/public/javascripts/all.js"
    puts "ROLLBACK"

  transaction do
    run "cd #{current_path}; RAILS_ROOT=#{current_path} rake bundle:js"

after 'deploy:update', 'deploy:bundle'

When I run cap staging deploy:bundle and set it up to fail, I get the following output:

   triggering start callbacks for `staging'
  * executing `staging'
    triggering start callbacks for `deploy:bundle'
  * executing `multistage:ensure'
  * executing `deploy:bundle'
 ** transaction: start
  * executing "cd /path/to/app/current; RAILS_ROOT=/path/to/app/current rake bundle:js"
    servers: [""]
    [] executing command
*** [err ::] rake aborted!
*** [err ::] invalid byte sequence in US-ASCII
# Trace here - removed for brevity
    command finished
failed: "sh -c 'cd /path/to/app/current; RAILS_ROOT=/path/to/app/current rake bundle:js'" on

So it is in a transaction, but my on_rollback hook doesn't get run. It does seem to know the task failed, as it outputs failed at the end - even though I haven't raised an exception.

Any ideas as to why my on_rollback isn't running?