From cf9438e5b9b0a82ddc83cc51f51bf80e55e09ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Ign=C3=A1cio=20Fontoura=20Solla?= Date: Thu, 30 Jul 2026 17:40:53 -0300 Subject: [PATCH] fix(ci): restore rollup checks job for branch protection Parallel ci-pr jobs no longer published the legacy `checks` context required by stage/main branch protection, blocking auto-merge with no link in the UI. Add a needs-based rollup that gates on all jobs green. --- .github/workflows/ci-pr.yml | 29 +++++++++++++++++++++++++++++ .github/workflows/ci.yml | 17 +++++++++++++++++ docs/AGENT-OPS.md | 10 +++++----- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index e3bdaf49..ff1aa302 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -281,6 +281,35 @@ jobs: if: steps.scope.outputs.mode == 'none' run: echo "No e2e-relevant changes in this PR — nothing to run." + # Branch protection on `stage`/`main` still requires the legacy context name + # `checks` from the pre-parallel monolithic job. This rollup satisfies that + # contract without re-serializing the suite. + checks: + name: checks + runs-on: ubuntu-latest + needs: + - lint + - format + - typecheck + - knip + - cycles + - unit + - int + - build + - e2e + - migration-lock + if: always() + steps: + - name: All parallel checks green + env: + NEEDS: ${{ toJSON(needs) }} + run: | + set -euo pipefail + echo "$NEEDS" | jq -e ' + to_entries + | all(.value.result == "success" or .value.result == "skipped") + ' + migration-lock: # At most ONE open PR may touch schema (migrations or generated types). # Two in flight guarantees a broken rebase and a poisoned drizzle snapshot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2510cb79..7ca22099 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,3 +139,20 @@ jobs: - name: E2E tests (full suite) run: pnpm test:e2e + + # Same legacy branch-protection context as ci-pr.yml (see comment there). + checks: + name: checks + runs-on: ubuntu-latest + needs: [static, int, build, e2e] + if: always() + steps: + - name: All parallel checks green + env: + NEEDS: ${{ toJSON(needs) }} + run: | + set -euo pipefail + echo "$NEEDS" | jq -e ' + to_entries + | all(.value.result == "success" or .value.result == "skipped") + ' diff --git a/docs/AGENT-OPS.md b/docs/AGENT-OPS.md index 13ef5766..04e25596 100644 --- a/docs/AGENT-OPS.md +++ b/docs/AGENT-OPS.md @@ -54,11 +54,11 @@ Labels: estado `ready|in-progress|blocked|done|in-prod`, `prio:P0..P3`, `kind:fe ## CI por alvo -| Workflow | Trigger | Banco | Passos | -| -------------- | ------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ci-pr.yml` | PR → `stage`/`main` | service Postgres 17 (mínimo) | jobs paralelos: `lint`/`format`/`typecheck`/`knip`/`cycles` · `unit`/`int` (**afetados pelo diff**: `vitest --changed` vs base do PR; fallback full em paths de risco — `scripts/test-affected.mjs`) · `e2e` (manifesto path→spec — `scripts/e2e-affected.mjs`, bloqueante) · `build` + `migration-lock` | -| `ci-stage.yml` | push em `stage` | `STAGE_DATABASE_URL` (Environment `stage`) | **só** `migrate` + smoke int (subset curado — a suíte completa é lenta demais contra Neon remoto, estourou timeout 2× em 2026-07-30; a full fica no ci-pr/ci.yml) — **NUNCA `pnpm build`** (build migra o banco que vê), nunca seed:minimal | -| `ci.yml` | push em `main` | service Postgres | **gate completo sempre** (rede de segurança pós-promote): estático + unit + int full (com seed:minimal) + build + e2e full | +| Workflow | Trigger | Banco | Passos | +| -------------- | ------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ci-pr.yml` | PR → `stage`/`main` | service Postgres 17 (mínimo) | jobs paralelos: `lint`/`format`/`typecheck`/`knip`/`cycles` · `unit`/`int` (**afetados pelo diff**: `vitest --changed` vs base do PR; fallback full em paths de risco — `scripts/test-affected.mjs`) · `e2e` (manifesto path→spec — `scripts/e2e-affected.mjs`, bloqueante) · `build` + `migration-lock`; job rollup **`checks`** agrega todos (nome legado exigido pela branch protection — não re-serializa a suíte) | +| `ci-stage.yml` | push em `stage` | `STAGE_DATABASE_URL` (Environment `stage`) | **só** `migrate` + smoke int (subset curado — a suíte completa é lenta demais contra Neon remoto, estourou timeout 2× em 2026-07-30; a full fica no ci-pr/ci.yml) — **NUNCA `pnpm build`** (build migra o banco que vê), nunca seed:minimal | +| `ci.yml` | push em `main` | service Postgres | **gate completo sempre** (rede de segurança pós-promote): estático + unit + int full (com seed:minimal) + build + e2e full | Fast gate local do agente antes do push: `pnpm gate:fast` (lint + typecheck + test:unit); o hook `.husky/pre-push` roda `pnpm gate:push` (fast + format:check + check:cycles). Fonte única: scripts `gate:*` em `package.json`. knip fica fora do hook (grafo incompleto — ledger P3; CI o roda bloqueante). Escape para WIP: `git push --no-verify` (o CI repete tudo). **E2e afetado localmente (mesmo critério do PR):** `pnpm test:e2e:affected`. int/build/e2e = CI.