Nach einem langen und harten Monat, in dem ich verschiedene Dinge ausprobiert und jedes Mal gebissen wurde, wenn ich merkte,
Nur weil Heroku ein Git-Repository als Bereitstellungsmechanismus verwendet, sollten Sie es nicht als Git-Repository behandeln
es hätte genauso gut rsync sein können, sie haben sich für git entschieden, lassen Sie sich deswegen nicht ablenken
Wenn Sie dies tun, öffnen Sie sich allen Arten von Verletzungen. Alle oben genannten Lösungen scheitern irgendwo kläglich:
- Es erfordert, dass jedes Mal oder in regelmäßigen Abständen etwas getan wird oder unerwartete Dinge passieren (Submodule verschieben, Teilbäume synchronisieren, ...)
- Wenn Sie zum Beispiel eine Engine verwenden, um Ihren Code zu modularisieren, wird Bundler Sie lebendig essen. Es ist unmöglich zu beschreiben, wie frustriert ich mit diesem Projekt war, als ich nach einer guten Lösung dafür gesucht habe
- Wenn Sie versuchen, die Engine als Git-Repo-Link hinzuzufügen +
bundle deploy
- fehlgeschlagen, müssen Sie jedes Mal ein Update bündeln
- Wenn Sie versuchen, die Engine als
:path
+ bundle deploy
- Fehler hinzuzufügen , betrachtet das :path
Entwicklerteam die Option als "Sie verwenden Bundler nicht mit dieser Edelsteinoption", sodass sie nicht für die Produktion gebündelt wird
- Außerdem möchte jede Aktualisierung des Motors Ihren Schienenstapel aktualisieren -_-
- Die einzige Lösung, die ich gefunden habe, besteht darin, die Engine als
/vendor
Symlink in der Entwicklung zu verwenden und die Dateien tatsächlich für die Produktion zu kopieren
Die Lösung
Die betreffende App hat 4 Projekte in Git Root:
- API - abhängig vom Profil läuft auf 2 verschiedenen Heroku-Hosts - Upload und API
- Web - die Website
- web-old - die alte Website, die sich noch in der Migration befindet
- common - die gemeinsamen Komponenten, die in einem Motor extrahiert werden
Alle Projekte haben einen vendor/common
Symlink, der die Wurzel der common
Engine betrachtet. Beim Kompilieren des Quellcodes für die Bereitstellung in Heroku müssen wir den Symlink entfernen und den Code rsyncieren, damit er sich physisch im Herstellerordner jedes einzelnen Hosts befindet.
- akzeptiert eine Liste von Hostnamen als Argumente
- Führt einen Git-Push in Ihrem Entwicklungs-Repo aus und führt dann einen sauberen Git-Pull in einem separaten Ordner aus, um sicherzustellen, dass keine schmutzigen (nicht festgeschriebenen) Änderungen automatisch auf die Hosts übertragen werden
- stellt die Hosts parallel bereit - jedes Heroku-Git-Repo wird gezogen, neuer Code wird an den richtigen Stellen synchronisiert und mit grundlegenden Push-Informationen im Git-Commit-Kommentar festgeschrieben.
- Am Ende senden wir einen Ping mit Locken, um den Hobby-Gastgebern zu sagen, dass sie aufwachen und die Protokolle verfolgen sollen, um zu sehen, ob alles Wein ist
- spielt auch gut mit Jenkins: D (automatischer Code-Push zum Testen von Servern nach erfolgreichen Tests)
Funktioniert sehr, sehr gut in freier Wildbahn mit minimalen (nein?) Problemen seit 6 Monaten
Hier ist das Skript https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f
Update 1
@AdamBuczynski, es ist noch nie so einfach.
Erstens haben Sie immer mindestens eine Produktions- und Testumgebung - und im schlimmsten Fall eine Reihe funktionsspezifischer Cluster - plötzlich muss 1 Ordner als ziemlich grundlegende Anforderung n Heroku-Projekten zugeordnet werden, und alles muss irgendwie so organisiert werden Das Skript "weiß", welche Quelle Sie wo bereitstellen möchten.
sync_common
Zweitens möchten Sie Code zwischen Projekten teilen - jetzt kommt der Teil, bei dem die Shennanigans mit Symlinks in der Entwicklung durch tatsächlichen rsynchronisierten Code auf Heroku ersetzt werden, da Heroku eine bestimmte Ordnerstruktur benötigt und Bundler und Rubygems die Dinge wirklich sehr, sehr, sehr hässlich machen, wenn Sie möchte die gemeinsamen Fäden in einen Edelstein extrahieren
3. Sie möchten CI einstecken und es ändert sich ein wenig, wie Unterordner und Git-Repo organisiert werden müssen. Am Ende erhalten Sie im einfachsten Anwendungsfall den oben genannten Kern.
In anderen Projekten muss ich Java-Builds einbinden. Wenn Sie Software an mehrere Clients verkaufen, müssen Sie Module filtern, die abhängig von den Installationsanforderungen installiert werden.
Ich sollte wirklich darüber nachdenken, Dinge in einem Rakefile oder so zu bündeln und alles so zu machen ...