chore: move the Angular train to 21.2.23 and run on Node 24 - #218
Open
adamjohnwright wants to merge 12 commits into
Open
adamjohnwright wants to merge 12 commits into
adamjohnwright wants to merge 12 commits into
Conversation
Replaces dependabot's #161, which cannot be merged as it stands. That PR moves eleven Angular packages from 21.2.20 to 21.2.22 and leaves `@angular/platform-browser-dynamic` and `@angular/compiler-cli` behind. Angular's packages peer-depend on one another at **exact** versions, so the result does not resolve: Conflicting peer dependency: @angular/core@21.2.23 peer @angular/core@"21.2.23" from @angular/platform-browser-dynamic@21.2.23 Its checks pass only because CI installs with `--legacy-peer-deps`, which accepts an inconsistent tree. #215 removes that flag; after it, #161 fails honestly. So the train moves together: core, common, compiler, compiler-cli, forms, router, elements, localize, platform-browser and platform-browser-dynamic to 21.2.23, and the CLI train -- cli, ssr, build-angular -- to its own 21.2.23. The lockfile is regenerated from scratch rather than hand-resolved, because a partially-merged lock is what produced the conflict in the first place. It resolves **strictly**: `npm ci --dry-run` with no `--legacy-peer-deps`. Verified: 242 unit tests, types, lint 652, dead code 145, format, a full build, and 49 e2e cases against the resulting build -- interactors, the threshold, the custom-resource dialog, the homepage, content pages and the back button. The diagram is what an Angular bump would break, so it is what was exercised. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two fixes, and the second explains why this branch failed CI all day. **The Angular train moves together.** Dependabot's #161 bumps eleven packages and leaves `platform-browser-dynamic` and `compiler-cli` behind; Angular's packages peer-depend at exact versions, so that set cannot resolve. Core, common, compiler, compiler-cli, forms, router, elements, localize, platform-browser and platform-browser-dynamic all go to 21.2.23, and the CLI train with them. **The lockfile is regenerated under Node 22, which is what CI runs.** I generated the first one on Node 24 / npm 11, and npm 10 rejected it: EBADPLATFORM lightningcss-android-arm64 wanted os "android", got linux npm 11 records optional platform packages in a shape npm 10 tries to install. Regenerated with `node:22` in docker, the android entries are `optional: true, os: ["android"]` and `npm ci` adds 2212 packages cleanly. `engines` is tightened from `>=22` to `22.x` so this cannot recur silently. `.nvmrc` has said 22 all along and CI has always used it; only `engines` was permissive enough to let a lockfile be written by the wrong npm. CONTRIBUTING records both failure signatures, because each looks like a dependency problem rather than a version problem. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`engines` pinned `node: 22.x` and `npm: >=10 <11`, which is why the lockfile and the local machine could not agree: npm 11 records optional platform packages that npm 10 leaves out, so a lockfile generated by either is a desync to the other. The pin was the cause, not the cure. Angular 21 declares `^20.19.0 || ^22.12.0 || >=24.0.0` and 24 is Latest LTS, so this moves engines, `.nvmrc`, all four workflows, both Dockerfiles and the local setup document to 24 together. **No dependency changes versions.** Compared across every path in the tree: 91 packages added, all of them optional platform binaries (@napi-rs/nice, @oxc-parser bindings, @emnapi); 0 removed; 0 that lost a version. Angular stays on 21.2.x throughout. `--legacy-peer-deps` stays, and now with a measured reason. Dropping it needs @analogjs/vitest-angular to move off 2.3.1, and letting npm re-resolve to get there dragged in 207 top-level version changes including React 18 -> 19 and @Angular-devkit 21 -> 22. That is a separate decision, not a side effect of changing Node. Recorded on #215. `scripts/preflight.sh` was running a bare `npm ci --dry-run` while every workflow installs with `--legacy-peer-deps`, so the gate whose whole job is to reproduce CI was running a different command and failing on a peer conflict the real build never sees. It now runs CI's command, and says which Node to run on. Verified: preflight green end to end on Node 24 / npm 11 — lockfile in sync, format, types, lint, dead code, unit tests, and the download smoke. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two changes that turned out to be the same problem.
The Angular train moves together. Dependabot's #161 bumps eleven packages
and leaves
platform-browser-dynamicandcompiler-clibehind; Angular'spackages peer-depend at exact versions, so that set cannot resolve. This moves
the whole train to 21.2.23.
Node 24.
enginespinnednode: 22.xandnpm: >=10 <11, which is whythe lockfile and a current machine could never agree — npm 11 records optional
platform packages npm 10 omits, so a lockfile from either is a desync to the
other. Angular 21 declares
>=24.0.0and 24 is Latest LTS, so engines,.nvmrc, all four workflows, both Dockerfiles and the local setup doc move to24 together.
No dependency changes version
Compared across every path in the tree, not just the top level:
The 91 are all optional platform binaries —
@napi-rs/nice-*,@oxc-parserbindings,
@emnapi. Angular stays on 21.2.x throughout.--legacy-peer-depsstays, and now we know whyDropping it requires
@analogjs/vitest-angularto move off 2.3.1, because thatis what pins vitest 3 against
@angular/build's vitest 4. Letting npmre-resolve to get there produced 207 top-level version changes, including
React 18 → 19,
@angular-devkit21 → 22, vite 6 → 7 and a batch ofdowngrades. That is a separate decision, not a side effect of changing Node.
Noted on #215.
A gate that wasn't reproducing CI
scripts/preflight.shran a barenpm ci --dry-runwhile every workflowinstalls with
--legacy-peer-deps. The gate whose entire purpose is to catchCI failures before the email was running a different command, and failing on a
peer conflict the real build never sees — the kind of false alarm that teaches
you to push with
--no-verify. It now runs CI's command and says which Node torun on.
Verified
Preflight green end to end on Node 24 / npm 11: lockfile in sync, format,
types, lint, dead code, unit tests, download smoke.
Closes #161.
🤖 Generated with Claude Code