Skip to content

feat(ui-react): capture the full [data-theme] × OS theme matrix in vi… #30

feat(ui-react): capture the full [data-theme] × OS theme matrix in vi…

feat(ui-react): capture the full [data-theme] × OS theme matrix in vi… #30

Workflow file for this run

name: Test - CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pull-requests: read
jobs:
ci:
runs-on: ubuntu-latest
env:
WORKSPACES: >-
@constructor-lab/ui-kit-demo
@constructor-lab/ui-kit-demos
@constructor-lab/uikit-docs
@constructor-lab/tokens
@constructor-lab/icons-react
@constructor-lab/icons-svg
@constructor-lab/ui-react
@constructor-lab/ui-spec
@constructor-lab/figma-icons-fetcher
@constructor-lab/figma-token-exporter
@constructor-lab/style-dictionary
@constructor-lab/token-emit
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Detect published-workspace changes
if: "github.event_name == 'pull_request' && github.event.pull_request.title != 'chore(release): version packages'"
id: changeset_filter
uses: dorny/paths-filter@v4
with:
list-files: shell
filters: |
published:
- 'packages/ui-react/**'
- 'packages/icons-react/**'
- 'packages/tokens/**'
changeset:
- '.changeset/*.md'
- name: Enforce changeset for published-surface PRs
if: "github.event_name == 'pull_request' && github.event.pull_request.title != 'chore(release): version packages'"
env:
PUBLISHED_FILES: ${{ steps.changeset_filter.outputs.published_files }}
HAS_CHANGESET: ${{ steps.changeset_filter.outputs.changeset }}
run: |
set -euo pipefail
if [ -z "${PUBLISHED_FILES:-}" ]; then
echo "No published-workspace changes detected."
exit 0
fi
requires_changeset=false
while IFS= read -r file; do
[ -z "$file" ] && continue
case "$file" in
# docs / metadata
*/README.md|*/CHANGELOG.md|*/CONTRIBUTING.md|*/AGENTS.md|*/context/*)
;;
# test-only/story-only changes
*/__tests__/*|*.test.*|*.spec.*|*.stories.*)
;;
*)
requires_changeset=true
echo "Published-surface change detected: $file"
;;
esac
done <<< "$PUBLISHED_FILES"
if [ "$requires_changeset" = true ] && [ "${HAS_CHANGESET}" != "true" ]; then
echo "A changeset is required for published-surface changes."
echo "Run 'pnpm changeset' and commit the generated .changeset/*.md file."
exit 1
fi
if [ "$requires_changeset" = true ]; then
echo "Changeset check passed."
else
echo "Only non-release-impacting published-workspace files changed."
fi
- name: Setup PNPM
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: 'pnpm'
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache node modules
id: cache-pnpm
uses: actions/cache@v6
env:
cache-name: cache-node-modules
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
${{ runner.os }}-
# --frozen-lockfile: refuse the install if pnpm-lock.yaml is out of
# sync with package.json. This is what guarantees CI sees the exact
# tree a contributor saw locally.
- name: Install dependencies
run: pnpm install --frozen-lockfile
# Apps import the libraries by package name, so their dist (incl. types)
# must exist before `pnpm -r typecheck`. Building ui-react's graph covers
# @constructor-lab/tokens (generated CSS), icons-react, and the design-data packages.
- name: Build library dependencies
run: pnpm --filter "@constructor-lab/ui-react..." run build
- name: Lint (per workspace)
run: |
set -euo pipefail
for workspace in $WORKSPACES; do
pnpm --filter "$workspace" lint
done
- name: Format check
run: pnpm format:check
# Generate the fumadocs .source files needed by apps/docs typecheck.
- name: Generate fumadocs source
run: pnpm --filter @constructor-lab/uikit-docs exec fumadocs-mdx
- name: Typecheck (per workspace)
run: |
set -euo pipefail
for workspace in $WORKSPACES; do
pnpm --filter "$workspace" typecheck
done
# Build runs last so the topological build order (ui → demo / docs)
# is exercised against the same lockfile we just installed from.
- name: Build
run: pnpm -r build
# @constructor-lab/tokens ships generated, committed artifacts (css/scss/js/dtcg).
# Fail the build if a token change wasn't re-generated + committed (the
# build above is idempotent).
- name: Verify generated tokens are committed
run: git diff --exit-code -- packages/tokens/css packages/tokens/scss packages/tokens/js packages/tokens/dtcg
- name: Test (per workspace)
run: |
set -euo pipefail
for workspace in $WORKSPACES; do
pnpm --filter "$workspace" test
done
# `test` no longer runs ui-react's vitest `typecheck` block — it made every
# `vitest run` also run `tsc` per test file, at 5–10× the cost, and a check
# too slow to run is a check that cannot fail. Moving it costs no coverage:
# the type-test files are inside the tsconfig `include`, so the per-workspace
# `typecheck` step above already reports every `expectTypeOf` failure as an
# ordinary type error (measured — a false assertion surfaces as `TS2344`).
# This step adds what `tsc` cannot: per-file and per-test-name attribution.
#
# ui-react only, because it is the only workspace with the block, and
# `pnpm --filter` fails outright on a package with no such script.
# `src/__tests__/typecheck-gate.test.ts` asserts the coupling that keeps the
# redundancy true.
- name: Type tests (ui-react)
run: pnpm --filter @constructor-lab/ui-react test:types
# `*.browser.test.tsx` — suites that assert real layout (resolved column
# widths, truncation at a given container width, pinned-column geometry,
# pointer drags with real capture). `vitest.config.ts` excludes them from
# `pnpm test` on purpose, so without this step they run nowhere: the
# ui-blocks DataGrid sync added 948 lines of them that no runner had ever
# executed. See `packages/ui-react/vitest.browser.config.ts`.
#
# ui-react only, for the same reason as the type tests: it is the only
# workspace with the script, and `pnpm --filter` fails outright on a package
# that has none.
- name: Install Chromium for browser tests
run: pnpm --filter @constructor-lab/ui-react exec playwright install --with-deps chromium
- name: Browser tests (ui-react)
run: pnpm --filter @constructor-lab/ui-react test:browser