> ## Documentation Index
> Fetch the complete documentation index at: https://docs.happyuptime.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD recipes

Drop-in workflows for GitHub Actions, GitLab CI, and CircleCI.

# CI/CD recipes

## GitHub Actions

```yaml
# .github/workflows/uptime.yml
name: Uptime config
on:
  push:
    branches: [main]
    paths: [happyuptime.yml]
  pull_request:
    paths: [happyuptime.yml]

jobs:
  apply:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install -g happyuptime-cli
      - name: Validate
        run: happy config validate happyuptime.yml
      - name: Plan (PR only)
        if: github.event_name == 'pull_request'
        env:
          HAPPYUPTIME_API_KEY: ${{ secrets.HAPPYUPTIME_API_KEY }}
        run: happy config push happyuptime.yml --dry-run
      - name: Apply (main only)
        if: github.ref == 'refs/heads/main'
        env:
          HAPPYUPTIME_API_KEY: ${{ secrets.HAPPYUPTIME_API_KEY }}
        run: happy config push happyuptime.yml
```

## Heartbeat ping after a deploy

```yaml
- name: Deploy
  run: ./deploy.sh
- name: Heartbeat success
  if: success()
  run: |
    curl -fsS -X POST https://happyuptime.com/api/heartbeat/${{ secrets.HEARTBEAT_SLUG }}
- name: Heartbeat failure
  if: failure()
  run: |
    curl -X POST https://happyuptime.com/api/heartbeat/${{ secrets.HEARTBEAT_SLUG }} \
      -H "Content-Type: application/json" \
      -d '{"status":"fail","message":"GitHub Actions deploy failed"}'
```

## Post-deploy verification

After a deploy, run an ad-hoc check to confirm your monitors are still healthy:

```yaml
- name: Verify monitors green
  env:
    HAPPYUPTIME_API_KEY: ${{ secrets.HAPPYUPTIME_API_KEY }}
  run: |
    happy monitors check api
    sleep 5
    DOWN=$(happy status --json | jq '.monitors.down')
    if [ "$DOWN" -gt 0 ]; then
      echo "❌ $DOWN monitors are down"
      exit 1
    fi
```

## Create an incident from a deploy failure

```yaml
- name: Open incident
  if: failure()
  env:
    HAPPYUPTIME_API_KEY: ${{ secrets.HAPPYUPTIME_API_KEY }}
  run: |
    happy incidents create \
      --title "Deploy ${{ github.sha }} failed" \
      --severity major \
      --message "GitHub Actions job failed at $(date -u). Investigate before next deploy."
```

## GitLab CI

```yaml
# .gitlab-ci.yml
uptime_config:
  image: node:20
  script:
    - npm install -g happyuptime-cli
    - happy config validate happyuptime.yml
    - happy config push happyuptime.yml --dry-run
  only:
    - main
  variables:
    HAPPYUPTIME_API_KEY: $HAPPYUPTIME_API_KEY
```