Skip to content
Scripting & CI/CD

Scripting & CI/CD

The CLI works the same in a script as in a terminal. Give it an API key in environment variables, read its answers as JSON, and let its exit code tell the script what happened. This page shows each of these, and complete pipelines for GitHub Actions, GitLab CI and Docker.

How a script uses the CLI

A deployment can ask Status200 first whether an incident is open, and stop if one is:

flowchart TB J["The CI job starts"] --> S["Its secrets set<br/>STATUS200_API_KEY<br/>and STATUS200_URL"] S --> Q["status200 incident count<br/>of incidents not resolved"] Q -->|"0"| D["Deploy"] Q -->|"1 or more"| X["Stop: an incident<br/>is open"] Q -->|"exit code 2"| A["Stop: check<br/>the API key"]

A deployment that waits while an incident is open

Give a script its API key

Set STATUS200_API_KEY and STATUS200_URL from your CI system's secrets. The CLI then needs no login and no configuration file. A flag still comes before them for one command, and they come before saved contexts.

Bash
export STATUS200_API_KEY="$CI_STATUS200_API_KEY"
export STATUS200_URL="https://status200.ru"
status200 incident count
Tip

Give each pipeline an API key of its own, with only the access it needs: a check that only reads needs a key that only reads. Delete the key in Status200 when the pipeline is retired.

If one machine runs jobs for several projects, save a context for each and name it in every command, so that a job never uses another's current context:

Bash
status200 --context production incident count
status200 --context staging monitor count

Exit codes

CodeMeaningFor example
0It workedA list, even one that finds nothing
1It failedStatus200 refused the request, such as API error (422); invalid JSON; a missing or unknown option; a context that is not saved
2No usable API keyNo credentials found; an invalid API key; a key below its plan (402); 401
3Not foundStatus200 answered 404: the record does not exist, is in another project, or the key may not read it

whoami and context current exit with 0 even when nothing is saved: they report what is set, they do not check it. A script tells the cases apart by the code:

Bash
status200 incident get "$INCIDENT_ID" -o json > incident.json
case $? in
  0) echo "Saved the incident to incident.json" ;;
  2) echo "Check STATUS200_API_KEY and STATUS200_URL" >&2; exit 1 ;;
  3) echo "There is no incident $INCIDENT_ID" >&2; exit 1 ;;
  *) echo "Status200 refused the request" >&2; exit 1 ;;
esac

Error messages go to the standard error, so incident.json holds only the answer.

Read answers with jq

Write -o json in scripts. In a pipe the CLI prints JSON anyway, but the flag keeps the script working wherever it runs:

Bash
# The title of each incident
status200 incident list -o json | jq -r '.[].title'

# The ID of a new monitor
MONITOR_ID=$(status200 monitor create --data '{"name":"Checkout API","monitorType":"Manual"}' -o json | jq -r '._id')

# When each incident was created: dates come as objects
status200 incident list -o json | jq -r '.[] | "\(.createdAt.value)  \(.title)"'

# The newest 100 incidents as CSV
status200 incident list --limit 100 -o json | jq -r '.[] | [._id, .title, .createdAt.value] | @csv'

A count prints one number, ready to compare:

Bash
OPEN=$(status200 incident count --query '{"currentIncidentState":{"isResolvedState":false}}')
echo "$OPEN incidents are open"

Create records from files

Keep records as JSON files next to your code, and create them from there:

monitors/checkout-api.jsonJSON
{
  "name": "Checkout API",
  "monitorType": "Manual"
}
Bash
status200 monitor create --file monitors/checkout-api.json

Many records from one JSON array, one create each:

Bash
jq -c '.[]' monitors.json | while IFS= read -r monitor; do
  status200 monitor create --data "$monitor" -o json | jq -r '._id'
done
Note

Each run creates new records. To keep monitors and status pages in step with files, change only what changed and remove what is gone, use the Terraform provider.

Pipeline examples

GitHub Actions

.github/workflows/deploy.ymlYAML
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install the Status200 CLI
        run: npm install -g @status200/cli
      - name: Stop while an incident is open
        env:
          STATUS200_API_KEY: ${{ secrets.STATUS200_API_KEY }}
          STATUS200_URL: https://status200.ru
        run: |
          OPEN=$(status200 incident count --query '{"currentIncidentState":{"isResolvedState":false}}')
          if [ "$OPEN" -gt 0 ]; then
            echo "$OPEN incidents are open: not deploying."
            exit 1
          fi
      - name: Deploy
        run: ./deploy.sh

GitLab CI

.gitlab-ci.ymlYAML
check-incidents:
  stage: test
  image: node:lts
  variables:
    STATUS200_URL: https://status200.ru
  script:
    - npm install -g @status200/cli
    - OPEN=$(status200 incident count --query '{"currentIncidentState":{"isResolvedState":false}}')
    - echo "$OPEN incidents are open"
    - test "$OPEN" -eq 0

Docker

DockerfileDockerfile
FROM node:lts-slim
RUN npm install -g @status200/cli
ENTRYPOINT ["status200"]

In GitHub Actions, add STATUS200_API_KEY under the repository's Settings → Secrets and variables → Actions; in GitLab, add it as a masked CI/CD variable. With the Docker image, pass the variables to each run:

Bash
docker build -t status200-cli .
docker run --rm -e STATUS200_API_KEY -e STATUS200_URL status200-cli incident count

Next steps