GitHub Actions
Any workflow can fire a heartbeat as its last step. One curl line per workflow.
Setup
- Add a repo secret
AGENTPING_PING_TOKEN. Paste the per-agent ping token from the AgentPing settings page. - Add a final step that calls curl. Use
if: always()so it runs on success or failure, and${{ job.status }}for the right status.
Recipe
name: Nightly rollup
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
rollup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run the rollup
id: rollup
run: |
START=$SECONDS
./scripts/nightly-rollup.sh
echo "duration_ms=$(( (SECONDS - START) * 1000 ))" >> "$GITHUB_OUTPUT"
- name: Heartbeat to AgentPing
if: always()
env:
AGENTPING_PING_TOKEN: ${{ secrets.AGENTPING_PING_TOKEN }}
DURATION_MS: ${{ steps.rollup.outputs.duration_ms }}
run: |
STATUS=ok
if [ "${{ job.status }}" != "success" ]; then STATUS=fail; fi
curl -fsS -H "X-AgentPing-Key: $AGENTPING_PING_TOKEN" \
"https://eu.ingest.agentping.io/v1/ping?agent=nightly-rollup&status=$STATUS&duration_ms=${DURATION_MS:-0}"
Credentials go in X-AgentPing-Key so they don't appear in logs. curl -fsS returns non-zero on HTTP errors and prints the response body, so misconfigured tokens surface as red steps.
Scheduled workflows
GitHub Actions schedules are best-effort; runs can be delayed during heavy load, and GitHub skips schedules for repos idle 60 days. AgentPing's schedule monitoring is the safety net. Set the same cron on the agent in the dashboard; Pulse pages you on missed windows.
Reusing the step
If multiple workflows fire the same heartbeat, extract it into a composite action at .github/actions/heartbeat/action.yml:
- uses: ./.github/actions/heartbeat
if: always()
with:
agent: nightly-rollup
status: ${{ job.status }}