Skip to content

ci: detect package.json dep/peerDep changes without a matching changeset#2627

Merged
colinaaa merged 3 commits into
mainfrom
feat/dep-changeset-check
May 14, 2026
Merged

ci: detect package.json dep/peerDep changes without a matching changeset#2627
colinaaa merged 3 commits into
mainfrom
feat/dep-changeset-check

Conversation

@upupming
Copy link
Copy Markdown
Collaborator

@upupming upupming commented May 14, 2026

Summary

Add a CI check that catches the case where a PR modifies a package's dependencies or peerDependencies but the changesets in that PR don't bump the affected package. Without this guard, the dep change lands on main and sits there until someone makes another change that triggers a release — silently shipping broken peer ranges and tripping the kind of npm hoist conflict that surfaced as #2624.

Concrete motivation

#2423 widened the @lynx-js/react-webpack-plugin peer range on @lynx-js/react-refresh-webpack-plugin, but the changeset only bumped @lynx-js/react, @lynx-js/react-webpack-plugin, and @lynx-js/react-rsbuild-plugin. The peer-range fix sat unreleased; npm install consumers continued to pull the old @lynx-js/react-refresh-webpack-plugin@0.3.5 with the narrow peer range, force a parallel @lynx-js/react-webpack-plugin@0.8.0 install, pin @lynx-js/template-webpack-plugin@0.10.9 at the top of node_modules next to nested 0.11.0 copies, and ultimately produce the build error tracked in #2624. The missed-changeset follow-up is #2626.

Running this new check against the #2423 state (locally, with --since=$(git rev-parse 1f4f1171^)) reproduces the catch:

The following packages changed `dependencies` or `peerDependencies` but no changeset bumps them:

  - @lynx-js/react-refresh-webpack-plugin  [peerDependencies]
    packages/webpack/react-refresh-webpack-plugin/package.json

Add a changeset (e.g. `pnpm changeset add`) bumping each affected package so the dependency change actually ships in the next release.

Exit code is non-zero — CI would have blocked the PR until either a changeset was added or the dep change was reverted.

What the check does

For each package.json modified relative to the PR's base ref:

  • Skip private: true packages (not published, so no release-time impact).
  • Skip files newly added in the PR (initial release is a separate workflow).
  • Diff dependencies and peerDependencies against the base. devDependencies is intentionally ignored — those don't affect downstream consumers.
  • If the diff is non-empty and the changeset status report does not list the package, flag it.
  • Print all flagged packages with the field that changed, then exit non-zero.

isShallowEqual is tolerant of key reordering and ignores anything outside the two examined fields, so changes that don't actually move the resolution surface (formatting, version-field re-sorts via pnpm meta-updater) don't trip the check.

Integration

Inserted in the existing code-style-check job, immediately after Changeset Heading Check. The script's own unit-test file is also exercised in the same step via node --test, so the helper logic gets regression coverage without spinning up a separate runner.

Test plan

  • node --test .github/scripts/check-dep-changes-have-changeset.test.cjs — 10 cases, all pass (key reorder tolerance, dev-deps-only skip, private-pkg skip, newly-added-pkg skip, multi-package flagging, etc.)
  • Running the script against the #2423 state reproduces the catch and exits non-zero
  • Running against this branch itself returns "all good" (no dep changes here)
  • CI pass on this PR

Summary by CodeRabbit

  • Chores
    • Enhanced internal validation processes for dependency changes during the development workflow.

Note: This release includes internal infrastructure improvements with no direct impact to end-user functionality.

Review Change Stack

Add `.github/scripts/check-dep-changes-have-changeset.cjs` that compares
the changeset status report against the set of package.json files whose
`dependencies` or `peerDependencies` actually changed in the PR. Any
non-private package with a dep/peer-dep diff but no changeset bump is
reported with an actionable message and the script exits non-zero.

Hook it into the existing `code-style-check` job after the other
changeset checks, and run the script's own unit tests in the same step.

Verified locally: re-running this check against the state of PR #2423
(where `react-refresh-webpack-plugin/package.json` had its peer range
widened but the changeset bumped only three other packages) reproduces
the catch — the script flags `@lynx-js/react-refresh-webpack-plugin`
and fails. With this check in place, the omission would have been
surfaced at review time.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 14, 2026

⚠️ No Changeset found

Latest commit: e437712

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

📝 Walkthrough

Walkthrough

This PR adds a new dependency changeset validation system: a Node.js CLI script that scans package.json changes between git refs, compares dependency maps, and ensures packages with dependency updates have corresponding changesets. The script is then integrated as a new CI workflow step to enforce this validation.

Changes

Dependency Changeset Validation

Layer / File(s) Summary
Helper utilities and core validation logic
.github/scripts/check-dep-changes-have-changeset.cjs
Implements git history queries (gitShow, changedPackageJsons), object comparison (isShallowEqual), and the main findMissingChangesets function that detects when dependency or peerDependency maps change without a corresponding changeset. Exports the two main functions for reuse.
CLI orchestration and workflow integration
.github/scripts/check-dep-changes-have-changeset.cjs, .github/workflows/test.yml
Implements the main() CLI function that orchestrates reading the changeset status file, computing missing changesets across changed manifests, and reporting detailed errors; integrates the script into the test workflow as a new "Dependency Changeset Check" step after the existing "Changeset Heading Check".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • lynx-family/lynx-stack#2117: Updates peerDependencies in package manifests, which this PR's new CI script is designed to detect and require changesets for.
  • lynx-family/lynx-stack#1992: Updates package peerDependencies and adds a corresponding changeset, exemplifying the pattern this PR enforces.
  • lynx-family/lynx-stack#2433: Updates the test.yml workflow to generate .changeset-status.json, which this PR's validation step consumes.

Suggested reviewers

  • colinaaa
  • PupilTong

Poem

🐰 A rabbit hops through Git history's trees,
Checking each package with ease and with glee,
If dependencies shift without changesets near,
The validation script catches it clear.
No stray updates escape the CI's keen eye! 📋✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a CI check to detect package.json dependency/peerDependency changes without matching changesets.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dep-changeset-check

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 14, 2026

Merging this PR will degrade performance by 8.34%

❌ 1 regressed benchmark
✅ 80 untouched benchmarks
⏩ 26 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 43.1 ms 47 ms -8.34%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/dep-changeset-check (e437712) with main (bdbcf79)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React MTF Example

#1304 Bundle Size — 207.46KiB (0%).

e437712(current) vs bdbcf79 main#1294(baseline)

Bundle metrics  no changes
                 Current
#1304
     Baseline
#1294
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 192 192
No change  Duplicate Modules 77 77
No change  Duplicate Code 44.38% 44.38%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1304
     Baseline
#1294
No change  IMG 111.23KiB 111.23KiB
No change  Other 96.23KiB 96.23KiB

Bundle analysis reportBranch feat/dep-changeset-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React Example with Element Template

#438 Bundle Size — 197.79KiB (0%).

e437712(current) vs bdbcf79 main#428(baseline)

Bundle metrics  Change 2 changes
                 Current
#438
     Baseline
#428
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 80(-1.23%) 81
No change  Duplicate Modules 23 23
Change  Duplicate Code 40.31%(+0.05%) 40.29%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#438
     Baseline
#428
No change  IMG 145.76KiB 145.76KiB
No change  Other 52.03KiB 52.03KiB

Bundle analysis reportBranch feat/dep-changeset-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

Web Explorer

#9746 Bundle Size — 901.38KiB (0%).

e437712(current) vs bdbcf79 main#9736(baseline)

Bundle metrics  Change 1 change
                 Current
#9746
     Baseline
#9736
No change  Initial JS 45.06KiB 45.06KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 228(-0.44%) 229
No change  Duplicate Modules 11 11
No change  Duplicate Code 27.22% 27.22%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9746
     Baseline
#9736
No change  JS 497.1KiB 497.1KiB
No change  Other 402.06KiB 402.06KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch feat/dep-changeset-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

@upupming upupming marked this pull request as ready for review May 14, 2026 03:40
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/check-dep-changes-have-changeset.cjs:
- Around line 55-60: The try/catch that parses package.json (parsing into curPkg
and basePkg from cur and base) should fail-fast instead of silently continuing;
in the catch block capture the thrown error and the filename being parsed and
terminate with a non-zero exit (e.g., throw or process.exit(1)) while logging a
clear message containing the filename and error details so a malformed
package.json cannot bypass the CI gate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2d88e61f-86e6-45c8-b787-8a75d4b330cc

📥 Commits

Reviewing files that changed from the base of the PR and between bdbcf79 and e437712.

📒 Files selected for processing (2)
  • .github/scripts/check-dep-changes-have-changeset.cjs
  • .github/workflows/test.yml

Comment thread .github/scripts/check-dep-changes-have-changeset.cjs
@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React Example

#8171 Bundle Size — 236.51KiB (0%).

e437712(current) vs bdbcf79 main#8161(baseline)

Bundle metrics  no changes
                 Current
#8171
     Baseline
#8161
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 197 197
No change  Duplicate Modules 80 80
No change  Duplicate Code 44.87% 44.87%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8171
     Baseline
#8161
No change  IMG 145.76KiB 145.76KiB
No change  Other 90.75KiB 90.75KiB

Bundle analysis reportBranch feat/dep-changeset-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React External

#1286 Bundle Size — 693.04KiB (0%).

e437712(current) vs bdbcf79 main#1276(baseline)

Bundle metrics  no changes
                 Current
#1286
     Baseline
#1276
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1286
     Baseline
#1276
No change  Other 693.04KiB 693.04KiB

Bundle analysis reportBranch feat/dep-changeset-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

@colinaaa colinaaa merged commit 46d3aa3 into main May 14, 2026
53 of 54 checks passed
@colinaaa colinaaa deleted the feat/dep-changeset-check branch May 14, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants