|
| 1 | +// Dependency automation for this repo (issue #54). Renovate, not Dependabot: |
| 2 | +// several of this project's dependency decisions are deliberate HOLDS whose |
| 3 | +// reasoning lives in CLAUDE.md prose, and Dependabot's `ignore` entries cannot |
| 4 | +// express most of them. Everything below exists to stop a bot from cheerfully |
| 5 | +// re-proposing, every week, the exact bump this project has already decided |
| 6 | +// against - and to make the reason travel with the proposal when there is one. |
| 7 | +// |
| 8 | +// This file does nothing on its own. Renovate only acts once the Renovate |
| 9 | +// GitHub App is enabled for the repository (https://github.com/apps/renovate). |
| 10 | +// Validated with `renovate-config-validator` before landing. |
| 11 | +// |
| 12 | +// THE pnpm INTERACTION, which is the subtle part. |
| 13 | +// This workspace relies on pnpm 11's built-in release-age cooldown - there is no |
| 14 | +// `minimumReleaseAge` line in pnpm-workspace.yaml, the guard is a pnpm default. |
| 15 | +// When pnpm is asked to install something newer than that cooldown allows it |
| 16 | +// does not fail; it writes a `minimumReleaseAgeExclude:` bypass into |
| 17 | +// pnpm-workspace.yaml, which is how `vue-tsc@3.3.8` once silently waived the |
| 18 | +// guard. A dependency bot is a machine for producing exactly that situation. |
| 19 | +// So `minimumReleaseAge` is declared HERE, explicitly, at a value comfortably |
| 20 | +// above pnpm's default: Renovate must never open a PR for a release pnpm would |
| 21 | +// want a bypass for. Declaring it also means a future pnpm changing its default |
| 22 | +// cannot move this repo's floor silently. |
| 23 | +// If `minimumReleaseAgeExclude:` ever appears in a Renovate PR's diff, that PR |
| 24 | +// is wrong - do not merge it, fix the age rule instead. |
| 25 | +{ |
| 26 | + $schema: "https://docs.renovatebot.com/renovate-schema.json", |
| 27 | + extends: [ |
| 28 | + "config:recommended", |
| 29 | + // Pin every GitHub Action to a commit SHA rather than a moving tag, and keep |
| 30 | + // the `# vX.Y.Z` comment beside it updated. .github/workflows/verify.yml is |
| 31 | + // already written that way by hand; this makes it the rule for anything |
| 32 | + // added later, so the choice cannot drift action-by-action. |
| 33 | + "helpers:pinGitHubActionDigests", |
| 34 | + ], |
| 35 | + |
| 36 | + // See the pnpm interaction above. This is a floor, not a preference. |
| 37 | + minimumReleaseAge: "3 days", |
| 38 | + |
| 39 | + // The central invariant here is byte-exactness against captured fixtures, and |
| 40 | + // a green CI run is evidence of consistency, not of a bump being *correct* |
| 41 | + // (`pnpm run verify` does not exercise every dependency - see the js-beautify |
| 42 | + // note in pnpm-workspace.yaml). Nothing merges unread. |
| 43 | + automerge: false, |
| 44 | + |
| 45 | + dependencyDashboard: true, |
| 46 | + |
| 47 | + // One weekly batch instead of a trickle. Times are UTC (no `timezone` set). |
| 48 | + schedule: ["before 6am on monday"], |
| 49 | + |
| 50 | + packageRules: [ |
| 51 | + { |
| 52 | + // THE ONE THAT MATTERS MOST. Without it a bot proposes 6.0.3 -> 7.x every |
| 53 | + // single week and someone re-derives the refusal every time (see #48, #52). |
| 54 | + // TypeScript 7 exposes no programmatic API yet, the official migration is |
| 55 | + // a dual-install alias, and vue-tsc/Volar cannot type-check .vue against |
| 56 | + // it. Revisit at 7.1 deliberately, by hand. |
| 57 | + matchPackageNames: ["typescript"], |
| 58 | + enabled: false, |
| 59 | + }, |
| 60 | + { |
| 61 | + // The codec's byte-exactness rests on `{ level: 9, legacyHash: true }`. |
| 62 | + // `legacyHash` is a pako EXTENSION with no zlib-API contract, from a |
| 63 | + // library that already flipped that default inside a single major (2.2.0 |
| 64 | + // added it defaulting true, 3.0.0 flipped it false). A pako bump is a |
| 65 | + // codec change until proven otherwise. |
| 66 | + matchPackageNames: ["pako"], |
| 67 | + minimumReleaseAge: "14 days", |
| 68 | + automerge: false, |
| 69 | + prBodyNotes: [ |
| 70 | + "**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.", |
| 71 | + ], |
| 72 | + }, |
| 73 | + { |
| 74 | + // @cloudflare/vitest-pool-workers hard-pins an exact wrangler. Split PRs |
| 75 | + // cannot resolve, so these two only ever move together. |
| 76 | + matchPackageNames: ["wrangler", "@cloudflare/vitest-pool-workers"], |
| 77 | + groupName: "cloudflare worker toolchain", |
| 78 | + prBodyNotes: [ |
| 79 | + "After merging, regenerate the worker types: `pnpm --filter @fmw/preview-worker exec wrangler types && pnpm vp check --fix`. The formatter pass is not optional.", |
| 80 | + ], |
| 81 | + }, |
| 82 | + { |
| 83 | + // `overrides.brace-expansion: 2.1.3` in pnpm-workspace.yaml is a |
| 84 | + // deliberate maintenance-backport pin, not a stale version. Renovate would |
| 85 | + // read it as three majors behind and propose 5.x, which is a spike into a |
| 86 | + // dual-ESM/CJS package consumed by a CJS minimatch - explicitly rejected. |
| 87 | + // The advisory's flat `<=5.0.7` range also means `pnpm audit` still flags |
| 88 | + // 2.1.3 even though it carries the fix, so "the audit is red" is not a |
| 89 | + // reason to take this bump. Read the comment in pnpm-workspace.yaml first. |
| 90 | + matchPackageNames: ["brace-expansion"], |
| 91 | + matchDepTypes: ["overrides", "pnpm.overrides"], |
| 92 | + enabled: false, |
| 93 | + }, |
| 94 | + { |
| 95 | + // `engines.node` is a deliberately permissive FLOOR (">=24.18.0"): older |
| 96 | + // versions are untested, not known-broken. It is not a version to keep |
| 97 | + // current. The version CI and development actually run on is |
| 98 | + // `.node-version`, which Renovate may bump (see below). |
| 99 | + matchDepTypes: ["engines"], |
| 100 | + enabled: false, |
| 101 | + }, |
| 102 | + { |
| 103 | + // `.node-version` became machinery, not documentation, the moment |
| 104 | + // .github/workflows/verify.yml started feeding it to setup-node. Bumps are |
| 105 | + // welcome but never unattended. |
| 106 | + matchFileNames: [".node-version"], |
| 107 | + prBodyNotes: [ |
| 108 | + "This changes the Node version **CI** runs on, not just a local hint. Run `pnpm run verify` locally on the proposed version before merging.", |
| 109 | + ], |
| 110 | + }, |
| 111 | + { |
| 112 | + // vite-plus is pre-1.0 and is the entire static-check + test toolchain. |
| 113 | + // Its tsgolint engine bumps have twice re-triggered the `TS2321: Excessive |
| 114 | + // stack depth ... UserConfig` pathology in vite.config.ts, which looks |
| 115 | + // like a type error in this repo and is not one. |
| 116 | + matchPackageNames: ["vite-plus"], |
| 117 | + prBodyNotes: [ |
| 118 | + "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.", |
| 119 | + ], |
| 120 | + }, |
| 121 | + ], |
| 122 | +} |
0 commit comments