Ich hasse GitHub Actions wirklich
(xlii.space)- Geteilte Frustration eines Entwicklers über die langsame Feedback-Schleife und den komplizierten Debugging-Prozess von GitHub Actions
- Im Projekt tmplr wurden über
build.rsmit CUE Dokumente erzeugt, doch mit dem Fehlschlagen des CI-Builds begannen die Probleme - Von vier Plattformen schlug nur der Build für Linux ARM fehl; Ursache ist das Verhalten von GitHub Actions, bei Cross-Builds x86_64-Binärdateien auf arm64-Runnern zu verbergen
- Die ineffiziente Feedback-Schleife mit 2–3 Minuten pro Test einer einzelnen Änderung wiederholte sich ständig
- Als Lösung wurde
build.rsentfernt und auf ein GNU Makefile umgestellt, um die CI-Logik direkt zu steuern
Hintergrund des Problems
- tmplr ist ein Datei-/Projekt-Scaffolding-Tool, das von Menschen lesbare und schreibbare Template-Dateien verwendet
- In
build.rswurde CUE genutzt, umREADME.md,CHANGELOG.mdsowie Versions-/Hilfedateien zu erzeugen und so Konsistenz sicherzustellen - Die eigentliche Arbeit war in etwa 1,5 Stunden erledigt, und ein dazugehöriger Artikel war ebenfalls bereits geschrieben
- Lokal funktionierte alles problemlos, doch in der CI-Umgebung von GitHub Actions schlug der Build fehl, weil die CUE-Binärdatei nicht installiert war
Ursache des Build-Fehlers
- Von vier Plattformen (Linux ARM, macOS ARM, Linux x86_64, macOS x86_64) trat nur auf Linux ARM der Fehler „command not found“ auf
- Ursache: Matrix-Cross-Builds sind stark isoliert, daher wurde CUE nur auf dem x86_64-Linux-Host und dem macOS-ARM-Host installiert
- macOS kann x86_64-Binärdateien problemlos ausführen
- Linux x86_64 kann x86_64-Binärdateien ebenfalls problemlos ausführen
- GitHub Actions jedoch verbirgt auf arm64-Runnern x86_64-Binärdateien, sodass sie nicht ausgeführt werden können
Ineffiziente Feedback-Schleife
- Zur Problemlösung wurde immer wieder derselbe Ablauf wiederholt:
1. Nach möglichen Lösungswegen suchen
2.ci.ymländern
3. Committen und pushen (jj squash --ignore-immutable && jj git push)
4. Den Tab „Actions“ öffnen
5. Den neuesten Lauf öffnen
6. Den Linux-ARM-Lauf öffnen
7. Einige Sekunden warten
8. Frustriert sein
9. Wiederholen - Pro einzelner Änderung vergingen 2–3 Minuten
- Im Idealfall würde GitHub entweder einen voll ausgestatteten lokalen Runner bereitstellen oder eine Möglichkeit bieten, nach dem Push den Fortschritt schnell zu überprüfen
- Etwa eine Funktion wie ein „scratch commit“: eine Möglichkeit, verschiedene Läufe zu testen, ohne die Git-Historie und den Verlauf der Actions-Ausführungen zu verschmutzen
- Eine solche Funktion gibt es derzeit jedoch nicht
Lösung
- Nach 30 Minuten in dieser Schleife wurde abgebrochen
- Es wurde ein bekannter Rat aus dem Internet übernommen: „Lass GitHub Actions nicht die Logik verwalten, sondern steuere die Skripte selbst und lasse Actions diese Skripte nur aufrufen“
build.rswurde gelöscht (bedauerlich, aber ein notwendiges Opfer)- Alle Generierungsaufgaben wurden in ein GNU Makefile verlagert
- Die erzeugten Dateien wurden ins Repository committed, und die Änderungen an der CI wurden zurückgenommen
- Das Problem war damit gelöst
Fazit
- GitHub Actions ist ein Grund dafür, dass man auf manche guten Dinge verzichten muss
- Beim Debuggen von Runnern oder beim Optimieren des Build-Prozesses geht viel Zeit verloren
- Gleichzeitig gibt es Vorteile wie macOS-Builds, die sich auf anderem Weg nur schwer bekommen lassen
- Natürlich ist auch kein anderes System bekannt, das sich einfacher einrichten lässt als GitHub Actions
We are all doomed to GitHub Actions. …but at least I dodged the bullet early.
3 Kommentare
Es scheint ein unvermeidbares Problem zu sein, weil die Struktur verlangt, Logik in YAML unterzubringen.
Der obige Artikel scheint grob die folgende Antwort zu geben, aber wenn man den Skriptteil durch Dagger ersetzt, könnte das nicht eigentlich die richtige Lösung sein.
„GitHub Actions sollte nicht die Logik verwalten; stattdessen sollte man die Skripte direkt kontrollieren und Actions nur diese Skripte aufrufen lassen.“
GitHub Actions sollte nur für das Setup der Umgebung (OS, Build-Toolchain, …) und das Ausführen von Skripten (Shell, Python, bat, ps1 …) verwendet werden. Selbst wenn GitHub ausfällt, sollte man überall bauen können, solange die Umgebung vorhanden ist. Wenn ich mir heutzutage GitHub-Action-Workflows anschaue, frage ich mich, ob man wirklich extra so etwas suchen und benutzen muss. Vor langer, langer Zeit (?) ist Ansible genau daran gescheitert.
Hacker-News-Kommentare
Das Kernproblem von GitHub Actions ist, dass die Feedback-Schleife viel zu langsam ist
Es ist wirklich frustrierend, nach einem Push warten zu müssen, nur um einen einfachen Fehler zu bestätigen
Ich halte es für besser, CI-Jobs in lokal ausführbare Skripte auszulagern und Actions nur als progressive Erweiterung zu verwenden
Die Kombination aus
workflow_dispatchundgh workflow runist auch ganz gut, aber es ist unpraktisch, dass Letzteres nicht direkt die URL des gestarteten Workflows liefertDas war ziemlich erfolgreich, um schnelles Feedback zu bekommen
Wenn es Probleme gibt, kann ich in einem Zustand debuggen, der der GitHub-Actions-Umgebung fast entspricht
Das sollte eine Grundanforderung jedes CI-Systems sein
Am Ende sind Dinge wie Queueing, Ausgabeanalyse und Build-Historien-Telemetrie entscheidend
gh workflow runeine URL zu bekommen, musste ich die Liste der Workflow-Ausführungen über die GitHub-API erneut abrufenWenn mehrere Läufe gleichzeitig stattfinden, kann das durcheinandergeraten, aber im Moment funktioniert es ganz ordentlich
Ich habe ein paar Tipps zum CI-Design zusammengestellt
Eine einfache Shell sollte ausreichen
Es ist gut, CI-Ziele in einer
Makefilezu definieren und sie dann einfach wiemake ci-testaufzurufenSeitdem verwalte ich alle CI-Abläufe mit einfachen Wrappern wie
make buildEs wäre gut, wenn man sie mit Markern wie
BeginStep("Step Name")trennen könnteDas Problem ist weniger GitHub Actions selbst als die chaotisch darauf aufgesetzte Automatisierung
Die Logik sollte in einer Sprache wie Python als Skript umgesetzt werden, damit sie auch lokal ausführbar ist
Stattdessen muss man jedes Mal den Workflow ändern, pushen und warten
Ich erledige meine gesamte CI innerhalb von Containern
Die CI-Plattform führt dann nur noch diesen Container aus, sodass lokal dasselbe läuft
Plattformen mögen diesen Ansatz nicht, weil er den Vendor Lock-in aufbricht
Bei Fehlern kann man sich per SSH direkt einloggen und debuggen, und man kann das Manifest ändern und erneut ausführen, ohne einen Branch zu pushen
Allerdings ist Self-Hosting nötig
Standardisierung wird dadurch einfacher, aber dafür entsteht der Trade-off der Image-Wartung
Eigentlich gibt es also kaum Lock-in, aber die Leute hängen im CI/CD-Cargokult fest
Ich mag GitHub Actions
Es ist besser als das frühere Travis und als kostenlose Ressource für OSS-Projekte sehr nützlich
Seit ich Nix eingeführt habe, ist die Reproduzierbarkeit der Umgebung viel besser, und dadurch passt es deutlich besser zu Actions
Einen mit flake gebauten Container kann man in Actions direkt unverändert ausführen
Beispielprojekt
Ich finde, GitHub Actions sollte schlicht bash- oder Python-Skripte aufrufen
bash hat viele Grenzen, Python ist flexibler und lässt sich auch lokal leicht ausführen
Ein Ansatz wie in diesem Artikel, bei dem
uvautomatisch installiert wird und Abhängigkeiten verwaltet, wäre idealEs ist komplexer als bash, aber in der Actions-Umgebung ist die Performance kein großes Problem
Das größte Problem von Actions ist die Werbebotschaft, man solle „Workflows zusammenbauen“
Debugging ist fast unmöglich, und die Cache-Konfiguration ist heikel, wodurch Builds langsam werden
Deshalb wirkt ein Ansatz, bei dem man direkt auf einer persistenten VM ausführt, attraktiv
Ich bin der Gründer von Depot
Ich betreibe einen Service, der GitHub-Actions-Runner schneller und günstiger bereitstellt
Vieles von dem Frust, den die Leute schildern, entspricht tatsächlich der Mehrheitsmeinung
Das Actions-System ist strukturell ineffizient, und wir entdecken jede Woche neue Flaschenhälse
Ich bin überzeugt, dass es bessere Wege gibt, und experimentiere damit
Mehr dazu auf depot.dev
Letztes Wochenende habe ich ein Tool namens
gg watch actiongebautEs findet die neueste oder aktuell laufende Action des aktuellen Branches
GitHub-Link
gh-CLI sein sollen“Es gab allerdings einen Bug, bei dem im Befehl
gg tuidas Repository nicht sichtbar warIch habe mich gefragt, ob ein Tool wie
acthelfen könntenektos/act
Wegen Architekturunterschieden können lokale und Online-Ausführung abweichen, aber es wirkt dennoch nützlich
Es hatte ungefähr 80 % Kompatibilität
SourceHut unterstützt das, und das ist wirklich praktisch