gatus-snitcher
Reusable GitHub Action that reports a success or error to a Gatus external endpoint using the official external endpoint API. It’s designed for jobs that run outside of Gatus but should still contribute to uptime/health via an external endpoint.
- Validates inputs and sends a JSON payload with status and optional details.
- Uses a bearer (or custom) auth header with your API token.
- Exposes outputs for the reported
endpoint,http-status, andstatus.
By default, the action performs a POST to:
<base-url>/api/v1/endpoints/{key}/external?success={true|false}&error={msg}&duration={duration}
Where key is built from <GROUP>_<NAME> with the characters space, /, _, ,, ., and # replaced by - (e.g., core_ext--ep-test). You can override the base path/suffix via endpoint-path and endpoint-suffix if your deployment differs.
Inputs
Required
base-url: Base URL of your Gatus instance (required whenmode: report).group: Group of the external endpoint.name: Name of the external endpoint.token: API token for Gatus (required whenmode: report).
Optional
auth-header: Header used for token; defaultAuthorization.auth-scheme: Scheme before token; defaultBearer(set to empty to send raw token).duration: Duration string (e.g.,10s,250ms). If omitted inreportmode, the action uses the timer started instartmode (if present).dry-run: Iftrue, logs request without sending.endpoint-path: API base path; default/api/v1/endpoints.endpoint-suffix: Suffix appended after the key; default/external.error-message: Description for failures.extra-headers: Additional HTTP headers as JSON or newline-delimitedKey: Valuelines (e.g., Cloudflare Access headers).mode:startto record a timer orreportto send the result; defaultreport.status:success(default) or anything else treated aserror(e.g., pass${{ job.status }}).timer-id: Optional namespace for the timer (defaults to the derived<GROUP>_<NAME>key).timeout-ms: HTTP timeout in ms; default15000.
Outputs
endpoint: Full URL used for the report.http-status: HTTP status code returned by Gatus.status: Status reported to Gatus (successorerror).
Usage
Replace elaunira/gatus-snitcher@v1 with the tag/commit of this repository once published.
Report success in a job
name: Example Success on: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run your workload run: | echo "Do something..." # Simulate some work sleep 2 - name: Report success to Gatus uses: elaunira/gatus-snitcher@v1 with: base-url: https://status.example.com group: ci name: nightly-build token: ${{ secrets.GATUS_TOKEN }} status: success duration: 2s
Two-phase timer (start/report) in one job
Use the action once to start a timer, run your workload, then call it again to report. The second call will compute the duration from the stored start time if you don’t pass duration explicitly. You can also pass job.status directly; the action treats any non-success value as an error.
name: Timed Job on: workflow_dispatch: jobs: timed: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Start timer uses: elaunira/gatus-snitcher@v1 with: mode: start group: ci name: timed-task - name: Do work run: | echo "Doing work..." sleep 2 - name: Report to Gatus if: always() uses: elaunira/gatus-snitcher@v1 with: mode: report base-url: https://status.example.com group: ci name: timed-task token: ${{ secrets.GATUS_TOKEN }} status: ${{ job.status }} # success -> success, others -> error # duration omitted -> computed from the earlier Start timer step
Notes:
- If you need multiple timers in the same job, add
timer-idto both calls with the same value to namespace the timer (defaults to the derived<GROUP>_<NAME>key). - Ensure the final report step uses
if: always()so it runs even when the job fails.
Report error on failure
name: Example Error on: workflow_dispatch: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run tests run: | npm test - name: Report error to Gatus if: failure() uses: elaunira/gatus-snitcher@v1 with: base-url: https://status.example.com group: ci name: nightly-tests token: ${{ secrets.GATUS_TOKEN }} status: error error-message: "Tests failed"
Customize auth header or API path
Some deployments may use X-API-Key or a custom path:
- name: Report with custom header and path uses: elaunira/gatus-snitcher@v1 with: base-url: https://status.example.com group: ci name: import-job token: ${{ secrets.GATUS_TOKEN }} auth-header: X-API-Key auth-scheme: "" # send token without scheme endpoint-path: /api/v1/endpoints endpoint-suffix: /external
Add Cloudflare Access headers
If your Gatus API is protected by Cloudflare Access, pass the required headers:
- name: Report with Cloudflare Access uses: elaunira/gatus-snitcher@v1 with: base-url: https://status.example.com group: ci name: protected-job token: ${{ secrets.GATUS_TOKEN }} status: success extra-headers: | CF-Access-Client-Id: ${{ secrets.CF_ACCESS_CLIENT_ID }} CF-Access-Client-Secret: ${{ secrets.CF_ACCESS_CLIENT_SECRET }}
Add to your step only (inline snippet):
with: extra-headers: | CF-Access-Client-Id: ${{ secrets.CF_ACCESS_CLIENT_ID }} CF-Access-Client-Secret: ${{ secrets.CF_ACCESS_CLIENT_SECRET }}
Security
- Always store tokens in
secrets(e.g.,${{ secrets.GATUS_TOKEN }}) and never commit them. - This action redacts header values in
dry-runlogs. Usedry-run: truefor safe debugging.
Development
- Source lives in
src/index.ts; compiled output isdist/index.js. - Build locally with Node.js LTS:
npm ci && npm run build. - Commit the generated
dist/when publishing a release tag (GitHub Actions runners fetch the compiled file).
Notes
- The action runs on the latest Node.js LTS on GitHub Actions and uses native
fetch. - Non-2xx responses or timeouts cause the step to fail and mark the job red.
- If you’re unsure of the expected path for your Gatus version, consult your Gatus docs and adjust
endpoint-path/endpoint-suffixaccordingly.
Releasing
- dist is bundled with
@vercel/nccinto a singledist/index.js. - On pushes to the default branch that touch source, CI builds and commits
dist/. - Tag a release like
v1.0.0to publish; the Release workflow verifiesdistand creates a GitHub Release. - After a release is published, a workflow automatically moves the floating tags for the major and minor series (e.g.,
v1andv1.2) to the new release commit.