133

我正在使用 capistrano 部署 RoR 应用程序。代码库位于 git 存储库中,分支在开发中被广泛使用。Capistrano 使用deploy.rb文件进行设置,其中之一是要部署的分支。

我的问题是这样的:假设我从master创建了一个新分支A。部署文件将引用master分支。我对其进行了编辑,因此可以将A部署到测试环境。我完成了该功能的工作,并将分支A合并到master。由于来自A的文件更新鲜,因此它被合并,现在in master分支引用A。是时候再次编辑了。deploy.rbdeploy.rb

这是很多看似不必要的手动编辑 - 参数应始终与当前分支名称匹配。最重要的是,很容易忘记每次都编辑设置。

自动化此过程的最佳方法是什么?

编辑:原来有人已经完成了我所需要的

今天早上,我有机会将 git 存储库的一个分支部署到临时服务器,但不知道如何部署。快速搜索 capistrano 源代码后发现我可以 :branch "branch_name"在部署脚本中使用 set。我试过了,它奏效了。然后我想我需要在我的所有分支机构中进行类似的更改。当然,我是一个懒惰的草皮,想知道是否有更好的方法。

如果您不熟悉 git,则 git branch 命令的输出是一个带有星号的分支列表,表示当前在本地计算机上签出的分支。例如:

> git branch
* drupal_authentication
fragment_caching
master

所以,我想,如果我只是解析输出并搜索标记为当前的分支怎么办:

set :branch, $1 if `git branch` =~ /\* (\S+)\s/m

现在,我可以从单个共享的部署脚本部署本地计算机上当前的任何分支。

4

13 回答 13

172

这适用于 Capistrano >= 3.1:

将此行添加到config/deploy.rb

set :branch, ENV['BRANCH'] if ENV['BRANCH']

然后使用以下命令调用 capistrano:

cap production deploy BRANCH=master

此解决方案适用于 Capistrano < 3.1:

# call with cap -s env="<env>" branch="<branchname>" deploy

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")
于 2012-01-30T17:32:38.737 回答
35

使用 Capistrano 3.1.0+,这些都不再适合我了。相反,根据他们的评论说明:

   ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

但是,您不想使用ask,否则它会提示您。相反,您应该使用set. HEAD是最顶层的分支;所谓的“边缘”。如果您想要不同的分支,请替换HEAD为您的分支名称,例如:master、、staging等。

以示例结束,在 中/config/deploy/production.rb,您可能包括以下行:

   set :branch, proc { `git rev-parse --abbrev-ref master`.chomp }

...或者

   set :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

顺便说一句,HEAD是默认设置,因此无需在文件中真正说明。可能在/config/deploy/edge.rb.

/config/deploy/staging.rb中,您可能会包含以下行:

   set :branch, proc { `git rev-parse --abbrev-ref staging`.chomp }

...或者

   set :branch, proc { `git rev-parse --abbrev-ref test`.chomp }

你明白了!

我希望这些示例对 capistrano 的未来用户有所帮助 (^_^)

于 2014-01-31T13:06:31.907 回答
32

我可以确认以下内容在 Cap 3.11.0 13/10/18 和 Cap 2 中仍然有效:

在 deploy.rb / stage.rb 中:

set :branch, ENV['BRANCH'] || 'develop'

在命令行上:

cap deploy BRANCH=featurex

这为您提供了一个默认分支(对于不同的环境可能会有所不同),并且可以在需要时更改分支。

于 2013-03-18T17:21:13.253 回答
28

使用多阶段,它实际上是现在:

cap production deploy -s branch=my-branch

以前的帖子语法在我的环境中不起作用

于 2012-10-15T21:34:21.287 回答
15

或者,您可以从具有默认分支和环境的命令行构造它,并且您还可以将参数传递给 cap 调用,其中可能包括环境和要使用的分支。这可能是一个明确传递的分支,或者您可以有一个参数来指示当前分支,如您列出的链接中所述。

#call with cap -S env="<env>" branch="<branchname>" deploy
...

# Prevents error if not parameter passed, assumes that default 'cap deploy' command
# and should deploy the master branch to the production server
set(:env, ‘production’) unless exists?(:env)
set(:branch, ‘master’) unless exists?(:branch)

if !env.nil? && env == "production"
   role :web, "production_ip_address"
else   # add more as needed 
   role :web, "development_ip_address"
end

if !branch.nil? && branch == "current"
   set :branch, $1 if `git branch` =~ /\* (\S+)\s/m
elsif !branch.nil?
   set :branch, branch
else   # add more as needed 
   set :branch, "master"
end
...

代码示例从这里大量借用

于 2009-11-17T23:36:19.230 回答
10

如果你使用capistrano-multistage,你只需要运行

cap -s branch=$MY_BRANCH deploy

或者

cap -s branch=$MY_BRANCH production deploy

无需对您的deploy.rb.

于 2012-07-09T16:06:32.793 回答
9

此命令将不再起作用:

cap deploy -s branch=your_branch

-sScapistrano v3+ 中删除了对标志的支持。
在这里您可以阅读更多相关信息:链接
它在几个答案中提到过,但目前不正确。

什么对我有用:
deploy.rb文件中添加

set :branch, ENV['BRANCH'] || :master

然后运行:

BRANCH=your_branch cap deploy

另请注意,为了成功运行此命令,您需要在 master 分支上。

于 2016-05-14T22:02:36.673 回答
3

此解决方案应适用于所有版本的 Capistrano。

def branch_name(default_branch)
  branch = ENV.fetch('BRANCH', default_branch)

  if branch == '.'
    # current branch
    `git rev-parse --abbrev-ref HEAD`.chomp
  else
    branch
  end
end

set :branch, branch_name('master')

用法:

BRANCH=. cap [staging] deploy
# => deploy current branch

BRANCH=master cap [staging] deploy
# => deploy master branch

cap [staging] deploy
# => deploy default branch
于 2014-06-25T09:35:27.830 回答
3

我使用的是3.3.5版,我有这个工作:

set :branch, 'develop'
于 2015-01-22T09:53:26.703 回答
1

一般回答:

如果您有一个设置文件,其内容从环境到环境进行了修改,您应该将该行作为“模板”(使用表示变量名称的字符串,如@BRANCH_NAME@or @ENV_NAME@)。

然后,您将拥有一个(版本化的)脚本,能够读取您的配置文件,并将“ @BRANCH_NAME@”变量替换为部署过程所需的适当值。

于 2009-10-06T09:06:35.123 回答
1

对于 capistrano 3 用户:

desc "prompt for branch or tag"
task :git_branch_or_tag do
  on roles(:all) do |host|
    run_locally do
      execute :git, 'tag'
      tag_prompt = "Enter a branch or tag name to deploy"
      ask(:branch_or_tag, tag_prompt)
      tag_branch_target = fetch(:branch_or_tag, 'master')
      set(:branch, tag_branch_target)
    end
  end
end

before 'deploy:updated',  :git_branch_or_tag
于 2014-11-03T03:15:56.067 回答
1

方法 1:为部署设置阶段特定的分支(例如测试、生产)

branch配置放在阶段文件而不是“deploy.rb”中,并为该阶段设置目标分支以进行部署。

对于具有关联分支名称test和的两阶段应用程序production,配置将如下所示,

# app_root/config/deploy/test.rb
...
set :branch, "test"
...

# app_root/config/deploy/production.rb
...
set :branch, "production"
...

此方法可以从特定阶段的分支进行部署。因此,唯一需要的额外步骤是从基本分支合并或重新构建最新代码。

方法二:直接从任意分支部署(使用标签)

另一种方法是使用标签进行部署。为了使用标签进行部署,请设置branch配置。在'deploy.rb'中如下,

set :branch, `git describe --tags $(git rev-list --tags --max-count=1)`.chomp

/.*-test$/并且,如果关联的标签模式匹配(例如),则将 CI 配置为有条件地部署到不同的阶段。

现在,可以从任何分支进行部署,

  • 首先,从任何分支创建一个标签,

    git tag -a v0.1.0-test -m "版本 0.1.0-test"

  • 而且,推

    git push origin v0.1.0-test

注意:以上方法基于 Capistrano 3。

于 2017-09-09T12:46:17.467 回答
0
git rev-parse --abbrev-ref HEAD

将返回您所在的当前分支。

我总是设置gpsh而不是git push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
于 2019-11-18T07:38:52.243 回答