# Deploys and maintenance from CI

Record deploys and open maintenance windows from GitHub Actions, GitLab CI or any pipeline.


Two calls from your pipeline make incidents easier to understand and quieter during planned work:

- **Deploy markers** show, on every incident, what was deployed just before it started. With
  [agent on-call](/docs/agents), the agent looks at those changes first.
- **Maintenance windows** pause checks and alerts while you migrate a database or restart things on
  purpose. The time doesn't count against your uptime, and status pages show it as scheduled work.

Both need an API key: the account owner creates one under **Account → API keys**. Store it as a
secret named `PULSEFAST_API_KEY`.

## GitHub Actions

```yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Quiet monitors while we migrate
        id: maintenance
        run: |
          id=$(curl -fsS -X POST https://pulsefast.io/api/v1/maintenance \
            -H "Authorization: Bearer ${{ secrets.PULSEFAST_API_KEY }}" \
            -d '{"title": "Deploy ${{ github.sha }}", "duration_minutes": 15}' | jq -r .id)
          echo "id=$id" >> "$GITHUB_OUTPUT"

      - run: ./deploy.sh

      - name: Record the deploy
        run: |
          curl -fsS -X POST https://pulsefast.io/api/v1/deploys \
            -H "Authorization: Bearer ${{ secrets.PULSEFAST_API_KEY }}" \
            -d '{"service": "checkout", "version": "${{ github.sha }}", "environment": "production",
                 "url": "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"}'

      - name: End maintenance early (also if the deploy failed)
        if: always() && steps.maintenance.outputs.id != ''
        run: |
          curl -fsS -X DELETE https://pulsefast.io/api/v1/maintenance/${{ steps.maintenance.outputs.id }} \
            -H "Authorization: Bearer ${{ secrets.PULSEFAST_API_KEY }}"
```

## GitLab CI

```yaml
deploy:
  stage: deploy
  script:
    - ./deploy.sh
    - >
      curl -fsS -X POST https://pulsefast.io/api/v1/deploys
      -H "Authorization: Bearer $PULSEFAST_API_KEY"
      -d "{\"service\": \"checkout\", \"version\": \"$CI_COMMIT_SHA\", \"environment\": \"$CI_ENVIRONMENT_NAME\"}"
```

## Any pipeline

```sh
curl -fsS -X POST https://pulsefast.io/api/v1/deploys \
  -H "Authorization: Bearer $PULSEFAST_API_KEY" \
  -d '{"version": "'"$GIT_SHA"'"}'
```

## Tips

- **Send the full 40-character commit SHA** as `version`: a hosted agent then checks out exactly that
  commit to investigate.
- **Use `service`** if you deploy several things. Incidents for a service show its deploys; deploys
  without a service show on every incident.
- **Keep maintenance windows short** and end them when the work is done: while one is open, a real
  outage on those monitors goes unnoticed.
- `curl -f` makes the step fail on an API error, so a bad key doesn't go unnoticed. If monitoring
  should never block a deploy, add `|| true`.

All fields: [Deploy markers](/docs/api#deploy-markers) and [Maintenance windows](/docs/api#maintenance-windows).
