Skip to content
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

Prototype a way to review NPM lockfiles in PRs #355

Open
2 tasks
timmc-edx opened this issue Jul 13, 2023 · 4 comments
Open
2 tasks

Prototype a way to review NPM lockfiles in PRs #355

timmc-edx opened this issue Jul 13, 2023 · 4 comments
Assignees
Labels
epic For issues at the epic level

Comments

@timmc-edx
Copy link
Member

timmc-edx commented Jul 13, 2023

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:

  • A GitHub workflow added to some repo that will detect at least the following kinds of errors:
    • Changes made to package.json but npm install has not been run since last change (which would update package-lock.json)
    • Well-intentioned manual editing of package-lock.json
  • A ticket created for generalizing this to other repos (make reusable workflow in openedx/.github and use it from other repos)

Notes:

  • GitHub has introduced a "rich view" for package files that summarizes their changes, which is helpful but not a complete solution (as adding one entry to package.json can add 60 entries to package-lock.json).
  • npm ci will error if there are certain kinds of mismatches between the two files
  • npm ls will detect certain kinds of mismatches between package-lock.json and the node_modules directory, after running npm ci
@jmbowman
Copy link

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

@jmbowman jmbowman added this to FED-BOM Jul 14, 2023
@jmbowman jmbowman moved this to Todo in FED-BOM Jul 14, 2023
@abdullahwaheed abdullahwaheed moved this from Todo to In Progress in FED-BOM Jul 19, 2023
@Syed-Ali-Abbas-Zaidi
Copy link

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
Copy link
Member Author

timmc-edx commented Jul 20, 2023

Some experimentation:

  • Changing the name or version of something in the packages dict of the lockfile
    • ✔️ Caught by npm ci --dry-run
    • ✔️ Caught by npm ls --all --package-lock-only
  • Adding a package to package.json
    • ✔️ Caught by npm ci --dry-run
    • ✔️ Caught by npm ls --all --package-lock-only
  • Changing the version number of a package in package.json
    • ✔️ Caught by npm ci --dry-run
    • ✔️ Caught by npm ls --all --package-lock-only
  • Deleting a package from package.json, or adding it to package-lock.json (e.g. "@commitlint/cli": "17.6.6" in frontend-app-profile)
    • ❌ Missed by npm ci --dry-run
    • ❌ Sort of caught by npm ls --all --package-lock-only but no exit code is generated.

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.

@abdullahwaheed abdullahwaheed moved this from In Progress to Todo in FED-BOM Aug 3, 2023
@Syed-Ali-Abbas-Zaidi
Copy link

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.

@abdullahwaheed abdullahwaheed moved this from Todo to In Progress in FED-BOM Aug 24, 2023
@abdullahwaheed abdullahwaheed added the epic For issues at the epic level label Aug 24, 2023
This was referenced Aug 31, 2023
This was referenced Aug 31, 2023
abdullahwaheed added a commit to openedx/stylelint-config-edx that referenced this issue Sep 6, 2023
Renamed `lockfileversion-check-v3` to `lockfile-check` in lockfile
version file.
# Ticket

[Prototype a way to review NPM lockfiles in
PRs](edx/edx-arch-experiments#355)

---------

Co-authored-by: Abdullah Waheed <[email protected]>
@abdullahwaheed abdullahwaheed moved this from In Progress to Author Team Review in FED-BOM Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic For issues at the epic level
Projects
Status: Author Team Review
Development

No branches or pull requests

5 participants