- Unzufriedenheit mit GitHub Actions
- Das Team besteht aus etwa 15 Engineers, und alle pushen fortlaufend Code in den
main-Branch
- Der Code liegt als Monorepo vor, das in mehrere Module aufgeteilt ist, und wird per trunk-basierter Entwicklung mehrmals täglich deployt
- Es gibt zwar Fälle, in denen sich GitHub Actions gut einsetzen lässt, aber ab einer bestimmten Größenordnung oder in bestimmten Umgebungen treten die Grenzen deutlich zutage
Pull Requests und verpflichtende Checks
- Das Monorepo ist in mehrere Ordner aufgeteilt, und für jeden Ordner werden Tests, Build und Deployment unabhängig voneinander ausgeführt
- Mithilfe der
paths-Funktion von GitHub Actions werden die jeweiligen Pipelines nur dann getriggert, wenn sich ein bestimmter Ordner geändert hat
- Dass vor dem Merge eines Pull Requests alle Checks erfolgreich sein müssen, ist grundsätzlich ein gutes Prinzip, führt aber in Kombination mit einer Monorepo-Struktur zu Problemen
- Beispiel: Der Check
web-app1 - Unit tests ist als „verpflichtend“ markiert, wird aber gar nicht ausgeführt, wenn es im Ordner web-app1 keine Änderungen gibt
- Das Ergebnis ist, dass selbst wenn nur ein Ordner geändert wurde, die Tests für andere Ordner nicht laufen und der Merge dadurch insgesamt unmöglich wird
- Wenn GitHub das nicht am Namen verpflichtender Checks festmachen würde, sondern nach dem Prinzip „Merge möglich, wenn alle aktuell getriggerten Checks bestanden haben“, ließe sich das lösen — bedauerlicherweise hat sich daran seit drei Jahren nichts geändert
- In den zugehörigen GitHub-Issue-Threads 1, 2 ist ebenfalls zu sehen, wie groß die Auswirkungen dieses Problems sind
- Am Ende führt das dazu, dass man zum Umgehen des Problems zusätzliche Pipelines ausführen oder pflegen muss, was komplex und teuer ist
Wiederverwendbarkeit und YAML
- Je größer die Pipelines werden, desto schwerer lassen sie sich mit GitHub Actions verwalten
- Es sammeln sich viele
if-Bedingungen an, und selbst wenn man Workflows aufteilt, sinkt die Wartbarkeit, weil zu viele Dateien verwaltet werden müssen
- Selbst bei wiederverwendbaren Komponenten erfordern Aufrufe, die eigentlich mit einer Zeile erledigt sein sollten, mehrere Zeilen und doppelte Konfigurationen; dadurch haben sich im
.github-Ordner bereits mehr als 30 Dateien angesammelt
- Auch
needs-Abschnitte sind problematisch: Wenn beim Refactoring gelöschte Jobs dort nicht nachgezogen werden, dauert es oft, bis der Fehler auffällt
- GitHub Actions lässt sich nicht lokal ausführen, was Entwicklung und Tests erschwert
- Es gibt zwar Tools wie
act, diese haben in der Praxis aber viele Einschränkungen und bleiben oft hinter den Erwartungen zurück
GitHubs mangelndes Interesse
- Das größte Problem an den genannten Punkten ist, dass GitHub diese Issues offenbar nicht besonders wichtig nimmt
- Viele Issues sind seit Jahren offen und nicht Teil der öffentlichen Roadmap, was nicht nach ernsthaftem Verbesserungswillen aussieht
- Auch bei Problemen, über die lange Zeit viel gesprochen wurde, gab es zuletzt Gegenwind aus der Community, nachdem viele Issues geschlossen wurden
Optionen
- Angesichts dieser Probleme und der fehlenden Bereitschaft von GitHub, sie zu verbessern, sollte man vor der Einführung von GitHub Actions sorgfältig abwägen
- Am Markt gibt es zahlreiche andere CI/CD-Optionen wie GitLab, Jenkins oder TeamCity
- Auch Tools wie Dagger, die einen neuen Ansatz verfolgen, sind einen Blick wert
6 Kommentare
CI/CD? GitLab ist einfach das Beste.
Ich hatte auch die Erinnerung daran, dass ich nach GitLab in einer GitHub-Actions-Umgebung das Gefühl hatte, dass einfach nichts funktioniert ...
Dass man Repositories auf GitHub nicht nach Gruppen gebündelt verwalten kann, ist für mich auch einer der größten Kritikpunkte..
Ich finde, GitLab ist für Pipelines wirklich sehr gut. Alles, was oben erwähnt wurde, ist in GitLab nämlich möglich.
Im Fall eines Monorepos lässt sich bequem konfigurieren, welche Tests oder sonstigen Abläufe ausgeführt werden sollen, wenn sich ein bestimmter Ordner ändert.
Dafür muss man die Geschichte von GitHub Actions kennen ...
Die ersten GitHub Actions sahen nämlich ganz anders aus als heute ...
Etwa 6 Monate vor der Öffnung (meine Erinnerung ist etwas verschwommen) wurde GitHub von Microsoft übernommen, und ich meine, die Entwicklung von Actions wurde dann bei Microsoft gemeinsam mit dem Azure-DevOps-Team vorangetrieben.
Damals kamen bei Azure DevOps keine neuen Funktionen mehr hinzu, während die Funktionen aus Azure DevOps in GitHub Actions als neue Features erschienen ...
Zu dieser Zeit wurde auch auf YAML umgestellt, und so entstand die heutige Umgebung ... schluchz.
Danach scheinen die Entwickler wieder in ihre jeweiligen Bereiche zurückgegangen zu sein, sodass es so wirkt, als würde daran nicht mehr wirklich gearbeitet werden ...
Schade ...
In unserer Firma haben wir CI/CD auf Basis von GitHub Actions aufgebaut ... Da es uns bisher noch an nichts fehlt, nutzen wir es weiterhin ...
Man sollte das wohl aufmerksam weiter beobachten ...
Hacker-News-Kommentare
Eine Pipeline-DSL sollte keine eigentliche Logik enthalten, sondern nur zum Orchestrieren von Jobs verwendet werden. Komplexe Aufgaben sollten als Skripte erstellt werden, damit sie sich einfach ausführen lassen. So können dieselben Aufgaben in GitHub Actions, Jenkins, Azure DevOps usw. unkompliziert ausgeführt werden.
Beim Einrichten von GitHub Actions ist es besser, vorgefertigte Actions zu vermeiden und sie nur als einfachen Shell-Runner zu verwenden. Wenn man Skripte in Python, Ruby, Bash usw. schreibt und sie in GitHub Actions ausführt, lassen sie sich lokal leichter testen und unnötiger Schmerz wird vermieden.
GitHub Actions kann Prüfungen nur ausführen, wenn bestimmte Bedingungen erfüllt sind. Wenn man solche Regeln verwendet, stößt man jedoch auf das Problem mit "Pull Requests und erforderlichen Checks". Bei der Nutzung mit externen Diensten müssen erforderliche Checks unbedingt erfolgreich sein, sonst kann nicht gemergt werden.
Um das Problem mit "Pull Requests und erforderlichen Checks" zu lösen, kann man für jeden erforderlichen Check-Workflow eine "No-op"-Version erzeugen, die ausgeführt wird, wenn die Bedingungen nicht erfüllt sind, und mit Code 0 beendet wird. Das ist zwar mit Bordmitteln möglich, aber eine etwas umständliche Lösung.
Travis CI war hervorragend, um CI lokal zu testen. GitHub Actions wurde geschaffen, um mit GitLab CI zu konkurrieren, und GitHub verlor damals Marktanteile im Enterprise-Markt.
Es wird empfohlen, Buildkite auszuprobieren. Wenn man über GitHub Actions hinausgeht, kann Buildkite eine gute Alternative sein. Nach Erfahrung aus einem großen US-Technologieunternehmen war es der einzige angenehme Teil von CI.
Die Architektur von GitHub Actions kann dazu verleiten, falsche Sicherheitsentscheidungen zu treffen. Zum Beispiel sind Organisations- oder Repository-Secrets zwar praktisch, können aber eine Sicherheitslücke sein. Repository-Umgebungen können separate Secrets haben, aber man muss sicherstellen, dass nur die richtigen Workflows auf die richtigen Umgebungen zugreifen können.
Die allgemeine Philosophie von CI-Systemen ist falsch. Anstatt dass CI den Code ausführt, sollte der Code das CI ausführen. CI sollte eine API bereitstellen, damit Nutzer dem System Informationen übergeben können.
Mit Bazel kann man CI-Tools Bazel-Targets bauen lassen und bei Bedarf durch Remote Build Execution die Parallelität erhöhen. Das eignet sich für etwa 10M+ Zeilen Code oder sehr große Services.
In GitHub kann man "erforderliche Checks" festlegen, und diese müssen immer grün sein. Sie werden jedoch nur ausgeführt, wenn es Änderungen in bestimmten Ordnern gibt; gibt es Änderungen in anderen Ordnern, kann nicht gemergt werden. Wenn nicht alle Tests ausgeführt werden, geht der Sinn der Integration verloren, daher sollten Tests so schnell ausführbar sein, dass man sie immer laufen lassen kann.