/ci-audit – Finde und behebe verschwendete GitHub Actions Zeit
Messen zuerst, dann die wenigen Dinge reparieren, die wirklich zählen. In echten Audits war der größte Gewinn selten eine langsame Testsuite. Es war eine geplante Pipeline, die monatelang jeden Tag fehlschlug, ein 30-Sekunden-stündlicher Cron, der als 730 Minuten pro Monat abgerechnet wurde, oder ein SDK, das eine tote Anfrage dreimal stillschweigend wiederholte.
Ein Stdlib-Skript, scripts/ci_audit.py in diesem Skill-Ordner, führt die Messungen durch. Du liest seine Ausgabe, entscheidest, was sich zu reparieren lohnt, und setzt es um.
python3 <skill-verzeichnis>/scripts/ci_audit.py inventory <besitzer> # welche Repos Actions ausführen, privat vs. öffentlich
python3 <skill-verzeichnis>/scripts/ci_audit.py month <besitzer/repo> # abrechenbare Minuten pro Workflow, 30 Tage
python3 <skill-verzeichnis>/scripts/ci_audit.py jobs <besitzer/repo> --runs 150 # Queue / Setup / Laufzeit pro Job
python3 <skill-verzeichnis>/scripts/ci_audit.py steps <besitzer/repo> <run-id> # Sekunden pro Schritt für einen Durchlauf
python3 <skill-verzeichnis>/scripts/ci_audit.py schedules <besitzer/repo> # jeden Cron als Läufe pro Monat
Es benötigt die GitHub CLI (gh), die angemeldet ist. month und jobs machen einen API-Aufruf pro Lauf, daher dauert ein aktives Repository ein oder zwei Minuten. Führe sie im Hintergrund aus.
Schritt 0 – Umfang und Regeln
Bevor gemessen wird, kläre mit dem Benutzer:
- Welche Besitzer und Repos. Ein Repository oder alles, was in den letzten 60 Tagen gepusht wurde.
- Nicht betretbare Repos. Jemand anderes (ein Teammitglied, ein anderer Agent) arbeitet dort an einer Funktion. Diese erhalten ein Issue mit Zahlen, niemals einen gepushten Branch.
- Wohin Merges gehen. Der Integrationsbranch (
development, beispielsweise) standardmäßig. Die Veröffentlichung auf den Standardbranch ist ein separates Ja, aber Crons und geplante Korrekturen werden erst danach wirksam (Schritt 6). - Was nicht im Rahmen ist: Reduzierung der Testabdeckung, kostenpflichtige Runner, Wechsel des CI-Anbieters. Empfehle diese mit Zahlen; führe sie nicht durch.
Lese jetzt references/gotchas.md.
Schritt 1 – Inventur und Geld
ci_audit.py inventory <besitzer>für jeden Besitzer. Notiere privat vs. öffentlich: Nur private Repos kosten Geld, aber die Wartezeit jedes Repos zählt, wenn Agenten auf CI blockieren.- Für eine Organisation: Rufe die echte Abrechnung ab:
gh api "/organizations/<org>/settings/billing/usage?year=JJJJ&month=M". Für ein persönliches Konto verwendeci_audit.py monthfür jedes private Repo und vergleiche die Summe mit den im Tarif enthaltenen Minuten. - Notiere die Top-5-Repos nach abrechenbaren Minuten. Dort geht die Zeit hin.
Schritt 2 – Defekt vor langsam
Für jedes Repository mit geplanten Workflows:
- Überprüfe die letzten 10 geplanten Läufe pro Workflow. Jeder Workflow, der jedes Mal fehlschlägt, ist der erste Befund, unabhängig von seinen Kosten. Lese seine Logs (
gh api repos/O/R/actions/runs/<id>/logs > logs.zip). - Führe
actionlintauf.github/workflows/aus. Eine Datei, die GitHub nicht parsen kann, führt ihren Zeitplan nie aus.
Erwarte geschichtete Fehler. Siehe references/fixes.md §1.
Schritt 3 – Zeitpläne
ci_audit.py schedules <repo> für jedes Repository mit Crons. Multipliziere Läufe/Monat mit den abgerechneten Minuten pro Lauf (von jobs). Markiere:
- Kurze Jobs mit engen Zeitplänen (ein stündlicher 30-Sekunden-Check entspricht 730 abgerechneten Minuten/Monat).
- Mehrere Crons zur gleichen Minute, die dieselbe ratenbegrenzte API aufrufen.
- Monatliche Crons, die einen einzigen riesigen Lauf machen. Verteile die Arbeit auf Nächte.
Schritt 4 – Aufschlüsselung pro Job
Für die Top-Repos: ci_audit.py jobs <repo> --runs 150, dann steps auf einem aktuellen grünen Lauf jedes teuren Jobs. Klassifiziere die Zeit jedes Jobs:
| Kategorie | Worauf es hinweist |
|---|---|
| Warteschlange hoch | Runner-Konkurrenz oder Parallelitätsgruppen. Meist nicht günstig behebbar; notiere es. |
| Setup hoch | Abhängigkeitsinstallation und Caching (references/fixes.md §3–4). |
| Laufzeit hoch, App-Tests | Echte Testzeit. Lass es, es sei denn, ein Schritt ist offensichtlich redundant. |
| Laufzeit hoch, Datenpipeline | Instrumentiere Phasen und behebe den Code, nicht die CI (references/fixes.md §6). |
| Fehlschläge > 5% | Flaky Tests oder defekte Pipelines (references/fixes.md §1, §7). |
Schritt 5 – Bericht und Auswahl
Erstelle eine Tabelle, sortiert nach geschätzten eingesparten Minuten pro Monat:
| Repo | Befund | Beleg | Korrektur | Geschätzte Einsparung/Monat | Risiko |
|---|
Füge Befunde hinzu, die du nicht beheben wirst (nicht betretbare Repos, Entscheidungen des Besitzers wie Cron-Frequenz oder Parallelität) mit den Zahlen, die der Besitzer benötigt, um zu entscheiden. Zeige sie dem Benutzer und hole eine Freigabe, welche Zeilen umgesetzt werden sollen. Archiviere sie als ${MAKERSKILLS_CONFIG:-$HOME/.config/makerskills}/ci-audit/archive/<YYYY-MM-DD>-<umfang>.md.
Schritt 6 – Korrekturdurchlauf
Ein Repository, ein Arbeiter. Auf Hosts, die Subagenten unterstützen, führe Repos parallel mit derselben Anweisung aus: frischer Klon, zuerst Issue, Branch benannt nach dem Issue, kleine Commits, Vorher/Nachher-Zahlen im PR-Text.
Für jede Korrektur:
- Öffne ein Issue mit der Messung.
- Nimm die Änderung auf einem Branch vor. Führe Lint und Tests lokal aus und bestätige durch den Exit-Code.
- Beweise es: Push, dann führe die CI des PR erneut aus, damit der Cache warm ist, und vergleiche mit einer Basislinie aus mehreren alten Läufen. Für Pipeline-Korrekturen löse den Workflow vom Branch mit einer kleinen Begrenzung aus.
- Wenn die Änderung nicht geholfen hat (das kommt vor, z.B. Playwright-Caches), schließe den PR mit den Zahlen. Das ist ein Ergebnis, kein Fehlschlag.
- Merge in den Integrationsbranch nach Review und grünen Checks.
- Für alles Geplante öffne den Release-PR zum Standardbranch, sobald der Benutzer zustimmt. Bis dahin ändert sich nichts in der Produktion.
Schritt 7 – Verifizieren und protokollieren
- Lies nach dem nächsten geplanten Lauf seine Zeitmessungen und Logs. Bestätige, dass die Korrektur in der Produktion und nicht nur im Branch gehalten hat.
- Füge die Ergebnisse zur Archivdatei hinzu: Vorher/Nachher pro Repo, was ohne Merge geschlossen wurde, und neue Stolperfallen.
- Schlage vor, das Audit monatlich oder immer dann zu wiederholen, wenn sich CI langsam anfühlt. Eine wiederkehrende Erinnerung (
loopify) funktioniert gut.
Kombiniert mit
loopify– plane ein monatliches Re-Audit oder eine Überprüfung am nächsten Morgen des ersten geplanten Laufs.castmate– hole eine zweite Modellbewertung zu einer riskanten Workflow-Änderung ein.unstuck– wenn eine Korrektur, die funktionieren sollte, langsamer misst, bevor du sie aufgibst.project-manager– verfolge Entscheidungen des Besitzers (Cron-Frequenz, kostenpflichtige Runner), die das Audit aufgedeckt, aber nicht umgesetzt hat.
Hinweise zur Qualität
- Defekt schlägt langsam. Überprüfe immer zuerst fehlschlagende geplante Workflows, bevor du Zeitmessungen durchführst. Eine tägliche Pipeline, die sechs Monate lang fehlschlägt, ist ein größerer Verlust als jeder Cache.
- Warme Zahlen oder keine Behauptung. Melde niemals eine Beschleunigung von einem einzelnen kalten Lauf. Wiederhole den Lauf, erstelle eine Basislinie aus mehreren alten Läufen und gib beide Zahlen im PR an.
- Abgerechnete Minuten, nicht Sekunden. Die Rundung pro Job bedeutet, dass weniger, vollere Jobs viele winzige auf privaten Repos schlagen. Parallelisierung ist eine Geschwindigkeitsentscheidung mit Kosten, kein kostenloser Gewinn.
- Gleiche Abdeckung, jedes Mal. Die Testanzahl vorher und nachher gehört in den PR-Text. Eine schnellere Suite, die weniger testet, ist keine Korrektur.
- Geplant bedeutet Standardbranch. Bezeichne eine Cron- oder Pipeline-Korrektur erst als erledigt, wenn sie auf dem Standardbranch ist und ein geplanter Lauf vergangen ist.
- Schließe fehlgeschlagene Experimente mit Daten. Ein PR, der langsamer gemessen hat, wird mit seinen Zahlen geschlossen, damit niemand im nächsten Quartal dieselbe Idee erneut versucht.
- Respektiere die Branches anderer. Nicht betretbare Repos erhalten Issues, niemals Pushe.