Skip to content

feat(scripts): compile documentation snippets against the built types (#5138) #1

feat(scripts): compile documentation snippets against the built types (#5138)

feat(scripts): compile documentation snippets against the built types (#5138) #1

name: Doc Snippet Types
# Compiles every fenced `ts` / `tsx` snippet in the documents this gate covers,
# `--strict`, against the packages' BUILT `dist/*.d.ts`. The gate itself, the
# fragment rule, the three self-controls and the coverage ledger are documented
# at length in `scripts/check-doc-snippet-types.mjs`.
#
# ── Why this is its own workflow ────────────────────────────────────────────
#
# Same reason `doc-component-types.yml`, `docs-links.yml` and `control-bytes.yml`
# are theirs, and it is worth restating because it is the whole point: the change
# that breaks a documentation snippet is a DOCS-ONLY change, and that is exactly
# the shape `ci.yml`'s expensive jobs short-circuit (their `git diff` excludes
# `content/**` and `'**/*.md'`). A snippet gate wired in there would be blind to
# every pull request most likely to introduce a defect. Hence: no `paths` and no
# `paths-ignore` here, deliberately, and
# `scripts/__tests__/check-doc-snippet-types.test.ts` fails if either is added,
# or if a second workflow starts running the same script.
#
# ── Why it builds, and why that is NOT the build a ruling rejected ──────────
#
# Unlike its install-free sibling `doc-component-types.yml`, this gate cannot
# read the checkout alone: its whole criterion is the PUBLISHED type surface, so
# the packages the covered snippets import have to exist as `dist/*.d.ts` first.
# Resolving against `src/` instead would be a different and weaker check — the
# root `tsconfig.json` maps the workspace to source, so that mistake is one
# inherited config away, and the script's RESOLUTION control fails the run rather
# than letting it pass quietly.
#
# The 2026-08-16 ruling on objectui#4846 (recorded in
# `.github/workflows/published-dist-gate.yml`) rejected a per-PR FULL-REPO build
# — all 39 published packages, on every pull request. This is not that, and the
# difference is mechanical rather than a matter of opinion: the build is filtered
# to the packages the COVERED documents actually import, and that list is emitted
# by the gate itself (`--build-filter`) rather than hand-maintained here. Today
# it is a minority of the workspace. It grows only when coverage grows, and when
# it does, the growth is visible in this job's log rather than hidden in a
# workflow edit.
#
# ⛔ Do not replace the filtered build with `pnpm build`. The filter is the reason
# this job is allowed to run on every pull request at all.
on:
pull_request:
branches: [main, develop]
push:
branches: [main, develop]
# Merge queue (objectui#3523 — `ci.yml`'s trigger block carries the full note).
# A required check that does not report on a queue build stalls the queue until
# the ruleset times it out, so an unfiltered gate subscribes from the start.
merge_group:
types: [checks_requested]
workflow_dispatch:
concurrency:
group: doc-snippet-types-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
doc-snippet-types:
name: Doc Snippet Type Check
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Enable Corepack
run: corepack enable
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22.x'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
# The filter comes from the gate, so it can never drift from what the
# covered documents import. A package the snippets need but nothing built
# is reported by the gate as `unbuilt-package` — its own failure reason,
# never as a page full of broken imports.
- name: Derive the packages the covered snippets import
id: filter
run: echo "args=$(node scripts/check-doc-snippet-types.mjs --build-filter)" >> "$GITHUB_OUTPUT"
- name: Build those packages
run: pnpm exec turbo run build ${{ steps.filter.outputs.args }} --concurrency=2
- name: Compile documentation snippets against the built types
run: node scripts/check-doc-snippet-types.mjs