Verwenden von Capistrano zum Bereitstellen aus verschiedenen Git-Zweigen

125

Ich verwende capistrano, um eine RoR-Anwendung bereitzustellen. Die Codebasis befindet sich in einem Git-Repository, und Verzweigungen werden in der Entwicklung häufig verwendet. Capistrano verwendet deploy.rbDateien für seine Einstellungen. Eine davon ist der Zweig, von dem aus bereitgestellt werden soll.

Mein Problem ist folgendes: Nehmen wir an, ich erstelle einen neuen Zweig A vom Master . Die deploy Datei Referenz Master - Zweig. Ich bearbeite das, damit A für die Testumgebung bereitgestellt werden kann. Ich beende die Arbeit an der Funktion und füge Zweig A in Master zusammen . Da die deploy.rbDatei von A frischer ist, wird es fusioniert und die jetzt deploy.rbin Master - Zweig Referenzen A . Zeit zum erneuten Bearbeiten.

Das ist eine Menge scheinbar unnötiger manueller Bearbeitung - der Parameter sollte immer mit dem aktuellen Zweignamen übereinstimmen. Darüber hinaus kann man leicht vergessen, die Einstellungen jedes Mal zu bearbeiten.

Was wäre der beste Weg, um diesen Prozess zu automatisieren?

Bearbeiten: Es stellte sich heraus, dass jemand bereits genau das getan hatte, was ich brauchte :

Heute Morgen hatte ich Gelegenheit, einen Zweig eines Git-Repositorys auf einem Staging-Server bereitzustellen, hatte aber nicht die geringste Ahnung, wie. Eine schnelle Suche im Capistrano-Quellcode ergab, dass ich set :branch "branch_name"in meinem Bereitstellungsskript verwenden konnte. Ich habe es versucht und es hat funktioniert. Ich dachte dann, ich müsste eine ähnliche Änderung in allen meinen Filialen vornehmen. Natürlich bin ich ein Faulpelz und habe mich gefragt, ob es keinen besseren Weg gibt.

Wenn Sie mit git nicht vertraut sind, ist die Ausgabe des Befehls git branch eine Liste von Zweigen mit einem Sternchen, das den aktuell auf Ihrem lokalen Computer ausgecheckten markiert. Beispielsweise:

> git branch
* drupal_authentication
fragment_caching
master

Also dachte ich mir, was wäre, wenn ich nur die Ausgabe analysieren und nach dem als aktuell markierten Zweig suchen würde:

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

Jetzt kann ich jeden auf meinem lokalen Computer aktuellen Zweig über ein einziges freigegebenes Bereitstellungsskript bereitstellen.

Toms Mikoss
quelle
Dies ist der aktualisierte Link: Bereitstellen von Zweigen mit Capistrano
Wacko

Antworten:

157

Dies funktioniert mit Capistrano> = 3.1:

Fügen Sie diese Zeile hinzu zu config/deploy.rb:

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

und dann capistrano anrufen mit:

cap production deploy BRANCH=master

Diese Lösung funktioniert mit Capistrano <3.1:

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

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")
Winterlösungen
quelle
4
Wenn Sie die Mustistage-Erweiterung verwenden, müssen Sie keine Einstellungen vornehmen env, aber dies funktionierte für mich nur mit einem Zweig
Tom Harrison
Wie von @lulalala angegeben, muss ich Kleinbuchstaben -s verwenden, damit der angegebene Zweig abgerufen wird .
Jahan
@Jani: Danke, anscheinend haben sie geändert, dass ich in neueren Capistrano-Versionen meine Antwort entsprechend bearbeitet habe.
Wintersolutions
Ich hatte genau das gegenteilige Problem als @Jani: Ich musste -S in Großbuchstaben schreiben, sonst würde das Argument nicht an cap weitergeleitet, wenn ich fetch (: var_name, 'default') verwende, um es zu erhalten.
Frederik Struck-Schøning
1
Option '-s' (--set) steht für 'Setze eine Variable, nachdem die Rezepte geladen wurden.' und die Option 'S' (--set-before) steht für 'Setze eine Variable, bevor die Rezepte geladen werden.'
Ramon Caldeira
33

Mit Capistrano 3.1.0+ funktionierte nichts mehr für mich. Stattdessen gemäß ihren kommentierten Anweisungen:

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

Aber Sie möchten nicht verwenden, askoder es wird Sie dazu auffordern . Stattdessen sollten Sie verwenden set. HEADist der oberste Zweig; 'Rand' wie es heißt. Wenn Sie einen anderen Zweig wollen, ersetzen Sie HEADmit Ihrem Zweignamen, zum Beispiel: master, stagingusw.

Um mit Beispielen abzuschließen, /config/deploy/production.rbkönnen Sie in diese Zeile einfügen:

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

...oder

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

Übrigens HEADist dies die Standardeinstellung, sodass Sie dies nicht wirklich in der Datei angeben müssen. Könnte besser in a verwendet werden /config/deploy/edge.rb.

In /config/deploy/staging.rbkönnen Sie diese Zeile einfügen:

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

...oder

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

Du hast die Idee!

Ich hoffe, diese Beispiele helfen zukünftigen Benutzern von capistrano (^_^)

Eric Wanchic
quelle
4
git rev-parse --abbrev-ref HEADwird verwendet, um herauszufinden, welcher Zweig HEAD aktiviert ist. Laufen git rev-parse --abbrev-ref stagingwird (fast) immer ausgegeben staging. Sie können einfach verwenden set :branch, 'staging'.
MiniGod
27

Mit mehrstufigen ist es eigentlich jetzt:

cap production deploy -s branch=my-branch

Die vorherige Post-Syntax funktioniert in meiner Umgebung nicht

David Hersey
quelle
1
-s branch=foosetzt den capistrano variablen Zweig auf, foonachdem die Rezepte geladen wurden
alvin
26

Ich kann bestätigen, dass das Folgende in Cap 3.11.0 13/10/18 sowie in Cap 2 weiterhin funktioniert:

In deploy.rb / stage.rb:

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

In der Befehlszeile:

cap deploy BRANCH=featurex

Dies gibt Ihnen einen Standardzweig (der für verschiedene Umgebungen unterschiedlich sein kann) und die Möglichkeit, Zweige zu ändern, wenn Sie möchten.

Paul Odeon
quelle
15

Alternativ können Sie es über die Befehlszeile strukturieren, in der Sie einen Standardzweig und eine Standardumgebung haben, und Sie können Parameter an den Cap-Aufruf übergeben, die die Umgebung und den zu verwendenden Zweig enthalten können. Dies kann ein Zweig sein, der explizit übergeben wird, oder Sie können einen Parameter haben, der den aktuellen Zweig angibt, wie in dem von Ihnen aufgelisteten Link beschrieben.

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

Codebeispiel stark von hier entlehnt

naven87
quelle
3
Ich muss Kleinbuchstaben verwenden -s, damit es den angegebenen Zweig
abruft
Ich hatte genau das gegenteilige Problem als @lulula: Ich musste -S in Großbuchstaben schreiben, sonst würde das Argument nicht an cap weitergeleitet, wenn ich fetch (: var_name, 'default') verwende, um es zu erhalten.
Frederik Struck-Schøning
10

Wenn Sie Capistrano-Multistage verwenden , müssen Sie nur ausführen

cap -s branch=$MY_BRANCH deploy

oder

cap -s branch=$MY_BRANCH production deploy

ohne weitere bearbeitung an deinem deploy.rb.

asymmetrisch
quelle
2
Das sollte branch=nicht sein branch-.
Jimothy
3
OptionParser :: AmbiguousOption: mehrdeutige Option: -s
giorgio
8

Dieser Befehl funktioniert nicht mehr:

cap deploy -s branch=your_branch

Die Unterstützung für -sSFlags wurde in capistrano v3 + entfernt.
Hier können Sie mehr darüber lesen: Link
Es wurde in einigen Antworten erwähnt, ist aber derzeit nicht korrekt.

Was bei mir funktioniert:
in deploy.rbDatei hinzufügen

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

dann renne:

BRANCH=your_branch cap deploy

Beachten Sie außerdem, dass Sie sich im Hauptzweig befinden müssen, um diesen Befehl erfolgreich ausführen zu können.

SakyHank
quelle
3

Diese Lösung sollte mit allen Versionen von Capistrano funktionieren.

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')

Verwendung:

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

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

cap [staging] deploy
# => deploy default branch
Pablo Cantero
quelle
2

Ich benutze Version 3.3.5 und ich habe diese Arbeit:

set :branch, 'develop'
David Rosa
quelle
1

Allgemeine Antwort:

Wenn Sie eine Einstellungsdatei mit einem von Umgebung zu Umgebung geänderten Inhalt haben, sollten Sie diese Zeile als "Vorlage" erstellen (mit einer Zeichenfolge, die den Variablennamen wie @BRANCH_NAME@oder darstellt @ENV_NAME@).

Dann hätten Sie ein (versioniertes) Skript, das Ihre Konfigurationsdatei lesen und die @BRANCH_NAME@Variable " " durch den entsprechenden Wert ersetzen kann, der für Ihren Bereitstellungsprozess benötigt wird.

VonC
quelle
1

Für Benutzer von 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
quelle
1

Methode 1: Legen Sie den stufenspezifischen Zweig (z. B. Test, Produktion) für die Bereitstellung fest

branchFügen Sie die Konfiguration in Stufendateien anstelle von 'deploy.rb' ein und legen Sie den Zielzweig für diese Stufe fest, von dem aus bereitgestellt werden soll.

Für eine zweistufige App mit dem zugehörigen Filialnamen testund productionsieht die Konfiguration folgendermaßen aus:

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

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

Diese Methode ermöglicht die Bereitstellung von stufenspezifischen Zweigen. Der einzige zusätzliche Schritt, der erforderlich ist, besteht darin, den neuesten Code aus dem Basiszweig zusammenzuführen oder neu zu starten.

Methode 2: Direkt von jedem Zweig aus bereitstellen (mithilfe des Tags)

Ein anderer Ansatz ist die Bereitstellung mithilfe von Tags. branchLegen Sie die Konfiguration fest , um die Bereitstellung mithilfe des Tags durchzuführen . in 'deploy.rb' wie folgt:

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

Konfigurieren Sie das CI so, dass es bedingt in verschiedenen Phasen bereitgestellt wird, wenn das zugehörige Tag-Muster übereinstimmt (z /.*-test$/. B. ).

Jetzt kann eine Bereitstellung von jedem Zweig aus erfolgen.

  • Erstellen Sie zunächst ein Tag aus einem beliebigen Zweig.

    Git-Tag -a v0.1.0-Test -m "Version 0.1.0-Test"

  • Und drücken

    Git Push Origin v0.1.0-Test

Hinweis: Die oben genannten Methoden basieren auf Capistrano 3.

Shakil
quelle
0
git rev-parse --abbrev-ref HEAD

gibt den aktuellen Zweig zurück, in dem Sie sich genau befinden.

Ich setze immer das gpshstattgit push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
TorvaldsDB
quelle