GitHub Actions: Fehlschläge als Push aufs iPhone
GitHub kann dich schon selbst über Workflow-Läufe informieren. Schalte in der App GitHub Mobile die Mitteilungen für Actions ein, und du bekommst einen Push für Läufe, die du gestartet hast. Wenn dir das reicht, brauchst du nichts weiter.
Honk geht einen Schritt weiter. Es meldet Fehlschläge aus vielen Repositories, auch aus Läufen, die andere gestartet haben, und bündelt sie in einer Gruppe pro Workflow und Branch. Sie landen im selben Posteingang wie deine Server und Cronjobs, und sobald der Branch wieder grün ist, gibt Honk Entwarnung. Am schnellsten geht es, wenn du den Webhook von GitHub mit Honk verbindest: eine URL und keine Änderung an deinen Workflows. Willst du lieber im Workflow selbst entscheiden, ergänzt die zweite Hälfte dieser Anleitung einen Schritt am Ende eines Jobs.
Voraussetzungen
- Ein Honk-Konto. Honk gibt es vorerst nur auf Einladung: Zugang anfragen.
- Ein Projekt für CI, in einem Workspace, in dem du Inhaber oder Admin bist.
- Admin-Rechte für das Repository oder die Organisation auf GitHub.
1. GitHub in Honk verbinden
Öffne in der Honk-Web-App das Projekt, geh zu Verbindungen und klick auf Dienst verbinden. Wähle GitHub und klick auf Verbinden. Honk zeigt die Webhook-URL der Verbindung. Sie beginnt mit https://honk-honk.app/v1/hooks/github/.
Klick unter Signaturschlüssel auf Erzeugen, kopiere den Schlüssel und klick dann auf Schlüssel speichern. GitHub signiert jede Zustellung damit, und Honk weist alle ab, die nicht passen. Nach dem Speichern zeigt Honk den Schlüssel nicht mehr an.
2. Den Webhook in GitHub anlegen
Öffne im Repository Settings ▸ Webhooks und klick auf Add webhook. Für alle Repositories auf einmal nimmst du stattdessen Settings ▸ Webhooks der Organisation. Fülle dann aus:
- Payload URL: die URL von Honk.
- Content type:
application/json. Die Standard-Formularkodierung von GitHub kann Honk nicht lesen. - Secret: den Schlüssel, den du erzeugt hast.
- Which events would you like to trigger this webhook?: Wähle Let me select individual events und hake Workflow runs an, dazu Deployment statuses, Releases und Issues, wenn du die auch willst.
Klick auf Add webhook. GitHub schickt sofort einen Ping, und die Verbindung in Honk zeigt ihn als letzte Zustellung.
3. Die Zustellungen prüfen
Der Tab Recent Deliveries des Webhooks in GitHub listet jede Zustellung mit der Antwort von Honk: 202, wenn Honk sie angenommen hat, auch bei Ereignistypen, die es ignoriert, und 401, wenn die Signatur nicht passt. In Honk zeigt die Verbindung, wann zuletzt etwas zugestellt wurde, oder den letzten Fehler.

Der nächste fehlgeschlagene Lauf auf irgendeinem Branch wird gepusht. Mehr braucht es nicht: keine Secrets im Repository, kein zusätzlicher Schritt, und jeder Workflow ist abgedeckt, auch neue.
Was aus jedem Ereignis wird
- Ein fehlgeschlagener Lauf (
workflow_run), auch einer, der nicht starten konnte oder ins Zeitlimit lief: ein Problem, ein Langes Hupen mit dem Titel „CI failed on main · acme/api“, mit der Laufnummer, wer ihn gestartet hat, der Commit-Nachricht und einem Link zum Lauf. Eine Gruppe pro Repository, Workflow und Branch. - Der nächste erfolgreiche Lauf auf diesem Branch: eine Entwarnung, „CI passed on main · acme/api“, die das Problem schließt. Ein Erfolg ohne vorherigen Fehlschlag wird verworfen, ein gesunder Branch meldet sich also nie. Abgebrochene und übersprungene Läufe werden ignoriert.
- Ein fehlgeschlagenes Deployment (
deployment_status): ein Problem, ein Langes Hupen, eine Gruppe pro Repository und Umgebung. Das nächste erfolgreiche Deployment schließt es, und ein erfolgreiches ohne vorherigen Fehlschlag ist ein Tüt-tüt, „Deployed to production · acme/api“. - Ein veröffentlichtes Release (
release): ein Leichtes Hupen, mit den Release Notes. - Ein neu eröffnetes Issue (
issues): ein Leichtes Hupen, eine Gruppe pro Issue.
Entferne bei der Verbindung unter Ereignisse, die zu Nachrichten werden den Haken bei allem, was du nicht willst, und klick auf Speichern. Jede Verbindung zählt zum Tarif deines Workspaces: Free enthält 2, Pro 20 und Team 100. Nachrichten zählen wie alle anderen zu den täglichen Limits des Tarifs; die Preise listen sie auf.
Oder: ein Schritt im Workflow
Ohne die Verbindung kann ein Schritt am Ende eines Jobs den Fehlschlag selbst melden. Du entscheidest pro Job, was gesendet wird, und es funktioniert auch dort, wo du keinen Webhook anlegen kannst. Nimm für dieselben Workflows nur einen der beiden Wege: Mit beiden erfährst du von jedem Fehlschlag zweimal.
Dieser Weg braucht einen Ingest-Schlüssel: Öffne in der Web-App das Projekt und erstelle unter Schlüssel einen neuen.
URL und Schlüssel als Secrets speichern
Repository-Secrets gelten für ein einzelnes Repository, Organisations-Secrets ersparen dir die Wiederholung in jedem. Mit der GitHub CLI geht das so:
# with the GitHub CLI, for one repository (or use --org for all of them)
gh secret set HONK_URL --body "https://honk-honk.app"
gh secret set HONK_KEY # paste the ingestion key when askedEinen Schritt hinzufügen, der nur bei Fehlschlag läuft
Setz diesen Schritt ans Ende des Jobs, der dir wichtig ist. if: failure() führt ihn nur aus, wenn ein früherer Schritt fehlgeschlagen ist. Er braucht nur jq und curl, und beide sind auf jedem GitHub-gehosteten Runner vorinstalliert:
- name: Tell Honk
if: failure()
env:
HONK_URL: ${{ secrets.HONK_URL }}
HONK_KEY: ${{ secrets.HONK_KEY }}
WORKFLOW: ${{ github.workflow }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
ATTEMPT: ${{ github.run_id }}-${{ github.run_attempt }}
run: |
jq -n --arg title "CI failed: $WORKFLOW on $BRANCH" --arg url "$RUN_URL" --arg key "ci/$REPO/$BRANCH" \
'{title: $title, message: $url, url: $url, severity: "long", event_type: "problem",
group_key: $key, source: "github-actions", category: "deployments"}' |
curl -sS --max-time 10 --retry 3 --retry-all-errors "$HONK_URL/v1/messages" \
-H "Authorization: Bearer $HONK_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: gh-$ATTEMPT" --data-binary @- || trueDarauf kommt es an:
- Der Gruppenschlüssel besteht aus Repository und Branch,
ci/acme/api/main. Der erste Fehlschlag aufmainwird gepusht. Weitere Fehlschläge aufmainlanden in derselben Gruppe und werden zu ruhigen Updates. Ein Fehlschlag auf einem anderen Branch bekommt eine eigene Gruppe. - Der Idempotency-Key ist die Run-ID plus die Versuchsnummer. Wiederholt curl die Anfrage nach einer verlorenen Antwort, gibt Honk das ursprüngliche Ereignis zurück, statt ein zweites anzulegen. Drückst du dagegen Re-run, ist der neue Versuch ein neues Ereignis.
jqbaut das JSON, damit ein Workflow- oder Branch-Name mit Anführungszeichen die Anfrage nicht kaputt machen kann.|| truesorgt dafür, dass ein Ausfall von Honk aus einem fehlgeschlagenen Build nie einen anderen Fehler macht.
Optional: Entwarnung, wenn wieder alles grün ist
Um die Störung zu schließen, sobald der Branch wieder durchläuft, fügst du einen zweiten Schritt hinzu. Er läuft bei Erfolg, fragt GitHub, ob der vorherige Lauf auf diesem Branch fehlgeschlagen ist, und gibt nur dann Entwarnung:
# needs `permissions: actions: read` when the workflow restricts the token
- name: Tell Honk it works again
if: success()
env:
GH_TOKEN: ${{ github.token }}
HONK_URL: ${{ secrets.HONK_URL }}
HONK_KEY: ${{ secrets.HONK_KEY }}
WORKFLOW: ${{ github.workflow }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
ATTEMPT: ${{ github.run_id }}-${{ github.run_attempt }}
run: |
previous=$(gh run list --repo "$REPO" --workflow "$WORKFLOW" --branch "$BRANCH" \
--limit 2 --json conclusion --jq '.[1].conclusion')
[ "$previous" = "failure" ] || exit 0
jq -n --arg title "CI green again: $WORKFLOW on $BRANCH" --arg key "ci/$REPO/$BRANCH" \
'{title: $title, message: "The last run passed.", severity: "beep", event_type: "recovery",
group_key: $key, source: "github-actions", category: "deployments"}' |
curl -sS --max-time 10 --retry 3 --retry-all-errors "$HONK_URL/v1/messages" \
-H "Authorization: Bearer $HONK_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: gh-$ATTEMPT-ok" --data-binary @- || trueOhne diesen Schritt geht nichts kaputt: Eine Episode ohne neue Ereignisse wird nach 24 Stunden inaktiv, und der nächste Fehlschlag eröffnet eine neue und wird wieder gepusht.
Dasselbe mit der honk-CLI
Lieber mit der honk-CLI? Sie übernimmt Wiederholungen mit einem Idempotency-Key und ein Gesamtzeitlimit für dich. Installiere sie in Schritten, die nur bei einem Fehlschlag laufen, und ruf uhoh auf. Go ist auf den GitHub-gehosteten Linux-Runnern vorinstalliert:
- name: Install the honk CLI
if: failure()
run: |
go install github.com/honk-hq/go/cmd/honk@latest
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
- name: Notify
if: failure()
env:
HONK_URL: ${{ secrets.HONK_URL }}
HONK_KEY: ${{ secrets.HONK_KEY }}
run: |
honk uhoh --group-key "ci/${{ github.repository }}/${{ github.ref_name }}" \
--title "CI failed: ${{ github.workflow }}" --message "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--source github-actions --category deployments \
--idempotency-key "gh-${{ github.run_id }}-${{ github.run_attempt }}" || trueWas du bekommst
Der erste Fehlschlag auf main kommt als Langes Hupen in Honk für iPhone an. Den Link zum Lauf öffnest du im Posteingang mit einem Tippen. Wiederholungen auf demselben Branch aktualisieren die Gruppe, statt dein Handy erneut vibrieren zu lassen. Ruhezeiten halten CI-Fehlschläge über Nacht zurück, außer sie sind dringend. Wie du Honk auch erfolgreiche Deploys meldest, zeigt die Deploy-Anleitung, und die Sentry-Anleitung ergänzt die Fehler, die deine App wirft, sobald sie live ist.
Honk gibt es vorerst nur auf Einladung: Zugang anfragen. Alles in dieser Anleitung funktioniert schon im Free-Tarif.