Come posso distribuire / inviare solo una sottodirectory del mio repository Git a Heroku?


121

Ho un progetto che utilizza Serve ed è controllato dalla versione tramite Git. Serve crea una outputcartella con file statici che voglio distribuire a Heroku.

Non voglio distribuire il progetto Serve in sé poiché lo stack Heroku Cedar non sembra troppo affezionato, ma soprattutto voglio sfruttare l'ottimo supporto di Heroku per i siti Web statici.

C'è un modo per distribuire una sottocartella a un telecomando git? Devo creare un repository Git nella outputcartella (sembra sbagliato) e inviarlo a Heroku?


1
Potresti cercare sottomoduli: book.git-scm.com/5_submodules.html
greg0ire

Risposte:


220

C'è un modo ancora più semplice tramite git-subtree . Supponendo che tu voglia inviare la tua cartella 'output' come root su Heroku, puoi fare:

git subtree push --prefix output heroku master

Al momento sembra che git-subtree sia stato incluso in git-core, ma non so se quella versione di git-core sia stata ancora rilasciata.


1
Sì, ma la sottostruttura (a partire dalla 1.8.0.2) non è ancora inclusa tramite il programma di installazione git . Fortunatamente l'installazione dai sorgenti è rapida e semplice, questa pagina ha funzionato per me su Mac.
Dribnet

14
Se hai bisogno --force, usa git push heroku `git subtree split --prefix output master`:master --force. Vedi stackoverflow.com/a/15623469/2066546 .
fiedl

2
Ma qual è il modo corretto per inviare un tag specifico. Ho pensato che dovrebbe essere git subtree push --prefix output heroku +refs/tags/v1.0.0:refs/heads/master. Ma questo non funziona e torna con +refs/tags/v1.0.0:refs/heads/master does not look like a ref. Ho bisogno di questo tipo di funzionalità per poter tornare indietro a tag specifici in seguito. Qual è il modo corretto di farlo?
denis

1
Ottengo l'errore "Gli aggiornamenti sono stati rifiutati perché una punta di ramo spinto è dietro il suo telecomando"
Ally

2
@ and-dev @Eric Burel Ho trasferito con successo la outputcartella che era presente solo sul mio developramo al heroku masterramo senza la necessità di specificarlo develop:master, quindi apparentemente spinge al ramo di destinazione che specifichi dal tuo ramo attualmente estratto.
cprcrack

10

Ho iniziato con quello che ha detto John Berryman, ma in realtà può essere più semplice se non ti interessa affatto della storia di heroku git.

cd bin
git init
git add .
git commit -m"deploy"
git push git@heroku.com:your-project-name.git -f
rm -fr .git

Immagino che ufficiale git subtreesia la risposta migliore, ma ho avuto problemi a far funzionare la sottostruttura sul mio Mac.


9

Ho avuto un problema simile. Nel mio caso non è mai stato un problema soffiare via tutto nel repository heroku e sostituirlo con qualunque cosa si trovi nella mia sottodirectory. Se questo è il tuo caso, puoi usare il seguente script bash. Mettilo nella directory delle app di Rails.

#!/bin/bash

#change to whichever directory this lives in
cd "$( dirname "$0" )"

#create new git repository and add everything
git init
git add .
git commit -m"init"
git remote add heroku git@heroku.com:young-rain-5086.git

#pull heroku but then checkback out our current local master and mark everything as merged
git pull heroku master
git checkout --ours .
git add -u
git commit -m"merged"

#push back to heroku, open web browser, and remove git repository
git push heroku master
heroku open
rm -fr .git

#go back to wherever we started.
cd -

Sono sicuro che ci sono molti modi per migliorare questo aspetto, quindi sentiti libero di dirmi come!


+1Grazie. Questa soluzione funziona alla grande se non ti interessano i log git su Heroku. È possibile modificare lo script sopra nel caso in cui ci siano alcune cartelle che si desidera ignorare, all'interno del sottopercorso dell'applicazione da distribuire. Ad esempio, non volevo la speccartella su heroku. Esempio Gist
ch4nd4n

+1ma puoi semplificare non tirando e fondendoti in heroku master e invece semplicementegit push --force heroku master
MK Safi

4

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:

  1. richiede qualcosa da fare ogni volta, o periodicamente, o accadono cose inaspettate (spingere i sottomoduli, sincronizzare i sottoalberi, ...)
  2. 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' :pathopzione "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 -_-
  3. l'unica soluzione che ho trovato è utilizzare il motore come /vendorcollegamento 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:

  1. api - a seconda del profilo verrà eseguito su 2 diversi host heroku - upload e api
  2. web: il sito web
  3. web-old - il vecchio sito web, ancora in fase di migrazione
  4. common - i componenti comuni estratti in un motore

Tutti i progetti hanno un vendor/commoncollegamento simbolico che guarda alla radice del commonmotore. 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.

  1. accetta un elenco di nomi host come argomenti
  2. 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
  3. 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,
  4. 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
  5. 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_commonparte, 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 ...


Ciao @bbozo, ti dispiacerebbe condensare un po 'la tua soluzione e renderla specifica per il caso d'uso di distribuire una sottocartella specifica a un progetto heroku specifico ed eliminare tutte le cose che non sono necessarie / specifiche per Heroku?
Adam Reis

Grazie per aver aggiornato la tua risposta. Penso che mi limiterò a mordere il proiettile e dividere il mio codice lato client e server in repository separati. Non è l'ideale per la nostra situazione, ma batterà le spinte forzate del sottoalbero che dobbiamo fare ora, e da quello che ho capito, sarà anche molto più semplice che provare a usare i collegamenti simbolici.
Adam Reis

Non aver paura di uno "script deploy", paga
bbozo
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.