使用capistrano从不同的git分支进行部署


125

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

我的问题是这样的:比方说,我创建了一个新的分支一个。部署文件将引用master分支。我对此进行了编辑,因此可以将A部署到测试环境。我完成了该功能,然后将分支A合并到master中。由于deploy.rb从文件一个是新鲜的,它被合并了,现在deploy.rb分支引用一个。是时候再次编辑了。

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

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

编辑:原来有人已经完全按照我的需要做了

今天早上,我有机会将git仓库的一个分支部署到一个登台服务器,但是却没有一个最模糊的主意。快速浏览capistrano源代码显示,我可以:branch "branch_name"在部署脚本中使用set 。我尝试了一下,它奏效了。然后,我认为我需要在所有分支机构中进行类似的更改。当然,我是一个懒汉,想知道是否有更好的方法。

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

> git branch
* drupal_authentication
fragment_caching
master

因此,我想到了,如果我只是解析输出并搜索标记为current的分支,该怎么办:

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

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


这是更新的链接:使用Capistrano部署分支
wacko 2014年

Answers:


157

这适用于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")

4
如果使用mustistage扩展,无需设置env,但这个工作对我来说只使用一个分支
汤姆·哈里森

@lulalala所述,我需要使用小写字母-s才能获取指定的分支。
Jahan 2013年

@Jani:谢谢,似乎他们改变了在新的capistrano版本中的情况,我相应地编辑了答案。
wintersolutions 2013年

我遇到的问题与@Jani完全相反:我必须使用大写字母-S,否则当使用fetch(:var_name,'default')获取参数时,该参数将不会传递给cap。
FrederikStruck-Schøning2014年

1
选项“ -s”(-set)代表“在加载配方后设置变量”。选项“ S”(-set-before)表示“在加载配方之前设置变量”。
拉蒙·卡德拉

33

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

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

但是,您不想使用ask它,否则它将提示您。相反,您应该使用setHEAD是最高的分支;所谓的“边缘”。如果你想要一个不同的分支,替换HEAD你的支行名称,如:masterstaging等等。

作为示例的总结/config/deploy/production.rb,您可以在中添加以下行:

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

...要么

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

btw 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 (^_^)的未来用户


4
git rev-parse --abbrev-ref HEAD用于找出HEAD在哪个分支上。running git rev-parse --abbrev-ref staging将(几乎)始终输出staging。您可以使用set :branch, 'staging'
MiniGod 2014年

27

对于多阶段,实际上是现在:

cap production deploy -s branch=my-branch

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


1
-s branch=foofoo食谱加载后将capistrano变量分支设置为
alvin

26

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

在deploy.rb / stage.rb中:

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

在命令行上:

cap deploy BRANCH=featurex

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


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
...

从这里大量借用的代码示例


3
我需要使用小写字母-s才能获取指定的分支
lulalala 2012年

我遇到的问题与@lulula完全相反:我必须使用大写字母-S,否则当使用fetch(:var_name,'default')获取参数时,该参数将不会传递给cap。
FrederikStruck-Schøning2014年

10

如果您使用的是capistrano-multistage,则只需运行

cap -s branch=$MY_BRANCH deploy

要么

cap -s branch=$MY_BRANCH production deploy

无需进一步修改deploy.rb


2
那应该是branch=,不是branch-
Jimothy

3
OptionParser :: AmbiguousOption:不明确的选项:-s
giorgio

8

此命令将不再起作用:

cap deploy -s branch=your_branch

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

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

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

然后运行:

BRANCH=your_branch cap deploy

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


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


1

一般回答:

如果您有一个设置文件,其内容在不同环境之间进行了修改,则应将该行作为“模板”(带有代表变量名的字符串,如@BRANCH_NAME@@ENV_NAME@)。

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



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

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"
...

此方法允许从阶段特定的分支进行部署。因此,仅需执行的其他步骤就是合并或重新分配来自基础分支的最新代码。

方法2:直接从任何分支部署(使用标记)

另一种方法是使用标签进行部署。为了使用标签进行部署,请设置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-测试

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


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`
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.