Description
Some of the assets use tools sourced from the npm software registry.
At the moment, we are not controlling the versions of these tools.
Current approach
These tools are currently installed via either of the following methods:
npx <pkg>
This approach has the following behaviors of interest:
https://docs.npmjs.com/cli/v8/commands/npx#description
If any requested packages are not present in the local project dependencies, then they are installed to a folder in the npm cache, which is added to the PATH environment variable in the executed process.
Package names provided without a specifier will be matched with whatever version exists in the local project. Package names with a specifier will only be considered a match if they have the exact same name and version as the local dependency.
This means that projects which are not doing dependency management via package.json
/ package-lock.json
will use the version:
- Whatever happens to be present in the local cache
- The latest available version if it is not already present
Problems
- A different version of the tool may be used on the contributor's machine than on the CI runner, resulting in confusing failures.
- The project is immediately subjected to disruption or breakage resulting from a release of the tool.
npm install --global <pkg>
The latest available version of the package is used.
This is used only in a few non-Task based workflows.
Problems
- The project is immediately subjected to disruption or breakage resulting from a release of the tool.
Possible solutions
These are approaches for ensuring the same tool version will be used on the contributor and CI machines for projects which are not currently doing dependency management via package.json
/ package-lock.json
:
Use package.json
+ package-lock.json
The installation instructions for the "template" asset would include this command:
npm install --save-dev <pkg>@<version>
This will generate package.json
and package-lock.json
files if they don't already exist in the project, so there is no need to instruct the installer to run an npm init
command before that.
The tool would be installed and executed in the asset via these commands:
npm install
npx <pkg>
npm install
will install all dependencies specified inpackage.json
. There is no way to avoid this (https://github.com/npm/rfcs/pull/364
).- The
npm install
command will error if the project does not contain npm metadata files. This means the assets that use this approach can not be also used in projects where it was determined that the benefits of managed dependencies don't outweigh the harm of adding two additional files to the repo. So a separate version of the workflows would need to be preserved for that use case.
Pros
- Dependabot PRs
- Vulnerability alerts
- Separates dependency management from the asset contents (i.e., no need to mess with the taskfile or workflow on every update)
- Matches how we are already managing Python dependencies (
pyproject.toml
+poetry.lock
)
Cons
- Adds two additional files in the repo root
npx <pkg>@<version>
The tool would be installed and executed via this command:
npx <pkg>@<version>
Pros
- Most simple solution.
- Gives the option of unmanaged updates within a version range (e.g.,
^1.2.3
,~1.2.3
)
Cons
- Does not give access to Dependabot updates, resulting in the use of outdated versions and difficult large version jumps when we are forced to update.