How to rewrite capistrano 2 task with `exception` to capistarano 3 - capistrano

I want to rewrite a capistrano 2 task in a way capistrano 3.
This code is from Railscast 335
%w[start stop restart].each do |command|
desc "#{command} unicorn server"
task command, roles: :app, except: {no_release: true} do
run "/etc/init.d/unicorn_#{application} #{command}"
end
end
I can rewrite according to the document of capistrano like this.
%w[start stop restart].each do |command|
desc "#{command} unicorn server"
task command do
on roles(:app) do
run "/etc/init.d/unicorn_#{application} #{command}"
end
end
end
But I have no idea how to rewrite except: {no_release: true} part, and I couldn't find document about it.
How can I rewrite it?

%w[start stop restart].each do |command|
desc "#{command} unicorn server"
task command do
on roles(:app), reject: lambda { |h| h.properties.no_release } do
run "/etc/init.d/unicorn_#{application} #{command}"
end
end
end
More info: http://capistranorb.com/2013/06/01/release-announcement.html

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

How to run a default task in Capistrano 3?

Due to the lack of documentation I resorted to reading the Capistrano 2 hanbook and came across 'default' task.
Example:
namespace :backup do
task :default do
web
db
end
task :web, :roles => :web do
puts "Backing Up Web Server"
end
task :db, :roles => :db do
puts "Backing Up DB Server"
end
end
The idea is that if I run cap backup it should execute the default task..which doesn't seem to work.
My code modified to suit the above:
namespace :status do
task :default do
webserver
db
end
desc "Check status of nginx on web server"
task :webserver do
on roles(:web) do |host|
execute 'hostname'
execute 'service nginx status'
end
end
desc "Check status of DB"
task :database do
on roles(:db) do |host|
execute 'hostname'
execute 'service postgresql status'
end
end
end
How do you run default tasks in Capistrano 3?
create a task outside a namespace and name that task the same as your namespace. Define that this task depends on your :default task within the name space
namespace :status do
task :default do
puts "Hello Default-Task!"
end
end
task :status => "status:default"
as you are using Rake within Capistrano 3 you can use that Rake trick.

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.

Capistrano: disable db:migrate

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.

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 )