Sử dụng capistrano để triển khai từ các nhánh git khác nhau


125

Tôi đang sử dụng capistrano để triển khai ứng dụng RoR. Codebase nằm trong kho git và phân nhánh được sử dụng rộng rãi trong phát triển. Capistrano sử dụng deploy.rbtệp cho các cài đặt của nó, một trong số chúng là nhánh để triển khai.

Vấn đề của tôi là thế này: giả sử tôi tạo một nhánh A mới từ chủ . Các tập tin triển khai sẽ tham chiếu chi nhánh tổng thể . Tôi chỉnh sửa nó, vì vậy A có thể được triển khai để kiểm tra môi trường. Tôi hoàn thành công việc trên tính năng và hợp nhất nhánh A thành chủ . Kể từ khi deploy.rbtập tin từ Một là tươi, nó được sáp nhập vào và bây giờ deploy.rbtrong tổng thể tham khảo chi nhánh Một . Thời gian để chỉnh sửa một lần nữa.

Đó là rất nhiều chỉnh sửa thủ công dường như không cần thiết - tham số phải luôn khớp với tên chi nhánh hiện tại. Trên hết, thật dễ dàng để quên chỉnh sửa các cài đặt mỗi lần.

Điều gì sẽ là cách tốt nhất để tự động hóa quá trình này?

Chỉnh sửa: Hóa ra ai đó đã thực hiện chính xác những gì tôi cần :

Sáng nay tôi có dịp triển khai một nhánh của kho git đến một máy chủ dàn dựng nhưng không có ý tưởng rõ ràng nhất. Một tìm kiếm nhanh thông qua mã nguồn capistrano cho thấy tôi có thể sử dụng được thiết lập :branch "branch_name"trong tập lệnh triển khai của mình. Tôi đã thử và nó đã hoạt động. Sau đó, tôi nghĩ rằng tôi sẽ cần phải thực hiện một thay đổi tương tự trên tất cả các chi nhánh của tôi. Tất nhiên, tôi là một người lười biếng và tự hỏi liệu có cách nào tốt hơn không.

Nếu bạn không quen với git, đầu ra của lệnh git nhánh là một danh sách các nhánh có dấu hoa thị đánh dấu cái hiện đang được kiểm tra trên máy cục bộ của bạn. Ví dụ:

> git branch
* drupal_authentication
fragment_caching
master

Vì vậy, tôi đã tìm ra, điều gì sẽ xảy ra nếu tôi chỉ phân tích cú pháp đầu ra và tìm kiếm nhánh được đánh dấu là hiện tại:

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

Bây giờ tôi có thể triển khai bất kỳ nhánh nào hiện có trên máy cục bộ của mình từ một tập lệnh triển khai, chia sẻ, duy nhất.


Đây là liên kết được cập nhật: Triển khai các chi nhánh với Capistrano
wacko

Câu trả lời:


157

Điều này hoạt động với Capistrano> = 3.1:

thêm dòng này vào config/deploy.rb:

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

và sau đó gọi capistrano với:

cap production deploy BRANCH=master

Giải pháp này hoạt động với Capistrano <3.1:

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

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")

4
Nếu sử dụng tiện ích mở rộng mustistage, không cần thiết lập env, nhưng điều này làm việc với tôi chỉ bằng cách sử dụng một chi nhánh
Tom Harrison

như đã nêu bởi @lulalala Tôi cần sử dụng chữ thường -s để nó lấy chi nhánh được chỉ định.
Jahan

@Jani: Cảm ơn, dường như họ đã thay đổi rằng trong các bản phát hành capistrano mới hơn, tôi đã chỉnh sửa câu trả lời của mình cho phù hợp.
mùa đông

Tôi đã có một vấn đề hoàn toàn ngược lại so với @Jani: Tôi đã phải viết hoa -S, loại bỏ đối số sẽ không chuyển qua giới hạn, khi sử dụng fetch (: var_name, 'default') để có được nó.
Frederik Struck-Schøning

1
tùy chọn '-s' (--set) là viết tắt của 'Đặt biến sau khi công thức nấu ăn được tải.' và tùy chọn 'S' (--set-before) là viết tắt của 'Đặt một biến trước khi các công thức nấu ăn được tải.'
Ramon Caldeira

33

Sử dụng Capistrano 3.1.0+, không ai trong số này hoạt động với tôi nữa. Thay vào đó, theo hướng dẫn nhận xét của họ:

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

Nhưng, bạn không muốn sử dụng askhoặc nó sẽ nhắc bạn. Thay vào đó bạn nên sử dụng set. HEADlà chi nhánh hàng đầu nhất; 'cạnh' như nó được gọi. Nếu bạn muốn có một chi nhánh khác nhau, thay thế HEADvới tên chi nhánh của bạn, ví dụ như: master, stagingvv

Để kết luận với các ví dụ, trong /config/deploy/production.rb, bạn có thể bao gồm dòng này:

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

...hoặc là

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

btw, HEADlà cài đặt mặc định, vì vậy không cần phải thực sự nêu nó trong tệp. Có thể được sử dụng tốt hơn trong một /config/deploy/edge.rb.

Trong /config/deploy/staging.rb, bạn có thể bao gồm dòng này:

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

...hoặc là

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

Bạn có được ý tưởng!

Tôi hy vọng những ví dụ này sẽ giúp người dùng tương lai của capistrano (^ ^ ^)


4
git rev-parse --abbrev-ref HEADđược sử dụng để tìm ra các chi nhánh đang ở trên. chạy git rev-parse --abbrev-ref stagingsẽ (gần như) luôn luôn đầu ra staging. Bạn chỉ có thể sử dụng set :branch, 'staging'.
MiniGod

27

Với đa tầng, giờ đây nó thực sự:

cap production deploy -s branch=my-branch

Cú pháp bài viết trước không hoạt động trong môi trường của tôi


1
-s branch=foođặt nhánh biến capistrano thành foosau khi công thức nấu ăn được tải
alvin

26

Tôi có thể xác nhận rằng bên dưới vẫn hoạt động trong Cap 3.11.0 13/10/18 cũng như Cap 2:

Trong triển khai.rb / giai đoạn.rb:

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

Trên dòng lệnh:

cap deploy BRANCH=featurex

Điều này cung cấp cho bạn một nhánh mặc định (có thể khác nhau cho các môi trường khác nhau) và khả năng thay đổi các nhánh khi bạn muốn.


15

Ngoài ra, bạn có thể cấu trúc nó từ dòng lệnh nơi bạn có một nhánh và môi trường mặc định và bạn cũng có thể truyền tham số cho lệnh gọi giới hạn có thể bao gồm môi trường và nhánh để sử dụng. Đây có thể là một nhánh được thông qua rõ ràng hoặc bạn có thể có một tham số cho biết nhánh hiện tại như được mô tả trong liên kết bạn đã liệt kê.

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

Mã ví dụ mượn rất nhiều từ đây


3
Tôi cần sử dụng chữ thường -sđể nó lấy chi nhánh được chỉ định
lulalala

Tôi đã có một vấn đề hoàn toàn ngược lại so với @lulula: Tôi đã phải viết hoa -S, loại bỏ đối số sẽ không chuyển qua giới hạn, khi sử dụng fetch (: var_name, 'default') để có được nó.
Frederik Struck-Schøning

10

Nếu bạn đang sử dụng đa tầng capistrano , bạn chỉ cần chạy

cap -s branch=$MY_BRANCH deploy

hoặc là

cap -s branch=$MY_BRANCH production deploy

mà không cần chỉnh sửa thêm deploy.rb.


2
Điều đó nên branch=, không phải branch-.
Jimothy

3
OptionParser :: AmbiguptOption: tùy chọn mơ hồ: -s
giorgio 14/1/2015

8

Lệnh này sẽ không hoạt động nữa:

cap deploy -s branch=your_branch

Hỗ trợ cho các -sScờ đã được gỡ bỏ trong capistrano v3 +.
Ở đây bạn có thể đọc thêm về nó: link
Nó đã được đề cập trong vài câu trả lời, nhưng hiện tại không chính xác.

Những gì làm việc cho tôi:
trong deploy.rbtập tin thêm

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

sau đó chạy:

BRANCH=your_branch cap deploy

Ngoài ra, vui lòng lưu ý rằng, để chạy thành công lệnh này, bạn cần phải ở nhánh chính.


3

Giải pháp này sẽ hoạt động với tất cả các phiên bản của 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')

Sử dụng:

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

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

cap [staging] deploy
# => deploy default branch

2

Tôi đang sử dụng phiên bản 3.3.5 và tôi đã làm việc này:

set :branch, 'develop'

1

Câu trả lời chung:

Nếu bạn có tệp cài đặt có nội dung được sửa đổi từ môi trường này sang môi trường khác, bạn nên đặt dòng đó dưới dạng "mẫu" (với một chuỗi đại diện cho tên biến như @BRANCH_NAME@hoặc @ENV_NAME@).

Sau đó, bạn sẽ có một tập lệnh (được phiên bản) có thể đọc tệp cấu hình của bạn và thay thế @BRANCH_NAME@biến "" bằng giá trị phù hợp cần thiết cho quá trình triển khai của bạn.



1

Đối với người dùng 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

Phương pháp 1: Đặt nhánh cụ thể của giai đoạn (ví dụ: thử nghiệm, sản xuất) để triển khai

Đặt branchcấu hình trong các tệp giai đoạn thay vì 'triển khai.rb' và đặt nhánh đích cho giai đoạn đó để triển khai từ đó.

Đối với ứng dụng hai giai đoạn có tên chi nhánh được liên kết testproduction, cấu hình sẽ trông như thế này,

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

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

Phương pháp này cho phép triển khai từ các nhánh cụ thể của giai đoạn. Vì vậy, chỉ có bước bổ sung sẽ được yêu cầu là hợp nhất hoặc khởi động lại mã mới nhất từ ​​nhánh cơ sở.

Phương pháp 2: Triển khai trực tiếp từ bất kỳ chi nhánh nào (sử dụng thẻ)

Một cách tiếp cận khác là triển khai bằng thẻ. Để triển khai bằng thẻ, hãy đặt branchcấu hình. trong 'triển khai.rb' như sau,

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

Và, định cấu hình CI để triển khai có điều kiện sang các giai đoạn khác nhau nếu mẫu thẻ được liên kết khớp (ví dụ /.*-test$/).

Bây giờ, một triển khai có thể được thực hiện từ bất kỳ chi nhánh nào,

  • Đầu tiên, tạo một thẻ từ bất kỳ chi nhánh,

    thẻ git -a v0.1.0-test -m "Phiên bản 0.1.0-test"

  • Và, đẩy

    git đẩy nguồn gốc v0.1.0-test

Lưu ý: Các phương pháp trên được dựa trên Capistrano 3.


0
git rev-parse --abbrev-ref HEAD

sẽ trả về chi nhánh hiện tại mà bạn đang ở chính xác.

Tôi luôn luôn đặt gpshthay vìgit push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.