GitHub Actions is the backbone of modern CI/CD pipelines. But when your deployment workflow breaks — a stale action version, an expired secret, a flaky test that blocks production deploys — you often find out when a developer reports "the deploy is broken" rather than through proactive monitoring.
This guide shows you how to monitor your GitHub Actions workflows with Vigilmon using heartbeat monitoring.
The Problem: Silent CI/CD Failures
GitHub Actions sends email notifications for failed runs, but these have limitations:
- Notification fatigue: teams mute GitHub email after too many false positives
- Missed patterns: a workflow that's been failing for 3 days before anyone notices
- No SLA: no concept of "this workflow should complete within X minutes"
- Silent stoppage: scheduled workflows that stop running silently when the workflow file has a YAML syntax error
Vigilmon's heartbeat monitoring solves all four: if your workflow doesn't ping the heartbeat within your expected window, you get alerted through your configured channel (Slack, PagerDuty, email).
Step 1: Add a Heartbeat Ping to Your Workflow
Add a final step to your workflow that pings Vigilmon on success:
# .github/workflows/deploy.yml
name: Deploy Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
- name: Deploy
run: ./deploy.sh
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
- name: Ping Vigilmon Heartbeat
if: success()
run: curl -fsS "https://hb.vigilmon.online/${{ secrets.VIGILMON_HEARTBEAT_ID }}"
Key details:
-
if: success()— only ping if all previous steps succeeded -
-fsSflags:-ftreats HTTP errors as failures,-ssilent mode,-Sshows errors. This means the curl step itself fails if Vigilmon returns an error, which is what you want. - Store your heartbeat ID in GitHub Secrets, not in the workflow file
Step 2: Configure the Heartbeat in Vigilmon
In Vigilmon, create a new heartbeat monitor:
- Name: "Production Deploy Workflow"
-
Grace period: set based on your deploy frequency
- Deploys multiple times per day → 4-hour grace period
- Daily deploys → 26-hour grace period
- Weekly deploys → 8-day grace period
- Alert channel: Slack #engineering or PagerDuty
The grace period is the window after the last successful ping during which missing another ping triggers an alert.
Step 3: Monitor Scheduled Workflows
Scheduled workflows are especially prone to silent failure. A cron expression typo, a YAML change that breaks the workflow, or a GitHub Actions outage can stop your scheduled jobs without any obvious notification.
# .github/workflows/weekly-report.yml
name: Weekly Report
on:
schedule:
- cron: '0 9 * * MON' # Every Monday at 9am UTC
jobs:
generate-report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate report
run: npm run report
- name: Ping Vigilmon
if: success()
run: curl -fsS "https://hb.vigilmon.online/${{ secrets.WEEKLY_REPORT_HEARTBEAT_ID }}"
For weekly workflows, set a 8-day (11,520-minute) grace period so a single missed run doesn't page you immediately but two consecutive misses does.
Step 4: Monitor Multiple Workflows
Add different heartbeat IDs for different workflows:
| Workflow | Heartbeat ID | Grace Period |
|---|---|---|
| Production deploy | PROD_DEPLOY_HB |
4 hours |
| Staging deploy | STAGING_DEPLOY_HB |
8 hours |
| Database backup | DB_BACKUP_HB |
25 hours |
| Dependency scan | DEP_SCAN_HB |
8 days |
| Weekly report | WEEKLY_REPORT_HB |
8 days |
Store each heartbeat ID in GitHub Secrets and reference them in the respective workflow file.
Step 5: Monitor GitHub Actions API Health
You can also monitor whether GitHub Actions is operational overall:
Monitor: GET https://www.githubstatus.com/api/v2/components.json
Type: HTTP(S)
Expected status: 200
Keyword check: "Actions"
Parse the response to check the Actions component's status. This helps distinguish "our workflow broke" from "GitHub Actions is having an outage."
Step 6: Monitor Self-Hosted Runners
If you use self-hosted GitHub Actions runners, add a heartbeat monitor:
# On your self-hosted runner, run this via cron every 5 minutes:
*/5 * * * * curl -fsS "https://hb.vigilmon.online/YOUR_RUNNER_HEARTBEAT_ID"
Or add it as a synthetic workflow that runs on your self-hosted runner:
# .github/workflows/runner-heartbeat.yml
name: Runner Heartbeat
on:
schedule:
- cron: '*/5 * * * *'
jobs:
ping:
runs-on: self-hosted # Targets your self-hosted runner
steps:
- name: Ping Vigilmon
run: curl -fsS "https://hb.vigilmon.online/${{ secrets.RUNNER_HEARTBEAT_ID }}"
Common CI/CD Monitoring Failures
- Expired secrets: a deploy token expires and the workflow silently fails every run
-
Deprecated actions:
actions/checkout@v2breaks when GitHub removes v2 support - Resource limits: workflows queue indefinitely when runner capacity is exhausted
- Branch protection: main branch protection blocks auto-merges that workflows depend on
Heartbeat monitoring catches all of these — if the workflow stops completing successfully, the heartbeat stops arriving, and you get alerted.
Set Up in 5 Minutes
Vigilmon heartbeat monitors require no agent installation and no infrastructure changes. Add the curl step to your workflow, store the heartbeat ID in GitHub Secrets, and configure your alert channel.
Top comments (0)