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..efc41ff 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -7,6 +7,23 @@ ":semanticCommits", ], + // `config:recommended` brings in mergeConfidence:age-confidence-badges, whose + // Age column is a Mend badge. Mend's Merge Confidence index only covers Maven + // Central: org.jetbrains.kotlin, junit, truth, turbine et al resolve, but + // every androidx/compose artifact lives on Google's Maven repo and comes back + // as a grey UNKNOWN — i.e. most of this project. Renovate already knows the + // real answer, since it derives release timestamps itself for the + // minimumReleaseAge rules below (Google Maven serves `last-modified` on its + // POMs), so take the age from there and leave Mend to the Confidence column, + // which still carries signal for the Maven Central half. + prBodyDefinitions: { + Age: "{{#if releaseTimestamp}}{{{newVersionAgeInDays}}} d{{else}}unknown{{/if}}", + }, + // Default heading links to the Merge Confidence docs; this column is ours now. + prBodyHeadingDefinitions: { + Age: "Age", + }, + // No automerge: a dependency bump goes through the same review (and, for // anything touching the build, the same on-device check) as a feature // before it can ride a release — see docs/RELEASING.md and the @@ -15,6 +32,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 +57,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 @@ -52,5 +94,15 @@ ], groupName: "test dependencies", }, + // Last word on the PR table. The merge-confidence preset sets prBodyColumns + // from inside a packageRule of its own, and only for the datasources Mend + // supports — so a plain top-level prBodyColumns would lose to it for maven + // 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. + { + matchPackageNames: ["*"], + prBodyColumns: ["Package", "Type", "Change", "Age", "Confidence"], + }, ], }