edx / edx-arch-experiments

A plugin to include applications under development by the architecture team at edx
GNU Affero General Public License v3.0
0 stars 3 forks source link

Prototype a way to review NPM lockfiles in PRs #355

Open timmc-edx opened 1 year ago

timmc-edx commented 1 year ago

When someone submits a PR with changes to Javascript dependencies, it generally involves changed to package.json (a set of dependencies and version constraints) as well as package-lock.json (the output of the dependency solver, as a lockfile). package.json is easy to review, but package-lock.json diffs can be huge, and manually reviewing them is generally infeasible.

This ticket is to create a way to review package-lock.json changes to prevent accidental mismatches from being committed. Malicious PRs are not in scope.

Acceptance criteria:

Notes:

jmbowman commented 1 year ago

I think npm ls --all --package-lock-only would let us detect mismatches without running npm ci first, but we should confirm that.

Syed-Ali-Abbas-Zaidi commented 1 year ago

Changes made to package.json but npm install has not been run since last change (which would update package-lock.json)

Hi @timmc-edx, Regarding the point where package.json is changed but package-lock.json is not updated, most repositories use npm ci, which already fulfills this acceptance criterion. Here is a working example.

However, if someone manually changes package-lock.json, it can create a mismatch, and npm ci will not be able to detect it. To identify this type of mismatch, we can use npm ls --all --package-lock-only. We should consider adding this step to our lockfile-check shared workflow. What do you think about this suggestion?

timmc-edx commented 1 year ago

Some experimentation:

So they're mostly equivalent, but that last one is a bit concerning; extraneous packages in the lockfile is exactly the kind of thing I'd want to catch. We can use the JSON output to get the actual list of problems, though! So the CI check should look something like this:

problems=$(npm ls --all --package-lock-only --json | jq '.problems[]?' -r)
if [[ -n "$problems" ]]; then
  echo "$problems"
  echo
  echo "Mismatch between package.json and package-lock.json. Please regenerate package lock file with 'npm install'."
  exit 1
fi

This still won't catch certain malicious edits (still researching that), but it should cover most well-intentioned mistakes.

Syed-Ali-Abbas-Zaidi commented 1 year ago

problems=$(npm ls --all --package-lock-only --json | jq '.problems[]?' -r) if [[ -n "$problems" ]]; then echo "$problems" echo echo "Mismatch between package.json and package-lock.json. Please regenerate package lock file with 'npm install'." exit 1 fi

We are planning to add the suggested step to this lockfile check workflow.