Callbacks are not called when 'cap deploy:migrations' is run #198

macmartine opened this Issue Apr 20, 2012 · 11 comments


None yet
5 participants

'cap deploy:migrations' is supposed to run the same tasks as 'cap deploy' plus migrations.

But it doesn't trigger callbacks such as 'before :deploy'.


leehambley commented Apr 20, 2012

@macmartine If this were really true, I expect you wouldn't be the first to report that - code in this area remains largely unchanged for many months.

Can you be absolutely certain (and reproduce in a sample project) this behaviour, or indeed point me to which bit of the code you believe is failing? Thanks!

Here's the start of the output for each command where you can see 'cap deploy' outputs the 'puts' in the 'before :deploy' callback and 'cap deploy:migrations' does not:

→ cap deploy:migrations

  • executing `deploy:migrations'
  • executing `deploy:update_code'
  • updating the cached checkout on all servers
  • executing locally: "git ls-remote staging"
  • command finished in 1657ms

→ cap deploy

  • executing `deploy'
  • triggering before callbacks for `deploy'
    • Push to github.
    • Everything up-to-date
  • executing `deploy:update'
    ** transaction: start
  • executing `deploy:update_code'
  • updating the cached checkout on all servers
  • executing locally: "git ls-remote staging"

And here's the deploy.rb

require "bundler/capistrano"
require './config/boot'
require 'airbrake/capistrano'
require 'active_support/time'

$:.unshift(File.expand_path('./lib', ENV['rvm_path'])) # Add RVM's lib directory to the load path.
require "rvm/capistrano" # Load RVM's capistrano plugin.
set :rvm_ruby_string, 'ruby-1.9.3-p0' # Or whatever env you want it to run in.
set :rvm_type, :system

set :deploy_to, "/apps/eg/staging"
set :rails_env, :staging
set :branch, "staging"

set :stages, %w(production staging)
set :default_stage, "staging"

default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :normalize_asset_timestamps, false #suppress < 3.1 warnings

set :application, "myapp"
set :repository, ""

set :scm, :git
set :deploy_via, :remote_cache

role :web, ""

set :user, "myuser"
set :use_sudo, false

before :deploy do
puts "Push to github."
system "git push github staging"

task :github do
set :repository, ""
set :user, "myuser"

For now I've had to add all my deploy callback to "deploy:migrations" as well to make it work.


leehambley commented Apr 24, 2012

Closing this issue, as deploy:migrations is not the same task as deploy, they are both top-level tasks, and are deploy:migrations is not implemented in terms of deploy, see

I can understand that this is confusing, but I'm also not prepared to patch it, as deploy.rb has no tests, and it's a dangerous area to change anything (the trouble with old, untested software, alas)

I would recommend the following workaround:

['deploy', 'deploy:migrations'].each do |task|
  before(task, 'my:important:callback')
  before(task, 'another:important:callback')

@leehambley leehambley closed this Apr 24, 2012

Oh, so it's not supposed to work after all? Yes, you're right, it's odd that this hasn't come up before.

It's probably worth updating the docs to mention that deploy callbacks are not run -- this makes it sounds like they would be "This will work similarly to the deploy’ task, but will also run any pending migrations (via thedeploy:migrate’ task) prior to updating the symlink."



leehambley commented Apr 24, 2012

@macmartine Yeah, it's certainly odd - I'm not sure that many people callback before deploy, to be honest - I can't think of many tasks to do before a deploy (sounds like I'd do them by hand before I invoked Capistrano) - i'd be interested to know your use-case, and if you'd like to edit the docs/wiki, please be my guest, after so many years working with Capistrano my old eyes can't read the documentation like daily users can :)

I push my changes to github on 'before :deploy' before pushing the changes from there to my server. I guess people generally do that manually?
I'll get on the docs.

Sidekiq runs their quiet task on before :deploy

asanghi commented Aug 22, 2012

before "deploy", "check:revision"

check:revision ensures that you have pushed up your commits before deploying.

asanghi commented Aug 22, 2012

It's bitten me more than a few times that deploy:migrations does not invoke the same hooks as deploy. We innocently hook stuff around deploy (before examples are given above; and there are plenty of after examples of course). Recently, I hooked stuff around deploy:update which is also not invoked when running with migrations.

Personally i feel migrations should be the default functionality of deploy. If there are no migrations to deploy, then it's an effective no-op. It's probably/potentially disastrous to deploy with pending migrations anyway, so i'm all +1 for including migration functionality in the default task.

For backwards compatibility a flag could be introduced to let capistrano NOT migrate by default.


I would add a flag in the deploy.rb, if this flag is not set (f.e. run_callbacks_on_deploy_migrations = [true, false]) then the deployment stops at the beginning. So there wont be any problems, you just have to set the flag.

mattbrictson added a commit to mattbrictson/capistrano that referenced this issue Aug 24, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment