Audit of the first completed dry runs (353/354) plus a debug-level local reproduction: - App-image updates edited only the generated apps/wave-*. A ServiceDefinition has no apiVersion, so the kubernetes manager extracts nothing from catalog/, and every such PR would fail render-golden (reproduced: GOLDEN DRIFT). New regex managers for catalog source.image and render.py OAUTH2_PROXY_IMAGE put the source and generated edits in one branch (render-golden rc 0, reproduced). - CNPG Cluster imageName was untracked (3 Clusters), while the grant Job was tracked. New manager. - allowedVersions mirror catalog update.range: this drops gitea 28.x, qbittorrent 20.x, radarr 6, nextcloud 35 and postgresql 18. - Never auto-merge: gitea, act_runner, postgresql (blast radius), flux range widening, python minors. Majors wait for a Dependency Dashboard tick. - velero plugin RC: semver versioning (v1.14.3-rc.2 -> v1.14.4 now proposed). - flux docker duplicates disabled (the "Cannot find replaceString" line). Two false comments corrected. Local dry run: regex deps 7 -> 20, branches 33 -> 29. The validator passes on 44.167.0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
9.1 KiB
date, branch, title
| date | branch | title |
|---|---|---|
| 2026-10-30 | fix/renovate-run-hygiene | Renovate's first completed dry runs, audited; it would have opened red PRs for every app and missed the databases. Config fixed |
What changed
renovate.json5 only. Each change carries a comment quoting the measurement behind it.
-
Three new regex managers, so updates edit the SOURCE.
catalog/*.yamlsource.image.catalog/render.pyOAUTH2_PROXY_IMAGE.- CNPG
imageName:underplatform/andapps/.
The first two match the rendered line's depName, so the catalog edit and the generated
apps/wave-*edit land in one branch. -
allowedVersionsmirroring each ServiceDefinition'supdate.range:- gitea/gitea
<2.0.0 - nextcloud
<32.0.0 - qbittorrent
<6.0.0 - radarr
<6.0.0 - sonarr
<5.0.0 - semaphore
<3.0.0
Plus CNPG postgresql
<17.0.0, because a Postgres major is a migration, not a bump. - gitea/gitea
-
The blast-radius never-automerge list gains
gitea/gitea,gitea/act_runnerandghcr.io/cloudnative-pg/postgresql. -
HelmRelease range widening (
matchManagers: flux, ranged currentValue) is never auto-merged and is labelledrange-widen. -
Majors need a Dependency Dashboard tick (
dependencyDashboardApproval) before a PR opens. -
fluxmanager docker deps are disabled. These are duplicates ofkubernetesmanager extractions. -
velero/velero-plugin-for-awsusessemverversioning, so its RC pin can reach a stable release. -
pythonminors are not auto-merged. -
Two false comments are corrected.
- Ranges "cap Renovate at patches": false, Renovate widens them.
nextcloud:31-apacheanddocker:27-dind"cannot be maintained": false, they were.
PR #85 is merged, so nothing here overlaps an open branch.
The audit: dispatch runs 353 (07:12 UTC) and 354 (07:23 UTC), on 593d0fa
Both runs ended success, Renovate "result": "done", exitCode 0. Both were at info level, so
I reproduced the per-dependency detail with a debug-level local dry run of the same commit (see
below).
The runs were inside the 03:00–06:00 America/New_York window, so branches were processed:
- run 353: 37 "Would commit" branches;
- run 354: 40, because the operator had added
RENOVATE_GITHUB_COM_TOKEN9 s before it.
Gitea's router log for the act-runner pod during both runs shows 317 2xx responses. The only non-2xx were all expected:
/v2/401: the registry challenge;/admin/orgs403: the #85 scope probe, by design;- 6×
HEAD …/manifests/sha256:000…404: the placeholder digests.
| # | Class | Count | Cause | Severity | Fix |
|---|---|---|---|---|---|
| 1 | App-image PRs edit only generated apps/wave-* |
9 branches | A ServiceDefinition has no apiVersion, so the kubernetes manager extracts 0 deps from catalog/. The oauth2-proxy sidecar is a Python constant (catalog/render.py:132) |
Real problem. Every such PR fails ci/render-golden.sh (reproduced: rc 1 "GOLDEN DRIFT"), stays red and holds a PR slot |
git (1) |
| 2 | CNPG imageName untracked |
3 Clusters | The kubernetes manager reads image: only. The one tracked postgres line was the grant Job (nextcloud-db.yaml:303, "keep in step with spec.imageName") |
Real problem. A real run bumps the Job and leaves the databases behind | git (1) |
| 3 | Bogus or out-of-policy majors | 5 branches: gitea 28.2.0, qbittorrent 20.04.1, radarr 6.x, nextcloud 35, postgresql 18.6 | Odd legacy tags, plus update.range in catalog/ not being read by Renovate |
Risk if run for real: unmergeable PRs, which hold slots | git (2) |
| 4 | Auto-merge of the merge gate's own host | gitea 1.24.3→1.27.3, act_runner 0.2.11→0.6.1, both "minor" | Not in the blast-radius list. A 0.x minor is breaking by semver | Risk if run for real | git (3) |
| 5 | Range widening auto-merged | external-dns, headlamp (minor); longhorn (blast radius); kube-prometheus-stack (major) | Renovate widens >=a <b. The config's comment claimed the opposite |
Risk if run for real: silently lets Flux adopt new minors | git (4, 9) |
| 6 | Majors hold PR slots | 10 majors in run 354 against prConcurrentLimit: 5 |
Majors never auto-merge, so they stay open | Risk: starves auto-mergeable PRs | git (5) |
| 7 | Cannot find replaceString … alpine:3.22 (INFO) |
1 per run | The same HelmRelease image: line is extracted by flux and kubernetes (also the velero plugin) |
Cosmetic. The branch is still right | git (6) |
| 8 | velero-plugin-for-aws stuck on v1.14.3-rc.2 |
1 dep, 0 updates | Docker versioning treats -rc.2 as a suffix, so stable v1.14.3 and v1.14.4 never qualify |
Real problem (silent) | git (7) |
| 9 | python 3.13→3.15 as auto-mergeable "minor" | 2 files | Language runtime minor | Risk if run for real | git (8) |
| 10 | WARN GitHub token is required |
run 353: 5 packages, 17 deps | No github.com token | Real (they were unmaintained) | operator, done: run 354 has no WARN and adds pin-dependencies, kubevirt-cdi, actions-checkout-7.x, major-github-artifact-actions |
| 11 | Floating or untagged images (invalid-value) |
4: jackett, plex latest; pihole, keycloak no tag |
No version to compare | Real, already documented | none in git. Pinning by hand is an operator/PM decision |
| 12 | runs-on: ubuntu-latest invalid-version |
11 | The github-actions manager extracts runner labels | Cosmetic, debug-only | none |
| 13 | Docker Manifest is unknown (debug) |
3 | HEAD on the all-zero placeholder digests | Expected. Clears when the own-image digest PRs merge | none |
| 14 | Docker: error fetching data from DockerHub 403 (debug) |
5 | Hub refuses page=11. Renovate already has the tags |
Cosmetic. Updates were still found | none |
| 15 | Config migration necessary |
1 | Top-level "docker": {"enabled": true} |
Cosmetic, pre-existing | none (as before) |
Checked and fine:
- The 3 own-image digest updates were found in both runs. All 4
# renovate-digest:markers parse. - No marker failed to parse.
- No package file is under
conformance/runsortests, nor isDECISIONS-LOG.md,decisions/or any*.sops.yaml(77 package files checked). kubevirt-cdigrouping works.- The schedule window behaved as designed.
- Vulnerability alerts: none in either log.
What I verified
- I read both job logs in full (132 and 129 lines), and the router log for 10.0.0.38 during both runs.
renovate-config-validatoron 44.167.0:Config validated successfully. The migration diff is only the pre-existingdockerblock.- Local dry runs. Pinned image,
--platform=local, debug, origin/main snapshot. "Before" is593d0faand "after" is this config; the GitHub-hosted deps were skipped in both.- Extraction:
regexwent from 6 files / 7 deps to 19 files / 20 deps. Every other manager is unchanged: flux 15, github-actions 24, kubernetes 131, kustomize 2. - Branches: 33 before, 29 after. Removed: gitea-28.x, qbittorrent-20.x, radarr-6.x,
nextcloud-35.x and postgresql-18.x. Added: velero
v1.14.3-rc.2 → v1.14.4(patch). - Gitea, qbittorrent, radarr, sonarr, semaphore and seerr branches now each carry
catalog/<svc>.yaml+apps/wave-*/<svc>.yaml. - The oauth2-proxy branch carries
catalog/render.pyplus the 5 rendered apps andplatform/crafty. - The postgresql-16.x branch carries all three Clusters.
- The 2 flux docker duplicates report
disabled.
- Extraction:
- render==golden holds for the new branch shape.
- In the toolbox, I applied the gitea branch edit (catalog + apps) and the oauth2-proxy branch
edit (
render.pyconstant + 5 apps) textually../ci/render-golden.shreportedall 10 onboarded service golden(s) reproduce, rc 0. - Negative control, the old shape with only
apps/wave-0/gitea.yamlbumped: rc 1,GOLDEN DRIFT. - Both edits were reverted afterwards.
- In the toolbox, I applied the gitea branch edit (catalog + apps) and the oauth2-proxy branch
edit (
What I did NOT verify
- The effect of the automerge, label and dashboard-approval rules (3, 4, 5, 8). UNVERIFIED in a
run.
--platform=localstops before branch processing, so I saw only which updates exist, not their merged flags. The matchers are standard (matchPackageNames,matchManagers,matchCurrentValue,matchUpdateTypes). The next dispatch's debug log shows them per branch. allowedVersionsunder docker versioning used Renovate's "Falling back to npm semver syntax" path (16 debug lines). That it filters is shown by the five removed branches.- render==golden for the other app branches (qbittorrent, radarr, sonarr, semaphore, seerr). I
proved it only for gitea and oauth2-proxy. They have the same shape: one
source.imageline ↔ one renderedimage:line. - The
allowedVersionsrules duplicatecatalog/*/update.rangeand can drift from it. Nothing checks them against each other. A lint comparing the two is the obvious follow-up. - Any real (non-dry) run. None has happened. PR creation, labels, auto-merge through Gitea's API and the Dependency Dashboard issue are all unobserved.
- Sensitive path?
renovate.json5is not ininfra/gitea/approval-policy.json, as far as I know. CI'sapproval-policyresult on the PR is the measurement.