Używanie Capistrano do wdrażania z różnych gałęzi git

125

Używam Capistrano do wdrażania aplikacji RoR. Baza kodu znajduje się w repozytorium git, a rozgałęzianie jest szeroko stosowane w programowaniu. Capistrano używa deploy.rbpliku dla swoich ustawień, z których jedną jest gałąź do wdrożenia.

Mój problem jest taki: powiedzmy, że tworzę nową gałąź A z mastera . Plik wdrażania będzie odnosił się do gałęzi głównej . I edycja że tak A może zostać wdrożony do środowiska testowego. Kończę pracę nad funkcją i łączę gałąź A w master . Ponieważ deploy.rbplik A jest świeższe, to zostanie połączone i teraz deploy.rbw głównej referencje Branża A . Czas ponownie edytować.

To dużo pozornie niepotrzebnej ręcznej edycji - parametr powinien zawsze pasować do nazwy aktualnej gałęzi. Co więcej, za każdym razem łatwo zapomnieć o edycji ustawień.

Jaki byłby najlepszy sposób na zautomatyzowanie tego procesu?

Edycja: okazuje się, że ktoś już zrobił dokładnie to, czego potrzebowałem :

Dziś rano miałem okazję wdrożyć gałąź repozytorium git na serwerze pomostowym, ale nie miałem pojęcia, jak to zrobić. Szybkie przeszukanie kodu źródłowego Capistrano ujawniło, że mogę użyć zestawu :branch "branch_name"w moim skrypcie wdrażania. Spróbowałem i zadziałało. Wtedy pomyślałem, że będę musiał dokonać podobnej zmiany we wszystkich moich oddziałach. Oczywiście jestem leniwym draniem i zastanawiałem się, czy nie ma lepszego sposobu.

Jeśli nie jesteś zaznajomiony z git, wynikiem polecenia git branch jest lista gałęzi z gwiazdką oznaczającą to, które jest aktualnie pobrane na twoim lokalnym komputerze. Na przykład:

> git branch
* drupal_authentication
fragment_caching
master

Pomyślałem więc, co jeśli po prostu przeanalizuję dane wyjściowe i poszukałem gałęzi oznaczonej jako bieżąca:

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

Teraz mogę wdrożyć bieżącą gałąź na moim komputerze lokalnym za pomocą pojedynczego, współużytkowanego skryptu wdrażania.

Toms Mikoss
źródło
To jest zaktualizowany link: Wdrażanie oddziałów z Capistrano
wacko

Odpowiedzi:

157

Działa to z Capistrano> = 3.1:

dodaj tę linię do config/deploy.rb:

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

a następnie zadzwoń do capistrano z:

cap production deploy BRANCH=master

To rozwiązanie działa z Capistrano <3.1:

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

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")
zimy
źródło
4
W przypadku korzystania mustistage rozszerzenie, bez potrzeby ustawiania env, ale ten pracował dla mnie po prostu za pomocą oddziału
Tom Harrison
zgodnie z @lulalala , muszę użyć małych liter -s, aby pobrać określoną gałąź.
Jahan
@Jani: Dzięki, wygląda na to, że zmienili, że w nowszych wydaniach Capistrano odpowiednio zredagowałem odpowiedź.
wintersolutions
Miałem dokładnie odwrotny problem niż @Jani: musiałem użyć wielkiej litery -S, orelse argument nie przeszedł do cap, gdy użyłem funkcji fetch (: var_name, 'default'), aby go uzyskać.
Frederik Struck-Schøning
1
opcja „-s” (--set) oznacza „Ustaw zmienną po załadowaniu receptur”. a opcja „S” (--set-before) oznacza „Ustaw zmienną przed załadowaniem receptur”.
Ramon Caldeira
33

Używając Capistrano 3.1.0+, żadne z nich już nie działało. Zamiast tego, zgodnie z ich skomentowanymi instrukcjami:

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

Ale nie chcesz używać asklub wyświetli się monit. Zamiast tego powinieneś użyć set. HEADjest najwyższą gałęzią; „krawędź”, jak to się nazywa. Jeśli chcesz inny oddział, należy wymienić HEADz nazwy oddziału, np master, stagingitp

Aby zakończyć przykładami, w programie /config/deploy/production.rbmożesz dołączyć następujący wiersz:

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

...lub

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

btw, HEADjest ustawieniem domyślnym, więc nie ma potrzeby określania tego w pliku. Może być lepiej używany w /config/deploy/edge.rb.

W /config/deploy/staging.rbmożesz dołączyć ten wiersz:

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

...lub

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

Masz pomysł!

Mam nadzieję, że te przykłady pomogą przyszłym użytkownikom capistrano (^_^)

Eric Wanchic
źródło
4
git rev-parse --abbrev-ref HEADsłuży do sprawdzenia, która gałąź jest włączona. uruchomiony git rev-parse --abbrev-ref stagingbędzie (prawie) zawsze staging. Możesz po prostu użyć set :branch, 'staging'.
MiniGod
27

Dzięki wielostopniowości jest to teraz:

cap production deploy -s branch=my-branch

Składnia poprzedniego postu nie działa w moim środowisku

David Hersey
źródło
1
-s branch=fooustawia gałąź zmiennej capistrano na foopo załadowaniu receptur
alvin
26

Mogę potwierdzić, że poniższe informacje nadal działają w Cap 3.11.0 13/10/18, a także Cap 2:

W pliku deploy.rb / stage.rb:

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

W wierszu poleceń:

cap deploy BRANCH=featurex

Daje to domyślną gałąź (która może być inna dla różnych środowisk) i możliwość zmiany gałęzi, kiedy chcesz.

Paul Odeon
źródło
15

Alternatywnie możesz utworzyć strukturę z wiersza poleceń, w której masz domyślną gałąź i środowisko, a także możesz przekazać parametry do wywołania cap, które może obejmować środowisko i gałąź do użycia. Może to być gałąź, która jest jawnie przekazana lub możesz mieć parametr, który wskazywałby bieżącą gałąź zgodnie z opisem w podanym łączu.

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

Przykład kodu zapożyczony z tego miejsca

naven87
źródło
3
Muszę używać małych liter -s, aby
pobrał
Miałem dokładnie odwrotny problem niż @lulula: musiałem użyć wielkiej litery -S, orelse, argument nie przeszedł do cap, gdy użyłem funkcji fetch (: var_name, 'default'), aby go uzyskać.
Frederik Struck-Schøning
10

Jeśli używasz capistrano-multistage , wystarczy biec

cap -s branch=$MY_BRANCH deploy

lub

cap -s branch=$MY_BRANCH production deploy

bez dalszej edycji deploy.rb.

asymetryczny
źródło
2
Tak powinno być branch=, nie branch-.
Jimothy
3
OptionParser :: AmbiguousOption: ambiguous option: -s
giorgio
8

To polecenie już nie będzie działać:

cap deploy -s branch=your_branch

Wsparcie dla -sSflag zostało usunięte w Capistrano v3 +.
Tutaj możesz przeczytać więcej na ten temat: link
Wspomniano o tym w kilku odpowiedziach, ale obecnie nie jest poprawne.

Co działa u mnie:
w deploy.rbpliku dodaj

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

następnie uruchomić:

BRANCH=your_branch cap deploy

Zwróć również uwagę, że aby pomyślnie uruchomić to polecenie, musisz być w gałęzi master.

SakyHank
źródło
3

To rozwiązanie powinno działać ze wszystkimi wersjami 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')

Stosowanie:

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

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

cap [staging] deploy
# => deploy default branch
Pablo Cantero
źródło
2

Używam wersji 3.3.5 i mam to działające:

set :branch, 'develop'
David Rosa
źródło
1

Ogólna odpowiedź:

Jeśli masz plik ustawień z zawartością modyfikowaną ze środowiska do środowiska, powinieneś utworzyć ten wiersz jako „szablon” (z ciągiem znaków reprezentującym nazwę zmiennej, np. @BRANCH_NAME@Lub@ENV_NAME@ ).

Wtedy miałbyś (wersjonowany) skrypt, który byłby w stanie odczytać plik konfiguracyjny i zastąpić @BRANCH_NAME@zmienną " " odpowiednią wartością wymaganą przez proces wdrażania.

VonC
źródło
1

Dla użytkowników 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
lfender6445
źródło
1

Metoda 1: Ustaw gałąź specyficzną dla etapu (np. Test, produkcja) do wdrożenia

Położyć branch konfigurację w plikach etapu zamiast w pliku „deploy.rb” i ustaw gałąź docelową dla tego etapu, z której ma zostać wdrożona.

W przypadku aplikacji dwuetapowej z powiązaną nazwą oddziału testi productionkonfiguracja będzie wyglądać następująco:

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

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

Ta metoda umożliwia wdrożenie z gałęzi specyficznych dla etapu. Tak więc jedynym dodatkowym krokiem, który będzie wymagany, jest scalenie lub zmiana bazy najnowszego kodu z gałęzi podstawowej.

Metoda 2: Wdróż bezpośrednio z dowolnej gałęzi (za pomocą tagu)

Innym podejściem jest wdrożenie przy użyciu tagów. Aby wdrożyć za pomocą tagu, ustaw branchplik config. w „deploy.rb” w następujący sposób,

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

Skonfiguruj CI tak, aby warunkowo wdrażał na różnych etapach, jeśli powiązany wzorzec tagu pasuje (np /.*-test$/.).

Teraz wdrożenie można wykonać z dowolnej gałęzi,

  • Najpierw utwórz tag z dowolnej gałęzi,

    git tag -a v0.1.0-test -m "Wersja 0.1.0-test"

  • I pchaj

    git push origin v0.1.0-test

Uwaga: powyższe metody są oparte na Capistrano 3.

Shakil
źródło
0
git rev-parse --abbrev-ref HEAD

zwróci bieżącą gałąź, w której się znajdujesz.

Zawsze ustawiam gpshzamiastgit push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
TorvaldsDB
źródło