From f36a74246bf2414bda1cc0fddf75fd2651e06124 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 25 Jul 2026 21:45:47 +0200 Subject: [PATCH] chore(renovate): surface release age and changelogs, without gating on them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three gaps in the Renovate setup, all about having enough information in front of you at review time: - The PR table had no Age/Adoption/Passing/Confidence columns. Those are Mend's Merge Confidence badges, which self-hosted Renovate only emits behind the `mergeConfidence:all-badges` preset. No credentials involved — Renovate embeds badge URLs and the browser resolves them on view. - Release notes came back empty. We run against Gitea, but the packages are *released* on GitHub, so changelog lookups were going out unauthenticated against a 60/h limit. A scopeless read-only PAT (GITHUB_COM_TOKEN secret) lifts that. - Nothing expressed how settled a release is. Cooling-off is now scaled by blast radius: 30 days major, 20 minor, 10 patch/digest. The age tiers are deliberately advisory. Renovate's default `internalChecksFilter: strict` would suppress the PR outright until the version aged in; "none" opens it at the highest version immediately and leaves a pending stability check behind, so merging ahead of the window stays a decision rather than a wait. Co-Authored-By: Claude Opus 5 (1M context) --- .gitea/workflows/renovate.yml | 5 +++++ renovate.json5 | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/.gitea/workflows/renovate.yml b/.gitea/workflows/renovate.yml index 5b5ebda..4a39197 100644 --- a/.gitea/workflows/renovate.yml +++ b/.gitea/workflows/renovate.yml @@ -39,4 +39,9 @@ jobs: RENOVATE_REPOSITORIES: '["makiolaj/calendula"]' # Commits/PRs authored as the bot, not a real maintainer. RENOVATE_GIT_AUTHOR: 'Renovate Bot ' + # Read-only github.com PAT (no scopes needed). We run on Gitea, but + # nearly every dependency is *released* on GitHub — without this, + # changelog/release-note lookups hit the 60/h anonymous rate limit + # and PRs arrive with an empty "Release Notes" section. + RENOVATE_GITHUB_COM_TOKEN: ${{ secrets.GITHUB_COM_TOKEN }} LOG_LEVEL: info diff --git a/renovate.json5 b/renovate.json5 index 103bd3d..ec105b9 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -5,6 +5,12 @@ "config:recommended", // chore(deps): … — match the repo's conventional-commit style. ":semanticCommits", + // Adds the Age / Adoption / Passing / Confidence columns to the PR table + // (Mend's Merge Confidence badges; free, no token — Renovate only embeds + // the badge URLs and the browser loads them when the PR is viewed). + // Covers the maven datasource, i.e. everything in libs.versions.toml; + // the github-actions datasource has no badges, so those PRs stay plain. + "mergeConfidence:all-badges", ], // No automerge: a dependency bump goes through the same review (and, for @@ -15,6 +21,16 @@ // 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 + // `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", + labels: ["dependencies"], prConcurrentLimit: 5, prHourlyLimit: 0, @@ -30,6 +46,21 @@ }, packageRules: [ + // Cooling-off period, scaled by blast radius: how long a release should + // have been out (and un-yanked, un-hotfixed) before it's considered + // settled. Advisory only — see `internalChecksFilter` above. + { + matchUpdateTypes: ["major"], + minimumReleaseAge: "30 days", + }, + { + matchUpdateTypes: ["minor"], + minimumReleaseAge: "20 days", + }, + { + matchUpdateTypes: ["patch", "digest", "pin", "rollback"], + minimumReleaseAge: "10 days", + }, // material3 is deliberately pinned to the 1.5 *alpha* line for the // Expressive APIs (see gradle/libs.versions.toml). Follow the alpha train // but keep it in its own PR, reviewed in isolation; revisit the pin when