You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The install-and-test job in unit.yml runs pnpm dedupe --check after install. Dependabot regenerates pnpm-lock.yaml during updates but never runs pnpm dedupe — Dependabot has no post-update hook (known upstream limitation, e.g. dependabot/dependabot-core#9763). Group bump PRs therefore fail CI whenever the update leaves a dedupable transitive duplicate.
Example: #2236 failed with ERR_PNPM_DEDUPE_CHECK_ISSUES (lru-cache 11.5.2 -> 11.5.3 under path-scurry) and needed a manual dedupe commit (#2240). Every future Dependabot npm PR can hit this.
Recommended approach: dedupe main, don't push to PR branches
Feedback on the original proposal raised a fair concern: pushing from CI to the Dependabot branch requires a contents: write token in a job that executes untrusted dependency code (pnpm dedupe triggers pnpm install, which runs postinstall/prepare lifecycle scripts). A compromised package in the bump could abuse that token to push to any branch, including main.
So instead of auto-pushing to PR branches:
Make --check non-blocking for Dependabot PRs in install-and-test — warn-only gated on github.actor == 'dependabot[bot]' (e.g. continue-on-error or || echo "::warning::"). Human PRs keep the strict check.
Add a lockfile-maintenance job on main (post-merge or scheduled) that runs pnpm dedupe and opens — or updates — a "Dedupe lockfile" PR when drift exists. The write token then only ever operates on first-party code on main, never on PR code.
Trade-off: main tolerates temporary duplicate-dep drift between merges, but duplicated transitive versions are lockfile hygiene, not a correctness issue — and main converges back every time the maintenance PR lands.
Fallback if auto-push to the bot branch is preferred
If a job must push to the Dependabot branch, harden it:
pnpm dedupe --ignore-scripts — removes the lifecycle-script execution vector
Only commit if git status --porcelain shows pnpm-lock.yaml alone modified
git push origin HEAD:${{ github.event.pull_request.head.ref }} — push to exactly that ref
concurrency group per PR to avoid racing Dependabot force-pushes
Prefer a fine-grained token scoped to that branch over repo-wide contents: write
A middle option that avoids touching the bot's ref: CI opens a fix PR into the Dependabot branch (the manual flow used in #2240). CI only ever creates new branches; a human merges.
Alternatives considered
pull_request_target for the auto-fix — elevated privileges on PR code; strictly worse than the options above.
Migrate to Renovate — supports postUpgradeTasks natively, but replaces the whole Dependabot setup including the tuned grouping/cooldown config in dependabot.yml.
The
install-and-testjob inunit.ymlrunspnpm dedupe --checkafter install. Dependabot regeneratespnpm-lock.yamlduring updates but never runspnpm dedupe— Dependabot has no post-update hook (known upstream limitation, e.g. dependabot/dependabot-core#9763). Group bump PRs therefore fail CI whenever the update leaves a dedupable transitive duplicate.Example: #2236 failed with
ERR_PNPM_DEDUPE_CHECK_ISSUES(lru-cache 11.5.2 -> 11.5.3underpath-scurry) and needed a manual dedupe commit (#2240). Every future Dependabot npm PR can hit this.Recommended approach: dedupe
main, don't push to PR branchesFeedback on the original proposal raised a fair concern: pushing from CI to the Dependabot branch requires a
contents: writetoken in a job that executes untrusted dependency code (pnpm dedupetriggerspnpm install, which runspostinstall/preparelifecycle scripts). A compromised package in the bump could abuse that token to push to any branch, includingmain.So instead of auto-pushing to PR branches:
--checknon-blocking for Dependabot PRs ininstall-and-test— warn-only gated ongithub.actor == 'dependabot[bot]'(e.g.continue-on-erroror|| echo "::warning::"). Human PRs keep the strict check.main(post-merge or scheduled) that runspnpm dedupeand opens — or updates — a "Dedupe lockfile" PR when drift exists. The write token then only ever operates on first-party code onmain, never on PR code.Trade-off:
maintolerates temporary duplicate-dep drift between merges, but duplicated transitive versions are lockfile hygiene, not a correctness issue — andmainconverges back every time the maintenance PR lands.Fallback if auto-push to the bot branch is preferred
If a job must push to the Dependabot branch, harden it:
pnpm dedupe --ignore-scripts— removes the lifecycle-script execution vectorgit status --porcelainshowspnpm-lock.yamlalone modifiedgit push origin HEAD:${{ github.event.pull_request.head.ref }}— push to exactly that refconcurrencygroup per PR to avoid racing Dependabot force-pushescontents: writeA middle option that avoids touching the bot's ref: CI opens a fix PR into the Dependabot branch (the manual flow used in #2240). CI only ever creates new branches; a human merges.
Alternatives considered
pull_request_targetfor the auto-fix — elevated privileges on PR code; strictly worse than the options above.postUpgradeTasksnatively, but replaces the whole Dependabot setup including the tuned grouping/cooldown config independabot.yml.Related: #2236, #2240
Important
Internal only — this issue is maintained by the core team and is not accepting external contributions.