How do you add some steps to a capistrano task? - capistrano

I'd like to stop some processes before running the deploy:migrate task. I know that I can redefine the deploy:migrate task by copying the existing code and adding the stop/start steps at the beginning and end of the task.
I'm wondering if there is a way to avoid copying the code from the default deploy:migrate task in my version of the task. Is there a way to refer to the existing deploy:migrate task when defining a new task of the same name?

Rather than redefining deploy:migrate, you should define a before or after hook for it. First, create a new task that does the stuff you need to do:
task :custom_name do
# whatever you need to do
end
And then set this new task to be run before or after the deploy:migrate task by doing one of the following:
before "deploy:migrate", :custom_name
after "deploy:migrate", :custom_name

For my requirements, I override the existing task in deploy.rb
namespace :deploy do
# to Override deploy:migrate task
task :precompile, :roles => :app, :except => { :no_release => true } do
run "your modified commands"
end
# to override deploy:assets:precompile task
namespace :assets do
task :precompile, :roles => :app, :except => { :no_release => true } do
run "your modified commands"
end
end
end

Related

remote_file capistrano 3 method

In capistrano 3 docs (http://capistranorb.com/documentation/advanced-features/remote-file/) an example is provided to show how this task (remote_file) works
namespace :deploy do
namespace :check do
task :linked_files => 'config/newrelic.yml'
end
end
remote_file 'config/newrelic.yml' => '/tmp/newrelic.yml', roles: :app
file '/tmp/newrelic.yml' do |t|
sh "curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml"
end
They tell it allows a presence of remote file to be set as a prerequisite.
Hovewer I still can't get how it works as remote_file is called outside task code. What does it actually do? Can someone explain?
What happens if config/newrelic.yml is absent and how is remote_file call connected with
:linked_files task?
Calling remote_file only defines a task named 'config/newrelic.yml'. It does not execute that task. The line
remote_file 'config/newrelic.yml' => '/tmp/newrelic.yml', roles: :app
is saying "create a task named 'config/newrelic.yml' that has a prerequisite task named '/tmp/newrelic.yml'". The file '/tmp/newrelic.yml' part defines this prerequisite task. Finally, task :linked_files => 'config/newrelic.yml' is specifying a prerequisite task named 'config/newrelic.yml' to be executed, which we defined using the remote_file method.

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.

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.

Inherit roles from parent tasks in Capistrano callbacks

I have several tasks which all must check that the machines serving as roles have a certain file with certain contents. The logic is reasonable to separate into a prerequisite, or a callback.
task t1, :roles => [:r1] do
...
end
task t2, :roles => [:r2,:r3] do
...
end
before <what?> do
# must only run on :r1 when triggered by t1,
# and only on :r2 and :r3 when triggered by t2!
<ensure role given to parent task has a given file>
end
How do we do that in Capistrano?
It turns out that a before callback can invoke a regular def, in which case it runs for the roles of the parent task. If, however, you call a task there, and that task has no roles, all roles will be used to run it. The real question is where are the dependencies across tasks...

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'