2023
CI/CD

CI/CD

Datum: Februar 2023
Lesedauer: 4 Minuten


Nach dem Lesen dieses Blogposts weisst du, was CI/CD ist und wie man es in Projekten implementieren kann.

Was ist CI/CD?

Continuous Integration / Continuous Deployment ist ein Prozess, bei welchem Code regelmässig und automatisch getestet, gebuildet und auf ein Repository oder sogar eine Produktionsumgebung gestellt wird.
Durch die Automatisierung wird sichergestellt, dass der Code jederzeit fehlerfrei ist. Zudem kann beim Deployment viel manueller Aufwand gespart werden, da die nötigen Schritte automatisch ausgeführt werden können.

In den nachfolgenden Zeilen beschreibe ich, wie man dieses Konzept mit GitLab verwenden kann.

.gitlab-ci.yml

Das .gitlab-ci.yml File ist die CI/CD Konfiguration eines Projektes. Die Datei definiert die Pipelines, Jobs und Umgebungen. Abgelegt wird sie im Root des Repos/Projekts.

Stages & Jobs

Ein Job ist eine einzelne Aufgabe. Es ist nichts Weiteres als ein Script, welches unter bestimmten Bedingungen und in einer definierten Umgebungen ausgeführt wird.
Eine Stage ist ein Abschnitt, der gruppierte Aufgaben/Jobs hält. Die Stages definieren, in welcher Reihenfolge welche Arten von Jobs durchgeführt werden.

.gitlab-ci.yml
stages:
	- test
	- export
	- deploy

test-job:
	stage: test
	image: cypress/base:16.17.0
	script:
		- echo "Running tests..."
		- npm ci
		- npm run test
		- echo "Tests done."

Einschränkungen

Jobs können so konfiguriert werden, dass sie beispielsweise nur bei Aktionen auf dem master durchgeführt werden.

.gitlab-ci.yml
only:
    - master

Artifacts

Da jeder Job einzeln ausgeführt wird, hat man vorerst keinen Zugriff auf Resultate der vorherigen Scripts. Mit Artefakten kann man aber Outputs zum nächsten Job übernehmen.
So kann man das Projekt beispielsweise in einem Job exportieren und im nächsten das Resultat dieses Exports deployen.
Genauer beschreiben ist dies hier: https://docs.gitlab.com/ee/ci/pipelines/job_artifacts.html (opens in a new tab)

Variables

Variablen sind in CI/CD nicht nur gut zur Speicherung von wiederkehrenden Werten, sondern auch zum Schutz von Passwörtern und Nutzernamen.
Denn solche sensible Daten darf man nicht sichtbar im Script platzieren.

Variablen können auf GitLab definiert werden.

vars

Im Code können diese dann mit einem Dollar Zeichen verwendet werden: $PASSWORD

Runner

Um das vorhin beschriebene .gitlab-ci.yml File verwenden zu können, benötigt man einen Runner. Ein Runner ist eine externe Maschine, welchen den Code ausführen kann.
Bei der Erstellung eines Runners kann gewählt werden, welche Infrastruktur/Plattform darauf sein soll.

runner

Dies sind die Features der Runner: https://docs.gitlab.com/runner/#features (opens in a new tab)

Specific Runner

Um Runners zu verwenden, gibt es zwei Möglichkeiten. Eine davon ist die Verwendung eines specific Runners. Dabei wird ein eigener Runner auf einem System erstellt.

Script zur Erstellung eines GitLab Runners
# Download and install binary
# Download the binary for your system
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
 
# Give it permission to execute
sudo chmod +x /usr/local/bin/gitlab-runner
 
# The rest of the commands execute as the user who will run the runner
# Register the runner (steps below), then run
cd ~
gitlab-runner install
gitlab-runner start
 
# Command to register runner
gitlab-runner register --url https://git.namics.com/ --registration-token $REGISTRATION_TOKEN

Beim Setup wird man nach einem Executer gefragt. Auf dem Executer wird schlussendlich der Code ausgeführt.

Shared Runners

Die gängigere Variante ist die Verwendung von shared Runners zu aktivieren. Shared Runners sind Runners, welche über die gesamte GitLab Instanz geteilt werden.
Um das Yaml File auszuführen, wird ein passender Runner des Pools genutzt.

shared-runners

Docker-Image

Die Scripts aus dem Yaml File werden in der Regel nicht direkt auf den Runners ausgeführt. Meistens wird, mithilfe eines Docker Images, eine passende Umgebungen definiert.

Ein Docker ist im Grunde genommen eine virtuelle Maschine, deren Konfiguration (Systeme und Versionen) definiert werden kann. Dadurch wird garantiert, dass der Code in einer konsistenten Umgebung ausgeführt wird. Insbesondere bei Testprozessen ist diese einheitliche Umgebung von Vorteil.
Und wenn nicht alle Mitglieder eines Entwicklungsteams dasselbe Betriebssystem verwenden, kann Docker ebenfalls die Lösung sein.

Ein Docker Image ist eine Definition, welche als Anleitung zum Bau eines Docker Containers verwendet wird. Sie gibt vor, was der Container für Spezifikation haben muss.

Beispiel

Ich habe ein Projekt, welches auf Node 16.17.0 läuft. Nun will ich es beim Merge auf den Master automatisch deployen.
Natürlich könnte ich im Export Script auf dem Runner eine Node-Version-Manager installieren und damit die Node-Version auslesen, herunterladen und verwenden. Dies wird aber schnell kompliziert. Und wenn man dann davor noch Tests durchführen will, benötigt man eventuell noch weitere Umgebungen. Der einfachste Weg ist also, ein Image bei den Scripts anzugeben. So kann man die Befehle direkt auf der gewünschten Umgebung ausführen.
Ein weiterer Vorteil dieses Vorgehens ist, dass man dieselbe Umgebung für mehrere Scripts verwenden kann.

Alle Images findet man hier: https://hub.docker.com/ (opens in a new tab)

Einsatzmöglichkeiten

Um einen Denkanstoss zu geben, werden hier drei der Einsatzmöglichkeiten von CI/CD aufgezeigt:

  • Builds & Deployments: Durch die Automatisierung dieser Prozesse spart man Zeit. Zudem können auch Fehler vermieden werden.
  • Testing: Die Code Qualität und Sicherheit kann bei jedem Push/Merge/Deployment sichergestellt werden.
  • Überwachung: Durch Scripts kann die Performance, Fehlermeldungen und Sicherheitsbedrohungen einer Applikation automatisch überwacht werden. So werden Probleme schneller erkannt.

Fazit

Mit einem guten CI/CD Setup, kann man Aufgaben zuverlässig und automatisiert durchführen.
Es ist also durchaus sinnvoll, sich ein solches Script zu erstellen. Denn auf lange Sicht wird dadurch viel Zeit und Arbeit gespart.