The YAML that reports a dead job does not need to know about Slack. If your on-call already lives in ntfy, keep the GitHub Actions failure() step pointed at AlertHub and paste one topic URL in Connections.
AlertHub stores every run in the dashboard and POSTs warning / critical to ntfy with Title, Priority, and Tags. Successful builds stay info and never hit the phone.
This is not repository webhooks (pushes, PRs). The pipeline itself says the job died.
Why ntfy for CI
| Need | ntfy | Slack / Teams |
|---|---|---|
| Solo maintainer, no chat workspace | Native | Overkill |
| Wake the phone at 2 a.m. | Priority 5 (urgent) | Channel mute wars |
| Rotate the destination | One topic URL | Bot + channel + app |
| Same event to a team channel later | Add Slack on the same project | Already there |
Critical AlertHub alerts map to ntfy priority 5; warning maps to 4. Info never leaves the dashboard.
Setup (once)
- Keep (or add) the
failure()curl from the GitHub Actions guide. Secret:ALERTHUB_KEY. - In ntfy: subscribe to a hard-to-guess topic. The URL is
https://ntfy.sh/YOUR_TOPIC(or?auth=…for a reserved topic). - In AlertHub: project Connections → ntfy → paste the topic URL. Send a test
warning.
Full destination steps: ntfy docs. The topic name is the password.
Alert 1: Workflow failed → ntfy urgent
Use "ah_level": "critical" on if: failure() so ntfy treats it as priority 5. Include the run URL in ah_description so one tap opens the red job.
The step is the same curl as the Slack-oriented guide — only the destination changes. Do not add a second curl ntfy.sh/… in YAML; that is the pile of scripts ntfy users already regret.
Alert 2: Main only, PRs stay quiet
Phone-first CI dies when every PR flake rings. Gate the step:
if: failure() && github.ref == 'refs/heads/main'
PR failures can stay warning on a different job (priority 4) or info so they exist in the feed without a buzz.
Alert 3: Deploy job vs test job
Monorepos often have a green test job and a red deploy job. Scope ah_source (GitHub Deploy vs GitHub Actions) so you can filter the dashboard. Same ntfy topic; different titles. Host deploys without Actions: Vercel + Gotify.
Ideas to squeeze more value
- One topic for all repos. Organization secret
ALERTHUB_KEY;ah_source= repo name. - Do not POST success to ntfy.
if: success()+infois dashboard history only. - Team still in Slack? Add Slack on the same project — see on-call ntfy with Slack.
- Self-hosted phone? Same ingest, Gotify destination instead of (or next to) ntfy.
FAQ
Does the Actions YAML mention ntfy?
No. It talks to AlertHub. ntfy is a Connection.
Will every failed PR wake me?
Only if you send warning/critical without a github.ref guard. Filter on main or drop PR noise to info.
Does self-hosted ntfy work?
Yes. Paste https://your-host/topic (HTTPS, reachable from the internet).
Next steps
Copy the failure step from GitHub Actions, paste an ntfy topic in Connections, and fail a test job on main.
Related: ntfy setup · GitHub Actions to Slack/Telegram · Uptime + VPS on ntfy