fix: split external dev dependencies into their own Renovate group - #1257
Merged
Conversation
The `renovate/stability-days` status check is computed per branch, not per package, so a single member still inside its minimum release age turns the whole grouped branch yellow and blocks automerge. With every external dependency in one group, that check is yellow most of the time. Split dev dependencies out of `external fixes` and `external major` into `external dev fixes` and `external dev major`. On helix-cli this halves the group size (44 runtime vs 16 dev at the root manifest), so each group reaches a fully-aged state far more often. Uses `matchDepTypes` rather than package names, so the split reads npm's own manifest sections and needs no maintenance as dependencies change. This is Renovate's documented grouping idiom. The two existing rules are left byte-for-byte unchanged. The new rules are appended after them, so they override only `groupName` and inherit `automerge`, `schedule` and `minimumReleaseAge` from the rule above. The catch-all rules deliberately keep no `matchDepTypes`, so anything that is not a devDependency -- runtime, optional and peer deps, npm `engines`, and every non-npm manager such as github-actions or dockerfile -- keeps its grouping and its 14-day minimum release age. The 14-day window itself is unchanged.
tripodsan
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits dev dependencies out of the two external Renovate groups, so each group is
smaller and the
renovate/stability-dayscheck can actually reach green.Stacked on #1256 — base is
fix-renovate-stability-days, notmain. Pleasemerge #1256 first; this PR's diff will then rebase down to just the two new rules.
The 14-day window is unchanged, and the two existing rules are left
byte-for-byte untouched.
Why
renovate/stability-daysis computed per branch, not per package. Any singlemember still inside its minimum release age turns the entire grouped branch
yellow (
lib/workers/repository/update/branch/index.ts):With every external dependency in one group, the odds of all of them being
simultaneously aged are poor, so the check is yellow most of the time and
automergenever fires. Smaller groups go quiet more often.This is the sibling of #1256. That PR fixes members that could never age
(
pin,digest); this one reduces how often a group contains a member thatmerely hasn't aged yet.
Why
matchDepTypesand not package namesmatchDepTypesreads npm's owndependencies/devDependenciesmanifestsections, so the split needs no maintenance as dependencies change — nothing to
update when a package is added. It is
Renovate's documented grouping idiom:
{ "packageRules": [ { "matchDepTypes": ["devDependencies"], "matchUpdateTypes": ["patch", "minor"], "groupName": "devDependencies (non-major)" } ] }Verified that the npm manager emits the plural manifest key as
depType(
devDependencies, notdevDependency— the singular is onlyprettyDepType,used for display), so these matchers hit:
lib/modules/manager/npm/extract/common/package-file.ts.Expected effect
On
adobe/helix-cli, the root manifest has 44 runtime vs 16 dev dependencies.Of the 14 packages currently batched in
helix-cli#2771, the split is
close to even:
Roughly halving group size means each branch is materially more likely to be
fully aged on any given Monday.
Runtime dependencies are where a supply-chain quarantine matters most, and they
keep the existing group name — so the group that ships code to production is the
one that stays conservative.
Nothing loses its quarantine
This is the part worth reviewing closely. The two catch-all rules deliberately
keep no
matchDepTypes, and the new rules are appended after them.Renovate evaluates all
packageRulesand merges matches, wherelater rules override earlier ones:
So a devDependency matches both the catch-all and the new rule, and the new rule
wins on
groupNameonly. It sets noautomerge,scheduleorminimumReleaseAge, so those are inherited unchanged from the rule above.Everything that is not a devDependency still matches only the catch-all and is
therefore unaffected — including cases an enumerated
matchDepTypeslist wouldhave silently dropped:
optionalDependenciesandpeerDependenciesengines(helix-cli has"engines": {"node": ">=18"})volta,resolutions,packageManager,overrides,pnpmgithub-actions,dockerfile,circleciand soon, which have no npm depType at all
An earlier draft of this change put
matchDepTypes: ["dependencies", "optionalDependencies", "peerDependencies"]on the runtime group. That wouldhave dropped all of the above out of both groups, losing their 14-day quarantine
and their grouping. Using an unrestricted catch-all plus a dev override avoids
that entirely.
Test plan
default.jsonis valid JSONrenovate-schema.jsonvia ajv — before and after, so no schema regression
depTypevalues are the plural manifest keys, againstRenovate's extractor source
packageRulesdocsexternal fixes/external majorrules unchanged (diff ispurely additive, +24/-0)
external fixes,external dev fixes,external major,external dev majorautomergeand the 14-day ageinherited from the catch-all, and that
engines/github-actions updatesstill land in the non-dev groups