fix(renovate): use a flexible internal-checks filter so ages resolve (!100)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release / release (push) Has been skipped

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: #100
This commit was merged in pull request #100.
This commit is contained in:
2026-07-25 20:31:33 +00:00
parent c6e83fc071
commit 314236ac0c

View File

@@ -33,14 +33,20 @@
// One reviewable surface; the dashboard issue lists everything pending. // One reviewable surface; the dashboard issue lists everything pending.
dependencyDashboard: true, dependencyDashboard: true,
// The cooling-off periods below are advisory, not a gate: "none" turns off // The cooling-off periods below are advisory, not a gate. "flexible" still
// filtering on the minimumReleaseAge check, so the PR is opened at the // prefers a version that has cleared its window, but when every candidate is
// highest version straight away and merging early stays a judgement call. // too young it opens the PR at the newest one anyway, so merging early stays
// (Renovate's default here is "strict", which suppresses the PR entirely // a judgement call. (The default, "strict", would suppress the PR entirely
// until the release has aged in.) A still-young release carries a pending // 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 // `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. // 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"], labels: ["dependencies"],
prConcurrentLimit: 5, prConcurrentLimit: 5,
@@ -52,8 +58,10 @@
// Gitea Actions workflows live under .gitea/workflows, not .github — extend // Gitea Actions workflows live under .gitea/workflows, not .github — extend
// the github-actions manager (same syntax) to watch them too. // 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": { "github-actions": {
fileMatch: ["^\\.gitea/workflows/[^/]+\\.ya?ml$"], managerFilePatterns: ["/^\\.gitea/workflows/[^/]+\\.ya?ml$/"],
}, },
packageRules: [ packageRules: [
@@ -100,9 +108,12 @@
// deps, and the Gradle wrapper / Actions / container bumps would keep the // 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, // default columns and show no age at all. A rule declared after it wins,
// and gives every PR the same table. // 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: ["*"], matchPackageNames: ["*"],
prBodyColumns: ["Package", "Type", "Change", "Age", "Confidence"], prBodyColumns: ["Package", "Type", "Change", "Age", "Pending", "Confidence"],
}, },
], ],
} }