【问题标题】:Passing parameters to Capistrano将参数传递给 Capistrano
【发布时间】:2012-04-30 07:18:17
【问题描述】:

我正在研究使用 Capistrano 作为通用部署解决方案的可能性。通过“通用”,我的意思是非导轨。我对我找到的文档的质量不满意,但是,当然,我不是在看那些假定您正在部署 Rails 的文档。所以我会尝试根据几个例子来破解一些东西,但是我从一开始就面临着一些问题。

我的问题是cap deploy 没有足够的信息来做任何事情。重要的是,它缺少我要部署的版本的标签,而这个 必须 在命令行上传递。

另一个问题是我如何指定我的 git 存储库。我们的 git 服务器是通过用户帐户上的 SSH 访问的,但我不知道如何更改 deploy.rb 以使用用户的 id 作为 scm URL 的一部分。

那么,我该如何完成这些事情呢?

示例

我想部署第二个版本的第一个 sprint 的结果。这在 git 存储库中被标记为 r2s1。另外,假设用户“johndoe”负责部署系统。要访问存储库,他必须使用 URL johndoe@gitsrv.domain:app。因此存储库的远程 URL 取决于用户 ID。

获取所需文件的命令行如下:

git clone johndoe@gitsrv.domain:app
cd app
git checkout r2s1

【问题讨论】:

  • 嘿,希望您不要忽视我们的回答。请至少评论他们。 :)

标签: deployment capistrano


【解决方案1】:

更新:对于 Capistrano 3,请参阅 scieslak's answer below


jarrad 说过,capistrano-ash 是一套很好的基本帮助模块,可用于部署其他项目类型,尽管最终它不是必需的。它只是一种脚本语言,大多数任务都是通过系统命令完成的,最终变成了类似于 shell 的脚本。

要传入参数,你可以在运行 cap 时设置 -s 标志给你一个键值对。首先创建一个这样的任务。

desc "Parameter Testing"
task :parameter do
  puts "Parameter test #{branch} #{tag}"
end

然后像这样开始你的任务。

cap test:parameter -s branch=master -s tag=1.0.0

最后一部分。我建议使用 ssh 密钥对您的服务器设置无密码访问。但是,如果您想从当前登录的用户那里获取它。你可以这样做。

desc "Parameter Testing"
task :parameter do
  system("whoami", user)
  puts "Parameter test #{user} #{branch} #{tag}"
end

更新:经过编辑,可与最新版本的 Capistrano 一起使用。配置数组不再可用。

全局参数:参见 cmets 使用 set :branch, fetch(:branch, 'a-default-value') 全局使用参数。 (并使用 -S 来传递它们。)

【讨论】:

  • 使用 -s 参数。所以我有一个这样的命令行来部署特定的标签。 cap production deploy -s tag=2.1.3 如果你使用 capistano-ash,你只需要 set :branch, #{configuration[:tag]} 那应该检查在命令行设置的标签
  • 这不再起作用了。根据groups.google.com/forum/?fromgroups=#!topic/capistrano/…等地方,configuration已被弃用:undefined local variable or method 'configuration' for #<Capistrano::Configuration:0x0000010145e708> (NameError)。现在您可以只使用变量名。这在几个月前是如何运作的??
  • 如果您使用 Capistrano 的多级扩展,stage.rb 文件似乎在 Capfile 中的代码之后进行评估,并且在那里设置的变量将覆盖通过 -s 参数设置的变量.我必须在我的多阶段文件中执行以下操作:set :p, "default" if ! :p 这可以防止参数被删除。
  • 我发现使用 -s param 传入的参数仅适用于任务,因此如果您需要全局访问参数(例如元编程某些任务创建),那么这不起作用...
  • 是的,完全正确 - 使用 set :branch, fetch(:branch, 'a-default-value') 全局使用参数。 (并使用-S 传递它们。)
【解决方案2】:

更新。仅关于将参数传递给 Capistrano 3 任务。

我知道这个问题已经很老了,但在搜索将参数传递给 Capistrano 任务时仍然首先在 Google 上弹出。不幸的是,Jamie Sutherland 提供的奇妙答案不再适用于 Capistrano 3。在您浪费时间尝试之前,除了结果如下:

cap test:parameter -s branch=master 

输出:

cap aborted!
OptionParser::AmbiguousOption: ambiguous option: -s
OptionParser::InvalidOption: invalid option: s

cap test:parameter -S branch=master 

输出:

invalid option: -S

@senz 和 Brad Dwyer 提供的 Capistrano 3 的有效答案可以通过单击此黄金链接找到: Capistrano 3 pulling command line arguments

为了完整起见,请参阅下面的代码以了解您拥有的两个选项。

第一个选项:

您可以像使用常规哈希一样使用键和值迭代任务:

desc "This task accepts optional parameters"

task :task_with_params, :first_param, :second_param do |task_name, parameter|
  run_locally do
    puts "Task name: #{task_name}"
    puts "First parameter: #{parameter[:first_param]}"
    puts "Second parameter: #{parameter[:second_param]}"
  end
end

确保调用cap时参数之间没有空格:

cap production task_with_params[one,two]

第二个选项:

当你调用任何任务时,你可以分配环境变量,然后从代码中调用它们:

set :first_param, ENV['first_env'] || 'first default'
set :second_param, ENV['second_env'] || 'second default'

desc "This task accepts optional parameters"
task :task_with_env_params do
  run_locally do
    puts "First parameter: #{fetch(:first_param)}"
    puts "Second parameter: #{fetch(:second_param)}"
  end
end

要分配环境变量,请像下面这样调用 cap:

cap production task_with_env_params first_env=one second_env=two

希望这会为您节省一些时间。

【讨论】:

    【解决方案3】:

    正如 Jamie 已经展示的那样,您可以使用 -s 标志将参数传递给任务。我想向您展示如何使用默认值。

    如果要使用默认值,则必须使用 fetch 而不是 ||= 或检查 nil

    namespace :logs do
      task :tail do
        file = fetch(:file, 'production') # sets 'production' as default value
        puts "I would use #{file}.log now"
      end
    end
    

    您可以运行此任务(使用默认值 production 表示 file

    $ cap logs:tail
    

    或(将值cron 用于file

    $ cap logs:tail -s file=cron
    

    【讨论】:

      【解决方案4】:

      我建议使用 ENV 变量。

      类似这样的东西(命令):

      $ GIT_REPO="johndoe@gitsrv.domain:app" GIT_BRANCH="r2s1" cap testing
      

      上限配置:

      #deploy.rb:
      task :testing, :roles => :app do
        puts ENV['GIT_REPO']
        puts ENV['GIT_BRANCH']
      end
      

      看看https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension,也许这种方法对你也有用。

      【讨论】:

      • 我注意到使用环境变量是在 Ruby 中使用的,但我认为它们非常不方便。例如,我需要在 Windows 上使用三个单独的命令以及您提出的建议,每个命令都会出现小的拼写错误,如果您确实打错了错误的反馈。
      • 我同意最后一条评论,我更喜欢带有 -s 或 -S var=value 的命令行,然后是 if variables.include?(:var) ... else ... end
      【解决方案5】:

      查看capistrano-ash 以获取有助于非 Rails 部署的库。我用它来部署 PyroCMS 应用程序,效果很好。

      这是我的 Capfile 中用于该项目的 sn-p:

      # deploy from git repo
      set :repository, "git@git.mygitserver.com:mygitrepo.git"
      # tells cap to use git
      set :scm, :git
      

      我不确定我是否理解问题的最后两部分。提供更多细节,我很乐意提供帮助。

      在给出示例后编辑:

      set :repository, "#{scm_user}@gitsrv.domain:app"
      

      然后每个拥有部署权限的人都可以将以下内容添加到他们的本地 ~/.caprc 文件中:

      set :scm_user, 'someuser'
      

      【讨论】:

      • 好的,给出的例子。请注意,我无法将存储库设置为固定值,就像您在 sn-p 中所做的那样。
      • Home 的.caprc 很不错,但不能是强制性的。我想在命令行传递参数。
      猜你喜欢
      • 2015-02-14
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 2013-11-19
      • 2011-01-06
      相关资源
      最近更新 更多