简体   繁体   中英

How do I use transactions within custom capistrano tasks?

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"
  end 

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

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: ["example.com"]
    [example.com] executing command
*** [err :: example.com] rake aborted!
*** [err :: example.com] 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 example.com

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?

@bgates is correct, the rollback needs to be within the transaction. Here's an example from one of my apache recipes:

task :update_and_test_config, :roles => [:app, :search] do
  transaction do
    on_rollback do
      apache.link_previous_config
      deploy.rollback.revision
      apache.restart
      deploy.rollback.cleanup
    end
    apache.render_config
    apache.link_config
    apache.configtest
  end
end

Looking at the example

task :deploy do
  transaction do
    update_code
    symlink
  end
end

task :update_code do
  on_rollback { run "rm -rf #{release_path}" }
  source.checkout(release_path)
end
...

I wonder if the on_rollback call shouldn't go inside the transaction block, like

  transaction do
    on_rollback do
      run "rm #{current_path}/public/javascripts/all.js"
      puts "ROLLBACK"
    end 
    run "cd #{current_path}; RAILS_ROOT=#{current_path} rake bundle:js"
  end  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM