GitHub Actions failure alerts on your iPhone
GitHub can already tell you about workflow runs. Turn on notifications for Actions in the GitHub Mobile app, and you get a push for runs you started. If that’s all you need, you’re done.
Honk is for when you need more: failures from many repositories, including runs other people started, folded into one group per branch, in the same inbox as your servers and cron jobs, with a recovery when the branch is green again. This guide adds it with one step at the end of a job.
Before you start
- A Honk account. Honk is invite-only for now: request access.
- A project for CI and an ingestion key: in the web app, open the project, then Keys, and create one.
1. Store the URL and the key as secrets
Repository secrets work for a single repository; organization secrets save you from repeating this everywhere. With the GitHub CLI:
# with the GitHub CLI, for one repository (or use --org for all of them)
gh secret set HONK_URL --body "https://honk-me.app"
gh secret set HONK_KEY # paste the ingestion key when asked2. Add a step that runs only on failure
Put this step last in the job you care about. if: failure() runs it only when an earlier step failed. It uses jq and curl, which every GitHub-hosted runner already has, so there is nothing to install:
- 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 @- || trueA few choices in there matter:
- The group key is the repository and the branch,
ci/acme/api/main. The first failure onmainpushes; more failures onmainfold into the same group and become calm updates. A failure on another branch gets its own group. - The idempotency key is the run ID plus the attempt number. If curl retries after a lost response, Honk returns the original event instead of a second one, but when you press Re-run, the new attempt is a new event.
jqbuilds the JSON, so a workflow or branch name with quotes in it can’t break the request.|| truemeans a Honk outage can never turn a failed build into a different failure.
3. Optional: a recovery when it’s green again
To close the incident when the branch passes again, add a second step that runs on success, asks GitHub whether the previous run on this branch failed, and only then reports a recovery:
# 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 @- || trueWithout this step nothing breaks: an episode with no new events becomes inactive after 24 hours, and the next failure opens a new one and pushes again.
The same with the honk-me CLI
If you prefer the CLI, which handles retries with one idempotency key and a total deadline for you, install it in steps that run only on failure and call problem. Go is preinstalled on GitHub-hosted Linux runners:
- name: Install honk-me
if: failure()
run: |
go install github.com/honk-me/honk-go/cmd/honk-me@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-me problem --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 }}" || trueWhat you get
The first failure on main arrives as a Long honk, with a link to the run one tap away in the inbox. Repeats on the same branch update one group instead of buzzing again, and quiet hours hold CI failures overnight unless you send them as urgent. The deploy guide also covers telling Honk about successful deploys.
Honk is invite-only for now: request access. Everything in this guide works on the Free plan.