-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: implement npmMinimalAgeGate and npmPreapprovedPackages config options
#6901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+714
−5
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
a05df86
feat: implement `minimumNpmReleaseAge` and `minimumNpmReleaseAgeExclu…
bienzaaron db24b78
fix: support `npm:` prefix for locators too
bienzaaron 900a7d2
test: adding tests for `minimumNpmReleaseAge` and `minimumNpmReleaseA…
bienzaaron 11f5edd
fix: rename options to better align with existing npm-related options
bienzaaron eccba6c
fix: change the way unknowns are resolved to fix `add`/`up`
bienzaaron 257fa2d
fix: fix release packages based on ci output
bienzaaron 84d4b5d
refactor: rename options
bienzaaron 0c7b130
Revert "fix: change the way unknowns are resolved to fix `add`/`up`"
bienzaaron ebd41b5
refactor: move exclusion logic to a helper
bienzaaron 79d3aa7
fix: crawl package versions from highest to lowest if `latest` tag do…
bienzaaron 55b5185
refactor: rename gate check function
bienzaaron 9db6b3b
docs: update doc language to match option name
bienzaaron 93957a6
refactor: move npm-related configs into plugin-npm
bienzaaron 98e58ad
fix: if latest is unsuitable, ensure we don't select a higher version
bienzaaron fb35bc8
simplify `npmPreapprovedPackages`
bienzaaron ef35b65
Couple of tweaks
arcanis b0d4031
Merge remote-tracking branch 'origin/master' into pr/bienzaaron/6901
arcanis 0cdbdfb
Merge remote-tracking branch 'origin/master' into pr/bienzaaron/6901
arcanis e4cd5dd
Versions
arcanis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix: rename options to better align with existing npm-related options
- Loading branch information
commit 11f5edd381f9c8eecf6d71a63808c0b9eee616d3
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| const ONE_DAY_IN_MINUTES = 24 * 60; | ||
|
|
||
| describe(`Features`, () => { | ||
| describe(`minimumNpmReleaseAge and minimumNpmReleaseAgeExclude`, () => { | ||
| describe(`npmMinimumReleaseAge and npmMinimumReleaseAgeExclude`, () => { | ||
| describe(`add`, () => { | ||
| // TODO failing | ||
| test( | ||
| `add should install the latest version allowed by the minimum release age`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date`); | ||
| await expect(source(`require('release-date/package.json')`)).resolves.toMatchObject({ | ||
|
|
@@ -20,7 +20,7 @@ describe(`Features`, () => { | |
| test( | ||
| `it should fail when trying to install exact version that is newer than the minimum release age`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run}) => { | ||
| await expect(run(`add`, `[email protected]`)).rejects.toThrowError(`No candidates found`); | ||
| }), | ||
|
|
@@ -29,7 +29,7 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install older package versions when the minimum release age disallows the newest suitable version`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -43,8 +43,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by exact locator; while transitive dependencies are not excluded`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`[email protected]`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`[email protected]`], | ||
| // we are checking a transitive dependencies version, which the pnp will throw an error for | ||
| // disabling these checks for the purpose of this test | ||
| pnpFallbackMode: `all`, | ||
|
|
@@ -67,8 +67,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by npm protocol locator`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@npm:1.1.1`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@npm:1.1.1`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `[email protected]`); | ||
|
|
||
|
|
@@ -82,8 +82,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by descriptor range`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@^1.0.0`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@^1.0.0`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -97,8 +97,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by npm protocol descriptor range`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@npm:^1.0.0`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@npm:^1.0.0`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -112,8 +112,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by package name glob pattern`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-*`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-*`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -127,8 +127,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install new version when excluded by package ident`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -142,7 +142,7 @@ describe(`Features`, () => { | |
| test( | ||
| `it should not impact semver prioritization of newer versions when multiple versions meet the age requirement`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: 0, | ||
| npmMinimumReleaseAge: 0, | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -156,7 +156,7 @@ describe(`Features`, () => { | |
| test( | ||
| `it should work with scoped packages`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run}) => { | ||
| await expect(run(`add`, `@scoped/[email protected]`)).rejects.toThrowError(`No candidates found`); | ||
| }), | ||
|
|
@@ -165,8 +165,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install scoped package when excluded`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`@scoped/release-date`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`@scoped/release-date`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `@scoped/release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -180,8 +180,8 @@ describe(`Features`, () => { | |
| test( | ||
| `it should install scoped package when excluded by scoped glob pattern`, | ||
| makeTemporaryEnv({}, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`@scoped/*`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`@scoped/*`], | ||
| }, async ({run, source}) => { | ||
| await run(`add`, `@scoped/release-date@^1.0.0`); | ||
|
|
||
|
|
@@ -198,7 +198,7 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `1.1.1`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run}) => { | ||
| await expect(run(`install`)).rejects.toThrowError(`No candidates found`); | ||
| }), | ||
|
|
@@ -209,7 +209,7 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -225,8 +225,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`[email protected]`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`[email protected]`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -242,8 +242,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `1.1.1`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@npm:1.1.1`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@npm:1.1.1`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -259,8 +259,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@^1.0.0`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@^1.0.0`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -276,8 +276,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date@npm:^1.0.0`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date@npm:^1.0.0`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -293,8 +293,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-*`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-*`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -310,8 +310,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`release-date`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`release-date`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -327,7 +327,7 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: 0, | ||
| npmMinimumReleaseAge: 0, | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -343,7 +343,7 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`@scoped/release-date`]: `1.1.1`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run}) => { | ||
| await expect(run(`install`)).rejects.toThrowError(`No candidates found`); | ||
| }), | ||
|
|
@@ -354,8 +354,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`@scoped/release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`@scoped/release-date`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`@scoped/release-date`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -371,8 +371,8 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`@scoped/release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| minimumNpmReleaseAgeExclude: [`@scoped/*`], | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAgeExclude: [`@scoped/*`], | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
|
|
||
|
|
@@ -390,7 +390,7 @@ describe(`Features`, () => { | |
| makeTemporaryEnv({ | ||
| dependencies: {[`release-date`]: `^1.0.0`}, | ||
| }, { | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
| await run(`set`, `resolution`, `release-date@npm:^1.0.0`, `npm:1.0.0`); | ||
|
|
@@ -416,7 +416,7 @@ describe(`Features`, () => { | |
| // disabling these checks for the purpose of this test | ||
| pnpFallbackMode: `all`, | ||
| pnpMode: `loose`, | ||
| minimumNpmReleaseAge: ONE_DAY_IN_MINUTES, | ||
| npmMinimumReleaseAge: ONE_DAY_IN_MINUTES, | ||
| }, async ({run, source}) => { | ||
| await run(`install`); | ||
| await run(`set`, `resolution`, `release-date@npm:^1.0.0`, `npm:1.0.0`); | ||
|
|
||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -407,23 +407,6 @@ | |
| } | ||
| ] | ||
| }, | ||
| "minimumReleaseAge": { | ||
| "_package": "@yarnpkg/core", | ||
| "title": "Minimum age of a package version according to the publish date on the npm registry in minutes to be considered for installation.", | ||
| "description": "If a package version is newer than the minimum release age, it will not be considered for installation. This can be used to reduce the likelihood of installing compromised packages.", | ||
| "type": "number", | ||
| "default": 0 | ||
| }, | ||
| "minimumReleaseAgeExcludes": { | ||
| "_package": "@yarnpkg/core", | ||
| "title": "Array of exact package descriptors, exact package locators, or package name glob patterns to exclude from the minimum release age check.", | ||
| "description": "If a package descriptor, locator, or name matches specified pattern, it will not be considered for the minimum release age check. That is, the newest matching package version will be selected for installation regardless of the minimum release age configuration.", | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string" | ||
| }, | ||
| "default": [] | ||
| }, | ||
| "networkConcurrency": { | ||
| "_package": "@yarnpkg/core", | ||
| "title": "Amount of HTTP requests that are allowed to run at the same time.", | ||
|
|
@@ -496,6 +479,24 @@ | |
| "type": "string", | ||
| "default": "pnp" | ||
| }, | ||
| "npmMinimumReleaseAge": { | ||
| "_package": "@yarnpkg/core", | ||
| "title": "Minimum age of a package version according to the publish date on the npm registry in minutes to be considered for installation.", | ||
| "description": "If a package version is newer than the minimum release age, it will not be considered for installation. This can be used to reduce the likelihood of installing compromised packages.", | ||
| "type": "number", | ||
| "default": 0 | ||
| }, | ||
| "npmMinimumReleaseAgeExclude": { | ||
| "_package": "@yarnpkg/core", | ||
| "title": "Array of exact package descriptors, exact package locators, or package name glob patterns to exclude from the minimum release age check.", | ||
| "description": "If a package descriptor, locator, or name matches specified pattern, it will not be considered for the minimum release age check. That is, the newest matching package version will be selected for installation regardless of the minimum release age configuration.", | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string" | ||
| }, | ||
| "default": [], | ||
| "examples": ["@scoped-package/*", "package", "package*", "package@^1.0.0", "[email protected]", "package@npm:1.0.0", "package@npm:^1.0.0"] | ||
| }, | ||
| "pnpmStoreFolder": { | ||
| "_package": "@yarnpkg/plugin-pnpm", | ||
| "title": "Path where the pnpm store will be stored", | ||
|
|
||
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
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
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -577,12 +577,12 @@ export const coreDefinitions: {[coreSettingName: string]: SettingsDefinition} = | |||||
| type: SettingsType.STRING, | ||||||
| default: `throw`, | ||||||
| }, | ||||||
| minimumNpmReleaseAge: { | ||||||
| npmMinimumReleaseAge: { | ||||||
| description: `Minimum age of a package version according to the publish date on the npm registry in minutes to be considered for installation`, | ||||||
| type: SettingsType.NUMBER, | ||||||
| default: 0, | ||||||
| }, | ||||||
| minimumNpmReleaseAgeExclude: { | ||||||
| npmMinimumReleaseAgeExclude: { | ||||||
|
||||||
| npmMinimumReleaseAgeExclude: { | |
| npmPreapprovedPackages: { |
Same reason, if there were multiple gates we'd want a single setting to bypass them all.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could envision multiple types of gates.