【问题标题】:How to run custom rake task via capistrano 3?如何通过 capistrano 3 运行自定义 rake 任务?
【发布时间】:2014-07-12 19:07:33
【问题描述】:

哪种方式,我可以通过远程服务器上的 capistrano 运行 rake 命令。

例如我有一个lib/task/reparse.rake 有一些方法

desc "it's take csv file, makes some changes and fill db with this info"
task :example1 => :environment do
  require 'csv'
  rows_to_insert = []
  # some actions
  # ...
end

在本地服务器上一切都很好 - 我只是运行 rake reparse:example1 它的工作(正确填写数据库)。 所以问题是 - 部署后如何在真实主机上运行此命令?

我正在使用 rails 4.1 + capistrano 3。

附:网站上的例子对我不起作用 How do I run a rake task from Capistrano?

如果我尝试cap production rake:invoke task=reparse:land 它失败了:

cap aborted!
Don't know how to build task 'rake:invoke'

一些修复

namespace :somenamespace do
  task :runrake do  
    on roles(:all), in: :sequence, wait: 5 do      
      within release_path do
        execute :rake, ENV['task'], "RAILS_ENV=production"
      end 
    end
  end
end

以这种方式开始执行通过

cap production somenamespace:runrake task=custom_task_file:custom_method1

【问题讨论】:

标签: ruby-on-rails ruby rake capistrano capistrano3


【解决方案1】:

基于capistrano/rails gem:https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rake

namespace :somenamespace do
  task :runrake do
    on roles(:all) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, ask :task
        end
      end 
    end
  end
end

【讨论】:

  • 谢谢!您能否添加一个示例命令行来显示如何运行它?
【解决方案2】:

您可以创建相应的 capistrano 任务来运行特定的 rake 任务,如下所示:

namespace :guests do
  desc 'Remove guest users older than 7 days'
  task :clean do
    on roles(:app) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, 'guests:delete_old_guest_users'
        end
      end
    end
  end
end

【讨论】:

    【解决方案3】:

    所以我一直在努力。它看起来运作良好。但是,您需要一个格式化程序才能真正利用代码。

    如果您不想使用格式化程序,只需将日志级别设置为调试模式即可。

    SSHKit.config.output_verbosity = Logger::DEBUG
    

    帽子的东西

    namespace :invoke do
      desc 'Run a bash task on a remote server. cap environment invoke:bash[\'ls -la\'] '
      task :bash, :execute do |_task, args|
        on primary :app do
          within deploy_to do
            with rails_env: fetch(:rails_env) do
              SSHKit.config.format = :supersimple
              execute args[:execute]
            end
          end
        end
      end
    
      desc 'Run a rake task on a remote server. cap environment invoke:rake[\'db:migrate\'] '
      task :rake, :task do |_task, args|
        on primary :app do
          within current_path do
            with rails_env: fetch(:rails_env) do
              SSHKit.config.format = :supersimple
              rake args[:task]
            end
          end
        end
      end
    end
    

    这是我为使用上述代码而构建的格式化程序。它基于 sshkit 中内置的 :textsimple,但它不是调用自定义任务的好方法。哦,这很多不适用于最新版本的 sshkit gem。我知道它适用于 1.7.1。我这样说是因为 master 分支更改了可用的 SSHKit::Command 方法。

    module SSHKit
      module Formatter
        class SuperSimple < SSHKit::Formatter::Abstract
          def write(obj)
            case obj
            when SSHKit::Command    then write_command(obj)
            when SSHKit::LogMessage then write_log_message(obj)
            end
          end
          alias :<< :write
    
          private
    
          def write_command(command)
            unless command.started? && SSHKit.config.output_verbosity == Logger::DEBUG
              original_output << "Running #{String(command)} #{command.host.user ? "as #{command.host.user}@" : "on "}#{command.host}\n"
              if SSHKit.config.output_verbosity == Logger::DEBUG
                original_output << "Command: #{command.to_command}" + "\n"
              end
            end
    
            unless command.stdout.empty?
              command.stdout.lines.each do |line|
                original_output << line
                original_output << "\n" unless line[-1] == "\n"
              end
            end
    
            unless command.stderr.empty?
              command.stderr.lines.each do |line|
                original_output << line
                original_output << "\n" unless line[-1] == "\n"
              end
            end
    
          end
    
          def write_log_message(log_message)
            original_output << log_message.to_s + "\n"
          end
        end
      end
    end
    

    【讨论】:

    【解决方案4】:

    您需要在 Capistrano 配置中加载自定义 rake 任务:

    # config/deploy.rb || config/deploy/production.rb
    load 'lib/task/reparse.rake'
    

    在控制台cap -T中检查新任务

    【讨论】:

      【解决方案5】:

      试试capistrano-rake

      无需弄乱自定义 capistrano 任务或详细说明,您只需安装 gem,即可开始在远程服务器上执行 rake 任务,如下所示:

      $ cap production invoke:rake TASK=some:rake_task
      

      【讨论】:

        猜你喜欢
        • 2010-09-23
        • 1970-01-01
        • 2016-11-03
        • 2015-04-15
        • 2020-01-17
        • 2013-12-03
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        相关资源
        最近更新 更多