From c66a1ee936c19f128ea712780678563936d6ecc4 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 5 Jul 2026 19:36:10 +0800 Subject: [PATCH 1/2] Add 5-day cooldown on updates to mitigate supply-chain attacks Co-Authored-By: Claude Opus 4.8 --- default.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/default.json b/default.json index aa32a44..2785908 100644 --- a/default.json +++ b/default.json @@ -17,6 +17,11 @@ "enabled": true, "automerge": true }, + "minimumReleaseAge": "5 days", + "internalChecksFilter": "strict", + "vulnerabilityAlerts": { + "minimumReleaseAge": "0" + }, "packageRules": [ { "matchManagers": ["npm", "pnpm", "yarn"], From efbd35396f9c6581c1c63e85054fb29461f85e3e Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 7 Jul 2026 16:55:09 +0800 Subject: [PATCH 2/2] Prune dead npm minor/patch automerge presets, document policy npm minor/patch updates are disabled and handled by weekly lockFileMaintenance, so the eslint/sass automerge presets (scoped to minor/patch only) could never fire. Remove them; their updates still auto-merge via the lockfile PR, and their majors now surface as reviewable PRs per policy. Wire the missing automerge-typescript preset into automerge-common so TypeScript majors auto-merge on green CI as intended. Add a README documenting the update policy, auto-merge safety model, and supply-chain hardening. Co-Authored-By: Claude Opus 4.8 --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++ automerge-common.json | 5 ++- automerge-eslint.json | 21 ----------- automerge-sass.json | 15 -------- 4 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 README.md delete mode 100644 automerge-eslint.json delete mode 100644 automerge-sass.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..dad17d0 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +# renovate-config + +Shared [Renovate](https://docs.renovatebot.com/) presets used across my repositories. + +## Usage + +In a repository's `renovate.json`: + +```json +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "local>iac/renovate-config", + "local>iac/renovate-config//automerge-common" + ] +} +``` + +- `local>iac/renovate-config` resolves to [`default.json`](default.json). +- Add `//automerge-common` to opt the repository into the trusted auto-merge list. + +## Update policy + +The goal is to stay current without being flooded by pull requests, while never +auto-merging anything risky. + +| Kind of update | What happens | +| --- | --- | +| **In-range minor/patch** (npm) | No individual PR. Pulled in weekly by `lockFileMaintenance`, which auto-merges on green CI. | +| **Security vulnerabilities** | A PR is opened immediately, bypassing the 5-day cooldown. | +| **Majors / out-of-range / pinned** | A PR is opened so it can be reviewed. **Not** auto-merged... | +| **...unless the package is a trusted exception** | Auto-merged, but only if CI passes (see below). | + +### Why npm minor/patch have no PRs + +`default.json` disables individual npm/pnpm/yarn minor and patch updates. Those +versions already satisfy the semver ranges in `package.json`, so +`lockFileMaintenance` refreshes them in the lockfile once a week and auto-merges +the result. Opening a PR per package would just be noise. + +> This relies on `package.json` using version *ranges* (e.g. `^1.2.3`). A +> dependency pinned to an exact version cannot be moved by lock file +> maintenance and will only update through a (reviewable) major/out-of-range PR. + +### How auto-merge stays safe + +Every consuming repository has a CI pipeline. Auto-merge uses +`automergeType: "branch"`: + +1. Renovate pushes the update to a branch. +2. CI runs on that branch. +3. **CI passes** → merged silently, no PR. +4. **CI fails** → a PR is opened instead, so the failure is visible. + +An update can therefore only ever auto-merge on green CI. + +### Supply-chain hardening + +- `minimumReleaseAge: "5 days"` — a freshly published release must age 5 days + before it is considered, mitigating compromised-release attacks. +- `vulnerabilityAlerts.minimumReleaseAge: "0"` — security fixes skip the + cooldown so they land as fast as possible. +- `osvVulnerabilityAlerts` + `:enableVulnerabilityAlerts` + merge-confidence + scoring drive vulnerability detection. + +## Presets + +| Preset | Purpose | +| --- | --- | +| [`default.json`](default.json) | Base configuration extended by every repo. | +| [`automerge-common.json`](automerge-common.json) | Wires in all the auto-merge exception presets below. | +| [`automerge-bootstrap.json`](automerge-bootstrap.json) | Trust `bootstrap`, `bootstrap-icons`. | +| [`automerge-docker.json`](automerge-docker.json) | Trust `alpine`, `go` base images. | +| [`automerge-go.json`](automerge-go.json) | Trust a curated set of Go modules (minor/patch); schedule AWS SDK bumps; run `go mod tidy`. | +| [`automerge-sveltekit.json`](automerge-sveltekit.json) | Trust SvelteKit and related packages. | +| [`automerge-typescript.json`](automerge-typescript.json) | Trust `typescript`. | +| [`replacement-sveltestrap.json`](replacement-sveltestrap.json) | Migrate `sveltestrap` → `@sveltestrap/sveltestrap`. | +| [`replacement-eslint-plugin-svelte.json`](replacement-eslint-plugin-svelte.json) | Migrate `eslint-plugin-svelte3` → `eslint-plugin-svelte`. | + +Trusted npm exceptions (typescript, sveltekit, bootstrap) auto-merge **all** +update types including majors — their minor/patch bumps are already handled by +lock file maintenance, so in practice the preset only fires for majors. Go and +Docker presets are unaffected by the npm minor/patch policy and auto-merge as +configured in their files. diff --git a/automerge-common.json b/automerge-common.json index 7cd1bca..c8d93c8 100644 --- a/automerge-common.json +++ b/automerge-common.json @@ -1,12 +1,11 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "description": "Default preset for use with my repos", + "description": "Wires in every automerge exception preset (packages trusted to merge on green CI)", "extends": [ "local>iac/renovate-config//automerge-bootstrap", "local>iac/renovate-config//automerge-docker", "local>iac/renovate-config//automerge-go", - "local>iac/renovate-config//automerge-eslint", - "local>iac/renovate-config//automerge-sass", "local>iac/renovate-config//automerge-sveltekit", + "local>iac/renovate-config//automerge-typescript" ] } diff --git a/automerge-eslint.json b/automerge-eslint.json deleted file mode 100644 index 5f1d42d..0000000 --- a/automerge-eslint.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "description": "Preset for automerging sveltekit related packages", - "packageRules": [ - { - "matchPackageNames": [ - "@babel/eslint-parser", - "@typescript-eslint/eslint-plugin", - "@typescript-eslint/parser", - "eslint", - "eslint-config-prettier", - "eslint-plugin-svelte", - "lint-staged", - "prettier" - ], - "automerge": true, - "automergeType": "branch", - "matchUpdateTypes": ["minor", "patch"] - } - ] -} diff --git a/automerge-sass.json b/automerge-sass.json deleted file mode 100644 index 1775819..0000000 --- a/automerge-sass.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "description": "Preset for automerging sass related packages", - "packageRules": [ - { - "matchPackageNames": [ - "sass", - "sass-loader" - ], - "automerge": true, - "automergeType": "branch", - "matchUpdateTypes": ["minor", "patch"] - } - ] -}