Monitor GitHub Actions, and get told why a run failed
Point one signed workflow_run
webhook from your repository at LastPing: zero changes to your
workflow YAML. Every run reports in; a run that fails, hangs, or never
starts opens an incident, alerts you where you work, and deep-links to
the run. Free for individuals, no monitor cap.
Your assistant can do this for you
Monitor my GitHub Actions workflows with LastPing
On this page
Scheduled workflows fail silently. By design.
If you run a nightly build, a scraper, a DB backup, or a cert renewal on a GitHub Actions schedule, three failure modes are waiting for you, and GitHub tells you about none of them reliably.
The 60-day silent disable
GitHub automatically disables schedule-triggered
workflows in public repositories after 60 days without activity. No error, and no
email when it happens: your nightly backup just stops existing.
Email to the wrong person
A failed scheduled run only notifies the user who last touched the workflow's cron: often a teammate who left, or you, in an inbox filter you stopped reading months ago.
The hung run
A run that starts and never finishes (stuck runner, hung step, infinite retry) notifies nobody. It isn't a failure yet, so no failure email ever comes.
Adding a curl ping step to each workflow (the classic
heartbeat approach) fixes none of the hard cases: the step never
executes when the runner hangs or when the schedule was
disabled. The fix is to listen to GitHub's own run signal instead,
and to expect it on a schedule, so absence is an alert too.
Setup: one webhook, about two minutes
No YAML changes, no agent, no GitHub App permissions: a plain repository webhook, HMAC-verified on every delivery.
Create a CI check in LastPing
In the console, create a monitor, choose CI pipeline, and pick GitHub Actions. Give it the same schedule as your workflow (e.g. daily with a grace window) so a run that never starts is caught too. Copy the webhook URL and the one-time secret shown on screen.
https://ping.lastping.dev/ci/github/<check-id>
Register the webhook in your repository
On GitHub: Settings → Webhooks → Add webhook.
- Payload URL: the webhook URL from step 1
- Content type:
application/json - Secret: the one-time secret from step 1
- Events: "Let me select individual events" → tick Workflow runs and Workflow jobs (untick the pre-selected Pushes)
- Why both?
workflow_runtells LastPing the run failed; onlyworkflow_jobcarries per-step conclusions, so it is the sole source of the failing step name in your alert. Skip it and alerts read "failed on main" instead of "failed at Run make test on main". Job events never count as extra runs.
Done: every run now reports in
LastPing verifies each delivery's HMAC signature against your
secret, then classifies the run: success, failure, started.
Branch and workflow filters let you count only the runs you care
about (say, main and the workflow named
nightly-backup). A filter only counts exact
matches, so a moved default branch can leave a branch filter
matching nothing. When the filters keep ignoring finished runs
and none has matched since they were set, the monitor's
Overview says so, counts the ignored runs, names the last one
and links to the filters; if every ignored run belonged to
another workflow, it says the monitor is waiting for the first
run of yours and that the workflow name has to match exactly.
It also speaks up when the
last match is more than 72 hours old and runs of the monitor's
own workflow have been ignored on other branches since; runs of
other workflows, which a repository webhook also sends, are the
filter doing its job and do not raise it. If your workflow has
not run for 72 hours while a workflow name that first appeared
after its last match has run at least twice, the Overview flags
a likely rename and names the new workflow. A rename is flagged
only after a monitor's first 7 days, and one made before this
check existed is not flagged after the fact; a scheduled monitor
still alerts when its runs stop arriving. Alerts go to email by default (your verified address is attached automatically) and to
Slack, Discord, Telegram, ntfy, Pushover, Microsoft Teams,
Google Chat or a signed webhook if you add them.
Optional: attach the failure reason to the incident
One if: failure() step POSTs a log excerpt (up to
64 KB, plain text) to the check's detail endpoint. It's
stored on the open incident and shown in the console, so the
alert doesn't just say "it broke," it shows why. The body is
never logged server-side.
LASTPING_CI_SECRET is the same CI secret this
monitor's webhook signs with: open the monitor in the console,
go to its CI settings and reveal the secret (the reveal is
password-gated), then save it as a repository secret alongside
LASTPING_CHECK_ID.
Sending it also lifts the throttle: without the token, detail
posts are limited to 60 per 15 minutes per monitor; with it,
there is no limit.
The trailing || true is not decoration: this step only
runs on a job that has already failed, and a hiccup reporting the
failure (a rate limit, a deleted monitor) must never be what
turns the job red a second time.
# optional last step of any job in the workflow
- name: Report failure detail to LastPing
if: failure()
env:
LASTPING_CI_SECRET: ${{ secrets.LASTPING_CI_SECRET }}
LASTPING_CHECK_ID: ${{ secrets.LASTPING_CHECK_ID }}
DETAIL: ${{ github.workflow }} / ${{ github.job }} failed on ${{ github.ref_name }} — run ${{ github.run_id }}
run: |
curl -fsS -X POST -H "Content-Type: text/plain" \
-H "X-LastPing-Token: $LASTPING_CI_SECRET" \
--data "$DETAIL" \
"https://ping.lastping.dev/ci/$LASTPING_CHECK_ID/detail" || true
What this catches
The same durable detection engine as LastPing's cron monitoring: deadlines live in the database, so a restart never misses a due check.
- Failed runs: incident opens with a deep link to the exact run, plus the failure detail if you added the optional step.
- Hung runs: the run started but never completed; the completion signal doesn't arrive in the window, and that silence opens an incident.
- Runs that never start: including scheduled workflows GitHub disabled after 60 days of inactivity in a public repo. No run signal in the expected window → incident.
- Recovery: the next successful run closes the incident and sends a recovery notice automatically. No manual reset.
- Flap protection: a run that fails and immediately recovers within the damping window doesn't page you.
Prefer the classic style? You can still end any workflow job with
curl -fsS https://ping.lastping.dev/<id> as a plain
heartbeat: it works, and it's the right tool for scripts inside
a run. Just know its limits: it can't see hung runs or disabled
schedules. The webhook can. GitLab CI
and Jenkins are supported the same way,
or see the copy-paste guides for cron,
Kubernetes, systemd, and more.
Questions people ask
Front-loaded answers: the most important fact first.
-
How do I get alerted when a GitHub Actions workflow fails?
Point one signed webhook from your repository at LastPing (Settings → Webhooks → Add webhook), ticking both the Workflow runs (
workflow_run) and Workflow jobs events, with zero changes to your workflow YAML. Every run reports in; a failed, hung, or never-started run opens an incident and alerts you by email, Slack, Discord, Telegram, ntfy, Pushover, Microsoft Teams, Google Chat or webhook, with a deep link to the run and the name of the step that failed. Free for individuals, no monitor cap. -
Why did my scheduled GitHub Action stop running?
In a public repository, GitHub automatically disables scheduled workflows after 60 days without activity, and nothing notifies anyone when it happens. Failed scheduled runs also only email the user who last touched the workflow's cron schedule, and a run that hangs notifies nobody. A dead-man's-switch monitor like LastPing catches all three cases: it expects a run signal on your schedule and opens an incident when the signal doesn't arrive.
-
Do I need to change my workflow YAML to monitor GitHub Actions with LastPing?
No. Monitoring uses GitHub's own
workflow_runwebhook, registered once per repository in Settings → Webhooks. Optionally, you can add a one-lineif: failure()step to a workflow to attach the failure log excerpt directly to the LastPing incident, but the monitoring itself needs zero YAML changes. -
Does GitHub Actions monitoring work for private repositories?
Yes. GitHub delivers repository webhooks for private repositories exactly as for public ones. LastPing verifies each delivery against your webhook secret (HMAC signature) before processing, and never needs read access to your code.
-
Is GitHub Actions monitoring free in LastPing?
Yes. LastPing is free for individuals, and CI/CD monitoring is a first-class feature with no monitor cap. GitLab CI and Jenkins are supported the same way. See how LastPing compares to Healthchecks.io and Cronitor.
Your next silent failure is already scheduled.
One webhook now beats a post-mortem later. First alert wired up in about two minutes, and LastPing monitors itself the same way.