Während der Entwicklung einer Anwendung gibt es immer eine kleine Besorgnis bei der Produktivsetzung. Diese kleine Stimme, die Ihnen sagt "wird mein Code nichts kaputtmachen?" oder auch "bin ich sicher, alle Tests bestanden zu haben, bevor ich pushe?". Diese Angst ist umso berechtigter, wenn Sie auf ein bestehendes Projekt stossen und Sie noch keine umfassende Kenntnis davon haben.
Noch schlimmer, wenn Sie als Entwickler an diesem Projekt arbeiten und ein neuer dazukommt, man ist nicht beruhigter. Man kann noch so viele Tests definiert haben,
nichts sichert uns dass die Entwickler diese vor der Produktivsetzung starten. Hier erhalten die Rollen von
der kontinuierlichen Integration (
CI) und der kontinuierlichen Entwicklung (
CD) ihre volle Bedeutung.
GitLab CI/CD ist eine Funktion von GitLab, die es ermöglicht, CI/CD-Pipelines für jedes beliebige Projekt einzurichten, egal ob neu oder bestehend, vorausgesetzt, es verwendet Git.
Motivationen
Für wen?
Sie können GitLab CI/CD auch verwenden, ohne Ihr Projekt auf GitLab zu hosten, indem Sie die Option wählen "Run CI/CD for external repository". Wenn Sie GitHub verwenden, können Sie so den Status Ihrer Pipeline sehen, nachdem Sie einen Commit gepusht haben:
Warum?
Die Einrichtung von CI/CD mit GitLab ermöglicht es Ihnen, die Schritte zu automatisieren:
der kontinuierlichen Integration: Build > Tests (Unit-, Integrations-, Regressionstests...)
der kontinuierlichen Bereitstellung: Review > Bereitstellung (staging, production...)
Diese Automatisierung beschleunigt die Code-Produktion: ein einziger Commit genügt um eine Pipeline auf GitLab-Seite auszulösen, die sich um die Generierung eines Production Builds kümmert, die Testsuite startet und die neue Version in staging/production bereitstellt! Dies erhöht auch das Vertrauen der Entwickler und die Qualität des in Production gesendeten Codes, da man die Gewissheit hat, dass jede Änderung diesen Prozess durchlaufen hat.
Einrichtung
Die Stages
Wir werden den praktischen Fall der Einrichtung einer CI/CD-Pipeline für eine Webanwendung, die in JavaScript geschrieben ist und Next.js verwendet, analysieren. Zuerst müssen die verschiedenen Stages der CI/CD-Pipeline, die wir erstellen möchten. Ich schlage Ihnen eine Aufteilung in drei Stages vor: Build, Tests und Deploy.
Diese Stages werden sequenziell gestartet und bestehen aus Jobs. Ein Stage muss mindestens einen Job enthalten, wobei letztere standardmässig parallel ausgeführt werden. Hier ist die Struktur der Pipeline, die wir einrichten werden, es steht Ihnen frei, sie anzupassen:
Man findet dort unsere drei Stages : Build, Tests und Deploy. In diesem Schema besitzen die Stages Tests und Deploy jeweils zwei Jobs.
Um die Architektur unserer Pipeline für GitLab zu beschreiben, müssen wir eine .gitlab-ci.yml-Datei im Stammverzeichnis unseres Projekts erstellen und diese Zeilen hinzufügen:
Sehen wir uns hier detaillierter den Inhalt unserer Datei an:
image ermöglicht es Ihnen, das Docker-Image zu spezifizieren, das zum Starten Ihrer Pipeline verwendet werden soll, natürlich an Ihre Bedürfnisse anzupassen,
cache ermöglicht es uns hier, unsere node_modules im Cache zu halten, um zu vermeiden, sie jedes Mal neu herunterladen zu müssen,
Schliesslich,
Stages ermöglicht es uns, unsere verschiedenen Schritte innerhalb der Pipeline zu definieren.
Die Jobs
Gut, die Stages wurden definiert, aber wie ich zuvor erwähnt habe, muss ein Stage mindestens einen Job enthalten, andernfalls führt unsere Pipeline nichts aus und hat keinen Sinn. Sehen wir uns also an, wie wir unseren ersten Job definieren, build, indem wir diese Zeilen zu unserem .gitlab-ci.yml hinzufügen:
Hier ist der Name unseres Jobs
build, und es befindet sich innerhalb des Stages
build. Der Teil
script definiert
meine Build-Prozedur für mein Projekt, das Next.js verwendet, und generiert nach Ausführung des Befehls
next export einen Ordner
out der meine generierten Dateien enthält.
Die Verwendung des Schlüsselworts artifacts ermöglicht es mir hier, Dateien und/oder Ordner zu definieren, die innerhalb dieser Pipeline gespeichert werden, um gegebenenfalls später an andere Jobs übergeben zu werden. In unserem Fall geben wir den Ordner out an, der unsere generierten Dateien enthält, um sie später an den Job deploy.
Wir können nun die entsprechenden Jobs zum Stage für tests. Fügen Sie diese Zeilen im Anschluss an Ihre .gitlab-ci.yml ein:
Das Hinzufügen mehrerer Jobs zu einem Stage ist problemlos möglich; man definiert einfach für jeden Job den Stage, zu dem er gehört, hier tests. Die GitLab-Runner verwenden unser Docker-Image node:12.1.0, das Jest standardmässig nicht enthält: Wir fügen daher die erforderliche Abhängigkeit hinzu, bevor wir die benötigten Befehle ausführen.
Diese beiden Jobs werden parallel zueinander gestartet, sobald der vorhergehende Schritt tests abgeschlossen ist. Wir können zum letzten Schritt übergehen: dem Deployment.
Die Umgebung
In diesem Artikel habe ich mich für ein Deployment mittels SSH entschieden; Sie können die Befehle selbstverständlich anpassen, wenn Sie andere Dienste wie AWS S3 oder GCP nutzen. GitLab bietet die Möglichkeit, Umgebungsvariablen zu verwenden, um zu vermeiden, dass die Anmeldeinformationen für den Deployment-Dienst direkt in die Datei .gitlab-ci.yml geschrieben werden.
Um Umgebungsvariablen zu definieren, begeben Sie sich zur GitLab-Oberfläche und gehen Sie zu Settings > CI / CD > Variables. Ich habe eine Variable USER_PASSWORD hinzugefügt, die dem Passwort meiner SSH-Verbindung entspricht.
Wir können nun unsere letzten beiden Jobs schreiben, die es ermöglichen, die Website in Staging und Produktion zu deployen! Ich schlage Ihnen vor, zuerst den Staging-Job zu betrachten:
Mehrere Punkte sind hier zu beachten. Erstens wurde ein resource_group mit dem Wert deploy für den Job definiert. Einfach ausgedrückt ist es für die GitLab-Runner, welche unsere Pipelines ausführen, nicht möglich, zwei Jobs desselben resource_group parallel zu starten, selbst wenn sich diese Jobs in zwei verschiedenen laufenden Pipelines befinden. Wir möchten hier mehrere Deployments zu unserem Server verhindern, um jeweils nur eine Verbindung zu haben, die Dateien sendet.
Das Schlüsselwort dependencies spezifiziert den oder die Jobs, deren artifacts wir abrufen möchten. Wir haben dafür gesorgt, dass unser Job build den Ordner out als artifacts sendet; dieser wird also vom Job deploy_staging.
Schliesslich das Schlüsselwort only ermöglicht es, anzugeben, von welchen Branches der Job ausgeführt werden kann. Hier habe ich mich entschieden, die Deployments vom Master-Branch einzuschränken.
Wir dürfen uns jedoch die Frage stellen: Was ist der Unterschied zwischen unserem Job deploy_staging und unserem Job deploy_production ? Schliesslich wäre deploy_production identisch, mit Ausnahme des Deployment-Befehls.
Die templates
GitLab hat ein Template-System implementiert, das die Wiederverwendung von Code ermöglicht und somit die
principes de développement DRY. In unserem Fall kann fast der gesamte Code des Jobs deploy_staging für deploy_production wiederverwendet werden. Ich schlage Ihnen daher vor, unsere .gitlab-ci.yml wie folgt zu ändern, um diese beiden Jobs zu definieren:
Wir definieren somit ein Template, indem wir dessen Namen mit einem Punkt beginnen. Um das Template zu referenzieren, genügt es dann, es mit dem Schlüsselwort <<: einzufügen und seinen Namen mit einem Stern zu referenzieren *. Eine kleine Besonderheit hier: Wir möchten nicht, dass der in den Jobs definierte Skriptinhalt deploy_staging und deploy_production das Skript des Templates überschreibt. GitLab erlaubt es, insbesondere drei Schlüsselwörter zu definieren: before_script, script und after_script. Ich habe mich daher entschieden, die Befehle des Templates in before_script zu platzieren, damit sie vor dem Befehl zur Dateiübertragung per SSH ausgeführt werden.
Ich habe zudem für das Deployment in die Produktion die Anweisung hinzugefügt when: manual. Diese sagt GitLab, dass der Job nur manuell ausgelöst werden kann (und nur, wenn die vorherigen Jobs erfolgreich waren!).
Ergebnisse
So sieht unsere finale Pipeline aus, gesehen über die GitLab-Oberfläche. Wir sehen unsere 3 Stages und die zugehörigen Jobs, sowie den Job deploy_production der nur manuell deployed werden kann.
Wenn Sie über den Status Ihrer Pipelines bei einem Push auf Slack, Discord oder einer anderen Applikation benachrichtigt werden möchten, können Sie zu GitLab gehen und in Settings > Integrations navigieren und die entsprechenden Benachrichtigungen aktivieren.
Fazit
Sie kennen nun die Grundlagen zur Einrichtung einer CI/CD-Pipeline mit GitLab! Selbstverständlich versteht es sich von selbst, dass der Nutzen dieses Vorgehens geringer ist, wenn Sie keine Tests für Ihre Applikationen schreiben.
Schreiben Sie Tests und profitieren Sie von den Vorteilen der GitLab-Dienste, um Ihren Entwicklungsflow zu verbessern und Ihre Produktivität zu steigern!
Diese kurze Einführung in GitLab ist nicht erschöpfend, und wenn Sie tiefer in die Materie eintauchen möchten, kann ich Ihnen nur empfehlen, zu lesen
die hervorragende GitLab CI/CD-Dokumentation und selbst Tests durchzuführen!