Monitor a GitLab CI scheduled pipeline
Scheduled pipelines fail in ways nobody sees. A job starts failing on a branch nobody watches, the schedule is deactivated when its owner leaves the project, or a runner goes offline and the pipeline sits pending. A heartbeat check catches all of these: the pipeline reports to Pingstack after it succeeds, and Pingstack alerts you when that report doesn’t arrive on time.
1. Create a heartbeat check that matches the schedule
Section titled “1. Create a heartbeat check that matches the schedule”Open the project’s Build › Pipeline schedules and find the schedule’s interval pattern and timezone. GitLab lets you choose the timezone per schedule.
Create a heartbeat check and set its schedule to Cron with the same pattern and timezone. See schedules and timezones.
Set a generous grace period. Scheduled pipelines can start a few minutes late, and the pipeline itself takes time. Allow for both, plus time waiting for a runner. Attach a notification group.
2. Store the ping URL as a CI/CD variable
Section titled “2. Store the ping URL as a CI/CD variable”Copy the location’s ping URL from the check in Pingstack. In the project,
open Settings › CI/CD › Variables and add PINGSTACK_PING_URL with
Mask variable turned on, so it’s hidden in job logs.
If you also mark it Protected, it’s only available to pipelines on protected branches. Make sure the schedule’s target branch is protected, or the report job won’t see the variable.
3. Report success in a final stage
Section titled “3. Report success in a final stage”Add a stage that runs after everything else, only for scheduled pipelines:
stages: - export - report
nightly-export: stage: export script: - ./scripts/export.sh rules: - if: $CI_PIPELINE_SOURCE == "schedule"
report-to-pingstack: stage: report image: name: curlimages/curl:8.10.1 entrypoint: [""] script: - curl --fail --silent --show-error --max-time 10 --retry 3 "$PINGSTACK_PING_URL" > /dev/null rules: - if: $CI_PIPELINE_SOURCE == "schedule" when: on_successThe empty entrypoint lets GitLab run the script in the curl image, whose
default entrypoint is curl itself. Jobs in a later stage run only when every job in the earlier stages
succeeded, so a failed run never reaches report-to-pingstack and Pingstack
alerts you when the deadline passes.
If one project has several schedules, give each its own check and variable,
and tell the jobs apart with a variable set on the schedule (for example
SCHEDULE_NAME) in their rules.
4. Confirm the first report
Section titled “4. Confirm the first report”In Build › Pipeline schedules, choose Run (the play button) next to the schedule. When the pipeline finishes, open the check in Pingstack and confirm the location received a heartbeat and shows a next deadline.
Optional: report a number
Section titled “Optional: report a number”Pass a count from an earlier job to the report job as a dotenv artifact, then send it as a numeric value:
nightly-export: stage: export script: - echo "ROWS=$(./scripts/export.sh --count)" >> export.env artifacts: reports: dotenv: export.env rules: - if: $CI_PIPELINE_SOURCE == "schedule"
report-to-pingstack: stage: report image: name: curlimages/curl:8.10.1 entrypoint: [""] script: - curl --fail --silent --show-error --max-time 10 --retry 3 --get --data-urlencode "value=$ROWS" "$PINGSTACK_PING_URL" > /dev/null rules: - if: $CI_PIPELINE_SOURCE == "schedule"Set warning and critical thresholds on the check, so a run that succeeds but exports nothing still raises an alert.
Why a healthy pipeline might still alert
Section titled “Why a healthy pipeline might still alert”- Deactivated schedule. GitLab deactivates a schedule when its owner can no longer run it, for example after leaving the project. Take ownership of the schedule and reactivate it.
- No runner. A pipeline waiting for an available runner starts late, or never. Check that a runner with the right tags is online.
- Protected variable. The report job can’t see a protected variable on an
unprotected branch, so
curlgets an empty URL and fails. - Timezone mismatch. The check and the schedule’s timezone must agree.
If alerts still don’t match what you expect, see troubleshooting monitoring.