Dopo un mese lungo e difficile in cui ho provato cose diverse e sono stato morso ogni volta che ho capito,
solo perché Heroku utilizza un repository git come meccanismo di distribuzione, non dovresti trattarlo come un repository git
avrebbe potuto essere rsync altrettanto bene, hanno scelto git, non distrarti per questo
se lo fai, ti apri a tutti i tipi di dolore. Tutte le soluzioni di cui sopra falliscono miseramente da qualche parte:
- richiede qualcosa da fare ogni volta, o periodicamente, o accadono cose inaspettate (spingere i sottomoduli, sincronizzare i sottoalberi, ...)
- se ad esempio usi un motore per modulare il tuo codice, Bundler ti mangerà vivo, è impossibile descrivere la quantità di frustrazione che ho avuto con quel progetto durante la ricerca di una buona soluzione per questo
- si tenta di aggiungere il motore come link repository git +
bundle deploy
- fallire, è necessario raggruppare l'aggiornamento ogni volta
- provi ad aggiungere il motore come errore
:path
+ bundle deploy
-, il team di sviluppo considera l' :path
opzione "non stai usando Bundler con questa opzione gemma" quindi non verrà raggruppato per la produzione
- inoltre, ogni aggiornamento del motore vuole aggiornare lo stack dei binari -_-
- l'unica soluzione che ho trovato è utilizzare il motore come
/vendor
collegamento simbolico in fase di sviluppo e copiare effettivamente i file per la produzione
La soluzione
L'app in questione ha 4 progetti in git root:
- api - a seconda del profilo verrà eseguito su 2 diversi host heroku - upload e api
- web: il sito web
- web-old - il vecchio sito web, ancora in fase di migrazione
- common - i componenti comuni estratti in un motore
Tutti i progetti hanno un vendor/common
collegamento simbolico che guarda alla radice del common
motore. Quando si compila il codice sorgente per la distribuzione su heroku, è necessario rimuovere il collegamento simbolico e rsync il suo codice per essere fisicamente nella cartella del fornitore di ogni host separato.
- accetta un elenco di nomi host come argomenti
- esegue un git push nel repository di sviluppo e quindi esegue un pull git pulito in una cartella separata, assicurandosi che nessuna modifica sporca (non registrata) venga inviata automaticamente agli host
- distribuisce gli host in parallelo: ogni repository git heroku viene estratto, il nuovo codice viene sincronizzato nei posti giusti, sottoposto a commit con informazioni push di base nel commento git commit,
- alla fine, inviamo un ping con curl per dire agli host per hobby di svegliarsi e seguire i registri per vedere se tutto è andato a buon fine
- gioca bene anche con jenkins: D (push automatico del codice per testare i server dopo i test riusciti)
Funziona molto molto bene in natura con problemi minimi (no?) 6 mesi ora
Ecco lo script https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f
Aggiorna 1
@AdamBuczynski, non è mai così semplice.
1 ° Avrai sempre almeno un ambiente di produzione e di test - e un mucchio di cluster specifici per la funzione al peggio - improvvisamente 1 cartella deve essere mappata sui progetti heroku come un requisito piuttosto basilare e tutto deve essere organizzato in qualche modo in modo che lo script "sa" quale fonte vuoi distribuire e dove,
2 ° vorrai condividere il codice tra i progetti - ora arriva la sync_common
parte, gli shennanigans con i collegamenti simbolici in fase di sviluppo vengono sostituiti dal codice rsynced effettivo su Heroku perché Heroku richiede una certa struttura di cartelle e bundler e rubygems davvero davvero davvero brutto molto male se tu voglio estrarre i fili comuni in una gemma
Terzo, dovrai collegare CI e cambierà un po 'il modo in cui devono essere organizzate le sottocartelle e il repository git, alla fine nel caso d'uso più semplice possibile ti ritroverai con l'essenza di cui sopra.
In altri progetti ho bisogno di collegare build Java, quando vendi software a più client dovrai filtrare i moduli che vengono installati a seconda dei requisiti di installazione e quant'altro,
Dovrei davvero considerare di esplorare il raggruppamento di cose in un Rakefile o qualcosa del genere e fare tutto in quel modo ...