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

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

我的问题是: 假设我从 师父创建了一个新的分支 A。部署文件将引用 师父分支。我编辑它,这样就可以将 A部署到测试环境中。我完成了该特性的工作,并将分支 A合并到 师父中。因为来自 Adeploy.rb文件比较新鲜,所以它被合并进来,现在 师父分支中的 deploy.rb引用 A。是时候再次编辑了。

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

自动化这个过程的最佳方式是什么?

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

今天早上,我有机会部署一个 git 存储库的分支 一个登台服务器,但不知道如何。快速搜索 通过 Capistrano 的源代码显示,我可以使用 set 在我的部署脚本中使用 :branch "branch_name"。我试过了,它起作用了。 然后我想我需要在我所有的 当然,我是一个懒惰的讨厌鬼,我想知道是否有一个 更好的方式。

如果您不熟悉 git,那么可以使用 git 分支命令的输出 是一个分行列表,用星号标记当前的分行 在本地机器上检出。例如:

> git branch
* drupal_authentication
fragment_caching
master

所以,我想,如果我只解析输出并搜索 标记为当前的分行:

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

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

81095 次浏览

一般答案:

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

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

或者,您可以从命令行构造它,在该命令行中您有一个默认的分支和环境,并且您还能够将参数传递给 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
...

代码示例大量借用了这里的内容

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

如果使用 卡皮斯特拉诺-多级,只需要运行

cap -s branch=$MY_BRANCH deploy

或者

cap -s branch=$MY_BRANCH production deploy

没有任何进一步的编辑到您的 deploy.rb

有了多阶段,实际上就是现在:

cap production deploy -s branch=my-branch

前面的 post 语法在我的环境中不起作用

我可以确认以下条文仍然适用于第3.11.013.10/18章及第2章:

在 loy.rb/stage. rb 中:

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

在命令行上:

cap deploy BRANCH=featurex

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

使用 Capistrano 3.1.0 + ,这些都不再适用于我,而是根据他们的注释说明:

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

但是,您不想使用 ask,否则它会提示您。相反,您应该使用 setHEAD是最顶端的分支; 它被称为“ edge”。如果您想要一个不同的分支,将 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 }

顺便说一句,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 (^ _ ^)的未来用户

这个解决方案应该适用于 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

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

我使用的版本 3.3.5和我有这个工作:

set :branch, 'develop'

这个命令不再起作用了:

cap deploy -s branch=your_branch

Capistrano v3 + 中删除了对 -sS标志的支持。
在这里你可以了解更多: 链接
有几个答案提到了这一点,但目前还不正确。

对我有效的方法:
deploy.rb文件中添加

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

然后跑:

BRANCH=your_branch cap deploy

还请注意,为了成功地运行这个命令,您需要在主分支上。

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

branch配置放在 stage 文件中,而不是放在“ loy.rb”中,并设置要从该 stage 部署的目标分支。

对于具有相关分支名称 testproduction的两阶段应用程序,配置如下所示,

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


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

此方法允许从阶段特定的分支进行部署。因此,唯一需要的附加步骤是从基本分支合并或重新设置最新代码的基础。

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

另一种方法是使用标记进行部署。要使用标记进行部署,请设置 branch配置。在“ loy.rb”中,如下所示,

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

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

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

  • 首先,从任意分支创建一个标记,

    Git 标签-a v0.1.0-test-m“ Version 0.1.0-test”

  • 用力

    Git 推送源 v0.1.0-test

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

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`