# CI com GitHub Actions

Guarde o token (escopos `deploy` e `projects:read`) como secret `NEBULAR_TOKEN` do repositório e os ids como variáveis (`NEBULAR_PROJECT`, `NEBULAR_SERVICE`). Nunca escreva o token no YAML. Crie o token com a menor permissão possível e restrinja a `project_ids`.

```yaml
name: deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      NEBULAR_API: https://api.nebularws.com
      NEBULAR_TOKEN: ${{ secrets.NEBULAR_TOKEN }}
      P: ${{ vars.NEBULAR_PROJECT }}
      S: ${{ vars.NEBULAR_SERVICE }}
    steps:
      - name: Disparar deploy
        run: |
          D=$(curl -fsS -X POST "$NEBULAR_API/v1/projects/$P/services/$S/deployments" \
            -H "Authorization: Bearer $NEBULAR_TOKEN" \
            -H "Idempotency-Key: gh-${{ github.sha }}" \
            -H "Content-Type: application/json" -d '{}' | jq -r '.id')
          echo "D=$D" >> "$GITHUB_ENV"
      - name: Esperar o deploy
        run: |
          delay=2; deadline=$(( $(date +%s) + 1200 ))
          while :; do
            state=$(curl -fsS "$NEBULAR_API/v1/projects/$P/services/$S/deployments/$D" \
              -H "Authorization: Bearer $NEBULAR_TOKEN" | jq -r '.status')
            echo "estado: $state"
            case "$state" in
              ready) exit 0 ;;
              failed|blocked|canceled|superseded) exit 1 ;;
            esac
            [ "$(date +%s)" -lt "$deadline" ] || exit 1
            sleep "$delay"; delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))
          done
```

- A `Idempotency-Key` com o SHA do commit faz o re-run do job não criar um segundo deploy.
- `-f` do curl faz o job falhar em 4xx/5xx. Em `429`/`503`, repita o job (veja [Rate limit e retry](/erros/rate-limit-e-retry/)).
- Auto-deploy por git (webhook do GitHub) é a alternativa sem workflow, quando o serviço tem fonte `git`.
- Para ler o motivo de uma falha, consulte `GET .../deployments/{d}/logs` (`logs:read`).

Erros comuns: `401` (secret ausente ou expirado), `403` (falta o escopo `deploy`), `404` (ids errados ou fora dos `project_ids` do token). Veja a [tabela de erros](/erros/tabela/).
