10 Punkte von GN⁺ 2026-01-15 | 3 Kommentare | Auf WhatsApp teilen
  • Geteilte Frustration eines Entwicklers über die langsame Feedback-Schleife und den komplizierten Debugging-Prozess von GitHub Actions
  • Im Projekt tmplr wurden über build.rs mit 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.rs entfernt 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.rs wurde CUE genutzt, um README.md, CHANGELOG.md sowie 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.rs wurde 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

 
anyflow 2026-01-18

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.“

 
iolothebard 2026-01-15

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.

 
GN⁺ 2026-01-15
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_dispatch und gh workflow run ist auch ganz gut, aber es ist unpraktisch, dass Letzteres nicht direkt die URL des gestarteten Workflows liefert

    • Mit nektos/act kann man Actions lokal ausführen
      Das war ziemlich erfolgreich, um schnelles Feedback zu bekommen
    • Ich habe standardisiert, dass Actions Docker-Images baut und testet
      Wenn es Probleme gibt, kann ich in einem Zustand debuggen, der der GitHub-Actions-Umgebung fast entspricht
    • Ich finde, dass es keinen Sinn ergibt, wenn sich CI-Schritte nicht lokal ausführen lassen
      Das sollte eine Grundanforderung jedes CI-Systems sein
    • Ich habe schon darüber nachgedacht, selbst ein CI-Tool zu bauen, das lokal laufen kann
      Am Ende sind Dinge wie Queueing, Ausgabeanalyse und Build-Historien-Telemetrie entscheidend
    • Um bei gh workflow run eine URL zu bekommen, musste ich die Liste der Workflow-Ausführungen über die GitHub-API erneut abrufen
      Wenn mehrere Läufe gleichzeitig stattfinden, kann das durcheinandergeraten, aber im Moment funktioniert es ganz ordentlich
  • Ich habe ein paar Tipps zum CI-Design zusammengestellt

    1. Eine CI-freundliche Skriptsprache wie pwsh statt bash verwenden
    2. Keine Logik in Workflows packen und sie einfach halten
    3. Als unabhängige Skripte bauen, damit sie lokal testbar sind
    4. Statusausgaben und Versionsinformationen hinterlassen, um Debugging zu erleichtern
    5. Drittanbieter-Runner mit guten Debugging-Funktionen in Betracht ziehen
    • Mit (1) stimme ich nicht überein. Wenn Build- oder Testprozesse komplex werden, ist das für mich ein Geruchssignal
      Eine einfache Shell sollte ausreichen
    • Mit (1) stimme ich nicht überein, aber (2) halte ich für richtig
      Es ist gut, CI-Ziele in einer Makefile zu definieren und sie dann einfach wie make ci-test aufzurufen
    • Ich habe früher einmal die Jenkins-Plugin-Hölle erlebt
      Seitdem verwalte ich alle CI-Abläufe mit einfachen Wrappern wie make build
    • Wenn man alle Builds in ein einzelnes Skript packt, verliert das CI-System die Einblicke in die einzelnen Schritte
      Es wäre gut, wenn man sie mit Markern wie BeginStep("Step Name") trennen könnte
    • Letztlich frage ich mich bei so einer Struktur, ob man nicht ein neues CI-Tool braucht, das Skripte direkt ausführt
  • Das 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

    • Viele Leute stören sich daran, dass man auf eine fehlgeschlagene VM nicht per SSH direkt zugreifen und debuggen kann
      Stattdessen muss man jedes Mal den Workflow ändern, pushen und warten
    • Manche machen Witze darüber, dass so eine Skriptisierung „eine bezahlte Aufgabe für ein paar Wochen“ sei
    • CI-spezifische Funktionen wie Deployment, Release oder Caching lassen sich lokal nur schwer vollständig nachbilden
    • Dieser Ansatz erinnert ein wenig an die Zeit, in der systemd init.d-Skripte aufrief, aber schlecht ist das nicht
    • Jemand behauptet sogar: „Das ist zu 100 % die Schuld von GitHub Actions“
  • 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

    • Ich mag SourceHut CI
      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
    • In GitLab CI habe ich ähnlich mit einem dedizierten Docker-Image gearbeitet
      Standardisierung wird dadurch einfacher, aber dafür entsteht der Trade-off der Image-Wartung
    • Ein Nachteil ist, dass sich macOS-Builds schwer containerisieren lassen
    • Die Webhooks von GitHub sind sehr detailliert
      Eigentlich gibt es also kaum Lock-in, aber die Leute hängen im CI/CD-Cargokult fest
    • Es gab auch Reaktionen wie: „Bitte schick das als Newsletter“
  • 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

    • Ich stimme dem Nix-Ansatz ebenfalls zu
      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 uv automatisch installiert wird und Abhängigkeiten verwaltet, wäre ideal
    Es ist komplexer als bash, aber in der Actions-Umgebung ist die Performance kein großes Problem

    • Tatsächlich ist YAML für die Definition der Laufzeitumgebung gedacht, und die Ausführungslogik sollte in externe Skripte ausgelagert werden
  • 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 action gebaut
    Es findet die neueste oder aktuell laufende Action des aktuellen Branches
    GitHub-Link

    • Die Reaktionen waren positiv, nach dem Motto: „Das hätte eine Funktion der gh-CLI sein sollen“
      Es gab allerdings einen Bug, bei dem im Befehl gg tui das Repository nicht sichtbar war
  • Ich habe mich gefragt, ob ein Tool wie act helfen könnte
    nektos/act
    Wegen Architekturunterschieden können lokale und Online-Ausführung abweichen, aber es wirkt dennoch nützlich

    • Als ich es früher angesehen habe, war es kein vollständiger Ersatz
      Es hatte ungefähr 80 % Kompatibilität
    • Es ist nicht vollkommen identisch, aber für eine schnelle Feedback-Schleife sehr nützlich
    • Was man eigentlich am meisten braucht, ist die Möglichkeit, nach einem Fehlschlag per SSH zuzugreifen und zu debuggen
      SourceHut unterstützt das, und das ist wirklich praktisch