From feb4f5756ac6f88a23f6101d1469adecacfa3ee7 Mon Sep 17 00:00:00 2001 From: Lucalopezz Date: Wed, 21 Oct 2026 18:51:58 -0300 Subject: [PATCH] ci: require isolated checks before main merges --- .github/workflows/ci.yml | 111 +++++++++++++++++++++++++++ docs/guides/frontend-testing-plan.md | 15 ++-- docs/guides/frontend-testing.md | 13 ++-- docs/guides/testing.md | 29 +++++++ docs/guides/vercel-deployment.md | 6 +- 5 files changed, 162 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a65535c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,111 @@ +name: CI + +on: + pull_request: + branches: [main] + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + quality: + name: quality + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4 + with: + version: 11.21.0 + run_install: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - name: Configure test environment + run: cp apps/api/.env.test.example apps/api/.env.test + - name: Generate Prisma Client for type checking + run: NODE_ENV=test pnpm --filter api exec prisma generate + - name: Lint API without changing files + run: pnpm --filter api exec eslint "{src,apps,libs,test}/**/*.ts" + - name: Lint web + run: pnpm --filter web lint + - name: Build all workspaces + run: pnpm build + - name: Type check browser tests + run: pnpm --filter web typecheck:e2e + - name: Test API units + run: pnpm --filter api exec jest --runInBand + - name: Test web units and components + run: pnpm --filter web test + - name: Test gateway + run: pnpm --filter gateway test + + integration: + name: integration + runs-on: ubuntu-24.04 + timeout-minutes: 35 + services: + postgres: + image: postgres:17-alpine + env: + POSTGRES_USER: devlog + POSTGRES_PASSWORD: ${{ github.run_id }} + POSTGRES_DB: devlog_test + ports: + - 5433:5432 + options: >- + --health-cmd "pg_isready -U devlog -d devlog_test" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4 + with: + version: 11.21.0 + run_install: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - name: Configure disposable test database + run: | + cp apps/api/.env.test.example apps/api/.env.test + sed -i "s|^DATABASE_URL=.*|DATABASE_URL=postgresql://devlog:${GITHUB_RUN_ID}@localhost:5433/devlog_test|" apps/api/.env.test + - name: Generate Prisma Client and apply migrations + run: | + NODE_ENV=test pnpm --filter api exec prisma generate + NODE_ENV=test pnpm --filter api exec prisma migrate deploy + # These suites share one database and the browser suites rebuild one dist directory. + - name: Test Prisma repositories + run: pnpm --filter api test:integration + - name: Test Nest HTTP API + run: pnpm --filter api test:e2e + - name: Build API for full-stack browser tests + run: pnpm --filter api build + - name: Install Chromium and system dependencies + run: pnpm --filter web exec env PLAYWRIGHT_BROWSERS_PATH=.playwright-browsers playwright install --with-deps chromium + - name: Test browser with intercepted API + run: pnpm --filter web test:e2e + - name: Test browser with real API and test database + run: pnpm --filter web test:e2e:full-stack + - name: Preserve browser failure reports + if: failure() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: playwright-failures + path: | + apps/web/test-results/ + apps/web/playwright-report/ + if-no-files-found: ignore + retention-days: 3 diff --git a/docs/guides/frontend-testing-plan.md b/docs/guides/frontend-testing-plan.md index 977daaf..dcdfae4 100644 --- a/docs/guides/frontend-testing-plan.md +++ b/docs/guides/frontend-testing-plan.md @@ -1397,8 +1397,9 @@ Implemented entry point: `pnpm --filter web test:e2e:full-stack`. The maintained [setup guide](frontend-testing.md#full-stack-browser-journeys) describes the current configuration and its six journeys. `e2e/fixtures/real-api.ts` owns account/manifest tracking; `apps/api/scripts/cleanup-e2e-users.ts` removes only -tracked E2E accounts after validating the test target. The inventory and CI -proposals below include follow-up work and are not a completion claim. +tracked E2E accounts after validating the test target. GitHub Actions now runs +both browser modes; the inventory and historical proposals below still include +follow-up work and are not a completion claim. **Goal:** establish that the built frontend, real authentication, API contracts, and database work together, then make the checks repeatable. Keep exhaustive @@ -1584,10 +1585,12 @@ owning part before accepting the corresponding journey. ### 9D. Continuous integration -There is no `.github/workflows` directory in the inspected baseline. If GitHub -Actions is the repository's CI host, create -`.github/workflows/frontend-tests.yml` during this phase. Use equivalent jobs -if another host is selected; the required checks are the same. +Implemented in `.github/workflows/ci.yml` with `quality` and `integration` +checks. The table below preserves the earlier proposed job breakdown for study; +the active commands and merge gate are in the +[testing guide](testing.md#pull-request-ci). The active `integration` job runs +both browser modes sequentially in one checkout to avoid build and port +collisions. | Job | Preparation and commands | Dependency and artifacts | | --- | --- | --- | diff --git a/docs/guides/frontend-testing.md b/docs/guides/frontend-testing.md index f46aa72..33eb94d 100644 --- a/docs/guides/frontend-testing.md +++ b/docs/guides/frontend-testing.md @@ -3,7 +3,7 @@ Status: learning guide and incremental strategy. Parts 0–6 and 8 of the [implementation plan](frontend-testing-plan.md) are implemented. Part 7 was intentionally skipped. Part 9 now includes six full-stack browser journeys; -its CI rollout and dedicated tag journey remain planned. +its CI rollout is implemented; a dedicated tag journey remains planned. This guide starts with the concepts. Read it before Part 0 of the plan. Examples use DevLog's current React, React Router, React Hook Form, Zod, Axios, and @@ -167,7 +167,9 @@ Full-stack traces/reports are separate under `test-results/full-stack` and directories so they cannot erase full-stack traces or interrupted-run manifests. These artifacts and account manifests are ignored. Open either HTML report with `pnpm --filter web exec playwright show-report playwright-report/full-stack` -or the equivalent `playwright-report/mocked` path. +or the equivalent `playwright-report/mocked` path. The CI workflow runs both +browser modes in sequence, after the API database suites, against its own +PostgreSQL service. Local HTTP tests establish the test cookie policy; production HTTPS deployment behavior still needs a check using the deployed origins. @@ -416,9 +418,10 @@ bypasses the integration that the test is meant to establish. Keep full-stack tests few and independent. They provide confidence at service boundaries but take longer to prepare and diagnose than a focused component test. The [full-stack setup](#full-stack-browser-journeys) describes the installed -suite. The plan's [Part 9](frontend-testing-plan.md#part-9--full-stack-journeys-ci-and-completion) -also records follow-up journeys, proposed CI jobs, and a completion checklist; -CI remains pending. +suite. The [API testing guide](testing.md#pull-request-ci) describes the active +CI jobs and merge gate. The plan's +[Part 9](frontend-testing-plan.md#part-9--full-stack-journeys-ci-and-completion) +retains historical proposed jobs and follow-up journeys. ## 12. How to judge whether a test is useful diff --git a/docs/guides/testing.md b/docs/guides/testing.md index 682cbe9..c75bb27 100644 --- a/docs/guides/testing.md +++ b/docs/guides/testing.md @@ -77,6 +77,35 @@ test service before running them. Repository integration suites clear test users between cases; run them sequentially with API and browser E2E suites that use the same database. Never use `pnpm db:reset` merely to run tests. +## Pull request CI + +`.github/workflows/ci.yml` runs for pull requests targeting `main`, pushes to +`main`, and manual dispatch. The `quality` check installs the pinned workspace +dependencies, generates Prisma Client, lints without modifying files, builds all +workspaces, type checks browser tests, and runs API, web, and gateway unit tests. +The `integration` check starts a disposable PostgreSQL service, applies the +committed migrations, and runs Prisma repository, Nest HTTP, intercepted browser, +and full-stack browser suites in sequence. The browser suites share a build +directory and port; database suites share the same test database within the job. + +CI copies `apps/api/.env.test.example` for these runs. The integration job +replaces the example password with its run ID so the PostgreSQL service and +test clients use the same disposable credential. It connects only to +`devlog_test`; GitHub Actions has no Neon or Vercel production secrets. The +API's local `lint` script includes `--fix`, so +the CI command calls ESLint without that flag: a check should fail on violations +instead of silently editing the runner's checkout. + +The repository's `main` ruleset requires a pull request plus successful +`quality`, `integration`, `Vercel`, and `GitGuardian Security Checks` results +before merge. Vercel verifies the Preview build; GitGuardian scans the PR for +secrets. An up-to-date branch is required, so the checks cover the candidate +merge with the latest `main`. A successful merge +triggers a second CI run on `main` and Vercel's automatic Production deployment. +The merge gate validates application behavior against disposable infrastructure; +it does not test an already published Vercel deployment or replace a post-deploy +health and browser check. + For real browser journeys, follow the [full-stack setup](frontend-testing.md#full-stack-browser-journeys). Their API-owned cleanup command validates the test database name and limits deletion diff --git a/docs/guides/vercel-deployment.md b/docs/guides/vercel-deployment.md index e6b4cdc..f7f9b11 100644 --- a/docs/guides/vercel-deployment.md +++ b/docs/guides/vercel-deployment.md @@ -94,7 +94,11 @@ same-origin gateway path. Local development still uses ## Validation and rollback -1. Before merging a later change, run focused gateway and web tests, lint, and builds. Run +1. Open a pull request against `main` and wait for its required `quality`, + `integration`, Vercel Preview, and GitGuardian checks. The workflow uses a + disposable PostgreSQL database; + see the [CI guide](testing.md#pull-request-ci). For changes to the Vercel + container or service routing, additionally run `pnpm --filter api test:vercel-container` with Docker available to build the API image and check health, authorization, and secret exclusion. Use `vercel build --environment preview` to verify all three services. The