> ## Documentation Index
> Fetch the complete documentation index at: https://pulse-41cf5b0d.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gating CI/CD Deployments with PulseGuard pulse wait

> Block deployments with pulse wait until your monitor reports UP. Integrates with GitHub Actions, GitLab CI, CircleCI, and any CI system.

Deploying code without verifying that your service is actually healthy afterwards is a gap that `pulse wait` closes. After your deployment step completes, run `pulse wait` with your production monitor's ID and the CLI will block until PulseGuard confirms the monitor is `UP` — or fail the pipeline if it doesn't recover in time. This works with GitHub Actions, GitLab CI, CircleCI, and any CI system that respects process exit codes.

## The `pulse wait` command

`pulse wait` polls the PulseGuard API on a configurable interval until the target monitor's status transitions to `UP`, or until the timeout is reached. It exits with code `0` on success and code `1` on timeout or error, so your CI system automatically marks the step as failed if the service doesn't recover.

```bash theme={null}
pulse wait <monitor-id>
```

### Flags

| Flag                   | Default | Description                                                      |
| ---------------------- | ------- | ---------------------------------------------------------------- |
| `--timeout <seconds>`  | `300`   | Maximum time to wait. Capped at `600` seconds.                   |
| `--interval <seconds>` | `15`    | How often to poll for the monitor's status. Minimum `5` seconds. |
| `--json`               | —       | Print a JSON result object to stdout on completion or timeout.   |

### Examples

Wait up to 5 minutes (the default):

```bash theme={null}
pulse wait mon_abc123
```

Wait up to 10 minutes with a 30-second polling interval:

```bash theme={null}
pulse wait mon_abc123 --timeout 600 --interval 30
```

Get a machine-readable result for post-deploy scripts:

```bash theme={null}
pulse wait mon_abc123 --json
```

On success the JSON output looks like:

```json theme={null}
{
  "success": true,
  "monitorId": "mon_abc123",
  "name": "Production API",
  "status": "UP",
  "lastCheck": "2024-11-01T14:32:00.000Z"
}
```

On timeout:

```json theme={null}
{
  "success": false,
  "monitorId": "mon_abc123",
  "name": "Production API",
  "status": "DOWN",
  "lastCheck": "2024-11-01T14:35:00.000Z"
}
```

### Exit codes

| Code | Meaning                                                                     |
| ---- | --------------------------------------------------------------------------- |
| `0`  | The monitor reached `UP` status within the timeout.                         |
| `1`  | The timeout was reached without recovery, or an API/network error occurred. |

<Note>
  `pulse wait` polls the PulseGuard API to read your monitor's reported status — it does not make any direct requests to your service. All traffic originates from PulseGuard's own check infrastructure.
</Note>

## GitHub Actions

Add a post-deploy step that blocks the workflow until your production monitor is healthy. Store your API key as a repository secret named `PULSEGUARD_API_KEY` and your monitor ID as a repository variable named `MONITOR_ID`. A dedicated `pulse auth login` step authenticates the CLI before any monitoring commands run.

```yaml .github/workflows/deploy.yml theme={null}
name: Deploy
on:
  push:
    branches: [main]

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

      - name: Install pulse CLI
        run: npm install -g pulseguard-cli

      - name: Authenticate pulse CLI
        run: pulse auth login --key ${{ secrets.PULSEGUARD_API_KEY }}

      - name: Deploy your application
        run: ./deploy.sh

      - name: Wait for production to be healthy
        run: pulse wait ${{ vars.MONITOR_ID }} --timeout 300
```

If the monitor does not return `UP` within 300 seconds, the `pulse wait` step exits with code `1` and GitHub Actions marks the workflow run as failed, preventing any subsequent steps from running.

## GitLab CI

The same pattern works in GitLab CI. Set `PULSEGUARD_API_KEY` and `MONITOR_ID` as masked CI/CD variables in your project settings. The `pulse auth login` call at the start of the script authenticates the CLI for the rest of the job.

```yaml .gitlab-ci.yml theme={null}
deploy:
  stage: deploy
  script:
    - npm install -g pulseguard-cli
    - pulse auth login --key $PULSEGUARD_API_KEY
    - ./deploy.sh
    - pulse wait $MONITOR_ID --timeout 300
```

## CircleCI

In CircleCI, store your API key in a context or as a project-level environment variable, then add a `pulse wait` call after your deployment script:

```yaml .circleci/config.yml theme={null}
version: 2.1

jobs:
  deploy:
    docker:
      - image: cimg/node:lts
    steps:
      - checkout
      - run:
          name: Install pulse CLI
          command: npm install -g pulseguard-cli
      - run:
          name: Authenticate pulse CLI
          command: pulse auth login --key $PULSEGUARD_API_KEY
      - run:
          name: Deploy
          command: ./deploy.sh
      - run:
          name: Wait for production monitor
          command: pulse wait $MONITOR_ID --timeout 300

workflows:
  deploy:
    jobs:
      - deploy:
          filters:
            branches:
              only: main
```

## Best practices

Follow these guidelines to get the most reliable results from `pulse wait` in your pipelines:

<Steps>
  <Step title="Store your API key as a secret">
    Always store your PulseGuard API key as a masked/protected CI secret (for example `PULSEGUARD_API_KEY` in GitHub or GitLab). Pass it to `pulse auth login --key $PULSEGUARD_API_KEY` at the start of your job. Never hardcode an API key in your pipeline configuration file or commit it to source control.
  </Step>

  <Step title="Use a read-only API key for CI">
    Create a dedicated API key for your CI pipelines with a descriptive name (for example `ci-pipeline-prod`). A read-only key is sufficient for `pulse wait` and `pulse monitors list`, and limits the blast radius if the key is ever exposed.
  </Step>

  <Step title="Set a realistic timeout">
    Measure how long your service typically takes to become healthy after a deployment and add a generous buffer. If your service is usually ready in 60 seconds, a `--timeout 180` gives you 3× headroom without blocking the pipeline indefinitely.
  </Step>

  <Step title="Parse JSON output in post-deploy scripts">
    If you have a post-deploy notification or rollback script, use `pulse wait --json` and pipe the output to `jq` to extract the monitor name, status, and last-check timestamp for richer diagnostics.
  </Step>
</Steps>

<Warning>
  Setting `--timeout` higher than `600` has no effect — the CLI enforces a maximum of 600 seconds. Design your deployment process so that a healthy service becomes `UP` well within this window.
</Warning>

## Combining with Monitoring as Code

For a fully automated workflow, combine `pulse monitors apply` with `pulse wait` in the same pipeline. Apply your YAML configuration first to ensure monitor definitions are up to date, deploy your application, then gate on the monitor becoming healthy:

```bash theme={null}
# Authenticate the CLI (run once per CI job)
pulse auth login --key $PULSEGUARD_API_KEY

# Sync monitor definitions from version control
pulse monitors apply -f pulseguard.yaml

# Deploy the application
./deploy.sh

# Gate: block until the production monitor is UP
pulse wait $MONITOR_ID --timeout 300
```

This approach means your monitor configuration, application code, and deployment verification all live in the same repository and evolve together.
