Utilizzo di capistrano per distribuire da diversi rami git


125

Sto usando capistrano per distribuire un'applicazione RoR. Il codebase è in un repository git e la ramificazione è ampiamente usata nello sviluppo. Capistrano utilizza il deploy.rbfile per le sue impostazioni, uno dei quali è il ramo da cui eseguire la distribuzione.

Il mio problema è questo: diciamo che creo un nuovo ramo A dal master . Il file di distribuzione farà riferimento al ramo principale . Lo modifico, quindi A può essere distribuito per testare l'ambiente. Finisco di lavorare sulla funzione e unisco il ramo A in master . Dal momento che il deploy.rbfile da A è più fresco, si ottiene fuse e ora il deploy.rbnel maestro riferimenti ramo A . È ora di modificare nuovamente.

Sono molte modifiche manuali apparentemente non necessarie: il parametro deve sempre corrispondere al nome del ramo corrente. Inoltre, è facile dimenticare di modificare le impostazioni ogni volta.

Quale sarebbe il modo migliore per automatizzare questo processo?

Modifica: risulta che qualcuno ha già fatto esattamente ciò di cui avevo bisogno :

Questa mattina ho avuto occasione di distribuire un ramo di un repository git su un server di gestione temporanea, ma non avevo la più pallida idea di come. Una rapida ricerca nel codice sorgente di Capistrano ha rivelato che avrei potuto usare set :branch "branch_name"nel mio script deploy. L'ho provato e ha funzionato. Ho quindi pensato che avrei dovuto fare un cambiamento simile in tutti i miei rami. Certo, sono una zolla pigra e mi chiedevo se non ci fosse un modo migliore.

Se non hai familiarità con git, l'output del comando git branch è un elenco di rami con un asterisco che contrassegna quello attualmente estratto sul tuo computer locale. Per esempio:

> git branch
* drupal_authentication
fragment_caching
master

Quindi, ho pensato, e se avessi semplicemente analizzato l'output e cercato il ramo contrassegnato come corrente:

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

Ora sono in grado di distribuire qualsiasi ramo è attivo sul mio computer locale da un singolo script di distribuzione condiviso.


Questo è il link aggiornato: Distribuire filiali con Capistrano
wacko,

Risposte:


157

Funziona con Capistrano> = 3.1:

aggiungi questa linea a config/deploy.rb:

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

e poi chiama capistrano con:

cap production deploy BRANCH=master

Questa soluzione funziona con Capistrano <3.1:

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

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

4
Se si utilizza l'estensione del mustistage, non è necessario impostare env, ma questo ha funzionato per me solo usando un ramo
Tom Harrison,

come affermato da @lulalala ho bisogno di usare lettere minuscole per poter recuperare il ramo specificato.
Jahan,

@Jani: Grazie, sembra che abbiano cambiato che nelle versioni più recenti di Capistrano, ho modificato la mia risposta di conseguenza.
Wintersolutions

Ho avuto l'esatto problema opposto rispetto a @Jani: ho dovuto scrivere in maiuscolo -S, altrimenti l'argomento non sarebbe passato a cap, quando si utilizzava fetch (: nome_var, 'default') per ottenerlo.
Frederik Struck-Schøning,

1
l'opzione '-s' (--set) sta per 'Imposta una variabile dopo il caricamento delle ricette'. e l'opzione 'S' (--set-before) sta per 'Imposta una variabile prima che le ricette vengano caricate.'
Ramon Caldeira,

33

Usando Capistrano 3.1.0+, nessuno di questi funzionava più per me. Invece, secondo le loro istruzioni commentate:

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

Ma non vuoi usarlo asko ti verrà richiesto. Invece dovresti usare set. HEADè il ramo più alto; 'bordo' come viene chiamato. Se si desidera un ramo diverso, sostituire HEADcon il tuo nome ramo, ad esempio: master,staging , etc.

Per concludere con esempi, in /config/deploy/production.rb, potresti includere questa riga:

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

...o

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

tra l'altro, HEADè l'impostazione predefinita, quindi non è necessario dichiararlo nel file. Potrebbe essere usato meglio in a/config/deploy/edge.rb .

In /config/deploy/staging.rb, potresti includere questa riga:

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

...o

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

Ti viene l'idea!

Spero che questi esempi possano aiutare i futuri utenti di capistrano (^_^)


4
git rev-parse --abbrev-ref HEADviene utilizzato per scoprire su quale ramo si trova HEAD. l'esecuzione git rev-parse --abbrev-ref stagingsarà (quasi) sempre in uscita staging. Puoi semplicemente usare set :branch, 'staging'.
MiniGod,

27

Con il multistadio, in realtà è ora:

cap production deploy -s branch=my-branch

La sintassi post precedente non funziona nel mio ambiente


1
-s branch=fooimposta il ramo variabile capistrano su foodopo aver caricato le ricette
alvin,

26

Posso confermare che quanto segue funziona ancora nel Cap 3.11.0 13/10/18 e nel Cap 2:

In deploy.rb / stage.rb:

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

Sulla riga di comando:

cap deploy BRANCH=featurex

Questo ti dà un ramo predefinito (che potrebbe essere diverso per ambienti diversi) e la possibilità di cambiare ramo quando vuoi.


15

In alternativa, è possibile strutturarlo dalla riga di comando in cui si dispone di un ramo e di un ambiente predefiniti e si è anche in grado di passare parametri alla chiamata cap che potrebbero includere l'ambiente e il ramo da utilizzare. Questo potrebbe essere un ramo che viene passato esplicitamente o potresti avere un parametro che indicherebbe il ramo corrente come descritto nel collegamento che hai elencato.

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

Esempio di codice preso in prestito pesantemente da qui


3
Devo usare le -s
lettere

Ho avuto l'esatto problema opposto rispetto a @lulula: ho dovuto scrivere in maiuscolo -S, oppure l'argomento non sarebbe passato a cap, quando si utilizzava fetch (: nome_var, 'default') per ottenerlo.
Frederik Struck-Schøning,

10

Se stai usando capistrano-multistage , devi solo eseguire

cap -s branch=$MY_BRANCH deploy

o

cap -s branch=$MY_BRANCH production deploy

senza ulteriori modifiche al tuo deploy.rb.


2
Questo dovrebbe essere branch=, no branch-.
Jimothy,

3
OptionParser :: AmbiguousOption: opzione ambigua: -s
giorgio

8

Questo comando non funzionerà più:

cap deploy -s branch=your_branch

Il supporto per le -sSbandiere è stato rimosso in capistrano v3 +.
Qui puoi leggere di più al riguardo: link
È stato menzionato in un paio di risposte, ma al momento non è corretto.

Cosa funziona per me:
nel deploy.rbfile aggiungere

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

quindi eseguire:

BRANCH=your_branch cap deploy

Inoltre, per eseguire correttamente questo comando, è necessario essere sul ramo principale.


3

Questa soluzione dovrebbe funzionare con tutte le versioni di 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')

Uso:

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

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

cap [staging] deploy
# => deploy default branch

2

Sto usando la versione 3.3.5 e ho questo lavoro:

set :branch, 'develop'

1

Risposta generale:

Se hai un file di impostazione con un contenuto modificato da un ambiente all'altro, dovresti creare quella linea come "modello" (con una stringa che rappresenta il nome della variabile come @BRANCH_NAME@o @ENV_NAME@).

Quindi avresti uno script (con versione) in grado di leggere il tuo file di configurazione e sostituire la " @BRANCH_NAME@" variabile con il valore appropriato richiesto dal processo di distribuzione.



1

Per gli utenti di 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

Metodo 1: impostare un ramo specifico della fase (ad es. Test, produzione) per la distribuzione

Inserisci la branchconfigurazione nei file dello stage anziché "deploy.rb" e imposta il ramo di destinazione per quello stage da cui distribuire.

Per un'app a due fasi con il nome del ramo associato teste production, la configurazione sarà simile a questa,

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

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

Questo metodo consente di distribuire dai rami specifici dello stage. Quindi, solo un passaggio aggiuntivo che sarà richiesto è quello di unire o riformulare il codice più recente dal ramo di base.

Metodo 2: distribuire direttamente da qualsiasi ramo (utilizzando il tag)

Un altro approccio è distribuire usando il tag. Per distribuire utilizzando il tag, impostare ilbranch configurazione. in "deploy.rb" come segue,

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

E, configurare l'IC per la distribuzione condizionale in diverse fasi se il modello di tag associato corrisponde (ad es /.*-test$/ .)

Ora, una distribuzione può essere effettuata da qualsiasi ramo,

  • Innanzitutto, crea un tag da qualsiasi ramo,

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

  • E, spingi

    git push origin v0.1.0-test

Nota: i metodi sopra indicati si basano su Capistrano 3.


0
git rev-parse --abbrev-ref HEAD

restituirà il ramo corrente in cui ci si trova esattamente.

Ho sempre impostato gpshinvece digit push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.