From c8a9d3b533c4dd4c98a99e181a3090a4e54840e6 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 00:28:38 +0000 Subject: [PATCH 01/28] Update lockfile description --- review/npm.md | 67 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/review/npm.md b/review/npm.md index 4711fd4..b24bdaf 100644 --- a/review/npm.md +++ b/review/npm.md @@ -17,6 +17,7 @@ alternative. * [Dependency management](#dependency-management) + [Intake](#intake) + [Declaration](#declaration) + + [Project types](#project-types) + [Reproducible installation](#reproducible-installation) - [Vendoring dependencies](#vendoring-dependencies) - [Use a Lockfile](#use-a-lockfile) @@ -94,6 +95,24 @@ commitish are allowed. **Note**: The manifest file ***does not*** list transitive dependencies; it lists only direct project dependencies. +### Project types + +In the rest of this document, we will refer to three types of projects: + +- **Libraries**: These are projects published on the Npm registry and consumed +by other projects in the form of API calls. (Their manifest file +contains a `lib` entry). + +- **Stand-alone CLIs**: These are projects published on the Npm registry +and consumed by end-users in the form of locally installed programs. +An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). +(Their manifest file contains a `main` entry). + +- **Application projects**: These are projects that teams collaborate on in +development and deploy, such as web sites and/or web applications. +An example would be a React web app for a company's user-facing SaaS. + + ### Reproducible installation A reproducible installation is one that guarantees the exact same copy the @@ -121,6 +140,11 @@ benefits, including: proxy packages from public registries. Note: Versions are immutable in principle, but immutability is enforced by the registry. +- Improve tthe accuracy of automated tools such as GitHub's security alerts. + +- Let maintainers test updates before accepting them in the `main` branch, + e.g., via renovatebot's [stabilityDays](https://docs.renovatebot.com/configuration-options/#stabilitydays). + There are two ways to reliably achieve a reproducible installation: vendoring dependencies and pinning by hash. @@ -215,8 +239,24 @@ run. 1. To add a dependency to a manifest file, ***locally*** run [`npm install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). -1. In automated environments (e.g., in CI or production) or when building - artifacts for end-users (e.g., container images, etc): +1. If a project is a standalone CLI, developers may publish a shrinkwrap.json. + Remember that, by declaring a shrinkwrap.json, you take responsibility + for updating all the dependencies in time. Your users will not be able + to update them. + +1. If a project is a library, a shrinkwrap.json should ***not*** be published. + The reasoning is that version resolution should be left to the package consumer. + Allow all versions from the minimum to the latest you support, e.g., + `^m.n.o` to pin to a major range; `~m.n.o` to pin to a minor range. Avoid versions + with critical vulnerabilities as much as possible. Visit the [semver + calculator](https://semver.npmjs.com/) to help you define the ranges. + +1. Projects that do no use a shrinkwrap.json (libraries, standalone CLIs + or application projects) should declare and commit a package-lock.json to their repository. + The reasoning is that this lockfile will provide the benefits highlighted in + [Reproducible installation](#reproducible-installation) by default for for privileged environments + (project contributors' machines, CI, production or other environments with access to sensitive data, + such as secrets, PII, write/push permission to the repository, etc). To generate the lockfile: 1. Always generate a package-lock.json ***locally*** and commit it to the repository. @@ -245,18 +285,17 @@ run. install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test). 1. If you need to run a CLI package from the registry, ensure the package is a part of - the dependencies defined in your project via the `package.json` file, prior to being installed at build-time in your CI or otherwise automated environment. - -1. If a project is a CLI application (`main` entry in the manifest file), - developers may publish a shrinkwrap.json. - -1. If a project is a library (`lib` entry in the manifest file), a - shrinkwrap.json should ***not*** be published. The reasoning is that version - resolution should be left to the package consumer. Allow all versions from - the minimum to the latest you support, e.g., `^m.n.o` to pin to a major - range; `~m.n.o` to pin to a minor range. Avoid versions with critical - vulnerabilities as much as possible. Visit the [semver - calculator](https://semver.npmjs.com/) to help you define the ranges. + the dependencies defined in your project via the `package.json` file, prior to + being installed at build-time in your CI or otherwise automated environment. + +1. In non-privileged environments, maintainers may **ignore** the lockfile. This is particularly useful in + situations where they want to exercise a wide range of dependency versions, to discover / fix problems before + their users do. This is useful for maintainers of libraries and standalone CLI projects + without shrinkwrap.json since their users may use `npm install`. If you run CI via GitHub Actions, + a non-privileged environment is a workflow with access to **no** GitHub secrets and with its + permissions defined as `read-all`. You may ignore the lockfile by running `npm install --no-package-lock` + in your pre-submit tests. If you are not certain whether the environment you are running is privileged or not, + reach out to your security team. ### Maintenance From f2e06a856fa6343ca88c8f0d82747e3fdc0c17cb Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 00:34:12 +0000 Subject: [PATCH 02/28] update --- review/npm.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/review/npm.md b/review/npm.md index b24bdaf..ed843c0 100644 --- a/review/npm.md +++ b/review/npm.md @@ -254,7 +254,7 @@ run. 1. Projects that do no use a shrinkwrap.json (libraries, standalone CLIs or application projects) should declare and commit a package-lock.json to their repository. The reasoning is that this lockfile will provide the benefits highlighted in - [Reproducible installation](#reproducible-installation) by default for for privileged environments + [Reproducible installation](#reproducible-installation) by default for privileged environments (project contributors' machines, CI, production or other environments with access to sensitive data, such as secrets, PII, write/push permission to the repository, etc). To generate the lockfile: @@ -284,14 +284,15 @@ run. 1. To run tests, run [`npm install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test). - 1. If you need to run a CLI package from the registry, ensure the package is a part of + 1. If you need to run a standalone CLI package from the registry, ensure the package is a part of the dependencies defined in your project via the `package.json` file, prior to being installed at build-time in your CI or otherwise automated environment. 1. In non-privileged environments, maintainers may **ignore** the lockfile. This is particularly useful in situations where they want to exercise a wide range of dependency versions, to discover / fix problems before their users do. This is useful for maintainers of libraries and standalone CLI projects - without shrinkwrap.json since their users may use `npm install`. If you run CI via GitHub Actions, + without shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, + so using flaoting versions in (non-privileged) tests is beneficial. If you run CI via GitHub Actions, a non-privileged environment is a workflow with access to **no** GitHub secrets and with its permissions defined as `read-all`. You may ignore the lockfile by running `npm install --no-package-lock` in your pre-submit tests. If you are not certain whether the environment you are running is privileged or not, From ed3eaf1a1749218d7711e28bd92a7d15727db12b Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 00:34:38 +0000 Subject: [PATCH 03/28] update --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index ed843c0..f335a65 100644 --- a/review/npm.md +++ b/review/npm.md @@ -103,7 +103,7 @@ In the rest of this document, we will refer to three types of projects: by other projects in the form of API calls. (Their manifest file contains a `lib` entry). -- **Stand-alone CLIs**: These are projects published on the Npm registry +- **Standalone CLIs**: These are projects published on the Npm registry and consumed by end-users in the form of locally installed programs. An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). (Their manifest file contains a `main` entry). From cc5c65441a8ffda9da85878765716aa54916f779 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 00:36:04 +0000 Subject: [PATCH 04/28] update --- review/npm.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/review/npm.md b/review/npm.md index f335a65..e813384 100644 --- a/review/npm.md +++ b/review/npm.md @@ -292,9 +292,12 @@ run. situations where they want to exercise a wide range of dependency versions, to discover / fix problems before their users do. This is useful for maintainers of libraries and standalone CLI projects without shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, - so using flaoting versions in (non-privileged) tests is beneficial. If you run CI via GitHub Actions, - a non-privileged environment is a workflow with access to **no** GitHub secrets and with its - permissions defined as `read-all`. You may ignore the lockfile by running `npm install --no-package-lock` + so using floating versions in (non-privileged) tests is beneficial. + + 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow with access to **no** GitHub secrets and with its + permissions defined as `read-all`. + + 1. You may ignore the lockfile by running `npm install --no-package-lock` in your pre-submit tests. If you are not certain whether the environment you are running is privileged or not, reach out to your security team. From 5d9d5fc66f4d91e7290d9576c473ab2e42ce0df8 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 00:38:43 +0000 Subject: [PATCH 05/28] update --- review/npm.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/review/npm.md b/review/npm.md index e813384..4edb80a 100644 --- a/review/npm.md +++ b/review/npm.md @@ -288,18 +288,17 @@ run. the dependencies defined in your project via the `package.json` file, prior to being installed at build-time in your CI or otherwise automated environment. -1. In non-privileged environments, maintainers may **ignore** the lockfile. This is particularly useful in - situations where they want to exercise a wide range of dependency versions, to discover / fix problems before +1. In **non-privileged environments**, maintainers may **ignore** the lockfile. This is particularly useful in + situations where they want to exercise a wide range of dependency versions in order to discover / fix problems before their users do. This is useful for maintainers of libraries and standalone CLI projects - without shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, - so using floating versions in (non-privileged) tests is beneficial. + without a shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, + so using floating versions in (non-privileged) tests can be beneficial. - 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow with access to **no** GitHub secrets and with its - permissions defined as `read-all`. + 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with its + permissions defined as `permissions: read-all` at the top of the workflow. - 1. You may ignore the lockfile by running `npm install --no-package-lock` - in your pre-submit tests. If you are not certain whether the environment you are running is privileged or not, - reach out to your security team. + 1. In a **non-privileged environment**, you may ignore the lockfile by running `npm install --no-package-lock`. + If you are not certain whether the environment you are running is privileged or not, reach out to your security team. ### Maintenance From 8b81f9c1155eb7bc87d1459cd01c2eb572f4e67d Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:38:34 -0700 Subject: [PATCH 06/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 4edb80a..58a756f 100644 --- a/review/npm.md +++ b/review/npm.md @@ -99,7 +99,7 @@ lists only direct project dependencies. In the rest of this document, we will refer to three types of projects: -- **Libraries**: These are projects published on the Npm registry and consumed +- **Libraries**: These are projects published on the npm registry and consumed by other projects in the form of API calls. (Their manifest file contains a `lib` entry). From 2fd0659aa1f091bd234835b5d11498437524e147 Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:39:02 -0700 Subject: [PATCH 07/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 58a756f..c46a1f5 100644 --- a/review/npm.md +++ b/review/npm.md @@ -103,7 +103,7 @@ In the rest of this document, we will refer to three types of projects: by other projects in the form of API calls. (Their manifest file contains a `lib` entry). -- **Standalone CLIs**: These are projects published on the Npm registry +- **Standalone CLIs**: These are projects published on the npm registry and consumed by end-users in the form of locally installed programs. An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). (Their manifest file contains a `main` entry). From ce3c62fea2b26a8ec62f60bf1a746c94085c9621 Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:41:14 -0700 Subject: [PATCH 08/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index c46a1f5..72f928c 100644 --- a/review/npm.md +++ b/review/npm.md @@ -106,7 +106,7 @@ contains a `lib` entry). - **Standalone CLIs**: These are projects published on the npm registry and consumed by end-users in the form of locally installed programs. An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). -(Their manifest file contains a `main` entry). +(Their manifest file contains a `bin` entry). - **Application projects**: These are projects that teams collaborate on in development and deploy, such as web sites and/or web applications. From a19a02033a7dc89b47e3cfabe96e68503202fde3 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:41:45 +0000 Subject: [PATCH 09/28] update --- review/npm.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/review/npm.md b/review/npm.md index 72f928c..2d55a4f 100644 --- a/review/npm.md +++ b/review/npm.md @@ -22,7 +22,7 @@ alternative. - [Vendoring dependencies](#vendoring-dependencies) - [Use a Lockfile](#use-a-lockfile) * [Package-lock.json](#package-lockjson) - * [Shrinkwrap.json](#shrinkwrapjson) + * [npm-shrinkwrap.json](#shrinkwrapjson) + [Maintenance](#maintenance) * [Release](#release) + [Account](#account) @@ -103,8 +103,9 @@ In the rest of this document, we will refer to three types of projects: by other projects in the form of API calls. (Their manifest file contains a `lib` entry). -- **Standalone CLIs**: These are projects published on the npm registry -and consumed by end-users in the form of locally installed programs. +- **Standalone CLIs**: These are projects published on the Npm registry +and consumed by end-users in the form of locally installed programs that +are **always** run stand alone via `npx` or via a global install. An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). (Their manifest file contains a `bin` entry). @@ -213,18 +214,18 @@ dependencies at load time using libraries available on the system. Using this lock file leaves the task of deciding dependencies' versions to use to the package consumer. -##### Shrinkwrap.json +##### npm-shrinkwrap.json -[Shrinkwrap.json](https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson) +[npm-shrinkwrap.json](https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson) is another lock file supported by npm. The main difference is that this lock file ***may*** be uploaded to a registry along with the package. This ensures that consumers of the dependency will obtain the same dependencies' hashes as the -repo owners intended. With shrinkwrap.json, the package producer takes +repo owners intended. With npm-shrinkwrap.json, the package producer takes responsibility for updating the dependencies on behalf of their consumers. It's akin to static linking for low-level programming languages: everything is declared at packaging time. -To generate the shrinkwrap.json, an existing package-lock.json must be present +To generate the npm-shrinkwrap.json, an existing package-lock.json must be present and the command [`npm shrinkwrap`](https://docs.npmjs.com/cli/v8/commands/npm-shrinkwrap) must be run. @@ -239,19 +240,21 @@ run. 1. To add a dependency to a manifest file, ***locally*** run [`npm install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). -1. If a project is a standalone CLI, developers may publish a shrinkwrap.json. - Remember that, by declaring a shrinkwrap.json, you take responsibility +1. If a project is a standalone CLI, developers may publish a npm-shrinkwrap.json. + Remember that, by declaring a npm-shrinkwrap.json, you take responsibility for updating all the dependencies in time. Your users will not be able - to update them. + to update them. If you expect your CLI to be used by other projects and defined + in their package.json or lockfile, do **not** use npm-shrinkwrap.json because it will + hinder dependency resolution for your consumers. -1. If a project is a library, a shrinkwrap.json should ***not*** be published. +1. If a project is a library, a npm-shrinkwrap.json should ***not*** be published. The reasoning is that version resolution should be left to the package consumer. Allow all versions from the minimum to the latest you support, e.g., `^m.n.o` to pin to a major range; `~m.n.o` to pin to a minor range. Avoid versions with critical vulnerabilities as much as possible. Visit the [semver calculator](https://semver.npmjs.com/) to help you define the ranges. -1. Projects that do no use a shrinkwrap.json (libraries, standalone CLIs +1. Projects that do no use a npm-shrinkwrap.json (libraries, standalone CLIs or application projects) should declare and commit a package-lock.json to their repository. The reasoning is that this lockfile will provide the benefits highlighted in [Reproducible installation](#reproducible-installation) by default for privileged environments @@ -291,7 +294,7 @@ run. 1. In **non-privileged environments**, maintainers may **ignore** the lockfile. This is particularly useful in situations where they want to exercise a wide range of dependency versions in order to discover / fix problems before their users do. This is useful for maintainers of libraries and standalone CLI projects - without a shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, + without a npm-shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, so using floating versions in (non-privileged) tests can be beneficial. 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with its From 9cca608a4257c4e9c73e7bc478db27b528c525d8 Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:44:45 -0700 Subject: [PATCH 10/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 2d55a4f..8cd342f 100644 --- a/review/npm.md +++ b/review/npm.md @@ -255,7 +255,7 @@ run. calculator](https://semver.npmjs.com/) to help you define the ranges. 1. Projects that do no use a npm-shrinkwrap.json (libraries, standalone CLIs - or application projects) should declare and commit a package-lock.json to their repository. + or application projects) should declare and commit a `package-lock.json` (or other dev-only lockfile) to their repository. The reasoning is that this lockfile will provide the benefits highlighted in [Reproducible installation](#reproducible-installation) by default for privileged environments (project contributors' machines, CI, production or other environments with access to sensitive data, From d014ad6cc6b56ad2e163c9be88c314bde313e1cc Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:46:14 +0000 Subject: [PATCH 11/28] update --- review/npm.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/review/npm.md b/review/npm.md index 8cd342f..ff5cd20 100644 --- a/review/npm.md +++ b/review/npm.md @@ -220,12 +220,12 @@ package consumer. is another lock file supported by npm. The main difference is that this lock file ***may*** be uploaded to a registry along with the package. This ensures that consumers of the dependency will obtain the same dependencies' hashes as the -repo owners intended. With npm-shrinkwrap.json, the package producer takes +repo owners intended. With `npm-shrinkwrap.json`, the package producer takes responsibility for updating the dependencies on behalf of their consumers. It's akin to static linking for low-level programming languages: everything is declared at packaging time. -To generate the npm-shrinkwrap.json, an existing package-lock.json must be present +To generate the `npm-shrinkwrap.json`, an existing package-lock.json must be present and the command [`npm shrinkwrap`](https://docs.npmjs.com/cli/v8/commands/npm-shrinkwrap) must be run. @@ -240,21 +240,21 @@ run. 1. To add a dependency to a manifest file, ***locally*** run [`npm install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). -1. If a project is a standalone CLI, developers may publish a npm-shrinkwrap.json. - Remember that, by declaring a npm-shrinkwrap.json, you take responsibility +1. If a project is a standalone CLI, developers may publish an `npm-shrinkwrap.json`. + Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility for updating all the dependencies in time. Your users will not be able to update them. If you expect your CLI to be used by other projects and defined - in their package.json or lockfile, do **not** use npm-shrinkwrap.json because it will + in their package.json or lockfile, do **not** use `npm-shrinkwrap.json` because it will hinder dependency resolution for your consumers. -1. If a project is a library, a npm-shrinkwrap.json should ***not*** be published. +1. If a project is a library, an `npm-shrinkwrap.json` should ***not*** be published. The reasoning is that version resolution should be left to the package consumer. Allow all versions from the minimum to the latest you support, e.g., `^m.n.o` to pin to a major range; `~m.n.o` to pin to a minor range. Avoid versions with critical vulnerabilities as much as possible. Visit the [semver calculator](https://semver.npmjs.com/) to help you define the ranges. -1. Projects that do no use a npm-shrinkwrap.json (libraries, standalone CLIs +1. Projects that do no use a `npm-shrinkwrap.json` (libraries, standalone CLIs or application projects) should declare and commit a `package-lock.json` (or other dev-only lockfile) to their repository. The reasoning is that this lockfile will provide the benefits highlighted in [Reproducible installation](#reproducible-installation) by default for privileged environments @@ -294,7 +294,7 @@ run. 1. In **non-privileged environments**, maintainers may **ignore** the lockfile. This is particularly useful in situations where they want to exercise a wide range of dependency versions in order to discover / fix problems before their users do. This is useful for maintainers of libraries and standalone CLI projects - without a npm-shrinkwrap.json. The reasoning is that many downstream users will use `npm install` to install a dependency, + without an `npm-shrinkwrap.json`. The reasoning is that many downstream users will use `npm install` to install a dependency, so using floating versions in (non-privileged) tests can be beneficial. 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with its From 1db35929f637619da1923cf1348ed1c17b94fb00 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:47:52 +0000 Subject: [PATCH 12/28] update --- review/npm.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/review/npm.md b/review/npm.md index ff5cd20..37bd425 100644 --- a/review/npm.md +++ b/review/npm.md @@ -197,7 +197,7 @@ cryptographic hash of their content: } ``` -The package-lock.json file is a ***snapshot of an installation*** that allows +The `package-lock.json` file is a ***snapshot of an installation*** that allows later reproduction of the same installation. As such, the lock file is generated or updated via the various commands that install packages, e.g., `npm install`. If some dependencies are missing or not pinned by hash (e.g., @@ -208,7 +208,7 @@ The lock file ***cannot*** be uploaded to a registry, which means that consumers who locally install the package via `npm install` may [see different dependency versions](https://dev.to/saurabhdaware/but-what-the-hell-is-package-lock-json-b04) -than the repo owners used during testing. Using package-lock.json is akin to +than the repo owners used during testing. Using `package-lock.json` is akin to dynamic linking for low-level programming languages: the loader will resolve dependencies at load time using libraries available on the system. Using this lock file leaves the task of deciding dependencies' versions to use to the @@ -225,7 +225,7 @@ responsibility for updating the dependencies on behalf of their consumers. It's akin to static linking for low-level programming languages: everything is declared at packaging time. -To generate the `npm-shrinkwrap.json`, an existing package-lock.json must be present +To generate the `npm-shrinkwrap.json`, an existing `package-lock.json` must be present and the command [`npm shrinkwrap`](https://docs.npmjs.com/cli/v8/commands/npm-shrinkwrap) must be run. @@ -261,7 +261,7 @@ run. (project contributors' machines, CI, production or other environments with access to sensitive data, such as secrets, PII, write/push permission to the repository, etc). To generate the lockfile: - 1. Always generate a package-lock.json ***locally*** and commit it to the + 1. Always generate a `package-lock.json` ***locally*** and commit it to the repository. 1. Never run commands that may update the lock files or fetch unpinned From 46ec48316d7b05bb5167ff28e2855c1119931f2f Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:49:04 +0000 Subject: [PATCH 13/28] update --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 37bd425..3db0fd5 100644 --- a/review/npm.md +++ b/review/npm.md @@ -112,7 +112,7 @@ An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cl - **Application projects**: These are projects that teams collaborate on in development and deploy, such as web sites and/or web applications. An example would be a React web app for a company's user-facing SaaS. - +(Their manifest file typically contains `"private": true`). ### Reproducible installation From 7908deb7e076bfd64122221ec8276a2779f76ec4 Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:49:45 -0700 Subject: [PATCH 14/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 3db0fd5..390d17a 100644 --- a/review/npm.md +++ b/review/npm.md @@ -141,7 +141,7 @@ benefits, including: proxy packages from public registries. Note: Versions are immutable in principle, but immutability is enforced by the registry. -- Improve tthe accuracy of automated tools such as GitHub's security alerts. +- Improve the accuracy of automated tools such as GitHub's security alerts. - Let maintainers test updates before accepting them in the `main` branch, e.g., via renovatebot's [stabilityDays](https://docs.renovatebot.com/configuration-options/#stabilitydays). From e8253af3c3c2320433517744e78d75202cef28bf Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:50:08 -0700 Subject: [PATCH 15/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index 390d17a..f543107 100644 --- a/review/npm.md +++ b/review/npm.md @@ -143,7 +143,7 @@ benefits, including: - Improve the accuracy of automated tools such as GitHub's security alerts. -- Let maintainers test updates before accepting them in the `main` branch, +- Let maintainers test updates before accepting them in the default branch, e.g., via renovatebot's [stabilityDays](https://docs.renovatebot.com/configuration-options/#stabilitydays). There are two ways to reliably achieve a reproducible installation: vendoring From 1ee1de4b0ba4dcac4457563368c4cdda2a2c3382 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:50:57 +0000 Subject: [PATCH 16/28] update --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index f543107..3dbf974 100644 --- a/review/npm.md +++ b/review/npm.md @@ -103,7 +103,7 @@ In the rest of this document, we will refer to three types of projects: by other projects in the form of API calls. (Their manifest file contains a `lib` entry). -- **Standalone CLIs**: These are projects published on the Npm registry +- **Standalone CLIs**: These are projects published on the npm registry and consumed by end-users in the form of locally installed programs that are **always** run stand alone via `npx` or via a global install. An example would be [clipboard-cli](https://github.com/sindresorhus/clipboard-cli). From 6d8eb0e4199ec90c9116259c16a02d4267f78cb1 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 01:52:22 +0000 Subject: [PATCH 17/28] update --- review/npm.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/review/npm.md b/review/npm.md index 3dbf974..f4b928b 100644 --- a/review/npm.md +++ b/review/npm.md @@ -240,13 +240,6 @@ run. 1. To add a dependency to a manifest file, ***locally*** run [`npm install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). -1. If a project is a standalone CLI, developers may publish an `npm-shrinkwrap.json`. - Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility - for updating all the dependencies in time. Your users will not be able - to update them. If you expect your CLI to be used by other projects and defined - in their package.json or lockfile, do **not** use `npm-shrinkwrap.json` because it will - hinder dependency resolution for your consumers. - 1. If a project is a library, an `npm-shrinkwrap.json` should ***not*** be published. The reasoning is that version resolution should be left to the package consumer. Allow all versions from the minimum to the latest you support, e.g., @@ -254,6 +247,13 @@ run. with critical vulnerabilities as much as possible. Visit the [semver calculator](https://semver.npmjs.com/) to help you define the ranges. +1. If a project is a standalone CLI, developers may publish an `npm-shrinkwrap.json`. + Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility + for updating all the dependencies in time. Your users will not be able + to update them. If you expect your CLI to be used by other projects and defined + in their package.json or lockfile, do **not** use `npm-shrinkwrap.json` because it will + hinder dependency resolution for your consumers. + 1. Projects that do no use a `npm-shrinkwrap.json` (libraries, standalone CLIs or application projects) should declare and commit a `package-lock.json` (or other dev-only lockfile) to their repository. The reasoning is that this lockfile will provide the benefits highlighted in From 238630e83f7636915e8ef7436cc78031023d910e Mon Sep 17 00:00:00 2001 From: laurentsimon <64505099+laurentsimon@users.noreply.github.com> Date: Tue, 28 Jun 2022 08:50:13 -0700 Subject: [PATCH 18/28] Update review/npm.md Co-authored-by: Jordan Harband --- review/npm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index f4b928b..4342f1c 100644 --- a/review/npm.md +++ b/review/npm.md @@ -101,7 +101,7 @@ In the rest of this document, we will refer to three types of projects: - **Libraries**: These are projects published on the npm registry and consumed by other projects in the form of API calls. (Their manifest file -contains a `lib` entry). +typically contains a `main`, `exports`, `browser`, `module`, and/or `types` entry). - **Standalone CLIs**: These are projects published on the npm registry and consumed by end-users in the form of locally installed programs that From 5bb7a87d58c3815387f869d6277fed27fc210633 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 15:57:25 +0000 Subject: [PATCH 19/28] comments --- review/npm.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/review/npm.md b/review/npm.md index 4342f1c..e99a54c 100644 --- a/review/npm.md +++ b/review/npm.md @@ -297,8 +297,10 @@ run. without an `npm-shrinkwrap.json`. The reasoning is that many downstream users will use `npm install` to install a dependency, so using floating versions in (non-privileged) tests can be beneficial. - 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with its - permissions defined as `permissions: read-all` at the top of the workflow. + 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with + non-write permissions defined, such as `permissions: read-all`, `permissions:`, `contents: none`, `contents: read`. + For more information about permissions, refer to the [official documentation](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). You may install the [OpenSSF Scorecard Action](https://github.com/ossf/scorecard-action) + to flag non-read permissions on your project. 1. In a **non-privileged environment**, you may ignore the lockfile by running `npm install --no-package-lock`. If you are not certain whether the environment you are running is privileged or not, reach out to your security team. From ecff0880d2a81ce6475c5324c6601c3a37150134 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Tue, 28 Jun 2022 15:58:15 +0000 Subject: [PATCH 20/28] update --- review/npm.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index e99a54c..cdb1678 100644 --- a/review/npm.md +++ b/review/npm.md @@ -299,7 +299,8 @@ run. 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with non-write permissions defined, such as `permissions: read-all`, `permissions:`, `contents: none`, `contents: read`. - For more information about permissions, refer to the [official documentation](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). You may install the [OpenSSF Scorecard Action](https://github.com/ossf/scorecard-action) + For more information about permissions, refer to the [official documentation](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). + You may install the [OpenSSF Scorecard Action](https://github.com/ossf/scorecard-action) to flag non-read permissions on your project. 1. In a **non-privileged environment**, you may ignore the lockfile by running `npm install --no-package-lock`. From 575b37601a76dca8138c2ae545362f6b21b21b66 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:31:11 +0000 Subject: [PATCH 21/28] update --- review/npm.md | 140 +++++++++++++++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 53 deletions(-) diff --git a/review/npm.md b/review/npm.md index cdb1678..0f77b55 100644 --- a/review/npm.md +++ b/review/npm.md @@ -14,6 +14,7 @@ alternative. - [npm Best Practices Guide](#npm-best-practices-guide) * [TOC](#toc) + * [CI configuration](#ci-configuration) * [Dependency management](#dependency-management) + [Intake](#intake) + [Declaration](#declaration) @@ -23,6 +24,7 @@ alternative. - [Use a Lockfile](#use-a-lockfile) * [Package-lock.json](#package-lockjson) * [npm-shrinkwrap.json](#shrinkwrapjson) + * [Lockfiles and commands](#lockfiles-and-commands) + [Maintenance](#maintenance) * [Release](#release) + [Account](#account) @@ -32,6 +34,18 @@ alternative. + [Scopes](#scopes) + [Private registry configurations](#private-registry-configurations) +## CI configuration + +Follow the [principle of least privilege](https://www.cisa.gov/uscert/bsi/articles/knowledge/principles/least-privilege) +for your CI configuration. + +If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to +GitHub secrets and with non-write permissions defined, such as `permissions: read-all`, `permissions:`, +`contents: none`, `contents: read`. For more information about permissions, refer to the [official documentation](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). + +You may install the [OpenSSF Scorecard Action](https://github.com/ossf/scorecard-action) +to flag non-read permissions on your project. + ## Dependency management ### Intake @@ -230,81 +244,101 @@ and the command [`npm shrinkwrap`](https://docs.npmjs.com/cli/v8/commands/npm-shrinkwrap) must be run. +##### Lockfiles and commands + +Certain `npm` commmands treat the lockfiles as read-only, while others do not. + +The following commands treat the lock file as read-only: + +1. To install a project and its dependencies, use [`npm + ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci). + +1. To run tests, run [`npm + install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test). + +The following commands ***do not*** treat the lock file as read-only, may fetch / install +the unpinned dependencies and update the lockfiles: + +1. `npm install`, `npm i`, `npm install -g` + +1. `npm update` + +1. `npm install-test` + +1. `npm pkg set` and `npm pkg delete` + +1. `npm exec`, `npx` + +1. `npm set-script` + **Recommendations:** 1. Developers should declare and commit a manifest file for ***all*** their projects. Use the official [Creating a package.json file](https://docs.npmjs.com/creating-a-package-json-file) documentation to - create the manifest file. + create the manifest file. 1. To add a dependency to a manifest file, ***locally*** run [`npm install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). -1. If a project is a library, an `npm-shrinkwrap.json` should ***not*** be published. - The reasoning is that version resolution should be left to the package consumer. - Allow all versions from the minimum to the latest you support, e.g., - `^m.n.o` to pin to a major range; `~m.n.o` to pin to a minor range. Avoid versions - with critical vulnerabilities as much as possible. Visit the [semver - calculator](https://semver.npmjs.com/) to help you define the ranges. - -1. If a project is a standalone CLI, developers may publish an `npm-shrinkwrap.json`. - Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility - for updating all the dependencies in time. Your users will not be able - to update them. If you expect your CLI to be used by other projects and defined - in their package.json or lockfile, do **not** use `npm-shrinkwrap.json` because it will - hinder dependency resolution for your consumers. - -1. Projects that do no use a `npm-shrinkwrap.json` (libraries, standalone CLIs - or application projects) should declare and commit a `package-lock.json` (or other dev-only lockfile) to their repository. - The reasoning is that this lockfile will provide the benefits highlighted in - [Reproducible installation](#reproducible-installation) by default for privileged environments - (project contributors' machines, CI, production or other environments with access to sensitive data, - such as secrets, PII, write/push permission to the repository, etc). To generate the lockfile: +1. Developers should declare and commit a lockfile for ***all*** their + projects. The reasoning is that this lockfile provides the + benefits listed in [Reproducible installation](#reproducible-installation) + by default for privileged environments (project developers' machines, + CI, production or other environments with access to sensitive data, + such as secrets, PII, write/push permission to the repository, etc). + + When running tests locally, developers should locally use commands that treat lockfiles + as read-only (see [Lockfiles and commands](#lockfiles-and-commands)), unless they + are intentionally adding / removing a dependency. - 1. Always generate a `package-lock.json` ***locally*** and commit it to the - repository. + Below we explain the type of lockfile acceptable by project type. - 1. Never run commands that may update the lock files or fetch unpinned - dependencies: +1. If a project is a library: - 1. `npm install`, `npm i`, `npm install -g` + 1. An `npm-shrinkwrap.json` ***should not*** be published. + The reasoning is that version resolution should be left to the package consumer. + Allow all versions from the minimum to the latest you support, e.g., + `^m.n.o` to pin to a major range; `~m.n.o` to pin to a minor range. Avoid versions + with critical vulnerabilities as much as possible. Visit the [semver + calculator](https://semver.npmjs.com/) to help you define the ranges. - 1. `npm update` + 1. The lockfile `package-lock.json` ***should*** be ignored for tests running in CI + (e.g. via `npm install --no-package-lock`) ***and*** the CI environment should be ***non-privileged*** + by following the [principle of least privilege](https://www.cisa.gov/uscert/bsi/articles/knowledge/principles/least-privilege). + This reasoning is that developers should exercise a wide range of dependency versions + in order to discover / fix problems before their users do, so tests need to pull the latest versions + of packages. - 1. `npm install-test` + 1. Follow the principle of least privilege in your [CI configuration](#ci-configuration). + This is particularly important since the lockfile is ignored. - 1. `npm pkg set` and `npm pkg delete` +1. If a project is a standalone CLI: - 1. `npm exec`, `npx` + 1. Developers may publish an `npm-shrinkwrap.json`. + Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility + for updating all the dependencies in time. Your users will not be able + to update them. If you expect your CLI to be used by other projects and defined + in their `package.json` or lockfile, do **not** use `npm-shrinkwrap.json` because it will + hinder dependency resolution for your consumers. - 1. `npm set-script` + 1. Developers should only run npm commands that treat the lockfile as + read-only (see [Lockfiles and commands](#lockfiles-and-commands)), except + when intentionally adding /removing a dependency. - 1. Only run commands that treat the lock file as read-only: + 1. Follow the principle of least privilege in your [CI configuration](#ci-configuration). - 1. To install a project and its dependencies, use [`npm - ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci). +1. If a project is an application: - 1. To run tests, run [`npm - install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test). + 1. Developers should declare and commit a lockfile to their repository. - 1. If you need to run a standalone CLI package from the registry, ensure the package is a part of - the dependencies defined in your project via the `package.json` file, prior to - being installed at build-time in your CI or otherwise automated environment. + 1. Developers should only run npm commands that treat the lockfile as + read-only (see [Lockfiles and commands](#lockfiles-and-commands)), except + when intentionally adding /removing a dependency. -1. In **non-privileged environments**, maintainers may **ignore** the lockfile. This is particularly useful in - situations where they want to exercise a wide range of dependency versions in order to discover / fix problems before - their users do. This is useful for maintainers of libraries and standalone CLI projects - without an `npm-shrinkwrap.json`. The reasoning is that many downstream users will use `npm install` to install a dependency, - so using floating versions in (non-privileged) tests can be beneficial. - - 1. If you run CI via GitHub Actions, a non-privileged environment is a workflow **without** access to GitHub secrets and with - non-write permissions defined, such as `permissions: read-all`, `permissions:`, `contents: none`, `contents: read`. - For more information about permissions, refer to the [official documentation](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). - You may install the [OpenSSF Scorecard Action](https://github.com/ossf/scorecard-action) - to flag non-read permissions on your project. - - 1. In a **non-privileged environment**, you may ignore the lockfile by running `npm install --no-package-lock`. - If you are not certain whether the environment you are running is privileged or not, reach out to your security team. + 1. If you need to run a standalone CLI package from the registry, ensure the package is a part of + the dependencies defined in your project via the `package.json` file, prior to + being installed at build-time in your CI or otherwise automated environment. ### Maintenance From 0d5e822a58f2aaac906e7225550810a10f36732d Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:32:41 +0000 Subject: [PATCH 22/28] update --- review/npm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/review/npm.md b/review/npm.md index 0f77b55..b3b1732 100644 --- a/review/npm.md +++ b/review/npm.md @@ -24,7 +24,7 @@ alternative. - [Use a Lockfile](#use-a-lockfile) * [Package-lock.json](#package-lockjson) * [npm-shrinkwrap.json](#shrinkwrapjson) - * [Lockfiles and commands](#lockfiles-and-commands) + - [Lockfiles and commands](#lockfiles-and-commands) + [Maintenance](#maintenance) * [Release](#release) + [Account](#account) @@ -244,7 +244,7 @@ and the command [`npm shrinkwrap`](https://docs.npmjs.com/cli/v8/commands/npm-shrinkwrap) must be run. -##### Lockfiles and commands +#### Lockfiles and commands Certain `npm` commmands treat the lockfiles as read-only, while others do not. From 893832de0c172ecd77dcae86946db8e2e62c6eb0 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:34:33 +0000 Subject: [PATCH 23/28] update --- review/npm.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/review/npm.md b/review/npm.md index b3b1732..e1b22ba 100644 --- a/review/npm.md +++ b/review/npm.md @@ -250,14 +250,14 @@ Certain `npm` commmands treat the lockfiles as read-only, while others do not. The following commands treat the lock file as read-only: -1. To install a project and its dependencies, use [`npm - ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci). +1. [`npm ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci), used to + install a project and its dependencies -1. To run tests, run [`npm - install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test). +1. [`npm install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test), + used to install a project and run tests. The following commands ***do not*** treat the lock file as read-only, may fetch / install -the unpinned dependencies and update the lockfiles: +unpinned dependencies and update the lockfiles: 1. `npm install`, `npm i`, `npm install -g` From 044fc7f389cae5130c4a553d17e03060124b0ad7 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:38:17 +0000 Subject: [PATCH 24/28] update --- review/npm.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/review/npm.md b/review/npm.md index e1b22ba..3f36fe1 100644 --- a/review/npm.md +++ b/review/npm.md @@ -251,7 +251,7 @@ Certain `npm` commmands treat the lockfiles as read-only, while others do not. The following commands treat the lock file as read-only: 1. [`npm ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci), used to - install a project and its dependencies + install a project and its dependencies, 1. [`npm install-ci-test`](https://docs.npmjs.com/cli/v8/commands/npm-install-ci-test), used to install a project and run tests. @@ -279,16 +279,17 @@ unpinned dependencies and update the lockfiles: create the manifest file. 1. To add a dependency to a manifest file, ***locally*** run [`npm - install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install). + install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install) + and commit the updated manifest to the repository. 1. Developers should declare and commit a lockfile for ***all*** their - projects. The reasoning is that this lockfile provides the - benefits listed in [Reproducible installation](#reproducible-installation) + projects. The reasoning is that this lockfile will provide of + [Reproducible installation](#reproducible-installation) by default for privileged environments (project developers' machines, CI, production or other environments with access to sensitive data, such as secrets, PII, write/push permission to the repository, etc). - When running tests locally, developers should locally use commands that treat lockfiles + When running tests locally, developers should use commands that treat a lockfile as read-only (see [Lockfiles and commands](#lockfiles-and-commands)), unless they are intentionally adding / removing a dependency. @@ -304,11 +305,9 @@ unpinned dependencies and update the lockfiles: calculator](https://semver.npmjs.com/) to help you define the ranges. 1. The lockfile `package-lock.json` ***should*** be ignored for tests running in CI - (e.g. via `npm install --no-package-lock`) ***and*** the CI environment should be ***non-privileged*** - by following the [principle of least privilege](https://www.cisa.gov/uscert/bsi/articles/knowledge/principles/least-privilege). - This reasoning is that developers should exercise a wide range of dependency versions - in order to discover / fix problems before their users do, so tests need to pull the latest versions - of packages. + (e.g. via `npm install --no-package-lock`). The reasoning is that developers should + exercise a wide range of dependency versions in order to discover / fix problems + before their users do, so tests need to pull the latest versions of packages. 1. Follow the principle of least privilege in your [CI configuration](#ci-configuration). This is particularly important since the lockfile is ignored. From 425571ebd6bc26c8f5c578752952929ed9b1c4f1 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:42:19 +0000 Subject: [PATCH 25/28] update --- review/npm.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/review/npm.md b/review/npm.md index 3f36fe1..9699f75 100644 --- a/review/npm.md +++ b/review/npm.md @@ -282,6 +282,10 @@ unpinned dependencies and update the lockfiles: install --save `](https://docs.npmjs.com/cli/v8/commands/npm-install) and commit the updated manifest to the repository. +1. If you need to run a standalone CLI package from the registry, ensure the package is a part of + the dependencies defined in your project via the `package.json` file, prior to + being installed at build-time in your CI or otherwise automated environment. + 1. Developers should declare and commit a lockfile for ***all*** their projects. The reasoning is that this lockfile will provide of [Reproducible installation](#reproducible-installation) @@ -321,7 +325,10 @@ unpinned dependencies and update the lockfiles: in their `package.json` or lockfile, do **not** use `npm-shrinkwrap.json` because it will hinder dependency resolution for your consumers. - 1. Developers should only run npm commands that treat the lockfile as + 1. In CI, only run npm commands that treat the lockfile as + read-only (see [Lockfiles and commands](#lockfiles-and-commands)). + + 1. Locally, developers should only run npm commands that treat the lockfile as read-only (see [Lockfiles and commands](#lockfiles-and-commands)), except when intentionally adding /removing a dependency. @@ -331,14 +338,13 @@ unpinned dependencies and update the lockfiles: 1. Developers should declare and commit a lockfile to their repository. - 1. Developers should only run npm commands that treat the lockfile as + 1. In CI, only run npm commands that treat the lockfile as + read-only (see [Lockfiles and commands](#lockfiles-and-commands)). + + 1. Locally, developers should only run npm commands that treat the lockfile as read-only (see [Lockfiles and commands](#lockfiles-and-commands)), except when intentionally adding /removing a dependency. - 1. If you need to run a standalone CLI package from the registry, ensure the package is a part of - the dependencies defined in your project via the `package.json` file, prior to - being installed at build-time in your CI or otherwise automated environment. - ### Maintenance It is important to update dependencies periodically, in particular when new From a47c8bec091d37b6849c2a5dc9091c9634ce4d12 Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:45:59 +0000 Subject: [PATCH 26/28] update --- review/npm.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/review/npm.md b/review/npm.md index 9699f75..ec6d19d 100644 --- a/review/npm.md +++ b/review/npm.md @@ -287,7 +287,7 @@ unpinned dependencies and update the lockfiles: being installed at build-time in your CI or otherwise automated environment. 1. Developers should declare and commit a lockfile for ***all*** their - projects. The reasoning is that this lockfile will provide of + projects. The reasoning is that this lockfile will provide the benefits of [Reproducible installation](#reproducible-installation) by default for privileged environments (project developers' machines, CI, production or other environments with access to sensitive data, @@ -309,9 +309,13 @@ unpinned dependencies and update the lockfiles: calculator](https://semver.npmjs.com/) to help you define the ranges. 1. The lockfile `package-lock.json` ***should*** be ignored for tests running in CI - (e.g. via `npm install --no-package-lock`). The reasoning is that developers should + (e.g. via `npm install --no-package-lock`). The reasoning is that CI tests should exercise a wide range of dependency versions in order to discover / fix problems - before their users do, so tests need to pull the latest versions of packages. + before the library users do, so tests need to pull the latest versions of packages. + + 1. Locally, developers should only run npm commands that treat the lockfile as + read-only (see [Lockfiles and commands](#lockfiles-and-commands)), except + when intentionally adding /removing a dependency. 1. Follow the principle of least privilege in your [CI configuration](#ci-configuration). This is particularly important since the lockfile is ignored. From 7ce831f4bfc013c76bc9f37410d02649cc0979cc Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:47:32 +0000 Subject: [PATCH 27/28] update --- review/npm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/review/npm.md b/review/npm.md index ec6d19d..ca51563 100644 --- a/review/npm.md +++ b/review/npm.md @@ -324,8 +324,8 @@ unpinned dependencies and update the lockfiles: 1. Developers may publish an `npm-shrinkwrap.json`. Remember that, by declaring an `npm-shrinkwrap.json`, you take responsibility - for updating all the dependencies in time. Your users will not be able - to update them. If you expect your CLI to be used by other projects and defined + for rapidly and consistently updating all the dependencies. Your users will not be able + to update or deduplicate them. If you expect your CLI to be used by other projects and defined in their `package.json` or lockfile, do **not** use `npm-shrinkwrap.json` because it will hinder dependency resolution for your consumers. From 42663ca2fc19355f0e89346a7c8f793f20b741dc Mon Sep 17 00:00:00 2001 From: laurentsimon Date: Fri, 1 Jul 2022 18:49:57 +0000 Subject: [PATCH 28/28] update --- review/npm.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/review/npm.md b/review/npm.md index ca51563..8341da7 100644 --- a/review/npm.md +++ b/review/npm.md @@ -327,7 +327,8 @@ unpinned dependencies and update the lockfiles: for rapidly and consistently updating all the dependencies. Your users will not be able to update or deduplicate them. If you expect your CLI to be used by other projects and defined in their `package.json` or lockfile, do **not** use `npm-shrinkwrap.json` because it will - hinder dependency resolution for your consumers. + hinder dependency resolution for your consumers: follow the recommendations as if your project + was a library. 1. In CI, only run npm commands that treat the lockfile as read-only (see [Lockfiles and commands](#lockfiles-and-commands)).