Capistrano: disable db:migrate - capistrano

How do you disable db:migrate when doing a cap deploy:cold with Capistrano?
In config/deploy.rb the only reference to deploy:migrate is commented out but it's still attempting to do:
bundle exec rake RAILS_ENV=production db:migrate

I got success by overriding the deploy:migrate method in my config/deploy.rb.
namespace :deploy do
desc "No ActiveRecord override"
task :migrate do
end
end

When re-defining a task in Capistrano v2, the original task was replaced. However the Rake DSL on which Capistrano v3 is built is additive. According to documentation.
Under most circumstances, you will simply want to use clear_actions, which removes the specified task’s behaviour, but does not alter it’s dependencies or comments:
namespace :deploy do
Rake::Task["migrate"].clear_actions
task :migrate do
puts "no migration"
end
end

I had the same problem. That's why I override it in the Rakefile. Like this:
namespace :db do
desc "db:migration fakes"
task :migrate => :environment do
p 'No. We will not migrate!'
end
end
Here you can add more logic if you like. You could for example trigger a real migration on certain environments.

Related

Why isn't environments/test.rb required when `rake test` is run via custom Rake task?

For $REASONS, I created a Rake task to paper over rake test. However, when I use the wrapper task, config/environments/test.rb is never required and, as a result, undesirable things happen (emails are sent out, the database is dropped, etc.).
(FWIW, Rails.env and ENV['RAILS_ENV'] are still set to test in the degenerate case.)
namespace :organization do
desc "Run unit tests."
task :unit do
puts Rails.env # test
Rake::Task["test"].invoke
end
end
you need to pass the :environment in rake tasks for it to work.
namespace :organization do
desc "Run unit tests."
task unit: [:environment] do
puts Rails.env # test
Rake::Task["test"].invoke
end
end

Creating and calling custom deployment task using run_locally in Capistrano version 3

I have a static page that I want to compile locally using gulp. The command I would run in the local shell, from the directory that contains gulp and the gulpfile (set by compile_path in this example) would be "$> gulp build".
# config valid only for Capistrano 3.1
lock '3.1.0'
set :application, 'appname'
set :repo_url, 'git#bitbucket.org/appname.git'
set :compile_path, '/Users/nico/DevOps/repo/appname'
# Default branch is :master
set :branch, 'cap3'
namespace :deploy do
after :started, :notify do
desc 'Run gulp to compile the static site'
task :gulp_build do
run_locally do
execute "#{fetch(:compile_path)}/gulp", " build"
end
end
end
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
# execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
Basically, what I'm trying to achieve is a local precompile so that my deployment consists of simply sending the locally compiled files to a deployment location. when I execute "bundle exec cap staging deploy:gulp_build" I get:
cap aborted!
Don't know how to build task 'deploy:gulp_build'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/gems/capistrano-3.1.0/lib/capistrano/application.rb:15:in run'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/gems/capistrano-3.1.0/bin/cap:3:in'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/bin/cap:23:in load'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/bin/cap:23:in'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/bin/ruby_executable_hooks:15:in eval'
/Users/nico/.rvm/gems/ruby-1.9.3-p545/bin/ruby_executable_hooks:15:in'
(See full trace by running task with --trace)
I realize that there are probably much better ways to deploy this, but it's a companion static site to a rails app which is being deployed successfully via capistrano, and I'd like to just use the same deployment method for both.
This was handled pretty well by creating a new task in the deploy namespace. in my code below are placeholders for real values that I didn't want to post on SO.
lib/capistrano/tasks/gulp_build_local.cap:
#assumes the gulpfile is in root of your cap install
namespace :deploy do
desc 'Run gulp to compile the static site'
task :gulp_build do
#run_locally doesn't play nice with the 'on' directive (it's 'on' localhost)
run_locally do
execute "gulp build"
end
end
end
deploy.rb:
# config valid only for Capistrano 3.1
lock '3.1.0'
set :application, '<appname>'
set :repo_url, 'git#bitbucket.org/<appname>.git'
namespace :deploy do
#custom tasks to build via gulp
before :deploy, 'gulp_build_local'
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
#nothing here, because there's no app server for this static site.
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
#nothing here
end
end
end
of course, once I figured this out I immediately deprecated it in favor of new tasks to install gulp in the release dir on the target, compiling there and linking the site root to the pub folder generated by the gulp process. Hopefully this learning experience will be useful for someone working though the use of run_locally, though.

How do I skip a rake task

Consider the following Rake tasks:
task deploy => [:package] do
end
task package => [:build] do
end
task build do
end
Is there a way to invoke Rake on the command line to execute the package and deploy tasks, but not the build task?
Short answer, no.
The way I usually go about this is instead of using the dependant task notion like you have above:
task deploy => [:package] do
end
I create an alias task for whatever action that is to be completed:
task all => [:build, :package, :deploy]
task fastDeploy => [:package, :deploy]
task deploy do
end
task package do
end
task build do
end
It's not very elegant, but I do find it to be more readable and you can visibly see the dependency of tasks on other tasks instead of the kind of spaghetti code structure the dependant notion can result in... when you have a lot of task it can be awkward to debug the logic to figure what's gone wrong and where at times.
Hope this helps.

whenever/capistrano `method_missing_with_variables': undefined method `role_names_for_host'

I'm using whenever/capistrano to update my cron_tab when deploying with capistrano, it was working great until recently my deploys started to fail when updating the cron_tab.
.rvm/gems/ruby-1.9.3-p362-turbo#psg-web/gems/capistrano-2.8.0/lib/capistrano/configuration/variables.rb:122:in `method_missing_with_variables': undefined method `role_names_for_host' for #<Capistrano::Configuration:0x000000018e6a10> (NoMethodError)
I am setting the *role_names_for_host*
set_default(:whenever_roles, [:workers])
and my tasks look like this
namespace :whenever do
desc "Stop whenever"
task :stop , roles: [:workers] do
clear_crontab
end
desc "Start whenever"
task :start , roles: [:workers] do
update_crontab
end
desc "Restart whenever"
task :restart , roles: [:workers] do
update_crontab
end
after 'deploy:symlink', 'whenever:update_crontab'
%w[start stop restart].each do |command|
after "deploy:#{command}", "whenever:#{command}"
end
end
Any Ideas on what I could be doing wrong?
Gem versions
capistrano (2.8.0)
whenever (0.8.2)
The method missing is introduced in capistrano after 2.9.0.
Patch: You can add this at the top of your Capfile or deploy.rb file:
require 'capistrano/server_definition'
require 'capistrano/role'
class Capistrano::Configuration
def role_names_for_host(host)
roles.map {|role_name, role| role_name if role.include?(host) }.compact || []
end
end
I would recommend whenever updating it's gem dependencies :)
( source: https://github.com/javan/whenever/issues/302#issuecomment-14962350 )

Adding actions to Capistrano tasks

How can I add something to Capistrano's deploy task? I need to create a symlink in "public" directory.
Create a new task to create the symlink, then use a hook to add your task into the Capistrano deploy workflow where appropriate.
e.g.
namespace :deploy do
desc "symlink my file"
task :symlink_file, :roles => :app do
run "ln -s file public/file"
end
end
after 'deploy:update_code', 'deploy:symlink_file'