-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrenovate.json5
More file actions
216 lines (206 loc) · 12.2 KB
/
Copy pathrenovate.json5
File metadata and controls
216 lines (206 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Dependency automation for this repo (issue #54). Renovate, not Dependabot:
// several of this project's dependency decisions are deliberate HOLDS whose
// reasoning lives in CLAUDE.md prose, and Dependabot's `ignore` entries cannot
// express most of them. Everything below exists to stop a bot from cheerfully
// re-proposing, every week, the exact bump this project has already decided
// against - and to make the reason travel with the proposal when there is one.
//
// The Renovate GitHub App was enabled on 2026-07-30 with "Automated PRs",
// "Require config file" and "Create onboarding PRs". Two consequences worth
// knowing: "Require config file" means Renovate does NOTHING, silently, if this
// file is absent or unparseable from the DEFAULT branch - so validate edits, and
// never let a broken config read as "no updates available". And onboarding PRs
// are moot while this file exists, since onboarding only fires with no config.
// Validate any edit with `renovate-config-validator` (run it from OUTSIDE the
// project root - a bare `npx` here fails with `EBADDEVENGINES`).
//
// `dependencyDashboardApproval` is deliberately NOT set. It would require ticking
// a box per update before a PR appears, which re-imposes scan-only behaviour at
// the config layer and would quietly defeat the app's "Automated PRs" setting.
// PRs are wanted; what is not wanted is anything MERGING unread - see `automerge`.
//
// THE pnpm INTERACTION, which is the subtle part.
// This workspace relies on pnpm 11's built-in release-age cooldown - there is no
// `minimumReleaseAge` line in pnpm-workspace.yaml, the guard is a pnpm default.
// When pnpm is asked to install something newer than that cooldown allows it
// does not fail; it writes a `minimumReleaseAgeExclude:` bypass into
// pnpm-workspace.yaml, which is how `vue-tsc@3.3.8` once silently waived the
// guard. A dependency bot is a machine for producing exactly that situation.
// So `minimumReleaseAge` is declared HERE, explicitly, at a value comfortably
// above pnpm's default: Renovate must never open a PR for a release pnpm would
// want a bypass for. Declaring it also means a future pnpm changing its default
// cannot move this repo's floor silently.
// If `minimumReleaseAgeExclude:` ever appears in a Renovate PR's diff, that PR
// is wrong - do not merge it, fix the age rule instead.
{
$schema: "https://docs.renovatebot.com/renovate-schema.json",
extends: [
"config:recommended",
// Pin every GitHub Action to a commit SHA rather than a moving tag, and keep
// the `# vX.Y.Z` comment beside it updated. .github/workflows/verify.yml is
// already written that way by hand; this makes it the rule for anything
// added later, so the choice cannot drift action-by-action.
"helpers:pinGitHubActionDigests",
],
// See the pnpm interaction above. This is a floor, not a preference.
minimumReleaseAge: "3 days",
// The central invariant here is byte-exactness against captured fixtures, and
// a green CI run is evidence of consistency, not of a bump being *correct*
// (`pnpm run verify` does not exercise every dependency - see the js-beautify
// note in pnpm-workspace.yaml). Nothing merges unread.
automerge: false,
dependencyDashboard: true,
// Seattle. Without this the schedule below is UTC, i.e. "before 6am Monday"
// fires around midnight Sunday local - which reads as a bot that runs at
// random times.
timezone: "America/Los_Angeles",
// One weekly batch instead of a trickle. To pull a run forward without editing
// this, tick the "Check this box to trigger a request for Renovate to run
// again" checkbox on the dependency dashboard issue.
schedule: ["before 6am on monday"],
// Now that PRs actually arrive unattended, cap the burst. The first run after
// enabling the app sees every pending update at once; without a limit that is
// a dozen PRs in one morning, each triggering a ~4 minute CI run.
prConcurrentLimit: 3,
prHourlyLimit: 2,
// Renovate's `lockFileMaintenance` is automated `pnpm up` for the lockfile, and
// that is the one dependency operation this repo has measured as harmful:
// re-resolving the ~22 surrounding transitive packages triggered
// `TS2321: Excessive stack depth comparing types ... 'UserConfig'` in
// vite.config.ts, while installing the SAME target versions directly did not.
// CLAUDE.md's "prefer targeted `pnpm add` over `pnpm up`" is exactly this.
// Off by default; pinned off explicitly so it cannot get switched on as tidying.
lockFileMaintenance: { enabled: false },
// Security fixes must not wait for the weekly window. Without this block a CVE
// fix could sit ~10 days: up to 3 for the age floor, then up to 7 for Monday.
//
// NOTE THE AGE VALUE, which is not zero and must not be. pnpm 11 refuses
// anything younger than 24h without writing a `minimumReleaseAgeExclude:`
// bypass into pnpm-workspace.yaml, so a same-day security PR would reintroduce
// precisely the hazard the top-of-file comment exists to prevent. 25 hours
// clears pnpm's floor with an hour to spare and drops 3 days to ~1.
vulnerabilityAlerts: {
schedule: [],
minimumReleaseAge: "25 hours",
prBodyNotes: [
'Security update - this bypassed the weekly schedule deliberately. Still read it: `brace-expansion`\'s advisory carries a flat `<=5.0.7` range, so `pnpm audit` flags a version that already has the fix. "The audit is red" is not by itself a reason to take a bump here.',
],
},
// GitHub's own advisories miss ecosystem-only reports; OSV catches more.
osvVulnerabilityAlerts: true,
packageRules: [
{
// The ONE automerge exception (#62), and it is narrow on purpose.
//
// Why this category and nothing else: a digest re-pin moves a SHA and the
// `# vX.Y.Z` comment beside it, together, and there is nothing else in the
// diff to read. It also recurs forever. Reviewing it by hand teaches
// nobody anything and trains the habit of skimming bot PRs, which is worse
// than automating the boring case.
//
// Why it is safe NOW and was not on 2026-07-30 morning: ruleset `EJ` makes
// `verify` a required check on `main` with `bypass_actors: []` AND
// `strict_required_status_checks_policy: true`. So an automerged PR cannot
// land red, and cannot land having been tested against a different `main`
// than the one it merges into. Both of those had to be true; the second
// arrived last and was the actual blocker.
//
// `platformAutomerge` hands the merge to GitHub's own auto-merge so the
// required check gates it, rather than Renovate polling and merging itself.
//
// If branch protection is ever loosened - bypass actors added, `verify`
// dropped, strict turned off - THIS RULE MUST GO WITH IT. It is not
// independently safe.
matchManagers: ["github-actions"],
matchUpdateTypes: ["digest", "pin", "pinDigest"],
automerge: true,
automergeType: "pr",
platformAutomerge: true,
},
{
// Everything below stays manual, and the global `automerge: false` above is
// the default for anything not named here. The load-bearing reason is that
// `pnpm run verify` proves the repo is CONSISTENT, not that a bump is
// CORRECT - and this repo has the counterexample on record: pako 3.0.0
// flipped `legacyHash` to false, which passes a green suite while silently
// breaking the codec's byte-exactness, and the resulting wrong belief
// survived about a year. Version bumps of real dependencies get read.
//
// THE ONE THAT MATTERS MOST. Without it a bot proposes 6.0.3 -> 7.x every
// single week and someone re-derives the refusal every time (see #48, #52).
// TypeScript 7 exposes no programmatic API yet, the official migration is
// a dual-install alias, and vue-tsc/Volar cannot type-check .vue against
// it. Revisit at 7.1 deliberately, by hand.
matchPackageNames: ["typescript"],
enabled: false,
},
{
// The codec's byte-exactness rests on `{ level: 9, legacyHash: true }`.
// `legacyHash` is a pako EXTENSION with no zlib-API contract, from a
// library that already flipped that default inside a single major (2.2.0
// added it defaulting true, 3.0.0 flipped it false). A pako bump is a
// codec change until proven otherwise.
matchPackageNames: ["pako"],
minimumReleaseAge: "14 days",
automerge: false,
prBodyNotes: [
"**Read `src/codec/deflate.ts` and the pako table in CLAUDE.md before merging.** Deflate must stay madler-zlib-compatible at level 9 and byte-exact against all 9 fixtures. `test/deflate.spec.ts` has a block that fails by name if `legacyHash` is dropped, renamed or re-defaulted - do not silence it by editing a fixture.",
],
},
{
// @cloudflare/vitest-pool-workers hard-pins an exact wrangler. Split PRs
// cannot resolve, so these two only ever move together.
matchPackageNames: ["wrangler", "@cloudflare/vitest-pool-workers"],
groupName: "cloudflare worker toolchain",
prBodyNotes: [
"**Regenerate the worker types on this branch BEFORE merging** - this PR cannot go green without it. A wrangler bump moves `workerd`, and `wrangler types --check` compares that version as well as the config hash, so `types:check` fails inside `preview:test` inside the required `verify` check. Run `pnpm run types:sync` and commit the result. That script is `wrangler types && vp check --fix` together, and the formatter half is not optional - a raw `wrangler types` buries the real one-line change in a whole-file whitespace diff (25,411 lines vs 1, measured on #169).",
],
},
{
// `overrides.brace-expansion: 2.1.3` in pnpm-workspace.yaml is a
// deliberate maintenance-backport pin, not a stale version. Renovate would
// read it as three majors behind and propose 5.x, which is a spike into a
// dual-ESM/CJS package consumed by a CJS minimatch - explicitly rejected.
// The advisory's flat `<=5.0.7` range also means `pnpm audit` still flags
// 2.1.3 even though it carries the fix, so "the audit is red" is not a
// reason to take this bump. Read the comment in pnpm-workspace.yaml first.
//
// Deliberately NOT narrowed with `matchDepTypes: ["pnpm.overrides"]`. The
// override lives in pnpm-workspace.yaml, not package.json, and if the
// depType Renovate reports for that location is anything other than the
// string guessed here the rule would silently match nothing - a config bug
// no validator can catch. brace-expansion appears in no manifest in this
// repo (only as a transitive of js-beautify), so matching it by name alone
// is both correct and the only form that cannot miss.
matchPackageNames: ["brace-expansion"],
enabled: false,
},
{
// `engines.node` is a deliberately permissive FLOOR (">=24.18.0"): older
// versions are untested, not known-broken. It is not a version to keep
// current. The version CI and development actually run on is
// `.node-version`, which Renovate may bump (see below).
matchDepTypes: ["engines"],
enabled: false,
},
{
// `.node-version` became machinery, not documentation, the moment
// .github/workflows/verify.yml started feeding it to setup-node. Bumps are
// welcome but never unattended.
matchFileNames: [".node-version"],
prBodyNotes: [
"This changes the Node version **CI** runs on, not just a local hint. Run `pnpm run verify` locally on the proposed version before merging.",
],
},
{
// vite-plus is pre-1.0 and is the entire static-check + test toolchain.
// Its tsgolint engine bumps have twice re-triggered the `TS2321: Excessive
// stack depth ... UserConfig` pathology in vite.config.ts, which looks
// like a type error in this repo and is not one.
matchPackageNames: ["vite-plus"],
prBodyNotes: [
"If `vp check` starts reporting `TS2321: Excessive stack depth comparing types ... 'UserConfig'`, that is the known vite.config.ts comparison-depth pathology, not a real type error - see the type-checking section of CLAUDE.md for the `vue() as Plugin` cast that collapses it.",
],
},
],
}