Skip to content

CI/CD Pipeline — Guia Completo

SSOT dos workflows GitHub Actions da Plataforma OLP. Esta documentação cobre todos os pipelines ativos, sua ordem, secrets necessários, padrões e troubleshooting.

Última atualização: 2026-05-09 — adicionados jobs unit-tests (Vitest src/**) e deno-tests (Edge Functions); contract/security tests agora usam vitest.staging.config.ts dedicado.


1. Workflows Ativos

WorkflowArquivoTriggerFunção
CI principal.github/workflows/ci.ymlpush em mainLint + build + deploy staging + testes + E2E
Security Audit.github/workflows/audit.ymlcron semanal (segunda 08:00 UTC) + manualnpm audit em deps
Release.github/workflows/release.ymlpush de tag v*Cria GitHub Release com changelog

Removidos / migrados

WorkflowMotivo
deploy-docs.ymlDeploy de docs/ migrou para Cloudflare Pages com integração Git nativa (auto-deploy ao push em docs/**). Workflow GH era duplicado e gerava race conditions.

2. ci.yml — Pipeline Principal

2.1 Cadeia de jobs

text
lint-and-build

   ├──► unit-tests        (Vitest src/** — unit + integration, sem rede)

   ├──► deno-tests        (Deno test em supabase/functions/** — black-box + helpers)

   └──► deploy-staging    (Supabase migrations + Edge Functions)


       contract-tests     (vitest.staging.config.ts → tests/contracts/)


       security-tests     (vitest.staging.config.ts → tests/security/ — IDOR cross-escola)


       e2e                (Playwright + ntfy on failure)


check-docs-auth-changes  (paths-filter — paralelo)


deploy-docs-auth         (só se workers/docs-auth/** mudou)

Falha em qualquer etapa bloqueia as seguintes via needs:. unit-tests, deno-tests e deploy-staging rodam em paralelo após lint-and-build. Os dois últimos jobs (check-docs-auth-changes + deploy-docs-auth) rodam em paralelo ao resto.

2.2 Detalhe por job

lint-and-build

  • Setup: Node 22 + Bun latest.
  • Comandos: bun installbun run lintbun run build.
  • Lint policy: eslint:recommended + react-hooks + react-refresh. Regra no-control-regex é error: control chars em regex precisam de // eslint-disable-next-line no-control-regex com comentário explicando a intenção (ex.: sanitização anti-injeção em templates-import-parser.ts).
  • Falha aqui = nada mais roda.

unit-tests

  • Vitest contra src/** (unit + integration sem rede).
  • Comando: bun run test (resolve vitest.config.ts).
  • Cobre os ~794 casos de hooks, componentes e helpers do frontend. Rodava só localmente até 2026-05-09.

deno-tests

  • deno test --allow-net --allow-env --allow-read . rodado a partir de supabase/functions/ para que o deno.json (nodeModulesDir: "auto") seja resolvido corretamente.
  • Etapa pré: deno install --allow-scripts popula node_modules para npm: specifiers (ex.: npm:hash-wasm@4.11.0 em _shared/password-helper.ts).
  • Cache de ~/.cache/deno + supabase/functions/node_modules reduz tempo de execução.
  • Cobre os ~600 casos de Edge Functions e helpers em _shared/.

deploy-staging

  • Roda Supabase CLI: supabase linksupabase db pushsupabase functions deploy.
  • Secrets: SUPABASE_ACCESS_TOKEN, STAGING_PROJECT_REF.
  • Aplica migrations pendentes e re-deploya todas as Edge Functions ao staging.
  • Migrations seguem MIGRATION_SAFETY_PROTOCOL (3 fases) — qualquer falha em fase 2 deve abortar antes do push.

contract-tests

  • Black-box HTTP contra staging via bunx vitest run --config vitest.staging.config.ts tests/contracts --reporter=verbose.
  • Config dedicado (vitest.staging.config.ts) é necessário porque vitest.config.ts filtra apenas src/**. Sem isso, o Vitest devolve No test files found.
  • Secrets: STAGING_SUPABASE_URL, STAGING_SUPABASE_ANON_KEY, E2E_TEST_PASSWORD.
  • Valida contratos das Edge Functions (status codes, payload shape, sem leak de dados internos).

security-tests

  • bunx vitest run --config vitest.staging.config.ts tests/security --reporter=verbose.
  • Testes IDOR cross-escola obrigatórios (ver IDOR Validation).
  • Mesmos secrets de contract-tests.

e2e

  • Playwright contra https://staging.olp.digital.
  • npx playwright install --with-deps chromium antes de rodar npx playwright test e2e/.
  • Secrets: E2E_TEST_PASSWORD, STAGING_SUPABASE_URL, STAGING_SUPABASE_ANON_KEY, NTFY_TOPIC_URL (opcional).
  • On failure:
    • Upload do playwright-report/ como artifact (retenção 7 dias).
    • Notificação via ntfy (continue-on-error: true — falha de notificação não derruba o job).

check-docs-auth-changes + deploy-docs-auth

  • Usa dorny/paths-filter@v3 para detectar mudanças em workers/docs-auth/**.
  • Se houve mudança: npm install + npx wrangler deploy no diretório do worker.
  • Secrets: CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID.
  • Worker: olp-docs-auth (proteção JWT HS256 do docs.olp.digital).

3. audit.yml — Auditoria Semanal

yaml
schedule: '0 8 * * 1'   # toda segunda 08:00 UTC = 05:00 BRT
workflow_dispatch: true # manual
  • Roda bun audit --prod (sem --audit-level — reporta tudo, parsing local pega contagem).
  • Notificação ntfy (3 sinais):
    • start (Priority: low, tag mag) — confirma que o cron disparou.
    • alert (Priority: urgent, tag skull) — só quando bun audit exit ≠ 0; corpo traz a linha "X vulnerabilities (Y high, Z moderate)" + link da run.
    • ok (Priority: default, tag white_check_mark) — quando exit = 0.
  • Sempre publica audit.log como artifact (retention 30d).
  • Pré-requisito: secret NTFY_TOPIC_URL no GitHub Actions (mesmo nome usado pelo ci.yml — aceita URL completa https://ntfy.sh/<hash> ou só o hash, normalizado em runtime). Ausência → steps de ping são pulados com ::warning:: explícito no log (graceful, não quebra job). Falha de envio também emite warning sem derrubar o job.
  • Vulnerabilidade ≠ incidente, mas falta de start por 2 semanas seguidas é incidente operacional (cron parou).

4. release.yml — GitHub Release

  • Trigger: push de tag v* (ex.: git tag v1.2.3 && git push --tags).
  • Permission: contents: write.
  • Gera changelog comparando HEAD^ ao tag anterior (git log --oneline --no-merges).
  • Publica via softprops/action-gh-release@v2 com generate_release_notes: true (notas automáticas do GitHub somam ao changelog manual).

5. Deploy de Documentação (sem workflow GH)

docs.olp.digital é servido por Cloudflare Pages (olp-anp290q1f9) com integração Git nativa:

  • Trigger: push em main quando há mudança em docs/** ou package.json.
  • Build: Cloudflare executa bun install && bun run docs:build (definido em Pages settings).
  • Output: docs/.vitepress/dist.
  • Auth: Worker olp-docs-auth valida JWT HS256 (OLP_JWT_SECRET) antes de servir o Pages — host real (olp-anp290q1f9.pages.dev) é ofuscado.

Por que sem workflow GH? O auto-deploy nativo do Cloudflare Pages é suficiente, evita race condition com workflow paralelo e poupa minutos GH Actions.

Ver VITEPRESS_SETUP e workers/docs-auth/README.md (fora do escopo do VitePress, ler no repositório).


6. Secrets Necessários (GitHub → Settings → Secrets)

SecretUsado emFunção
SUPABASE_ACCESS_TOKENdeploy-stagingCLI auth
STAGING_PROJECT_REFdeploy-stagingProject ref do Supabase staging
STAGING_SUPABASE_URLcontract/security/e2eURL do projeto staging
STAGING_SUPABASE_ANON_KEYcontract/security/e2eAnon key staging
E2E_TEST_PASSWORDcontract/security/e2eSenha dos usuários de teste seed
NTFY_TOPIC_URLe2e (opcional)URL ntfy para alerta de E2E quebrado
NTFY_TOPIC_URLauditEndpoint ntfy (URL completa ou hash) para pings start/alert/ok do Security Audit — mesmo secret do e2e
CLOUDFLARE_API_TOKENdeploy-docs-authDeploy do Worker
CLOUDFLARE_ACCOUNT_IDdeploy-docs-authAccount ID Cloudflare

Nunca versionar valores. .env.example contém apenas nomes.


7. Padrões e Regras

Versões

  • Node 22 em todos os jobs JS (alinhar com package.json#engines se existir).
  • Bun latest — install + lint + build + vitest. Usado no lugar de npm por velocidade.
  • Playwright rodado via npx (não migrado p/ bun por compatibilidade com browsers binários).

Falhas

  • Bloqueante por padrão (needs: cascade).
  • continue-on-error: true apenas em notificações (ntfy) e auditorias semanais. Nunca em testes.
  • NUNCA relaxar assertions de teste para passar CI — falha real exige correção do produto. Ver TEST_ERROR_PLAYBOOK.

Reproducibilidade local

JobComando local equivalente
lint-and-buildbun install && bun run lint && bun run build
unit-testsbun run test
deno-testscd supabase/functions && deno install --allow-scripts && deno test --allow-net --allow-env --allow-read .
contract-testsbunx vitest run --config vitest.staging.config.ts tests/contracts --reporter=verbose
security-testsbunx vitest run --config vitest.staging.config.ts tests/security --reporter=verbose
e2enpx playwright test e2e/ (com BASE_URL=https://staging.olp.digital)

Variáveis de staging em .env.local (jamais commitar).

Lint específico — control chars

Regra no-control-regex é error. Para regex de sanitização legítima (ex.: bloquear \x00-\x1F em nomes de arquivo, conteúdo de import), adicionar diretiva inline:

ts
// eslint-disable-next-line no-control-regex -- sanitização intencional: bloqueia control chars
const NoControlChars = /^[^\x00-\x08\x0B\x0C\x0E-\x1F]+$/;

Sempre incluir comentário explicando por que os control chars estão presentes — facilita auditoria.


8. Troubleshooting

SintomaDiagnósticoAção
lint falhou com no-control-regexRegex novo com \xNN sem disableAdicionar eslint-disable-next-line no-control-regex com comentário
lint com Unused eslint-disable directiveDisable obsoleto após mudançaRemover a diretiva
unit-tests falhou só no CISnapshot/timezone/QueryClient leakReproduzir com bun run test local; conferir setupFiles em vitest.config.ts
deno-tests com Could not find a matching package for 'npm:...'deno test rodou fora de supabase/functions/ (deno.json não resolvido)Confirmar working-directory: supabase/functions no job + step deno install --allow-scripts antes do deno test
deno-tests com OOM/exit 135 no deploy*.test.ts co-localizado na raiz da functionMover para <func>/__tests__/ (guard)
contract-tests ou security-tests com No test files foundFalta --config vitest.staging.config.ts (config padrão filtra só src/**)Usar o comando de §7
deploy-staging falhou com 401SUPABASE_ACCESS_TOKEN expirado/inválidoRegenerar em supabase.com/account/tokens, atualizar secret
deploy-staging falhou com migration errorSQL inválido / dependência faltanteVerificar MIGRATION_SAFETY_PROTOCOL, rodar supabase db push --dry-run local
contract-tests falhou apenas no CIDiferença de env (anon key, URL)Conferir secrets staging; rodar local com mesmas envs
e2e falhouBaixar artifact playwright-report (7 dias)Inspecionar trace, verificar TEST_ERROR_PLAYBOOK
e2e notificação ntfy não chegouNTFY_TOPIC_URL não setado ou inválidoVerificar warning no log do step "Notificar falha E2E via ntfy"
deploy-docs-auth não rodoupaths-filter não detectou mudança em workers/docs-auth/**Conferir caminho exato do arquivo modificado
Docs não atualizou em docs.olp.digitalAuto-deploy Pages quebradoVerificar dashboard Cloudflare Pages → Deployments; nunca recriar workflow GH

9. Referências cruzadas