GitHub Action
Run sutramx plan on pull requests and sutramx apply on merge with the SutramX GitHub Action, so monitor changes are reviewed like code.
The SutramX GitHub Action runs the SutramX CLI against the sutramx.yml in your repository. Use it to post the plan on every pull request that changes your monitors, and to apply the file when the change is merged.
The action lives in the SutramX/cli repository and is used as sutramx/cli/action@v1.
What the action does#
The action is a composite action. Each run:
- Sets up Node.js 22.
- Runs the published
@sutramx/clipackage withnpx(the version you choose withcli-version). - Runs
plan,difforapplyagainst your file. Plan and diff run with--detailed-exitcode; apply runs with--auto-approve. - Writes the output (including any error messages) to the job summary and to the
planoutput, and setshas-changes.
Colour is turned off so the output reads cleanly in logs and comments. Your API key is passed to the CLI through the environment, never written into the script, and is masked in the logs.
Inputs#
| Input | What it does | Default |
|---|---|---|
command | plan, diff or apply. Anything else fails the step. | plan |
file | Path to the configuration file | sutramx.yml |
api-key | SutramX API key. Required. Store it as a repository or environment secret. See Set up the API key for the access level. | |
api-url | API base URL. You only need it for a non-default API. | https://api.sutramx.com |
prune | true deletes keyed monitors that are not in the file (--prune). Empty or false never deletes; settings.prune in the file alone deletes nothing | empty |
cli-version | Version of @sutramx/cli to run: latest, next or a version such as 0.1.0. Pin an exact version in production; latest follows every release. | latest |
Outputs#
| Output | What it contains |
|---|---|
has-changes | 'true' when plan or diff found changes, or when apply changed something; otherwise 'false' |
plan | The plain-text output of the command |
For plan and diff, "there are changes" is not a failure: the step succeeds and has-changes is true. The step fails when the CLI reports an error, for example an invalid file, a missing environment variable, an API error or a failed change during apply.
Set up the API key#
Every API key has one of three access levels, fixed when the key is created. Choose the level for what the job does:
| Job | Lowest access level |
|---|---|
command: plan or diff (pull request plans, drift checks) | Read-only, unless the file sets config.notification_emails, which needs Automation even to plan |
command: apply for monitors and status pages | Standard |
command: apply for a file with integrations (alert channels) or per-monitor alert recipients (config.notification_emails) | Automation |
- In SutramX, open Account settings → API keys → Create API key.
- Choose the Access level from the table above. The dashboard selects Read-only by default, which can plan but not apply.
- Copy the key; it is shown only once.
- In GitHub, add it as a secret named
SUTRAMX_API_KEY(Settings → Secrets and variables → Actions).
You can use one Standard or Automation key for every job, or give the plan job its own read-only key (in a separate secret) so pull request runs never hold a key that can make changes. Whether you can create API keys, and how many, depends on your plan: see Plans & limits.
Plan on pull requests, apply on merge#
Save this as .github/workflows/sutramx.yml. Pull requests that touch sutramx.yml get the plan as a comment (updated in place on each push), and merging to main applies it.
name: SutramX monitors
on:
pull_request:
paths: [sutramx.yml]
push:
branches: [main]
paths: [sutramx.yml]
permissions:
contents: read
pull-requests: write
concurrency:
group: sutramx-${{ github.ref }}
cancel-in-progress: false
jobs:
plan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: plan
uses: sutramx/cli/action@v1
with:
command: diff
api-key: ${{ secrets.SUTRAMX_API_KEY }}
- name: Comment the plan on the pull request
uses: actions/github-script@v7
env:
PLAN: ${{ steps.plan.outputs.plan }}
HAS_CHANGES: ${{ steps.plan.outputs.has-changes }}
with:
script: |
const marker = '<!-- sutramx-plan -->';
const body = `${marker}\n### SutramX plan${process.env.HAS_CHANGES === 'true' ? '' : ' (no changes)'}\n\`\`\`\n${process.env.PLAN}\n\`\`\``;
const { data: comments } = await github.rest.issues.listComments({ ...context.repo, issue_number: context.issue.number });
const existing = comments.find((comment) => comment.body?.startsWith(marker));
if (existing) await github.rest.issues.updateComment({ ...context.repo, comment_id: existing.id, body });
else await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body });
apply:
if: github.event_name == 'push'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: sutramx/cli/action@v1
with:
command: apply
api-key: ${{ secrets.SUTRAMX_API_KEY }}A few details worth knowing:
command: diffputs every changed field (old -> new) in the comment. Useplanfor a shorter list of field names.concurrencywithcancel-in-progress: falsestops two applies from running at once.environment: productionlets you add required reviewers or restrict the secret to the main branch with GitHub environment protection rules. Remove it if you don't use environments.- Pull requests from forks don't get repository secrets, so the plan job can't run for them.
Pass secrets used in the file#
If sutramx.yml reads environment variables, for example ${SLACK_WEBHOOK_URL} for an integration, set them on the step. The CLI fails with a clear message if one is missing.
- uses: sutramx/cli/action@v1
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
with:
command: apply
api-key: ${{ secrets.SUTRAMX_API_KEY }}Prune on apply#
To delete keyed monitors that were removed from the file, pass prune: 'true' to the action. Setting settings.prune: true in sutramx.yml isn't enough; it only prints a warning:
- uses: sutramx/cli/action@v1
with:
command: apply
prune: 'true'
api-key: ${{ secrets.SUTRAMX_API_KEY }}Pruning deletes the monitors' check history. As a safety catch, an apply that would prune every managed monitor because the file declares none is refused. Read Pruning before turning it on, especially if other tools create keyed monitors in the same workspace.
Fail a check when there are changes#
To make a scheduled job flag drift (someone changed a managed monitor in the dashboard), use the has-changes output:
on:
schedule:
- cron: '0 6 * * *'
jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: plan
uses: sutramx/cli/action@v1
with:
command: plan
api-key: ${{ secrets.SUTRAMX_API_KEY }}
- if: steps.plan.outputs.has-changes == 'true'
run: |
echo "SutramX differs from sutramx.yml" >&2
exit 1Recording deploys#
The action only plans and applies sutramx.yml; it doesn't record deployments. To see deploys next to incidents and response times, see Deployment correlation.
Troubleshooting#
| Problem | What to do |
|---|---|
command must be plan, diff or apply | Fix the command input |
Cannot read sutramx.yml: file not found | Add actions/checkout before the action, or set file to the right path |
Environment variables referenced in sutramx.yml are not set | Pass the variables with env: on the step |
integrations can only be changed with an API key whose access level is "Automation" | Create a new key with the Automation access level and update the secret. Nothing was applied. |
READ_ONLY_ACCESS on apply | The secret holds a read-only key. Use a Standard key, or Automation for integrations and alert recipients. |
ALERT_ROUTING_NOT_ALLOWED | The file sets config.notification_emails. Use an Automation key, or remove the field. |
cli-version must be latest, next or a version like 0.1.0 | Fix the cli-version input |
the file declares no monitors, so prune would delete all ... managed monitors | The file has no monitors while pruning is on. The action can't pass --allow-delete-all; check the file, and if you really mean to delete every managed monitor, run sutramx apply --prune --allow-delete-all with the CLI. |
... changed type and would be deleted with its history and created again | A monitor's type changed. The action can't pass --allow-replace; run sutramx apply --allow-replace with the CLI, or apply with prune: 'true', which also allows it. |
| The apply job fails after some changes | Changes that succeeded are kept. Fix the error and re-run the job; it only changes what is still different. |
| The comment step fails with a permissions error | Add pull-requests: write under permissions |
Related
- CLI & monitors as code
- Terraform provider
- REST API
- Deployment correlation
- Features: API Monitoring
- Guides: Monitoring APIs Effectively
- Integrations: Webhooks alerts setup and GitHub issues alerts setup
- Use cases: Monitoring for Developers & Indie Hackers
- More from SutramX: Developers & API
Last updated . Something unclear or missing on this page? Tell us at support@sutramx.com.