如何有条件地覆盖 Capistrano 的 deploy:migrate 任务?
How to conditionally override Capistrano's deploy:migrate task?
我想有条件地覆盖 deploy:migrate
以便我们可以 运行 手动进行某些迁移。
这是我在 config/deploy/tasks/deploy.rake
中的内容:
namespace :deploy do
if ENV['DB_MIGRATE'] == 'skip'
desc "Override Capistrano's default behavior, do not migrate on deploy"
task :migrate do
raise 'BOO!'
end
end
end
这是我在 运行 DB_MIGRATE=skip cap staging deploy:migrate
:
时看到的
INFO [deploy:migrate] Run `rake db:migrate`
DEBUG [c0ed2f81] Running /usr/bin/env if test ! -d /path/current; then echo "Directory does not exist '/path/current'" 1>&2; false; fi as deploy@host.
DEBUG [c0ed2f81] Command: if test ! -d /path/current; then echo "Directory does not exist '/path/current'" 1>&2; false; fi
DEBUG [c0ed2f81] Finished in 1.061 seconds with exit status 0 (successful).
INFO [2f3a4cc7] Running bundle exec rake db:migrate as deploy@host.
DEBUG [2f3a4cc7] Command: cd /path/current && ( RAILS_ENV="staging" bundle exec rake db:migrate )
INFO [2f3a4cc7] Finished in 6.518 seconds with exit status 0 (successful).
(Backtrace restricted to imported tasks)
cap aborted!
BOO!
Tasks: TOP => deploy:migrate
(See full trace by running task with --trace)
从输出来看,Capistrano 似乎在做它一直做的事情,此外,还做了我要求它做的事情(引发异常)。
如何完全摆脱 Capistrano 的默认 deploy:migrate
?
根据我的经验,我会说它正在查看远程而不是本地的环境变量。调用 cap staging deploy 将远程环境变量设置为 RAILS_ENV=staging。但是因为这意味着登录远程并设置 var,所以它使使用 capistrano 变得很容易。
更好的方法可能是使用 capistrano 条件:https://github.com/deviantech/capistrano-conditional
其自述文件指出:
A major change from Capistrano 2 to Capistrano 3 is that task definitions are now additive, so defining a new task doesn't overwrite the existing definition.
文档中有一章 Overriding Capistrano Tasks 解释了整个过程:
When re-defining a task in Capistrano v2, the original task was replaced. The Rake DSL on which Capistrano v3 is built is additive however […]
But it is also possible to completely clear a task and then re-defining it from scratch.
这正是我所需要的。
在此处扩展已接受的答案,这将 OP 和链接的文档整合到一个完整的解决方案中:
if ENV['DB_MIGRATE'] == 'skip'
Rake::Task["deploy:migrate"].clear_actions
namespace :deploy do
desc "Override Capistrano's default behavior, do not migrate on deploy"
task :migrate do
puts 'BOO!'
end
end
end
我通过在 Capfile
中有条件地要求 capistrano/rails/migrations
解决了这个问题,即
# Migrations can be skipped by setting up local 'SKIP_MIGRATIONS' variable, i.e.
# SKIP_MIGRATIONS=true bundle exec cap production deploy
unless ENV['SKIP_MIGRATIONS']
require 'capistrano/rails/migrations'
end
我想有条件地覆盖 deploy:migrate
以便我们可以 运行 手动进行某些迁移。
这是我在 config/deploy/tasks/deploy.rake
中的内容:
namespace :deploy do
if ENV['DB_MIGRATE'] == 'skip'
desc "Override Capistrano's default behavior, do not migrate on deploy"
task :migrate do
raise 'BOO!'
end
end
end
这是我在 运行 DB_MIGRATE=skip cap staging deploy:migrate
:
INFO [deploy:migrate] Run `rake db:migrate`
DEBUG [c0ed2f81] Running /usr/bin/env if test ! -d /path/current; then echo "Directory does not exist '/path/current'" 1>&2; false; fi as deploy@host.
DEBUG [c0ed2f81] Command: if test ! -d /path/current; then echo "Directory does not exist '/path/current'" 1>&2; false; fi
DEBUG [c0ed2f81] Finished in 1.061 seconds with exit status 0 (successful).
INFO [2f3a4cc7] Running bundle exec rake db:migrate as deploy@host.
DEBUG [2f3a4cc7] Command: cd /path/current && ( RAILS_ENV="staging" bundle exec rake db:migrate )
INFO [2f3a4cc7] Finished in 6.518 seconds with exit status 0 (successful).
(Backtrace restricted to imported tasks)
cap aborted!
BOO!
Tasks: TOP => deploy:migrate
(See full trace by running task with --trace)
从输出来看,Capistrano 似乎在做它一直做的事情,此外,还做了我要求它做的事情(引发异常)。
如何完全摆脱 Capistrano 的默认 deploy:migrate
?
根据我的经验,我会说它正在查看远程而不是本地的环境变量。调用 cap staging deploy 将远程环境变量设置为 RAILS_ENV=staging。但是因为这意味着登录远程并设置 var,所以它使使用 capistrano 变得很容易。
更好的方法可能是使用 capistrano 条件:https://github.com/deviantech/capistrano-conditional
其自述文件指出:
A major change from Capistrano 2 to Capistrano 3 is that task definitions are now additive, so defining a new task doesn't overwrite the existing definition.
文档中有一章 Overriding Capistrano Tasks 解释了整个过程:
When re-defining a task in Capistrano v2, the original task was replaced. The Rake DSL on which Capistrano v3 is built is additive however […]
But it is also possible to completely clear a task and then re-defining it from scratch.
这正是我所需要的。
在此处扩展已接受的答案,这将 OP 和链接的文档整合到一个完整的解决方案中:
if ENV['DB_MIGRATE'] == 'skip'
Rake::Task["deploy:migrate"].clear_actions
namespace :deploy do
desc "Override Capistrano's default behavior, do not migrate on deploy"
task :migrate do
puts 'BOO!'
end
end
end
我通过在 Capfile
中有条件地要求 capistrano/rails/migrations
解决了这个问题,即
# Migrations can be skipped by setting up local 'SKIP_MIGRATIONS' variable, i.e.
# SKIP_MIGRATIONS=true bundle exec cap production deploy
unless ENV['SKIP_MIGRATIONS']
require 'capistrano/rails/migrations'
end