Skip to content

build(deps): upgrade Nx 20 → 22, Angular 19 → 21, migrate to @nx/gradle#3

Open
jdwillmsen wants to merge 44 commits into
mainfrom
feat/nx-v22-upgrade
Open

build(deps): upgrade Nx 20 → 22, Angular 19 → 21, migrate to @nx/gradle#3
jdwillmsen wants to merge 44 commits into
mainfrom
feat/nx-v22-upgrade

Conversation

@jdwillmsen
Copy link
Copy Markdown
Member

Summary

  • Nx: 20.6.4 → 22.7.3 (sequential hops: 20→21→22 via nx migrate)
  • Angular: 19.2.x → 21.2.9 (Angular Material/CDK/CLI all bumped in step)
  • Spring Boot plugin: @nxrocks/nx-spring-boot@nx/gradle (nxrocks has no Nx 21+ release)
  • Gradle companion plugin: dev.nx.gradle.project-graph 0.1.8 → 0.1.20
  • Jest: 29 → 30; jest-preset-angular 14 → 16
  • Cypress: 13 → 15; @cypress/webpack-dev-server 3 → 5
  • TypeScript: 5.7 → 5.9
  • @nx-go/nx-go: 3 → 4 (breaking: now runs from project dir, not workspace root)

Non-obvious issues resolved

  • @nxrocks/nx-spring-boot has no Nx 21+ release → replaced with @nx/gradle before migrating
  • @nx/gradle migration has a chicken-and-egg problem: nxProjectGraph Gradle task needed to build project graph, but task only added by migration → temporarily removed plugin from nx.json during migrations, manually set dev.nx.gradle.project-graph to final target version post-migration
  • nx migrate doesn't update @angular/cdk and @angular/material in dependencies (only devDependencies) → manually fixed both times
  • @nx/gradle/plugin-v1 in Nx 22 uses legacy projectReport task; switched to plain @nx/gradle which uses nxProjectGraph from the companion plugin
  • @nx-go/nx-go v4 runs from project dir: {workspaceRoot} token not substituted in executor options; changed main to . and outputPath to relative path from project dir
  • Angular lib package.json files had Angular 19.x peer dep versions → updated to ^21.2.9
  • VersionService constructor injection → inject() function for @angular-eslint/prefer-inject rule

Test plan

  • nx show projects — all 24 projects detected
  • nx build container — Angular MF shell builds (82s)
  • nx build authui rolesui usersui — all 3 MF remotes build
  • nx build servicediscovery — Go app builds
  • nx run-many -t lint test — all 24 projects pass (50 tasks total)

🤖 Generated with Claude Code

jdwillmsen and others added 30 commits May 23, 2026 16:59
@nxrocks/nx-spring-boot has no released version supporting Nx 21+,
blocking the planned Nx v22 upgrade. @nx/gradle is first-party and
ships with each Nx version.

- Add project-report Gradle plugin to usersrole (required for task
  discovery by @nx/gradle)
- Add explicit build target to project.json (Gradle lifecycle tasks
  not inferred by plugin's projectReport scan)
- Scope @nx/gradle plugin to apps/springboot/**/* in nx.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restore @nx/gradle plugin in nx.json (was temporarily removed to
  break project-graph chicken-and-egg during migrations)
- Replace project-report Gradle plugin with dev.nx.gradle.project-graph
  v0.1.8 in usersrole build.gradle.kts (required by @nx/gradle v21)
- Fix @nx-go/nx-go v4 breaking change: outputPath now relative to
  project folder, use {workspaceRoot} token to preserve dist/ location
- Upgrade @nx-go/nx-go ^3 -> ^4 (Nx 21 support)
- Upgrade ngx-cookie-service 19 -> ^20 (Angular 20 peer dep)
- Remove migrations.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch @nx/gradle plugin from plugin-v1 to plain @nx/gradle in nx.json;
  plugin-v1 uses legacy projectReport task, but dev.nx.gradle.project-graph
  v0.1.20 provides nxProjectGraph which only the main plugin uses
- Bump dev.nx.gradle.project-graph from 0.1.8 to 0.1.20 manually since
  the 8 gradle version-bump migrations ran without the plugin in nx.json
  (chicken-and-egg workaround) and made no changes
@nx-go v4 runs from project dir instead of workspace root.
- main: "{projectRoot}/main.go" resolved to workspace-root-relative path,
  not findable from project dir; change to "." (build current package)
- outputPath: {workspaceRoot} token not substituted by @nx-go executor;
  use explicit relative path back to workspace root instead
- Update Angular peer/deps versions in shared lib package.json files from
  19.x to ^21.2.9 to satisfy @nx/dependency-checks rule
- Migrate VersionService constructor injection to inject() function to
  satisfy @angular-eslint/prefer-inject rule (Angular 21 best practice)
- Replace npm ci with pnpm install --frozen-lockfile; add pnpm/action-setup@v4
- nx@22.7.3 requires @swc/core ^1.15.8; bump from 1.15.5 to 1.15.8
- Replace npx with pnpm exec throughout workflow
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 24, 2026

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit f9676b5

Command Status Duration Result
nx affected -t build ✅ Succeeded 1s View ↗
nx affected -t lint test ✅ Succeeded 2s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-25 06:30:40 UTC

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 24, 2026

View your CI Pipeline Execution ↗ for commit 9fb2af7

Command Status Duration Result
nx-cloud record -- nx format:check ❌ Failed 2s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-24 00:33:55 UTC

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 24, 2026

View your CI Pipeline Execution ↗ for commit 9fb2af7

Command Status Duration Result
nx-cloud record -- nx format:check ❌ Failed 2s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-24 00:44:19 UTC

jdwillmsen and others added 12 commits May 23, 2026 19:42
nx migrate ran set-inject-document-domain twice (once per hop: 20→21
and 21→22), duplicating the block in all 9 cypress.config.ts files.

Closes duplicate introduced in feat/nx-v22-upgrade migration.
Prettier reformatted HTML templates (self-closing tag alignment) and TS
imports (trailing commas, indentation). Also updates pnpm-lock.yaml to
new lockfile format and inlines short arrays in nx.json.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
memfs@4.57.x introduced @jsonjoy.com/fs-snapshot@4.57.x as a dep.
That package ships src/index.ts which imports ./sync, but src/sync.ts
does not exist. Cypress 15.8.0's bundled tsx loader intercepts require
and prefers TS source over compiled lib/, triggering the missing module
error on CI.

Pinning memfs to 4.56.11 (last version before fs-snapshot was added)
via pnpm.overrides eliminates the broken transitive dep entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pnpm strict mode prevents @babel/runtime from being resolved when
babel-loader transforms rxjs ESM files from within rxjs's virtual
store directory. Hoisting makes it findable via root node_modules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…component tests

Angular Material 21 MDC renders mat-error content only when the form
control error state is active (touched+invalid). focus().blur() no
longer reliably triggers Angular's CD cycle to mark controls as
touched in AM21. click({force:true}) fires events through Angular's
zone properly; force:true bypasses the mat-label overlay check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lution

Replaces specific public-hoist-pattern entries with shamefully-hoist=true.
pnpm strict mode blocked bluebird (Cypress xvfb.js) and other undeclared
internal deps from resolving in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove all Cypress component tests (30+ .cy.ts) from 5 libs
- Remove per-MF e2e projects (authui-e2e, rolesui-e2e, usersui-e2e, container-e2e)
- Create platform-e2e with Playwright covering full user flows:
  shell, auth (sign-in/sign-up), users (profile/account), roles (create/edit)
- Service discovery API mocked via Playwright page.route() so MF routes load
  without a real backend in CI
- Add Jest form validator unit tests to 5 key form components replacing
  the coverage previously provided by Cypress component tests
- Remove cypress/@nx/cypress/@cypress/webpack-dev-server deps
- Update CI: remove component-test target, build before e2e, install
  Playwright browsers; update nx.json to replace cypress plugin and inputs

Cypress 15 bundles its own @cypress/webpack-dev-server that cannot resolve
@angular-devkit/build-angular from the project node_modules — not fixable
with any hoisting strategy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root config has ignorePatterns: ["**/*"] — project-level config with
ignorePatterns: ["!**/*"] is required to opt the project back in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- '@nx/playwright/preset/playwright' is not exported — use '@nx/playwright/preset'
- Add skipInstall: true to executor options so CI install step controls browsers
  instead of the executor re-downloading Firefox + WebKit unnecessarily

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant