Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Closed
macmartine opened this Issue · 11 comments

5 participants

@macmartine

'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
Owner

@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!

@macmartine

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 git@github.com:macmartine/xxxxx.git 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 git@github.com:macmartine/xxxxx.git 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, "git@github.com:macmartine/xxxxx.git"

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

role :web, "mydomain.net"

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

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

task :github do
set :repository, "git@github.com:macmartine/xxxxx.git"
set :user, "myuser"
end

@macmartine

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

@leehambley
Owner

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 https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb#L408

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')
end
@leehambley leehambley closed this
@macmartine

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

Thanks.

@leehambley
Owner

@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 :)

@macmartine

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.

@rogercampos

Sidekiq runs their quiet task on before :deploy

@asanghi

before "deploy", "check:revision"

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

@asanghi

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.

Thoughts?

@lichtamberg

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.