Skip to content

docs(feature-map): keep the page's sources in the repo; npm run docs:feature-map #904

docs(feature-map): keep the page's sources in the repo; npm run docs:feature-map

docs(feature-map): keep the page's sources in the repo; npm run docs:feature-map #904

Workflow file for this run

name: Build Gate
# Correctness gates for every change, run before it can reach main.
#
# These same checks already existed in release-gate.yml, but that workflow only
# triggers on a `v*` tag push — so nothing ran on a pull request or on a push to
# main. Two green PRs whose merge result did not compile were merged that way,
# and the breakage was only found later, locally. This workflow closes that gap:
# the gates run on the merge result, not just at release time.
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
# A new push supersedes an in-flight run for the same ref.
concurrency:
group: build-gate-${{ github.ref }}
cancel-in-progress: true
jobs:
typecheck:
# A version-bump commit changes four package.json version fields and
# nothing else, so there is nothing here for it to check. It used to carry
# `[skip ci]` for this, but that marker also suppresses the *tag* push that
# rides on the same commit, which silently disabled every release — see
# version-bump.yml. Skipping by message keeps the saving without that cost.
# Guarded on event_name so pull_request runs are never skipped.
if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}"
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
# npm 10 (what Node 22 ships) cannot resolve this workspace graph
# without a lockfile — arborist dies in #loadPeerSet on vitest with
# "Cannot read properties of null (reading 'edgesOut')". npm 11 does
# it fine. Verified on a clean clone at Node 22.23.1.
- run: npm i -g npm@11
- run: npm ci --ignore-scripts
# apps/web's tsconfig covers the frontend, the backend, and — through the
# workspace path aliases — packages/sql. apps/e2e's covers the Playwright
# suite, where byTestId() turns a selector for a removed test ID into a
# compile error.
- run: npm run typecheck
unit-tests:
# A version-bump commit changes four package.json version fields and
# nothing else, so there is nothing here for it to check. It used to carry
# `[skip ci]` for this, but that marker also suppresses the *tag* push that
# rides on the same commit, which silently disabled every release — see
# version-bump.yml. Skipping by message keeps the saving without that cost.
# Guarded on event_name so pull_request runs are never skipped.
if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}"
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
# npm 10 (what Node 22 ships) cannot resolve this workspace graph
# without a lockfile — arborist dies in #loadPeerSet on vitest with
# "Cannot read properties of null (reading 'edgesOut')". npm 11 does
# it fine. Verified on a clean clone at Node 22.23.1.
- run: npm i -g npm@11
- run: npm ci --ignore-scripts
- run: npx vitest run
frontend-build:
# A version-bump commit changes four package.json version fields and
# nothing else, so there is nothing here for it to check. It used to carry
# `[skip ci]` for this, but that marker also suppresses the *tag* push that
# rides on the same commit, which silently disabled every release — see
# version-bump.yml. Skipping by message keeps the saving without that cost.
# Guarded on event_name so pull_request runs are never skipped.
if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}"
name: Frontend build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
# npm 10 (what Node 22 ships) cannot resolve this workspace graph
# without a lockfile — arborist dies in #loadPeerSet on vitest with
# "Cannot read properties of null (reading 'edgesOut')". npm 11 does
# it fine. Verified on a clean clone at Node 22.23.1.
- run: npm i -g npm@11
- run: npm ci --ignore-scripts
# Typecheck and tests both passed while `vite build` was broken for
# months: a dependency's `exports` map changed and only the bundler's
# resolver could see it. Nothing else in this workflow builds the
# frontend, which is the artifact users actually run.
- run: npm run build -w @foxschema/web
# What a first visit downloads (index.html and the files it names). Over
# budget means something heavy became a static import on the first page;
# the report lists the largest files. Was 398 KB gzip before on-demand
# loading (2026-10-05), 210 KB after #481, 140 KB after the second round.
- run: node scripts/bundle/first-load.mjs apps/web/dist --budget-gzip-kb=170
lint:
# A version-bump commit changes four package.json version fields and
# nothing else, so there is nothing here for it to check. It used to carry
# `[skip ci]` for this, but that marker also suppresses the *tag* push that
# rides on the same commit, which silently disabled every release — see
# version-bump.yml. Skipping by message keeps the saving without that cost.
# Guarded on event_name so pull_request runs are never skipped.
if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}"
name: ESLint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
# npm 10 (what Node 22 ships) cannot resolve this workspace graph
# without a lockfile — arborist dies in #loadPeerSet on vitest with
# "Cannot read properties of null (reading 'edgesOut')". npm 11 does
# it fine. Verified on a clean clone at Node 22.23.1.
- run: npm i -g npm@11
- run: npm ci --ignore-scripts
# Everything: security rules are errors, quality rules are warnings.
- run: npx eslint .
# Security rules only, zero tolerance. This is the gate that was defined
# in package.json but never run here, and could not have passed if it
# had been — it counted quality warnings too. It runs its own config now.
- run: npm run lint:security
# Production dependencies only, at `high`, and blocking. The threshold was
# `critical`, which meant the two HIGH advisories in the ibm_db -> adm-zip
# chain never failed anything and nobody was told; the `adm-zip: 0.6.1`
# override plus a committed lockfile clears them, so this is a real gate.
- run: npm run audit:security