【问题标题】:Is there a better way to run a capistrano task from within rake?有没有更好的方法从 rake 中运行 capistrano 任务?
【发布时间】:2010-11-01 06:36:30
【问题描述】:

我有一组 rake 任务,我需要在某些时候调用 capistrano。 Edwin Goei 的 blog 建议通过“sh”向 capistrano 发起攻击。

有没有更简单的方法?看起来您应该能够以编程方式调用适当的任务。提前致谢。

【问题讨论】:

  • 我了解到,在我的情况下,使用“system”比“sh”更可取,因为“sh”返回的非零退出代码会导致 rake 立即退出,而“system”允许它继续。

标签: ruby rake capistrano


【解决方案1】:

是的,Capistrano 可以通过编程方式访问命令行组件。但是,如果您想从 rake 任务中调用它们,则需要做一些额外的工作。

task :deploy
  require 'rubygems'
  require 'capistrano'
  require 'capistrano/cli'

  parameters = ["deploy"] # this is an array of the strings that come after
                          # cap on the command line. e.g., 
                          # ["deploy", "-S", "revision=1024"] gives you local var
                          # revision in your deploy.rb.

  # The following is required ONLY when you run Capistrano 2+ from Rake, 
  # because Rake adds the methods from FileUtils to Object. FileUtils includes 
  # a method called symlink which interferes with Capistrano's symlink task.
  Capistrano::Configuration::Namespaces::Namespace.class_eval { undef :symlink }

  Capistrano::CLI.parse(parameters).execute!
end

【讨论】:

  • 请注意我上面关于“sh”与“system”的评论。似乎 capistrano 通过“sh”在远程服务器上执行我的命令,并且非零返回值导致我的 rake 任务比我想要的更早退出。我的情况是否有任何程序解决方案?谢谢您的帮助;我已经继续并将这个问题标记为已回答,因为我认为我的特殊情况是一个边缘情况。
  • Capistrano 确实使用 sh - 无论是在默认任务中还是在您通过运行调用某些东西时。您可以将参数传递给 run 方法,:shell => false,它将在没有 sh 的情况下运行它。我相信您也可以在 deploy.rb 中设置一个全局变量,即 set :shell, false。
  • 你的回答已经有一段时间了,我试图让它与 Capistrano 2.12.0 一起工作。当我确实像你解释的那样,我得到:“定义一个名为‘disable’的任务会影响具有该名称的现有方法”。好像有些任务被加载了两次?有什么想法吗?
  • 此命令有效,但我在deploy.rb 中的要求之一失败:require whenever/capistrano(当我手动运行它时,没关系)
  • 这仍然适用于 capistrano v3 吗?
【解决方案2】:

对于 capistrano 3:

http://capistranorb.com/documentation/advanced-features/capistrano-pure-ruby/

require 'capistrano/all'

  stages = "production"
  set :application, 'my_app_name'
  set :repo_url, 'git@github.com:capistrano/capistrano.git'
  set :deploy_to, '/var/www/'
  set :stage, :production
  role :app, %w{}

  require 'capistrano/setup'
  require 'capistrano/deploy'
  Dir.glob('capistrano/tasks/*.cap').each { |r| import r }

  Capistrano::Application.invoke("production")
  Capistrano::Application.invoke("deploy")

【讨论】:

    【解决方案3】:

    乔纳森,你的里程可能会因执行 set(:shell, false) 之类的操作来停止 capistrano 在子 sh-shell 中运行的任务而有所不同。

    只是一个想法,如果您需要帮助,请随时联系我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-23
      • 2020-01-17
      • 2015-04-15
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 2012-11-15
      • 2011-10-06
      相关资源
      最近更新 更多