Skip to content

[full-ci] chore(web): adopt Nx as task orchestrator for web/ - #13011

Open
mzner wants to merge 1 commit into
fix/web-pkg-dependency-cyclefrom
chore/introduce-nx-v2
Open

mzner wants to merge 1 commit into
fix/web-pkg-dependency-cyclefrom
chore/introduce-nx-v2

Conversation

@mzner

@mzner mzner commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds Nx as the task runner for web/, so CI only lints/tests the packages a PR actually touches
instead of the whole workspace every time.

  • devDependency on nx + nx.json, no behavior change on its own
  • @nx/vitest gives every package with a vitest.config.ts a real per-project test target
  • @nx/eslint gives every package a per-project lint target
  • @nx/vite gives the packages with their own vite.config.ts (design-system, web-client,
    web-pkg, web-test-helpers) a per-project typecheck target. Everything else still relies on
    the whole-repo pnpm check:types
  • CI now runs nx affected -t lint/test on normal PRs, and the full whole-repo run on
    master/stable/[full-ci] — same as before

Small side fixes:

  • removed design-system's lint script alias — it was broken (tried to exec a script name as a
    binary) and never actually ran; needed the name free for Nx's own lint target anyway
  • made the design system's webfontloader import fire-and-forget, so it doesn't throw an
    unhandled rejection when tests tear down mid-flight
  • same typescript pin as fix(web): break web-pkg/design-system/web-test-helpers dependency cycle #13010 — this branch touches package.json too, so it hits the same
    peer-resolution fork independently

Related Issue

  • Fixes OCISDEV-1440

Motivation and Context

Every PR to web/ runs the same lint/test/build regardless of what changed. Nx knows the
dependency graph, so it can scope CI to just what's affected.

Targets #13010, not master — Nx refuses to build a task graph across a circular dependency,
and web-pkg/design-system/web-test-helpers had exactly that cycle. Once #13010 merges,
GitHub will retarget this PR to master automatically.

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation ticket raised: n/a — build tooling only, nothing user-facing

@mzner
mzner requested a review from a team as a code owner September 26, 2026 10:51
@update-docs

update-docs Bot commented Sep 26, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@kw-security

kw-security commented Sep 26, 2026 •

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Introduces Nx on top of the existing pnpm workspace, so lint/typecheck/
test can be scoped to only the projects affected by a change instead of
running against the whole monorepo on every PR.

- Phase 0: add nx (^23.2.1) as a workspace devDependency, nx.json with a
  targetDefaults entry for test:unit (cache: true), ignore .nx/cache and
  .nx/workspace-data. No behavior change to any existing script.
- Phase 1: register @nx/vitest's inference plugin so every package with
  a vitest.config.ts gets a real, cached "test" target read directly
  from its own config, not just the packages that happened to already
  declare a "test:unit" npm script. Excludes vite.config.common.ts,
  the root vite.config.ts and vite.cern.config.ts from the plugin's
  default glob - none of them are test configs, and loading them as one
  aborts the whole project graph. defaultBase: "master" (bare `nx
  affected` defaults to a branch named "main"). testMode: "run" so `nx
  run <project>:test` doesn't default to vitest's watch mode locally.
- Phase 2a: register @nx/eslint/plugin for a per-project "lint" target
  on every project (root `lint` script untouched).
- Phase 2b: register @nx/vite/plugin's typecheckTargetName for a
  per-project "typecheck" target on projects with their own real
  vite.config.ts (design-system, web-client, web-pkg, web-test-helpers).
  The ~20 web-app-*/web-runtime projects only have a vitest.config.ts
  and aren't covered; root `pnpm run check:types` (whole-repo vue-tsc)
  stays the one check that covers everything.
- Phase 3 (CI): adds a `full-run` output to detect-web-changes - true for
  push to master/stable-* or a `[full-ci]` PR title (unchanged behavior),
  false for a normal PR, which instead runs `nx affected -t lint` / `nx
  affected -t test --base=<PR base sha>`. Added fetch-depth: 0 to
  web-build-test's checkout, needed for `nx affected --base=<sha>` to
  find that commit. Check types and the full-run unit-test path
  deliberately stay whole-repo (see inline comments for why).

Also:
- removes design-system's broken "lint": "lint:stylelint" alias (needed
  the "lint" name free for the new per-project target; it was never
  callable as written - "lint:stylelint" isn't a binary - and nothing
  called it).
- makes the design system's webfontloader import fire-and-forget so an
  in-flight rejection at test teardown doesn't surface as an unhandled
  rejection under vitest's per-project runs.
- pin `typescript` via `pnpm.overrides`. Adding nx's own devDependencies
  makes pnpm re-resolve the workspace's peer graph, and today's registry
  now has a typescript 6.x that some peer ranges accept - without the
  pin, half the vue-peer-dependent packages (pinia, vue-router,
  vue3-gettext, focus-trap-vue, ...) fork into a second, incompatible
  module instance. Same pin as the dependency-cycle fix, for an
  unrelated reason; needed independently here since this branch changes
  package.json on its own.

nx's `dependsOn: ["^target"]` errors outright on a circular task graph,
so this only works once the pre-existing web-pkg/design-system/
web-test-helpers dependency cycle is fixed - see
fix(web): break web-pkg/design-system/web-test-helpers dependency cycle,
which this PR targets rather than master.

Verified: nx run-many -t test / lint / typecheck succeed for all
projects; nx show projects --affected --files=... resolves correctly for
shared config changes; nx affected -t lint --base=<sha> matches pnpm
lint; root pnpm lint/check:types/check:format/test:unit/build all still
pass unchanged (380 files / 3128 tests).
@mzner
mzner added this pull request to stack #13012 September 26, 2026 11:02
@mzner
mzner force-pushed the chore/introduce-nx-v2 branch from 3a6a9d2 to 12725ae Compare September 26, 2026 11:09

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants