--- date: 2026-11-08 branch: chore/renovate-config-cleanup title: Renovate config — hand-migrate the docker key, track gitea/runner, keep HelmRelease range lower bounds --- ## What changed - **`renovate.json5`: the deprecated top-level `"docker": {"enabled": true}` is hand-migrated** to `packageRules[0] = {"matchCategories": ["docker"], "enabled": true}`, the exact shape Renovate's own migration produced on `origin/renovate/migrate-config` (PR #139). Its comment moved with it. This replaces #139, which was closed because its rewrite deleted every comment in the file. No other comment was removed or reflowed (diff is additions plus the moved block). - **`gitea/runner` added to the blast-radius rule** beside `gitea/act_runner`, with a comment: act_runner was renamed upstream to gitea/runner after 0.6.1; Renovate does not follow renames, so the actual image migration is a separate manual PR. - **Two new packageRules for flux/helm `>=A enabled: false`, so in-range releases (which Flux adopts on its own) do not become PRs. Cause of the bug, from the 44.167.0 source: rangeStrategy is unset (`auto`); the flux manager has no `getRangeStrategy`/`updateLockedDependency`, so `lib/modules/manager/index.ts getRangeStrategy` resolves `auto` to `replace`; helm versioning is the npm api verbatim, and npm `getNewValue` under `replace` turns `>=1.12.0 <1.13.0` into `<1.14.0` (what PRs #131, #130 and #115 did). - **`platform/headlamp/helmrelease.yaml`: `version: "<0.47.0"` -> `">=0.46.0 <0.47.0"`**, comment refreshed. The live chart is 0.46.0, so the set of installable charts is unchanged. ## What I verified - **Semantic diff of #139:** I parsed `renovate.json5` on `origin/renovate/migrate-config` and on its parent `5b484f6` with json5 (the copy inside the renovate image). With `docker` removed from the parent and `packageRules[0]` removed from the migrated file, the two are identical. So the only change was `{"matchCategories":["docker"],"enabled":true}`, inserted at packageRules[0]. - **Validator, `ghcr.io/renovatebot/renovate:44.167.0`** (the tag that `.gitea/workflows/renovate.yaml` pins as `container.image`): `renovate-config-validator` gives `Config validated successfully` (rc 0), and so does `--strict` (rc 0), both as a file path and in repo mode. **`--strict` on origin/main's file gives rc 1** and prints the `docker` migration diff. Nothing is left to migrate. - **`getNewValue` called in the 44.167.0 image** (helm versioning), currentValue `>=1.12.0 <1.13.0`, newVersion 1.13.0: replace `<1.14.0`, widen `>=1.12.0 <1.14.0`, bump `>=1.13.0 <1.14.0`, pin/update-lockfile `<1.14.0`. On `<0.47.0`, bump returns the value unchanged, so it would never propose anything for that range. That is why the rule is scoped to the `>=A =1.9.0 <1.10.0` -> `>=1.13.0 <1.14.0` (minor). kube-prometheus-stack `>=88.0.0 <89.0.0` -> `>=93.1.0 <94.0.0` (major). The in-range bump `>=88.6.5 <89.0.0` was dropped (`Filtered out 1 disabled update(s)`). headlamp `>=0.46.0 <0.47.0` and `<0.47.0`: no update. - Control run with origin/main's config: `Config migration necessary`, longhorn -> `<1.14.0`, kube-prometheus-stack -> `<94.0.0`. This reproduces the reported bug. - Live headlamp HelmRelease (read-only kubectl, k3s-prod): spec `<0.47.0`, history chartVersion `0.46.0`, Ready `True`. ## What I did NOT verify - **I have not seen a real scheduled Renovate run against this repo with this config.** The claim that Renovate stops reopening the migrate-config PR rests on the validator and on `No config migration necessary` in the local dry run, not on the Gitea bot. After merge, watch the next run, and if `renovate/migrate-config` is still on the remote, delete it. - **Under bump, the new lower bound is the release Renovate proposes**, e.g. `>=1.13.2 <1.14.0`, not `>=1.13.0`. Flux still installs the newest release in the window. Ranges with other shapes keep the default `replace`: `3.9.x`, `~`, ceiling-only, and exact pins. - **The open PRs #131, #115 and any others still carry unbounded `