Jak mogę wdrożyć / przekazać tylko podkatalog mojego repozytorium git do Heroku?

121

Mam projekt, który używa usługi Serve i jest kontrolowany wersjami za pomocą Git. Serve tworzy outputfolder z plikami statycznymi, które chcę wdrożyć w Heroku.

Nie chcę wdrażać samego projektu Serve, ponieważ stos Heroku Cedar nie wydaje się za bardzo go lubi, ale co najważniejsze, chcę skorzystać z doskonałego wsparcia Heroku dla statycznych witryn internetowych.

Czy istnieje sposób na wdrożenie podfolderu na pilocie Git? Czy powinienem utworzyć repozytorium Git w outputfolderze (to brzmi źle) i przekazać to do Heroku?

Olivier Lacan
źródło
1
Być może szukasz modułów podrzędnych
greg0ire

Odpowiedzi:

220

Jest jeszcze łatwiejszy sposób poprzez poddrzewo git . Zakładając, że chcesz wypchnąć folder wyjściowy jako katalog główny do Heroku, możesz wykonać:

git subtree push --prefix output heroku master

Obecnie wydaje się, że git-subtree jest dołączane do git-core, ale nie wiem, czy ta wersja git-core została już wydana.

anshumans
źródło
1
Tak, ale poddrzewo nadal (od 1.8.0.2) nie jest uwzględnione w instalatorze git . Na szczęście instalacja ze źródła jest szybka i prosta, ta strona działała dla mnie na Macu.
dribnet
14
Jeśli potrzebujesz --force, użyj git push heroku `git subtree split --prefix output master`:master --force. Zobacz stackoverflow.com/a/15623469/2066546 .
fiedl
2
Ale jaki jest właściwy sposób wypychania konkretnego tagu. Myślałem, że tak powinno być git subtree push --prefix output heroku +refs/tags/v1.0.0:refs/heads/master. Ale to nie działa i wraca +refs/tags/v1.0.0:refs/heads/master does not look like a ref. Potrzebuję tego rodzaju funkcji, aby móc później wrócić do określonych tagów. Jaki jest właściwy sposób zrobienia tego?
denis
1
Otrzymuję błąd „Aktualizacje zostały odrzucone, ponieważ wypchnięta końcówka gałęzi jest za pilotem”
Ally
2
@ and-dev @Eric Burel Pomyślnie wypchnąłem outputfolder, który był obecny tylko w mojej developgałęzi, do heroku mastergałęzi bez potrzeby określania develop:master, więc najwyraźniej wypycha do gałęzi docelowej, którą określisz z aktualnie wyewidencjonowanej gałęzi.
cprcrack
10

Zacząłem od tego, co powiedział John Berryman, ale w rzeczywistości może być prostsze, jeśli w ogóle nie obchodzi cię historia git heroku.

cd bin
git init
git add .
git commit -m"deploy"
git push [email protected]:your-project-name.git -f
rm -fr .git

Wydaje mi się, że oficjalna git subtreejest najlepszą odpowiedzią, ale miałem problem z uruchomieniem poddrzewa na moim Macu.

LessQuesar
źródło
9

Miałem podobny problem. W moim przypadku nigdy nie było problemu z wysadzeniem wszystkiego w repozytorium heroku i zastąpieniem go tym, co jest w moim podkatalogu. W takim przypadku możesz użyć następującego skryptu bash. Po prostu umieść go w katalogu aplikacji 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 [email protected]: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 -

Jestem pewien, że istnieje wiele sposobów, aby to poprawić - więc możesz mi powiedzieć, jak to zrobić!

JnBrymn
źródło
+1Dzięki. To rozwiązanie działa świetnie, jeśli nie zależy Ci na logach git na Heroku. Można zmodyfikować powyższy skrypt na wypadek, gdyby istnieją foldery, które chcesz zignorować, w ścieżce podrzędnej aplikacji do wdrożenia. Na przykład nie chciałem mieć specfolderu na heroku. Przykład Gist
ch4nd4n
+1ale możesz uprościć, nie ciągnąc i nie łącząc się z mistrzem heroku, a zamiast tego po prostugit push --force heroku master
MK Safi
4

Po długim i ciężkim miesiącu próbowania różnych rzeczy i bycia ugryzionym za każdym razem, gdy zdałem sobie sprawę,

tylko dlatego, że Heroku używa repozytorium git jako mechanizmu wdrażania, nie powinieneś traktować go jako repozytorium git

równie dobrze mógł to być rsync, wybrali git, nie rozpraszaj się z tego powodu

jeśli to zrobisz, otworzysz się na wszelkiego rodzaju krzywdy. Wszystkie powyższe rozwiązania gdzieś fatalnie zawodzą:

  1. wymaga wykonania czegoś za każdym razem lub okresowo, albo zdarzają się nieoczekiwane rzeczy (wysyłanie modułów podrzędnych, synchronizowanie poddrzew, ...)
  2. jeśli używasz silnika na przykład do modularyzacji kodu, Bundler pożre cię żywcem, nie da się opisać ilości frustracji, jaką miałem z tym projektem podczas poszukiwania dobrego rozwiązania tego problemu
    • próbujesz dodać silnik jako link do repozytorium git + bundle deploy- niepowodzenie, za każdym razem musisz pakować aktualizację
    • próbujesz dodać silnik jako :path+ bundle deploy- niepowodzenie, zespół :pathdeweloperów uważa, że opcja „nie używasz Bundlera z tą opcją klejnotu”, więc nie zostanie ona dołączona do produkcji
    • ponadto każde odświeżenie silnika chce zaktualizować stos szyn -_-
  3. Jedynym rozwiązaniem, które znalazłem, jest użycie silnika jako /vendordowiązania symbolicznego w trakcie opracowywania i skopiowanie plików do produkcji

Rozwiązanie

Ta aplikacja ma 4 projekty w git root:

  1. api - w zależności od profilu będzie działać na 2 różnych hostach Heroku - upload i api
  2. web - strona internetowa
  3. web-old - stara strona internetowa, wciąż w trakcie migracji
  4. wspólne - wspólne komponenty wyodrębnione w silniku

Wszystkie projekty mają vendor/commondowiązanie symboliczne do katalogu głównego commonsilnika. Podczas kompilowania kodu źródłowego do wdrożenia w heroku musimy usunąć dowiązanie symboliczne i rsync, aby kod znajdował się fizycznie w folderze dostawcy na każdym oddzielnym hoście.

  1. akceptuje listę nazw hostów jako argumenty
  2. uruchamia git push w twoim repozytorium programistycznym, a następnie uruchamia czysty git pull w oddzielnym folderze, upewniając się, że żadne brudne (niezatwierdzone) zmiany nie są automatycznie przesyłane do hostów
  3. wdraża hosty równolegle - ściągane jest każde repozytorium git heroku, nowy kod jest rsynowany we właściwe miejsca, zatwierdzany z podstawowymi informacjami push w komentarzu git commit,
  4. na koniec wysyłamy ping z zawinięciem, aby powiedzieć hobbystom, aby się obudzili i śledzili dzienniki, aby sprawdzić, czy wszystko poszło na wino
  5. też dobrze gra z jenkinsem: D (automatyczne wypychanie kodu do testowania serwerów po udanych testach)

Działa bardzo dobrze na wolności z minimalnymi (nie?) Problemami już od 6 miesięcy

Oto skrypt https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f

Zaktualizuj 1

@AdamBuczynski, to nigdy nie jest takie proste.

Po pierwsze, zawsze będziesz mieć przynajmniej środowisko produkcyjne i testowe - a kilka klastrów specyficznych dla funkcji w gorszym - nagle 1 folder musi być mapowany do n projektów heroku jako dość podstawowy wymóg i wszystko musi być jakoś zorganizowane, aby skrypt „wie”, jakie źródło chcesz wdrożyć i gdzie,

Po drugie, będziesz chciał udostępniać kod między projektami - teraz przychodzi sync_commonczęść, shennanigany z linkami symbolicznymi w trakcie opracowywania zostaną zastąpione przez rzeczywisty kod rsynced na Heroku, ponieważ Heroku wymaga określonej struktury folderów i bundlera, a rubygemy naprawdę naprawdę sprawiają, że rzeczy są brzydkie, jeśli ty chcą wydobyć wspólne wątki w klejnot

Po trzecie, będziesz chciał podłączyć CI i zmieni się nieco sposób, w jaki muszą być zorganizowane podfoldery i repozytorium git, w końcu w najprostszym możliwym przypadku użycia skończysz z wyżej wymienioną treścią.

W innych projektach muszę podłączać kompilacje Javy, sprzedając oprogramowanie wielu klientom będziesz musiał filtrować moduły, które są instalowane w zależności od wymagań instalacji i tak dalej,

Naprawdę powinienem rozważyć dołączenie rzeczy do pliku Rakefile lub czegoś podobnego i zrobić wszystko w ten sposób ...

bbozo
źródło
Cześć @bbozo, czy mógłbyś trochę skondensować swoje rozwiązanie i uczynić je specyficznym dla przypadku użycia polegającego na wdrożeniu jednego konkretnego podfolderu w jednym konkretnym projekcie Heroku i usunięciu wszystkich rzeczy, które nie są potrzebne / specyficzne dla Heroku?
Adam Reis
Dziękujemy za zaktualizowanie odpowiedzi. Myślę, że po prostu ugryzę punkt i podzielę mój kod po stronie klienta i serwera na osobne repozytoria. Nie jest to idealne rozwiązanie dla naszej sytuacji, ale pokona wymuszone wypychanie poddrzewa, które musimy teraz zrobić, iz tego, co wiem, będzie również znacznie prostsze niż próba użycia dowiązań symbolicznych.
Adam Reis,
Nie bój się „skryptu wdrożenia”, to się opłaca
bbozo