fix(@angular/cli): respect client-side release age settings during update resolution#33468
fix(@angular/cli): respect client-side release age settings during update resolution#33468clydin wants to merge 1 commit into
Conversation
dc88f1f to
b4ea3b0
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces support for a minimum release age gate configuration (such as minimum-release-age for pnpm, npmMinimalAgeGate for yarn, or environment variables) to filter out package versions that were published too recently. It updates the RegistryClient and PackageManager to retrieve and respect this configuration when resolving package versions, and adds corresponding tests and parsers. The review feedback suggests extracting the release age validation logic into a reusable helper function isReleaseAgeSatisfied to reduce code duplication across several functions and safely handle potential NaN values from Date.parse.
…date resolution Query the active package manager's release age gate configuration (like pnpm's `minimum-release-age` or yarn's `npmMinimalAgeGate`) and parse it into milliseconds. This config limit is passed to the `RegistryClient` in `resolveUserUpdatePlan` and is used to filter out version candidates that violate the release-age gate by checking the package's publish timestamps in the metadata `time` record. This guarantees that `ng update` resolves targeting versions that satisfy all active client-side release-age restrictions.
b4ea3b0 to
f4ad109
Compare
| }); | ||
|
|
||
| describe('getMinimumReleaseAge', () => { | ||
| it('should return 0 when the package manager descriptor does not support getReleaseAgeConfigCommand', async () => { |
There was a problem hiding this comment.
NPM supports minReleaseAge though it can be defined from multiple places.
https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e93104
| return 0; | ||
| } | ||
|
|
||
| // Parse Yarn duration format (e.g. "3d", "24h") or a raw millisecond/unitless value. |
There was a problem hiding this comment.
In yarn, the unit-less value is minutes not milliseconds.
| }); | ||
|
|
||
| describe('getMinimumReleaseAge', () => { | ||
| it('should return 0 when the package manager descriptor does not support getReleaseAgeConfigCommand', async () => { |
There was a problem hiding this comment.
NPM supports minReleaseAge it can be set in a number of ways.
https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e93104
| expect(manifest).toEqual({ name: 'foo', version: '1.0.0' }); | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
Bun also supports release age.
https://bun.com/docs/pm/cli/install#minimum-release-age
| } | ||
| } | ||
|
|
||
| const envValue = |
There was a problem hiding this comment.
I am confused by why this is needed. IE: the env variable and yarn parsing logic as fallback.
In NPM don't ENV variables override what is defined in the config?
| } | ||
|
|
||
| const envValue = | ||
| process.env.NPM_CONFIG_MIN_RELEASE_AGE ?? |
There was a problem hiding this comment.
These Env variables can also be defined in lower case
| } | ||
| } | ||
|
|
||
| function isReleaseAgeSatisfied( |
There was a problem hiding this comment.
Technically, this isn't 100% accurate behavior, since packages can also be explicitly excluded. Although handling this, would make this far more complex.
| } | ||
|
|
||
| async #resolveMinimumReleaseAge(): Promise<number> { | ||
| if (this.descriptor.getReleaseAgeConfigCommand && this.descriptor.outputParsers.getReleaseAge) { |
There was a problem hiding this comment.
Based on the package manager and versions this will return incorrect results.
Example, In pnpm 11 and yarn 6 this will return undefined, but by default this is 1440, before that it was 0
Query the active package manager's release age gate configuration (like pnpm's
minimum-release-ageor yarn'snpmMinimalAgeGate) and parse it into milliseconds.This config limit is passed to the
RegistryClientinresolveUserUpdatePlanand is used to filter out version candidates that violate the release-age gate by checking the package's publish timestamps in the metadatatimerecord. This guarantees thatng updateresolves targeting versions that satisfy all active client-side release-age restrictions.