Dev Life
Private GitHub Actions-Vorlagen für Ihre Organisation
GitHub Actions ist ein relativer Neuling im CI/CD-Bereich, übertrifft aber schnell traditionelle Open-Source-Automatisierungsserver. Das Entwicklungsteam von Sinch Mailgun weiß schon seit einiger Zeit, dass die Community für einige der Tools und Technologien, mit denen wir dies eingerichtet haben, schrumpft und sie Gefahr laufen, zu einer schwer zu pflegenden Nische zu werden. Aus diesen Gründen stellen wir derzeit unsere Jenkins-basierte CI/CD auf GitHub Actions-CI/CD um. Zur vollen Transparenz: Manchmal ist nicht alles im Lieferumfang enthalten – es sei denn, Sie sind ein GitHub Enterprise-Kunde …
Das liegt daran, dass Workflow-Vorlagen in privaten Repositories bis vor kurzem nicht unterstützt wurden und wir auf einen Workaround zurückgreifen mussten. Glücklicherweise hat GitHub kürzlich ein Update veröffentlicht, das diese Funktionalität nun für Enterprise-Abonnements unterstützt. Aber für alle, die die Abonnements GitHub Free oder Team nutzen, besteht das Problem weiterhin. Wir wissen nicht, ob oder wann GitHub dieses Update für andere Abonnements bereitstellt. Hier erfahren Sie in der Zwischenzeit, was wir erlebt und wie wir das Problem gelöst haben.
Die Herausforderung bei der Wiederverwendung von Workflows
Meine bisherige Erfahrung mit GitLab CI verkürzte die Einarbeitungszeit in GitHub Actions, aber die feineren Details erwiesen sich als unterschiedlich. Zum Beispiel ist das Einbinden einer Reihe von Schritten aus einem Projekt in ein anderes ganz anders. Sowohl GitHub Actions als auch GitLab CI unterstützen die Wiederverwendung von Schritten aus einem Repository in einem anderen, aber die Abonnements GitHub Actions Free und Team erfordern, dass die einzubindenden Schritte öffentlich zugänglich sind. In GitLab CI kann man die Authentifizierung verwenden, um die Jobs, Phasen, Variablen usw. eines privaten Repos zu importieren, und zwar mit der includes -Direktive.
Zum Zeitpunkt der Verfassung dieses Artikels gab es bei GitHub Actions Issues (genau genommen zwei), in denen diese gewünschte Funktionalität für private Repos verfolgt wurde. Diese Issues waren seit fast 18 Monaten offen, und die Funktion wurde erst kürzlich für Enterprise-Abonnements hinzugefügt. Ich bin mir nicht sicher, wann (oder ob) diese Funktionalität für alle verfügbar sein wird, aber sie scheint eine wesentliche Voraussetzung zu sein, um die private Wiederverwendung von Workflows zu unterstützen.
Workflow-Vorlagen synchronisieren
Ich habe Stack Overflow-Beiträge durchforstet und mich durch Kommentar-Threads zu GitHub-Issues gegraben, aber keine guten Workarounds für die fehlende Möglichkeit gefunden, Workflows aus anderen privaten Repositories derselben Organisation einzubinden.
Ich dachte, dass Git-Submodule vielleicht eine mögliche Lösung wären. Schließlich ermöglichen sie es, dass ein Repo ein anderes Repo einbindet. Könnten wir unsere Workflow-Vorlagen als Submodul in unser Repo aufnehmen und die Submodul-Verwaltung von Git nutzen, um die Vorlagen auf dem neuesten Stand zu halten? Das könnten wir, allerdings nicht, wenn wir im Vorlagen-Repository Vorlagen haben möchten, die für bestimmte andere Repos irrelevant sind. Git behandelt ein Repo als kleinste Einheit bei der Submodul-Verwaltung, sodass unsere Lösung entweder ein Repo ausschließlich mit relevanten Workflows erfordern oder den Einsatz von Submodulen komplett vermeiden würde.
Wir entschieden uns gegen Submodule, da wir ein einziges Workflow-Repo für Vorlagen in Go und Python (neben anderen) verwenden möchten, aber ich habe aus diesem Gedankengang einige wertvolle Informationen gewonnen. Einige Einige Leute verwenden Symlinks, um Teile eines Repos in ein anderes Repo einzubinden, anstelle von Submodulen.
Also haben wir versucht, unsere Vorlage mit dem Workflow unserer App zu verknüpfen. ln $DIR/workflows/go/build_and_push.yml $DIR/my-app/.github/workflows/build_and_push.yml funktioniert gut, um unsere Workflow-Vorlage mit unserer App zu synchronisieren … bis wir einen Git-Befehl ausführen, der die Vorlage ändert (Git ändert die Inodes von Dateien, die es modifiziert). Da wir Git Pulls für Updates der Vorlagen durchführen möchten, mussten wir eine Lösung finden, die Änderungen aus dem Vorlagen-Repo automatisch auf die Datei einer App anwendet.
GitHub Actions-Vorlagen: Ein akzeptabler Workaround für Nicht-Enterprise-Abonnements
Da es keine native Möglichkeit gibt, private Vorlagen in unsere Workflows einzubinden, und wir unsere Workflow-Vorlagen in einem einzigen Repository speichern möchten, haben wir uns für diese einfache Lösung entschieden, die das Anwenden von Vorlagen-Updates optimiert. Bis die Abonnements GitHub Free und Team private Vorlagen unterstützen, können Sie migrieren, aber dies ist eine mögliche Lösung, die wir erprobt und getestet haben.
Wir fügen Beispiele für Git-Hooks in unser Vorlagen-Repository ein (z. B. hooks/post-checkout.sample), da alle Git-Befehle, die Verknüpfungen aufheben, diese auch wiederherstellen müssen. Die Hooks für post-checkout und post-merge sehen beide so aus:
#!/bin/sh
#
# An example hook script to keep your application workflow up-to-date with this
# template. For example, this updates my-app's workflow with the go template.
#
# To activate, this must have execute permission and be copied like so:
#
# $ cp hooks/post-checkout.sample .git/hooks/post-checkout
# $ chmod +x .git/hooks/post-checkout
# setup our project directory, assumes my-app is sibling
export PROJ_DIR=..
# remove existing workflow for clean install
rm $PROJ_DIR/my-app/.github/workflows/build_and_push.yml
# link app workflow to template
ln -v $PROJ_DIR/workflows/go/build_and_push.yml $PROJ_DIR/my-app/.github/workflows/build_and_push.yml
git merge und git checkout sind häufige Vorgänge, die Verknüpfungen aufheben. Daher führen wir dieses Skript nach diesen Aktionen aus.
Damit Nutzer also Workflow-Vorlagen auf ihre Apps anwenden können, müssen sie Folgendes tun:
- Unser
workflows-Repo klonen. - Die Dateien
hooks/post-checkout.sampleundhooks/post-merge.samplean die jeweilige(n) App(s) anpassen. - Sie an die entsprechenden
.git/hooks-Speicherorte kopieren und ihnen Ausführungsberechtigungen erteilen. - Einen
git checkoutodergit pullausführen (git checkout mastervom primären Branch funktioniert).
Leider hält dies das Vorlagen-Repo nicht von alleine aktuell und erfordert etwas Interaktion von den Projektverantwortlichen, um Updates zu übernehmen – schließlich müssen die Änderungen auf das Remote-Repo angewendet werden. Dies geschieht über die folgenden Befehle:
# from the workflow templates repo
$ git pull
# from the project repo
$ git add .github/workflows/
$ git commit -m "upgrade workflow template"
$ git push
Und danach wird der Workflow mit den aktuellsten Änderungen aus dem Vorlagen-Repo ausgeführt.
Die Einrichtung durch einen Git-basierten Paketmanager vereinfachen
Da wir den Prozess zum Anwenden der Vorlagen optimiert haben, sind wir mit unserem Workaround andere Kompromisse eingegangen. Der offensichtlichste ist die erforderliche Einrichtung. Wir fordern die Nutzer auf, ihre Repositories auf eine bestimmte Weise zu strukturieren und Dateien manuell zu kopieren und einzufügen. Diese Anforderungen tragen zu einer gewissen Fehleranfälligkeit bei, da das System ausfallen kann, wenn Dateien verschoben werden oder sich Inodes ohne unser Wissen ändern.
Wir ziehen jedoch auch einen interessanten Vorteil aus diesem Workaround. Wir haben ein Toolset und Skripte entdeckt, die in einem generischen Kontext funktionieren können. Wir haben einen Git-basierten, generischen Paketmanager erstellt, der Verknüpfungen und Git-Hooks verwendet, um Dateien zwischen Git-Repos zu aktualisieren:
#!/bin/sh
# set paths/files (relative to workflows repo)
export TEMPLATE_DIR=.
export APP_DIR=../my-app
export DOCKER_TEMPL=go/Dockerfile
export WKFLW_TEMPL=go/build.yml
#remove files for clean install
rm $APP_DIR/Dockerfil $APP_DIR/.github/workflows/build.yml
# link app workflow to template
ln -v $TEMPLATE_DIR/$DOCKER_TEMPL $APP_DIR/Dockerfile
ln -v $TEMPLATE_DIR/$WKFLW_TEMPL $APP_DIR/.github/workflows/build.yml
Vor- und Nachteile von GitHub Actions
Warum also GitHub Actions? Nun, unser aktuelles System erfordert Modifikationen, Pull-Requests, Deployments und mehr, um einen neuen Dienst bereitzustellen. Und als GitHub Enterprise-Nutzer verfügen wir über ein großes Kontingent an Ausführungsminuten innerhalb von GitHub Actions und haben uns daher entschlossen, dies als Alternative zu evaluieren.
Nachdem wir einige Zeit mit GitHub Actions verbracht haben, sind hier meine Erkenntnisse:
| Vorteile von GitHub Actions | Nachteile von GitHub Actions |
|---|---|
| Dank gehosteter Runner müssen wir uns nicht um deren Wartung kümmern. | Die Abrechnung erfolgt nach Ausführungsminuten. Wir haben also keinen Anreiz, lang andauernde Tests auf von GitHub gehosteten Runnern durchzuführen. |
| Es bietet einige Sicherheitsvorteile (obwohl es dort kürzlich einen Sicherheitsvorfall). | Es fehlen noch einige Funktionen, die Jenkins bietet. |
| Es verfügt über eine weiter verbreitete, in YAML definierte CI/CD-Syntax. | GitHub verwendet in Actions ähnliche Metaphern und Begrifflichkeiten wie die Konkurrenz, aber diese sind nicht immer identisch. Dies macht die Migration und das Erlernen etwas schwierig. |
| Es ist einfacher, OSS- oder öffentliche Jobs zu integrieren. | Die Arbeit mit Secrets kann gefährlich sein, und das Entwicklungsteam kann unbewusst Daten preisgeben. |
| Die Integration in die GitHub-Benutzeroberfläche macht das Einsehen der CI-Ergebnisse einfach. |
Wie Sie sehen, ist das Gras nicht immer grüner. Wir gehen jedoch davon aus, dass GitHub mit seinen endlosen Ressourcen von Microsoft auf lange Sicht Jenkins überholen wird.
Wie es weitergeht
Unser Workaround ist zwar nicht elegant, aber es ist eine funktionierende Lösung, bis GitHub private Vorlagen für Nicht-Enterprise-Abonnements unterstützt. Wenn dies der Fall ist, können Sie Vorlagen in ein einziges Repository migrieren.
Trotzdem haben wir ein GitHub Enterprise-Konto, aber noch nicht die Möglichkeit, die von GitHub hinzugefügte Funktion für private Repos zu aktivieren. Wir suchen noch nach der Ursache für dieses Problem. Bis dahin nutzen wir unseren Workaround und werden in Zukunft prüfen, ob wir Zugriff auf diese neue Funktion erhalten können. Bleiben Sie dran!