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/**) edeno-tests(Edge Functions); contract/security tests agora usamvitest.staging.config.tsdedicado.
1. Workflows Ativos
| Workflow | Arquivo | Trigger | Função |
|---|---|---|---|
| CI principal | .github/workflows/ci.yml | push em main | Lint + build + deploy staging + testes + E2E |
| Security Audit | .github/workflows/audit.yml | cron semanal (segunda 08:00 UTC) + manual | npm audit em deps |
| Release | .github/workflows/release.yml | push de tag v* | Cria GitHub Release com changelog |
Removidos / migrados
| Workflow | Motivo |
|---|---|
deploy-docs.yml | Deploy 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
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 install→bun run lint→bun run build. - Lint policy:
eslint:recommended+react-hooks+react-refresh. Regrano-control-regexé error: control chars em regex precisam de// eslint-disable-next-line no-control-regexcom comentário explicando a intenção (ex.: sanitização anti-injeção emtemplates-import-parser.ts). - Falha aqui = nada mais roda.
unit-tests
- Vitest contra
src/**(unit + integration sem rede). - Comando:
bun run test(resolvevitest.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 desupabase/functions/para que odeno.json(nodeModulesDir: "auto") seja resolvido corretamente.- Etapa pré:
deno install --allow-scriptspopulanode_modulesparanpm:specifiers (ex.:npm:hash-wasm@4.11.0em_shared/password-helper.ts). - Cache de
~/.cache/deno+supabase/functions/node_modulesreduz tempo de execução. - Cobre os ~600 casos de Edge Functions e helpers em
_shared/.
deploy-staging
- Roda Supabase CLI:
supabase link→supabase db push→supabase 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 porquevitest.config.tsfiltra apenassrc/**. Sem isso, o Vitest devolveNo 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 chromiumantes de rodarnpx 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).
- Upload do
check-docs-auth-changes + deploy-docs-auth
- Usa
dorny/paths-filter@v3para detectar mudanças emworkers/docs-auth/**. - Se houve mudança:
npm install+npx wrangler deployno diretório do worker. - Secrets:
CLOUDFLARE_API_TOKEN,CLOUDFLARE_ACCOUNT_ID. - Worker:
olp-docs-auth(proteção JWT HS256 dodocs.olp.digital).
3. audit.yml — Auditoria Semanal
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, tagmag) — confirma que o cron disparou.alert(Priority: urgent, tagskull) — só quandobun auditexit ≠ 0; corpo traz a linha "X vulnerabilities (Y high, Z moderate)" + link da run.ok(Priority: default, tagwhite_check_mark) — quando exit = 0.
- Sempre publica
audit.logcomo artifact (retention 30d). - Pré-requisito: secret
NTFY_TOPIC_URLno GitHub Actions (mesmo nome usado peloci.yml— aceita URL completahttps://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
startpor 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@v2comgenerate_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
mainquando há mudança emdocs/**oupackage.json. - Build: Cloudflare executa
bun install && bun run docs:build(definido em Pages settings). - Output:
docs/.vitepress/dist. - Auth: Worker
olp-docs-authvalida 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)
| Secret | Usado em | Função |
|---|---|---|
SUPABASE_ACCESS_TOKEN | deploy-staging | CLI auth |
STAGING_PROJECT_REF | deploy-staging | Project ref do Supabase staging |
STAGING_SUPABASE_URL | contract/security/e2e | URL do projeto staging |
STAGING_SUPABASE_ANON_KEY | contract/security/e2e | Anon key staging |
E2E_TEST_PASSWORD | contract/security/e2e | Senha dos usuários de teste seed |
NTFY_TOPIC_URL | e2e (opcional) | URL ntfy para alerta de E2E quebrado |
NTFY_TOPIC_URL | audit | Endpoint ntfy (URL completa ou hash) para pings start/alert/ok do Security Audit — mesmo secret do e2e |
CLOUDFLARE_API_TOKEN | deploy-docs-auth | Deploy do Worker |
CLOUDFLARE_ACCOUNT_ID | deploy-docs-auth | Account ID Cloudflare |
Nunca versionar valores.
.env.examplecontém apenas nomes.
7. Padrões e Regras
Versões
- Node 22 em todos os jobs JS (alinhar com
package.json#enginesse existir). - Bun latest — install + lint + build + vitest. Usado no lugar de
npmpor 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: trueapenas 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
| Job | Comando local equivalente |
|---|---|
lint-and-build | bun install && bun run lint && bun run build |
unit-tests | bun run test |
deno-tests | cd supabase/functions && deno install --allow-scripts && deno test --allow-net --allow-env --allow-read . |
contract-tests | bunx vitest run --config vitest.staging.config.ts tests/contracts --reporter=verbose |
security-tests | bunx vitest run --config vitest.staging.config.ts tests/security --reporter=verbose |
e2e | npx 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:
// 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
| Sintoma | Diagnóstico | Ação |
|---|---|---|
lint falhou com no-control-regex | Regex novo com \xNN sem disable | Adicionar eslint-disable-next-line no-control-regex com comentário |
lint com Unused eslint-disable directive | Disable obsoleto após mudança | Remover a diretiva |
unit-tests falhou só no CI | Snapshot/timezone/QueryClient leak | Reproduzir 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 function | Mover para <func>/__tests__/ (guard) |
contract-tests ou security-tests com No test files found | Falta --config vitest.staging.config.ts (config padrão filtra só src/**) | Usar o comando de §7 |
deploy-staging falhou com 401 | SUPABASE_ACCESS_TOKEN expirado/inválido | Regenerar em supabase.com/account/tokens, atualizar secret |
deploy-staging falhou com migration error | SQL inválido / dependência faltante | Verificar MIGRATION_SAFETY_PROTOCOL, rodar supabase db push --dry-run local |
contract-tests falhou apenas no CI | Diferença de env (anon key, URL) | Conferir secrets staging; rodar local com mesmas envs |
e2e falhou | Baixar artifact playwright-report (7 dias) | Inspecionar trace, verificar TEST_ERROR_PLAYBOOK |
e2e notificação ntfy não chegou | NTFY_TOPIC_URL não setado ou inválido | Verificar warning no log do step "Notificar falha E2E via ntfy" |
deploy-docs-auth não rodou | paths-filter não detectou mudança em workers/docs-auth/** | Conferir caminho exato do arquivo modificado |
Docs não atualizou em docs.olp.digital | Auto-deploy Pages quebrado | Verificar dashboard Cloudflare Pages → Deployments; nunca recriar workflow GH |
9. Referências cruzadas
- TEST_ERROR_PLAYBOOK — diagnóstico de falhas de teste
- MIGRATION_SAFETY_PROTOCOL — protocolo pré-migration
- TESTING_MASTER — pirâmide de testes
- VITEPRESS_SETUP — infra das docs
- CLOUDFLARE_WORKER_GATEWAY — gateway prod
- STAGING_REFERENCE — URLs e dados staging