From 5b725994add94f096a239fef0fff36dfca3e127e Mon Sep 17 00:00:00 2001 From: Simon Axelsson Date: Wed, 22 Jul 2026 18:54:35 +0200 Subject: [PATCH] ci: add typecheck/lint/test quality gate (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ci: add typecheck/lint/test quality gate (was deploying unguarded) * ci: make quality gate functional — typecheck + test, drop unwired lint The lint step ran `pnpm run lint` = `eslint .`, but eslint is not a dependency of this repo (absent from pnpm-lock.yaml), so the step failed on command-not-found and, since a failed step aborts the job, prevented typecheck from ever running — a red, useless gate on every PR. Replace it with the vitest suite (`pnpm run test`, 88 passing) so the gate matches the PR's stated 'typecheck + test' intent and is green on a clean tree. Typecheck now uses `pnpm run typecheck` (carries the `-p tsconfig.json` the script defines). Wiring eslint is left as a separate decision. Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) 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..582c510 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +# Quality gate: typecheck + test on every PR and non-main push. +# 0pt previously relied solely on the Vercel build with no pre-merge gate. +# Build is intentionally NOT run here because it needs runtime secrets +# (POSTGRES_URL, ENGINE_URL, STRIPE, RESEND) — Vercel owns the build; CI owns +# the static gate. +# +# Lint is intentionally NOT a step: this repo has no eslint dependency or +# config wired (package.json's "lint" script is `eslint .`, but eslint is not +# in the lockfile), so a lint step fails unconditionally on `command not found` +# and — because a failed step aborts the job — would prevent typecheck/test +# from ever running. Wiring eslint is a separate decision; until then the gate +# is typecheck + the existing vitest suite, both of which pass on a clean tree. +# Python engine (services/api) is gated separately if/when a Python workflow +# is added. +on: + pull_request: + push: + branches-ignore: [main] + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + gate: + name: Typecheck + test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - name: Enable corepack (pnpm) + run: corepack enable + - name: Install (frozen lockfile) + run: pnpm install --frozen-lockfile + - name: Typecheck (tsc --noEmit) + run: pnpm run typecheck + - name: Test (vitest) + run: pnpm run test