Unsere Migration von GitHub zu GitLab

David Feb 13, 2018
Unsere Migration von GitHub zu GitLab

Hintergrund



Seit mehreren Jahren verwenden wir GitHub zur Speicherung des Codes unserer privaten und Open-Source-Projekte. 

Wir verwenden ausserdem eine Lösung zur kontinuierlichen Integration (Continuous Integration / CI), um sicherzustellen, dass die Funktion unserer Applikationen nicht durch jedes neue Stück Code, das wir schreiben, gestört wird. Diese Lösung besteht aus drei Teilen:



Teil 1: Jenkins

Wir haben Jenkins eingesetzt, um unsere CI-Builds bei jedem Git-Push in einem Branch (Master Branch oder Andere) auszuführen. Die Jenkins Instanz wurde von uns selbst gemanaged.

Teil 2: Janky

Wir haben Janky verwendet, um die Kommunikation zwischen GitHub und Jenkins zu ermöglichen: GitHub leitet Events an Janky  weiter und Janky wiederum leitet diese an Jenkins weiter (und umgekehrt).

 Zum Einrichten neuer Projekte mit hinterlegter Logik standen uns XML-Vorlagen zur Verfügung. Diese Janky-Instanz wird ebenfalls selbst bei uns betrieben. 



Teil 3: Babysteps

Wir bemühen uns immer unsere Arbeitsschritte einfach zu gestalten und dafür meist  Einzeiler-Befehle zu nutzen. Die Veröffentlichung eines Debian-Pakets oder einer Gem-Version sind da keine Ausnahmen.

 Wir verwendeten Babysteps, um Applikationsversionen automatisch zu verwalten. Babysteps hat eine  integrierte REST API, die von unserem Slackbot aus angestossen wird.


Warum der Wechsel?

Mit der Zeit sind wir auf Probleme mit dieser CI-Lösung gestossen, die uns veranlasste, nach Alternativen zu suchen:


Unzuverlässiger CI-Prozess

Es kam vor, dass einige Aufgaben von Jenkins nicht abgearbeitet wurden, obwohl diese von der GitHub- / Janky- / Jenkins-Kette hätten angestossen werden sollen. Weiterhin kam es zu Problemen, da manche Events in Jenkins direkt angestossen wurden, aber Janky davon nichts wusste.

 Dadurch waren wir gezwungen, unnötige und manchmal zeitaufwendige Debugging-Prozesse durchzuführen, um sicherzustellen, dass alles funktioniert.



CI/CD Pipelines Support in Jenkins

Auch wenn Jenkins grosse Fortschritte im Bereich Pipeline-Support gemacht hat, fanden wir die Verwendung der Lösung in unserem Fall doch eher kompliziert und umständlich.

Wir suchten nach einer ähnlichen Lösung, welche derjenigen gleicht, die in einer modernen CI-Lösung zu finden sind: eine yaml-Datei für jedes Projekt, das eine Pipeline beschreibt.



Es war Zeit für etwas Neues

Unsere CI-Lösung war bereits seit über 5 Jahren im Einsatz, und wir hatten zunehmend das Gefühl, dass sie nicht mehr unseren Anforderungen entsprach.

 Wir wussten, es war Zeit für etwas Neues.

Warum keine cloudbasierte Lösung?


Eine cloudbasierte Lösung kam aufgrund der Anzahl unserer Projekte (mehr als 150) und der damit entstehenden Kosten nicht in Frage.

 Hinzu kommt, dass wir über das notwendige Know-how verfügen, um unsere interne CI-Lösung problemlos selbst zu entwickeln und zu managen. Diesen Vorteil wollten wir nutzen.

Unser neues Setup



Für unsere privaten Projekte haben wir GitLab als Ersatz für GitHub gewählt. Dort hosten wir unseren Source Code und führen gleichzeitig unsere CI-Pipelines durch. Es ist ein gut strukturierter Monolith, der sich unglaublich einfach installieren, aktualisieren und individuell anpassen lässt.

 In GitLab stehen Pipelines und Docker ganz oben, und genau das fehlte uns in unserer alten CI-Lösung.



Das Gitlab-Kernteam arbeitet derzeit ausserdem an der Veröffentlichung einer neuen Version am 22. jeden Monats und stellt in der Zwischenzeit Patches bereit. In unseren Augen ist das erstklassige Pflege.

Zudem handelt es sich um ein Open-Source-Projekt, sodass wir unsere eigene Instanz behalten konnten (#TakeThatNSA).



Unsere Erfahrung bis heute

Reibungsloser Wechsel

Mithilfe des Projekt-Importers in GitLab konnten wir all unsere Projekte aus GitHub innerhalb von etwa 30 Minuten importieren. Sogar unsere Pull Requests und Versionen, Tags und Kommentare wurden allesamt übernommen!



Anschliessend mussten wir für jedes Projekt, je nach Art (Debian-Paket, Web-Applikation, Gem, ...), eine gitlab-ci.yml anlegen. Zum Taggen unserer Projekte und Hochladen der gewünschten gitlab-ci.yml zu diesen haben wir ein kleines Skript entwickelt. Unsere Migration konnte deshalb so reibungslos verlaufen, weil wir für unsere Entwicklungs-/Testumgebungen Docker Compose verwenden.



Wir haben einen GitLab-Runner eingerichtet und Docker Compose als Abhängigkeit installiert, und schon konnten wir loslegen!



Einfachere Arbeitsabläufe

Zur Veröffentlichung einer neuen RubyGem-Version oder eines Debian-Pakets brauchen wir jetzt nur noch einen Befehl für unseren Slackbot: lita release <Projektname>. Der gesamte Prozess läuft dann als eine GitLab Pipeline ab: Testen der Applikation, Entwicklung des Gems/Pakets und Pushen in unser internes Repository.



Alle Informationen zur Pipeline sind in der gitlab-ci.yml enthalten, was unsere Prozesse unglaublich flexibel macht: Ruby App mit Docker Compose zum Testen, GO Applikation welche in ein Debian-Paket verpackt wird, Web-Applikationen welche direkt auf Openshift deployed werden kann. Und das alles ohne grosse Anstrengung.



Fazit

Bis jetzt ist unsere CI sehr stabil und vorhersehbar: Endlich funktioniert sie einfach. Wir sind sehr zufrieden mit dem Wechsel und wir sind der Überzeugung, dass er uns befähigen wird, unseren Kunden noch häufiger und mit grösserer Zuversicht Mehrwert zu bieten.