Skip to content

fix: npm-resolution fixture self-conflicts on every Angular patch release - #1897

Merged
lskramarov merged 1 commit into
mainfrom
fix/npm-resolution-angular-pin
Aug 14, 2026
Merged

fix: npm-resolution fixture self-conflicts on every Angular patch release#1897
lskramarov merged 1 commit into
mainfrom
fix/npm-resolution-angular-pin

Conversation

@lskramarov

Copy link
Copy Markdown
Contributor

Problem

check-npm-resolution is failing on every open pull request. It gates build.yml (on every PR) and publish.yml (on release), so releases are blocked too.

The angular-20-app and angular-20-app-ng-add-icons fixtures contradict themselves. angularAppWithPeers() inherits @angular/core and its siblings at ^20.3.0 from ngNewApp(), but declares the two extra peers at this repository's exact pins:

'@angular/animations': angularVersion,   // "20.3.27"
'@angular/cdk': cdkVersion               // "20.2.14"

Every @angular/animations release peers on @angular/core exactly. So when Angular published 20.3.28 on 2026-08-13, the inherited packages floated to 20.3.28 while @angular/animations@20.3.27 held @angular/core at 20.3.27:

npm error Found: @angular/core@20.3.27
npm error   peer @angular/core@"20.3.27" from @angular/animations@20.3.27
npm error Could not resolve dependency:
npm error   peer @angular/core@"20.3.28" from @angular/common@20.3.28

No @koobiq/* package takes part in that conflict — the fixture app fails to resolve before koobiq's peer ranges are ever evaluated, so the fixture currently exercises nothing. This recurs on every Angular patch release, until the repository bumps its own Angular pin.

An earlier failure the same day had a second cause, now self-healed: Angular published 20.3.28 in a staggered sequence (@angular/forms at 17:09:24 UTC, @angular/common only at 17:33:14), so for ~24 minutes ^20.3.0 resolved forms to 20.3.28 and common to 20.3.27, which forms@20.3.28 rejects. Nothing here can prevent a half-published upstream release; that window closed on its own.

Fix

Declare both extra peers in the same range shape as the rest of the fixture — the way ngAddInstalls (@angular/animations@${angularRange}) and documentedInstalls (ngNewRange(cdkVersion)) already do. That is also the shape a real consumer has: an app that ran ng new and then ng add carries ^20.3.0, not the monorepo's pin.

@angular/cdk is not part of today's conflict — cdk@20.2.14 peers on the wide ^20.0.0 || ^21.0.0 — but pinning it exactly is the same latent trap, so it gets the same treatment.

Deliberately not bumping the root Angular pin to 20.3.28: that goes green today and breaks again on 20.3.29, on every open PR. The file already argues against exactly this treadmill for @koobiq/icons.

Verification

Run locally against the live registry, with dist/ built:

Before (this branch's parent) — reproduces CI exactly:

  ✅ ng-new-app-ng-add
  ✅ ng-new-app-documented-install
  ❌ angular-20-app
  ❌ angular-20-app-ng-add-icons
npm failed to install the built packages in: angular-20-app, angular-20-app-ng-add-icons.

After:

  ✅ ng-new-app-ng-add — `ng add @koobiq/components` into a fresh `ng new` application
  ✅ ng-new-app-documented-install — the manual install from docs/guides/installation.en.md
  ✅ angular-20-app — an application already depending on @angular/animations and @angular/cdk
  ✅ angular-20-app-ng-add-icons — an existing application with the @koobiq/icons range `ng add` installs

✅ npm resolves the built packages in every fixture.

Since actions/checkout builds the merge ref on pull_request, every open PR picks this up on a plain re-run of the failed build job — no rebase needed.

…ease

`angularAppWithPeers` inherited `@angular/core` and its siblings at `^20.3.0` from `ngNewApp()` but
declared the two extra peers at this repository's exact pins. Every `@angular/animations` release
peers on `@angular/core` exactly, so once Angular published 20.3.28 the inherited packages floated
to it while `@angular/animations@20.3.27` held `@angular/core` back — and npm failed on a conflict
no `@koobiq/*` package takes part in, which is the only thing this fixture exists to exercise.

The fixture now declares both peers in the same range shape as the rest of it, the way
`ngAddInstalls` and `documentedInstalls` already do. `check-npm-resolution` gates build.yml on every
pull request and publish.yml on release, so this was failing every open pull request until the
repository bumped its own Angular pin — and would break again on the next patch.
Copilot AI lite review requested due to automatic review settings August 13, 2026 19:36
@github-actions github-actions Bot added the bug Something isn't working label Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the check-npm-resolution fixture apps so they don’t self-conflict on every upstream Angular patch release, ensuring the npm-resolution gate is stable for both PR validation and releases.

Changes:

  • Updates the angularAppWithPeers() fixture to use the same “ng new”-style range shapes (e.g. ^x.y.0) for @angular/animations and @angular/cdk instead of pinning exact repo versions.
  • Expands the inline documentation to explain why mixing floated Angular ranges with exact pins causes immediate peer conflicts on Angular patch releases.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 30e209c):

https://koobiq-next--prs-1897-hw6wq0q0.web.app

(expires Sun, 16 Aug 2026 19:40:21 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@lskramarov
lskramarov merged commit 651b06b into main Aug 14, 2026
16 checks passed
@lskramarov
lskramarov deleted the fix/npm-resolution-angular-pin branch August 14, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants