From f33b47c5ace75ddb247ba697a616ff0cffcd8eea Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Wed, 15 Jul 2026 23:33:13 +0200 Subject: [PATCH] =?UTF-8?q?fix(renovate):=20delete=20shadowing=20.github/r?= =?UTF-8?q?enovate.json5=20=E2=80=94=20the=20real=20cause=20of=20every=20a?= =?UTF-8?q?rtifact=20failure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original Dependabot->Renovate migration config at .github/renovate.json5 was never removed when renovate.json was added at the root (#821/#822). Renovate (and Mend's cached config-file name) kept reading the old file, so weeks of edits to renovate.json were silently ignored while the json5's 14-day minimumReleaseAge broke every uv artifact update (renovate#41624). There was never an org-level Mend config layer — just this forgotten file. One config file now: renovate.json, carrying the low-noise design plus the json5 pieces worth keeping (ngmix pin guard, Actions digest pinning, OSV/ vulnerability automerge, majors behind dashboard approval). All age gates gone — fundamentally incompatible with uv-owned resolution. The '0 days' override from #831 is dropped as moot. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01VZvom4Uzdoz5KbJeG8yhde --- .github/renovate.json5 | 86 ------------------------------------------ renovate.json | 23 +++++++---- 2 files changed, 16 insertions(+), 93 deletions(-) delete mode 100644 .github/renovate.json5 diff --git a/.github/renovate.json5 b/.github/renovate.json5 deleted file mode 100644 index 6d4147d6c..000000000 --- a/.github/renovate.json5 +++ /dev/null @@ -1,86 +0,0 @@ -{ - $schema: "https://docs.renovatebot.com/renovate-schema.json", - - // ── Renovate replaces Dependabot for shapepipe ────────────────────────────── - // - // Why the switch: Dependabot's only noise control is grouping, and its - // security channel bypasses even that — so a same-day burst of advisories - // arrives as N separate PRs that a human must merge by hand. Renovate gives a - // single Dependency Dashboard issue plus *branch automerge*: routine updates - // land silently on green CI with no PR at all. The supply-chain posture from - // the old dependabot.yml is carried over below and, via OSV, strengthened. - // - // Requires the Renovate GitHub App (or a self-hosted runner) — see the PR - // body for the one-time org-admin step. - - extends: [ - "config:recommended", - "helpers:pinGitHubActionDigests", // keep GitHub Actions SHA-pinned, as before - ], - - // One issue is the control surface: everything pending lives there, and - // nothing that needs a human decision becomes a PR until ticked. - dependencyDashboard: true, - - // pyproject declares ABSTRACT minimums; uv.lock holds the EXACT pins. Routine - // updates therefore touch only the lockfile — abstract floors change solely by - // deliberate human edit, never by the bot. (This makes the old "floor bumps - // need maintainer sign-off" rule structural rather than a manual hold.) - rangeStrategy: "update-lockfile", - - // Supply-chain cooldown (was 14d / 30d-major in dependabot.yml). 2025-26 saw a - // wave of maintainer-compromise attacks (Shai-Hulud, …); a release-age gate - // lets a malicious version be caught and yanked before it reaches us. - minimumReleaseAge: "14 days", - internalChecksFilter: "strict", // genuinely withhold updates until aged, not "surface as pending" - - // Keep the queue calm. - prConcurrentLimit: 5, - prHourlyLimit: 2, - - // Weekly batched lockfile refresh, merged on green CI — the routine - // "keep uv.lock current" job, fully hands-off. - lockFileMaintenance: { - enabled: true, - schedule: ["before 6am on monday"], - automerge: true, - }, - - // CVE fixes (GitHub alerts + OSV, which adds malicious-package detection) skip - // the long cooldown but keep a short 3-day window, then automerge on green CI — - // fast, not instant. Flip `automerge` to false here if you want eyes on every - // security fix. - osvVulnerabilityAlerts: true, - vulnerabilityAlerts: { - minimumReleaseAge: "3 days", - automerge: true, - labels: ["security"], - }, - - packageRules: [ - { - // Routine minor / patch / digest: batch into ONE weekly branch and land - // silently on green CI — no PR, no noise. (One branch = one container-build - // CI run, which matters since that build is slow.) - matchUpdateTypes: ["minor", "patch", "pin", "digest"], - groupName: "all non-major", - schedule: ["before 6am on monday"], - automerge: true, - automergeType: "branch", - }, - { - // Majors: never silent, never auto. 30-day age, then surface on the - // dashboard for explicit approval before a PR is even opened. - matchUpdateTypes: ["major"], - minimumReleaseAge: "30 days", - dependencyDashboardApproval: true, - }, - { - // ngmix is intentionally pinned to a tag in [tool.uv.sources] - // (esheldon v2.4.0). Tag changes are a deliberate shape-measurement - // decision, not a dependency bump — Renovate must not touch it. - matchDepNames: ["ngmix"], - enabled: false, - }, - ], -} diff --git a/renovate.json b/renovate.json index 9148c8ac7..8cbfa34de 100644 --- a/renovate.json +++ b/renovate.json @@ -1,16 +1,25 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "description": [ - "Low-noise dependency updates; uv owns version resolution. pyproject keeps floor ranges and Renovate uses the org default rangeStrategy=update-lockfile, so `uv lock` picks versions jointly — cross-package conflicts (e.g. numba capping numpy) resolve silently instead of failing the batch, and un-stick themselves when upstream catches up. No minimumReleaseAge: it is unenforceable with uv resolution (renovatebot/renovate#41624 forced exact pins, which forced manual conflict caps); CI running the full suite in the container is the automerge gate.", - "Noise: all non-major updates grouped into one weekly PR that automerges when CI is green; majors surface individually; lockFileMaintenance refreshes transitive deps weekly.", - "python is guarded: Renovate classes base-image bumps like 3.12 -> 3.14 as 'minor', so it gets its own PR and never automerges — a Python upgrade gets human eyes without holding the weekly batch hostage.", - "minimumReleaseAge is EXPLICITLY zeroed, not merely absent: Mend's hosted org layer injects an age gate invisibly, and merely deleting the key here does not override inherited config — artifact updates then fail on every uv-resolved transitive that is younger than the invisible gate (see #816). An explicit '0 days' should win the merge over the inherited value; if artifact errors persist, the gate lives in Mend portal-global settings and must be removed at developer.mend.io." + "THE ONLY Renovate config file — do not add another. A forgotten .github/renovate.json5 (the original Dependabot->Renovate migration config) shadowed this file for weeks: Renovate's config discovery (and Mend's cached config-file name) preferred it, so edits here were silently ignored while its 14-day minimumReleaseAge broke every uv artifact update (renovatebot/renovate#41624). Deleted 2026-07; if Renovate ever again behaves contrary to this file, first check for a second config file (renovate.json5, .github/renovate.json*, .renovaterc*), then the Mend portal's resolved config.", + "Low-noise dependency updates; uv owns version resolution. pyproject keeps floor ranges and rangeStrategy=update-lockfile means `uv lock` picks versions jointly — cross-package conflicts (e.g. numba capping numpy) resolve silently instead of failing the batch, and un-stick themselves when upstream catches up. No minimumReleaseAge anywhere: any age gate is unenforceable with uv resolution (#41624 — uv resolves transitives past the gate and the artifact step fails); CI running the full suite in the container is the automerge gate.", + "Noise: all non-major updates grouped into one weekly PR that automerges when CI is green; majors are gated behind an explicit dashboard-approval tick; lockFileMaintenance refreshes transitive deps weekly. Security fixes (GitHub + OSV alerts) automerge on green CI without waiting for the weekly schedule.", + "python is guarded: Renovate classes base-image bumps like 3.12 -> 3.14 as 'minor', so it gets its own PR and never automerges — a Python upgrade gets human eyes without holding the weekly batch hostage. ngmix is pinned to a tag in [tool.uv.sources] as a deliberate shape-measurement decision — Renovate must not touch it." ], - "extends": ["config:recommended", "group:allNonMajor", "schedule:weekly"], - "minimumReleaseAge": "0 days", + "extends": [ + "config:recommended", + "group:allNonMajor", + "schedule:weekly", + "helpers:pinGitHubActionDigests" + ], + "rangeStrategy": "update-lockfile", "lockFileMaintenance": { "enabled": true }, + "osvVulnerabilityAlerts": true, + "vulnerabilityAlerts": { "automerge": true, "labels": ["security"] }, "packageRules": [ { "matchUpdateTypes": ["minor", "patch", "pin", "digest"], "automerge": true }, - { "matchPackageNames": ["python"], "groupName": "python", "automerge": false } + { "matchUpdateTypes": ["major"], "dependencyDashboardApproval": true }, + { "matchPackageNames": ["python"], "groupName": "python", "automerge": false }, + { "matchDepNames": ["ngmix"], "enabled": false } ] }