From 314236ac0cd0ce09b31a1ec2b3b15effd0615f54 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 25 Jul 2026 20:31:33 +0000 Subject: [PATCH] fix(renovate): use a flexible internal-checks filter so ages resolve (!100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Age came back `unknown` for every dependency after #98. That's the `internalChecksFilter: "none"` from that PR doing what it says on the tin — and rather more. ### Why `lib/workers/repository/process/lookup/filter-checks.ts` short-circuits on `none`: ```js if (internalChecksFilter === 'none') { release = sortedReleases.pop(); // returns here } else { for (let candidateRelease of sortedReleases.reverse()) { ... const updatedCandidateRelease = await postprocessRelease(...) ``` `postprocessRelease` is the only caller that fetches a Maven artifact's `Last-Modified` header (`lib/modules/datasource/maven/index.ts:222`), so skipping the loop leaves `releaseTimestamp` unset. That empties the Age column — but it also silently voids `minimumReleaseAge` and the `renovate/stability-days` check, since both compare against that same timestamp. The cooling-off tiers were decorative. ### Fix `flexible` keeps the intent — still prefers a version that has cleared its window, but opens the PR at the newest candidate when none has — while running the loop that populates the timestamps. Verified with a local `--platform=local --dry-run=full`: | dependency | new version | age | | --- | --- | --- | | `androidx.compose:compose-bom` | 2026.06.01 | 24 d | | `androidx.compose.material3:material3` | 1.5.0-alpha24 | 10 d | | `androidx.work:work-runtime-ktx` | 2.11.2 | 122 d | | `com.android.application` (AGP) | 9.3.1 | 2 d | | `gradle` | 9.6.1 | 29 d | Only `ghcr.io/renovatebot/renovate` stays unknown, because the docker registry serves no timestamps at all — the run marks all 176 of its tags pending for that reason, and `flexible` is what still lets that PR through. `Pending` rejoins the table: under a flexible filter it names the newer version being held back, rather than leaving it invisible. ### Also Migrates the Gitea workflow manager off the deprecated `fileMatch`. Renovate's config migration was rewriting it to `managerFilePatterns` (delimited regex) on every run and warning about it; the dry run confirms the manager still picks up `.gitea/workflows` afterwards. Validated with `renovate-config-validator` against the pinned 43.232.0. Reviewed-on: https://gitea.jeanlucmakiola.de/makiolaj/calendula/pulls/100 --- renovate.json5 | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index efc41ff..378bf07 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -33,14 +33,20 @@ // One reviewable surface; the dashboard issue lists everything pending. dependencyDashboard: true, - // The cooling-off periods below are advisory, not a gate: "none" turns off - // filtering on the minimumReleaseAge check, so the PR is opened at the - // highest version straight away and merging early stays a judgement call. - // (Renovate's default here is "strict", which suppresses the PR entirely - // until the release has aged in.) A still-young release carries a pending + // The cooling-off periods below are advisory, not a gate. "flexible" still + // prefers a version that has cleared its window, but when every candidate is + // too young it opens the PR at the newest one anyway, so merging early stays + // a judgement call. (The default, "strict", would suppress the PR entirely + // until a release aged in.) A still-young branch carries a yellow // `renovate/stability-days` check so it's visible which side of the line // it's on; with automerge off, nothing acts on that check by itself. - internalChecksFilter: "none", + // + // NOT "none": that short-circuits the candidate loop in filter-checks.ts, and + // that loop is what calls postprocessRelease — the only thing that fetches a + // Maven artifact's Last-Modified header. Skipping it leaves releaseTimestamp + // unset, which empties the Age column and quietly makes minimumReleaseAge and + // the stability check no-ops, since both need that timestamp to compare. + internalChecksFilter: "flexible", labels: ["dependencies"], prConcurrentLimit: 5, @@ -52,8 +58,10 @@ // Gitea Actions workflows live under .gitea/workflows, not .github — extend // the github-actions manager (same syntax) to watch them too. + // `fileMatch` is deprecated; the replacement takes the regex delimited, and + // Renovate's config migration was already rewriting this on every run. "github-actions": { - fileMatch: ["^\\.gitea/workflows/[^/]+\\.ya?ml$"], + managerFilePatterns: ["/^\\.gitea/workflows/[^/]+\\.ya?ml$/"], }, packageRules: [ @@ -100,9 +108,12 @@ // deps, and the Gradle wrapper / Actions / container bumps would keep the // default columns and show no age at all. A rule declared after it wins, // and gives every PR the same table. + // "Pending" earns its place under a flexible filter: when the bump lands on + // a version that has cleared its window but a newer one hasn't, that newer + // version is named here rather than silently withheld. { matchPackageNames: ["*"], - prBodyColumns: ["Package", "Type", "Change", "Age", "Confidence"], + prBodyColumns: ["Package", "Type", "Change", "Age", "Pending", "Confidence"], }, ], }