Skip to content

Commit b46d20c

Browse files
Copiloticlanton
andauthored
Deprecate minimumReleaseAge, add minimumReleaseAgeMinutes in pnpm-config.json
Agent-Logs-Url: https://github.com/microsoft/rushstack/sessions/2a108c92-3a48-45c3-84b3-ac209a297f21 Co-authored-by: iclanton <5010588+iclanton@users.noreply.github.com>
1 parent f022484 commit b46d20c

10 files changed

Lines changed: 65 additions & 20 deletions

File tree

common/config/rush/pnpm-config.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,18 @@
7474
*
7575
* For example, the following setting ensures that only packages released at least one day ago can be installed:
7676
*
77-
* "minimumReleaseAge": 1440
77+
* "minimumReleaseAgeMinutes": 1440
7878
*
7979
* (SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)
8080
*
8181
* PNPM documentation: https://pnpm.io/settings#minimumreleaseage
8282
*
8383
* The default value is 0 (disabled).
8484
*/
85-
// "minimumReleaseAge": 1440,
85+
// "minimumReleaseAgeMinutes": 1440,
8686

8787
/**
88-
* An array of package names or patterns to exclude from the minimumReleaseAge check.
88+
* An array of package names or patterns to exclude from the minimumReleaseAgeMinutes check.
8989
* This allows certain trusted packages to be installed immediately after publication.
9090
* Patterns are supported using glob syntax (e.g., "@myorg/*" to exclude all packages from an organization).
9191
*

common/reviews/api/rush-lib.api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,10 @@ export interface _IPnpmOptionsJson extends IPackageManagerOptionsJsonBase {
760760
globalPackageExtensions?: Record<string, IPnpmPackageExtension>;
761761
globalPatchedDependencies?: Record<string, string>;
762762
globalPeerDependencyRules?: IPnpmPeerDependencyRules;
763+
// @deprecated (undocumented)
763764
minimumReleaseAge?: number;
764765
minimumReleaseAgeExclude?: string[];
766+
minimumReleaseAgeMinutes?: number;
765767
pnpmLockfilePolicies?: IPnpmLockfilePolicies;
766768
pnpmStore?: PnpmStoreLocation;
767769
preventManualShrinkwrapChanges?: boolean;
@@ -1189,8 +1191,8 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration
11891191
static loadFromJsonFileOrThrow(jsonFilePath: string, commonTempFolder: string): PnpmOptionsConfiguration;
11901192
// @internal (undocumented)
11911193
static loadFromJsonObject(json: _IPnpmOptionsJson, commonTempFolder: string): PnpmOptionsConfiguration;
1192-
readonly minimumReleaseAge: number | undefined;
11931194
readonly minimumReleaseAgeExclude: string[] | undefined;
1195+
readonly minimumReleaseAgeMinutes: number | undefined;
11941196
readonly pnpmLockfilePolicies: IPnpmLockfilePolicies | undefined;
11951197
readonly pnpmStore: PnpmStoreLocation;
11961198
readonly pnpmStorePath: string;

libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,18 @@
7474
*
7575
* For example, the following setting ensures that only packages released at least one day ago can be installed:
7676
*
77-
* "minimumReleaseAge": 1440
77+
* "minimumReleaseAgeMinutes": 1440
7878
*
7979
* (SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)
8080
*
8181
* PNPM documentation: https://pnpm.io/settings#minimumreleaseage
8282
*
8383
* The default value is 0 (disabled).
8484
*/
85-
/*[LINE "HYPOTHETICAL"]*/ "minimumReleaseAge": 1440,
85+
/*[LINE "HYPOTHETICAL"]*/ "minimumReleaseAgeMinutes": 1440,
8686

8787
/**
88-
* An array of package names or patterns to exclude from the minimumReleaseAge check.
88+
* An array of package names or patterns to exclude from the minimumReleaseAgeMinutes check.
8989
* This allows certain trusted packages to be installed immediately after publication.
9090
* Patterns are supported using glob syntax (e.g., "@myorg/*" to exclude all packages from an organization).
9191
*

libraries/rush-lib/src/logic/installManager/InstallHelpers.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ interface ICommonPackageJson extends IPackageJson {
3535
ignoredOptionalDependencies?: typeof PnpmOptionsConfiguration.prototype.globalIgnoredOptionalDependencies;
3636
allowedDeprecatedVersions?: typeof PnpmOptionsConfiguration.prototype.globalAllowedDeprecatedVersions;
3737
patchedDependencies?: typeof PnpmOptionsConfiguration.prototype.globalPatchedDependencies;
38-
minimumReleaseAge?: typeof PnpmOptionsConfiguration.prototype.minimumReleaseAge;
38+
minimumReleaseAge?: typeof PnpmOptionsConfiguration.prototype.minimumReleaseAgeMinutes;
3939
minimumReleaseAgeExclude?: typeof PnpmOptionsConfiguration.prototype.minimumReleaseAgeExclude;
4040
trustPolicy?: typeof PnpmOptionsConfiguration.prototype.trustPolicy;
4141
trustPolicyExclude?: typeof PnpmOptionsConfiguration.prototype.trustPolicyExclude;
@@ -124,23 +124,24 @@ export class InstallHelpers {
124124
commonPackageJson.pnpm.patchedDependencies = pnpmOptions.globalPatchedDependencies;
125125
}
126126

127-
if (pnpmOptions.minimumReleaseAge !== undefined || pnpmOptions.minimumReleaseAgeExclude) {
127+
if (pnpmOptions.minimumReleaseAgeMinutes !== undefined || pnpmOptions.minimumReleaseAgeExclude) {
128128
if (
129129
rushConfiguration.rushConfigurationJson.pnpmVersion !== undefined &&
130130
semver.lt(rushConfiguration.rushConfigurationJson.pnpmVersion, '10.16.0')
131131
) {
132132
terminal.writeWarningLine(
133133
Colorize.yellow(
134134
`Your version of pnpm (${rushConfiguration.rushConfigurationJson.pnpmVersion}) ` +
135-
`doesn't support the "minimumReleaseAge" or "minimumReleaseAgeExclude" fields in ` +
135+
`doesn't support the "minimumReleaseAgeMinutes" or "minimumReleaseAgeExclude" fields in ` +
136136
`${rushConfiguration.commonRushConfigFolder}/${RushConstants.pnpmConfigFilename}. ` +
137137
'Remove these fields or upgrade to pnpm 10.16.0 or newer.'
138138
)
139139
);
140140
}
141141

142-
if (pnpmOptions.minimumReleaseAge !== undefined) {
143-
commonPackageJson.pnpm.minimumReleaseAge = pnpmOptions.minimumReleaseAge;
142+
if (pnpmOptions.minimumReleaseAgeMinutes !== undefined) {
143+
// NOTE: the pnpm setting is `minimumReleaseAge`, but the Rush setting is `minimumReleaseAgeMinutes`
144+
commonPackageJson.pnpm.minimumReleaseAge = pnpmOptions.minimumReleaseAgeMinutes;
144145
}
145146

146147
if (pnpmOptions.minimumReleaseAgeExclude) {

libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,11 @@ export interface IPnpmOptionsJson extends IPackageManagerOptionsJsonBase {
153153
*/
154154
autoInstallPeers?: boolean;
155155
/**
156-
* {@inheritDoc PnpmOptionsConfiguration.minimumReleaseAge}
156+
* {@inheritDoc PnpmOptionsConfiguration.minimumReleaseAgeMinutes}
157+
*/
158+
minimumReleaseAgeMinutes?: number;
159+
/**
160+
* @deprecated Use `minimumReleaseAgeMinutes` instead.
157161
*/
158162
minimumReleaseAge?: number;
159163
/**
@@ -308,11 +312,11 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration
308312
*
309313
* The default value is 0 (disabled).
310314
*/
311-
public readonly minimumReleaseAge: number | undefined;
315+
public readonly minimumReleaseAgeMinutes: number | undefined;
312316

313317
/**
314318
* List of package names or patterns that are excluded from the minimumReleaseAge check.
315-
* These packages will always install the newest version immediately, even if minimumReleaseAge is set.
319+
* These packages will always install the newest version immediately, even if minimumReleaseAgeMinutes is set.
316320
*
317321
* @remarks
318322
* (SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)
@@ -551,7 +555,15 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration
551555
this._globalPatchedDependencies = json.globalPatchedDependencies;
552556
this.resolutionMode = json.resolutionMode;
553557
this.autoInstallPeers = json.autoInstallPeers;
554-
this.minimumReleaseAge = json.minimumReleaseAge;
558+
559+
if (json.minimumReleaseAge !== undefined && json.minimumReleaseAgeMinutes !== undefined) {
560+
throw new Error(
561+
'The "minimumReleaseAge" setting is deprecated. Use "minimumReleaseAgeMinutes" instead.' +
562+
' Both settings cannot be specified together in pnpm-config.json.'
563+
);
564+
}
565+
this.minimumReleaseAgeMinutes = json.minimumReleaseAgeMinutes ?? json.minimumReleaseAge;
566+
555567
this.minimumReleaseAgeExclude = json.minimumReleaseAgeExclude;
556568
this.trustPolicy = json.trustPolicy;
557569
this.trustPolicyExclude = json.trustPolicyExclude;

libraries/rush-lib/src/logic/pnpm/test/PnpmOptionsConfiguration.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,37 @@ describe(PnpmOptionsConfiguration.name, () => {
8787
]);
8888
});
8989

90-
it('loads minimumReleaseAge', () => {
90+
it('loads minimumReleaseAgeMinutes', () => {
9191
const pnpmConfiguration: PnpmOptionsConfiguration = PnpmOptionsConfiguration.loadFromJsonFileOrThrow(
9292
`${__dirname}/jsonFiles/pnpm-config-minimumReleaseAge.json`,
9393
fakeCommonTempFolder
9494
);
9595

96-
expect(pnpmConfiguration.minimumReleaseAge).toEqual(1440);
96+
expect(pnpmConfiguration.minimumReleaseAgeMinutes).toEqual(1440);
9797
expect(TestUtilities.stripAnnotations(pnpmConfiguration.minimumReleaseAgeExclude)).toEqual([
9898
'webpack',
9999
'@myorg/*'
100100
]);
101101
});
102102

103+
it('loads deprecated minimumReleaseAge as minimumReleaseAgeMinutes', () => {
104+
const pnpmConfiguration: PnpmOptionsConfiguration = PnpmOptionsConfiguration.loadFromJsonFileOrThrow(
105+
`${__dirname}/jsonFiles/pnpm-config-minimumReleaseAge-deprecated.json`,
106+
fakeCommonTempFolder
107+
);
108+
109+
expect(pnpmConfiguration.minimumReleaseAgeMinutes).toEqual(720);
110+
});
111+
112+
it('throws if both minimumReleaseAge and minimumReleaseAgeMinutes are specified', () => {
113+
expect(() =>
114+
PnpmOptionsConfiguration.loadFromJsonFileOrThrow(
115+
`${__dirname}/jsonFiles/pnpm-config-minimumReleaseAge-both.json`,
116+
fakeCommonTempFolder
117+
)
118+
).toThrow(/Both settings cannot be specified together/);
119+
});
120+
103121
it('loads trustPolicy', () => {
104122
const pnpmConfiguration: PnpmOptionsConfiguration = PnpmOptionsConfiguration.loadFromJsonFileOrThrow(
105123
`${__dirname}/jsonFiles/pnpm-config-trustPolicy.json`,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"minimumReleaseAge": 720,
3+
"minimumReleaseAgeMinutes": 1440
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"minimumReleaseAge": 720
3+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"minimumReleaseAge": 1440,
2+
"minimumReleaseAgeMinutes": 1440,
33
"minimumReleaseAgeExclude": ["webpack", "@myorg/*"]
44
}

libraries/rush-lib/src/schemas/pnpm-config.schema.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,16 @@
200200
"type": "boolean"
201201
},
202202

203-
"minimumReleaseAge": {
203+
"minimumReleaseAgeMinutes": {
204204
"description": "The minimum number of minutes that must pass after a version is published before pnpm will install it. This setting helps reduce the risk of installing compromised packages, as malicious releases are typically discovered and removed within a short time frame.\n\n(SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/settings#minimumreleaseage\n\nThe default value is 0 (disabled).",
205205
"type": "number"
206206
},
207207

208+
"minimumReleaseAge": {
209+
"description": "DEPRECATED - Use \"minimumReleaseAgeMinutes\" instead. Cannot be combined with \"minimumReleaseAgeMinutes\".\n\nThe minimum number of minutes that must pass after a version is published before pnpm will install it. This setting helps reduce the risk of installing compromised packages, as malicious releases are typically discovered and removed within a short time frame.\n\n(SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/settings#minimumreleaseage\n\nThe default value is 0 (disabled).",
210+
"type": "number"
211+
},
212+
208213
"minimumReleaseAgeExclude": {
209214
"description": "List of package names or patterns that are excluded from the minimumReleaseAge check. These packages will always install the newest version immediately, even if minimumReleaseAge is set. Supports glob patterns (e.g., \"@myorg/*\").\n\n(SUPPORTED ONLY IN PNPM 10.16.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/settings#minimumreleaseageexclude\n\nExample: [\"webpack\", \"react\", \"@myorg/*\"]",
210215
"type": "array",

0 commit comments

Comments
 (0)