drainpipe icon indicating copy to clipboard operation
drainpipe copied to clipboard

Add support for package-lock.json and yarn.lock diffs posted to PRs

Open Copilot opened this issue 4 months ago • 10 comments

resolves: #476

Overview

This PR adds support for package-lock.json and yarn.lock diffs to be posted to Pull Requests, similar to the existing composer.lock diff functionality. When a PR includes changes to these lock files, markdown table-formatted changes will be posted as sticky comments on the PR.

Implementation

GitHub Actions (Security Workflow)

The Security workflow now generates and posts package-lock.json and yarn.lock diffs alongside composer.lock diffs:

  • Uses diff-lockfiles npm package with --format markdown to generate markdown table diffs for package-lock.json (matching the composer.lock table format)
  • Uses git-based diff approach for yarn.lock (as there is no mature CLI tool for yarn.lock diffs comparable to diff-lockfiles)
  • Posts diffs as sticky comments with HTML markers (<!-- package-lock-diff --> and <!-- yarn-lock-diff -->) for easy updating
  • Only generates diffs when the respective lock files exist in the repository
  • Automatically downloads diff-lockfiles via npx when needed

GitLab CI (ComposerLockDiff)

The ComposerLockDiff job now also handles package-lock.json and yarn.lock:

  • Triggers on changes to composer.json, composer.lock, package-lock.json, or yarn.lock
  • Installs Node.js and npm when package-lock.json is present
  • Uses diff-lockfiles --format markdown for package-lock.json (table format)
  • Generates yarn.lock diffs using git diff with filtering for package changes
  • Adds both package lock and yarn lock diffs to merge request descriptions with proper HTML comment markers

Task (test:security)

The security task now includes additional commands for package-lock.json and yarn.lock:

  • Checks for package-lock.json existence before running
  • Uses npx diff-lockfiles --format markdown to compare the base branch to HEAD for package-lock.json (outputs markdown table)
  • Checks for yarn.lock existence and uses git diff with grep filtering for yarn.lock
  • Gracefully handles errors (e.g., version format differences, missing tools)
  • Outputs to configurable markdown files via package_lock_diff and yarn_lock_diff parameters

Error Handling

As noted in the issue, diff-lockfiles can encounter issues with different lockfile version formats. The implementation handles this gracefully:

  • Uses || true to prevent task failures on errors
  • Falls back to creating empty diff files when errors occur
  • Checks for npx availability before attempting to run
  • Git-based yarn.lock diff handles errors gracefully

Example Output

When a PR modifies package-lock.json or yarn.lock, reviewers will see sticky comments showing:

  • Which packages were added, updated, or removed
  • Old and new version numbers for changed packages
  • Node module dependency changes formatted as markdown tables for package-lock.json (similar to composer.lock), and diff code blocks for yarn.lock

Testing

All modified YAML files have been validated for:

  • YAML syntax correctness
  • Shell script syntax validity
  • Task schema compliance

Closes #476


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot avatar Oct 10 '25 02:10 Copilot

@copilot Let's also include yarn.lock diffs with this.

mrdavidburns avatar Oct 10 '25 19:10 mrdavidburns

@copilot Let's also include yarn.lock diffs with this.

Added yarn.lock diff support in commit 0d8e0d6. The implementation uses a git-based diff approach since there isn't a mature npm package for yarn.lock diffs comparable to diff-lockfiles for package-lock.json. The diff shows added/removed packages and version changes in a code block format.

Copilot avatar Oct 10 '25 19:10 Copilot

Confirming that this is working on a project that had a node package update.

image

mrdavidburns avatar Oct 10 '25 21:10 mrdavidburns

@copilot Update this pull request so that it rendesr the package-lock.json and yarn.lock diff as a table the same way we're displaying composer.lock diff?

image

mrdavidburns avatar Oct 10 '25 21:10 mrdavidburns

@copilot make package-lock.json and yarn.lock ddiff render as a table. Similar to how our composer.lock diff is displayed. It looks like you can use this command diff-lockfiles --format markdown HEAD~1 HEAD example:

Composer Lock Diff

Production Changes From To Compare
laravel/prompts v0.3.6 v0.3.7 ...
lullabot/drainpipe v3.14.2 ada570a ...
psy/psysh v0.12.10 v0.12.12 ...
symfony/console v7.3.3 v7.3.4 ...
symfony/dependency-injection v7.3.3 v7.3.4 ...
symfony/process v7.3.3 v7.3.4 ...
symfony/string v7.3.3 v7.3.4 ...
symfony/var-dumper v7.3.3 v7.3.4 ...
symfony/var-exporter v7.3.3 v7.3.4 ...
Dev Changes From To Compare
lullabot/drainpipe-dev v3.14.2 2de306d ...
myclabs/deep-copy 1.13.3 1.13.4 ...
phpdocumentor/reflection-docblock 5.6.2 5.6.3 ...
phpspec/prophecy v1.22.0 v1.23.0 ...
phpstan/phpdoc-parser 2.2.0 2.3.0 ...
phpstan/phpstan 2.1.21 2.1.31
phpunit/php-code-coverage 11.0.10 11.0.11 ...
phpunit/phpunit 11.5.27 11.5.42 ...
sebastian/comparator 6.3.1 6.3.2 ...
sebastian/exporter 6.3.0 6.3.2 ...
sebastian/recursion-context 6.0.2 6.0.3 ...
sebastian/type 5.1.2 5.1.3 ...
sirbrillig/phpcs-variable-analysis v2.12.0 v2.13.0 ...
slevomat/coding-standard 8.20.0 8.22.1 ...
squizlabs/php_codesniffer 3.13.2 3.13.4 ...
symfony/browser-kit v7.3.0 v7.3.2 ...
symfony/dom-crawler v7.3.1 v7.3.3 ...
symfony/phpunit-bridge v7.3.1 v7.3.4 ...
vincentlanglet/twig-cs-fixer 3.9.0 3.10.0 ...

mrdavidburns avatar Oct 10 '25 22:10 mrdavidburns

@mrdavidburns the original issue says to find an existing NPM package to do this. I found https://github.com/Simek/yarn-lock-changes for example (no idea if it's good or not). Did you find anything specific that led you to creating our own code to do this?

If there is some fatal flaw in upstream libraries, I think we could give a gift to ourselves by:

  1. Not inlining so much logic in github workflows.
  2. Create our own separate upstream projects for each ecosystem (a JS one for yarn, another for npm, etc), that Drainpipe can then recommend or even require.

deviantintegral avatar Oct 14 '25 15:10 deviantintegral

@deviantintegral It should be using diff-lockfiles. https://github.com/Lullabot/drainpipe/pull/968/files#diff-6f8ab6205f52df2a5cd455cbb03da4c4bd91f6edc7eaf6a25d1dc5a4b219f615R33

It looks like Github Copilot went rouge and decided to do a lot of the diff'ing itself instead of using that package. Let's give it another chance to correct that. I'll create a new comment to see if we can get it to use that package correctly.

mrdavidburns avatar Oct 14 '25 15:10 mrdavidburns

@copilot Please update this pull request to use https://github.com/Simek/yarn-lock-changes for yarn.lock diff.

mrdavidburns avatar Oct 14 '25 16:10 mrdavidburns

Is it reasonable rather than updating the PR description, to use a sticky pull request comment action instead? I tried to advocate for that before because of multiple issues with updating the PR descriptions, or preventing editing it while someone else might be editing the description, which can be fairly common when creating a new PR.

davereid avatar Oct 28 '25 19:10 davereid

Yes, given that there's no locking on pull request descriptions, I think we should never automate changes to them unless a bot is supposed to entirely own it (like renovate does).

deviantintegral avatar Oct 30 '25 17:10 deviantintegral