feat(renovate): PR-age cooldown for registries without trusted timestamps - #286
Merged
Conversation
…mestamps Renovate v42+ defaults `minimumReleaseAgeBehaviour` to `timestamp-required` and does not trust the publisher-controlled OCI `created` annotation. Images from ghcr.io / lscr.io / quay.io expose no trusted release timestamp, so every release is marked "pending" and `internalChecksFilter: strict` refuses to open a branch — the update sits under the dependency dashboard's "Pending Status Checks" forever and no PR is ever created (DevSecNinja/truenas-apps#115, e.g. ghcr.io/italypaleale/traefik-forward-auth stuck for months). Preserve the ADR 0004 soak by measuring it from PR age instead of release age for exactly those registries: - packageRules.json5: set `minimumReleaseAgeBehaviour: "timestamp-optional"` for docker deps on ghcr.io/lscr.io/quay.io so Renovate opens the PR and enables platformAutomerge. - New reusable workflow `renovate-pr-cooldown.yml` posts a required `pr-cooldown` status check that stays pending until the PR branch head commit is >=14 days old (rebasing to a newer version restarts the clock). GitHub auto-merge then merges once it turns green. Human and non-gated PRs always get a passing status so the required check never blocks them. - Add local caller + workflow-template + properties for adoption. - Document the decision in ADR 0005 and correct the misleading base.json5 `internalChecksFilter` comment (strict is the correct default for the timestamp-required path, not the fix for the stuck updates). Datasources with trusted timestamps (docker.io, github tags/releases) keep the native `timestamp-required` soak and are not gated by pr-cooldown. Refs DevSecNinja/truenas-apps#115 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Verified against the latest Renovate run log for
DevSecNinja/truenas-apps(Renovate 43.280.0):Renovate v42+ defaults
minimumReleaseAgeBehaviour: timestamp-requiredand deliberately does not trust the publisher-controlled OCIorg.opencontainers.image.createdannotation. Images from ghcr.io / lscr.io / quay.io expose no trusted release timestamp, so every release is marked pending andinternalChecksFilter: strictrefuses to open a branch. The update parks under the dashboard's "Pending Status Checks" section and no PR is ever created — 30 of 35 branches were blocked this way, incl.traefik-forward-auth(stuck at4.8.0since March, ref DevSecNinja/truenas-apps#115).Neither native option alone is acceptable:
timestamp-requirednever merges these;timestamp-optionalopens PRs but skips the soak entirely, contradicting ADR 0004.Solution — measure the soak from PR age for these registries
.renovate/packageRules.json5:minimumReleaseAgeBehaviour: "timestamp-optional"scoped todockerdeps onghcr.io/lscr.io/quay.io→ Renovate opens the PR and enablesplatformAutomerge..github/workflows/renovate-pr-cooldown.yml(new reusable workflow): posts a requiredpr-cooldowncommit status that stayspendinguntil the PR branch head commit is ≥ 14 days old (a rebase to a newer version restarts the clock). GitHub auto-merge merges the moment it turns green. Human and non-gated PRs always getsuccess, so the required check never blocks anything else.renovate-pr-cooldown-caller.yml),workflow-templates/entry +.properties.jsonfor adoption.base.json5internalChecksFiltercomment from fix(renovate): set internalChecksFilter to strict #284 is corrected (strict is the right default for the timestamp-required path, not the fix for the stuck updates).Datasources with trusted timestamps (docker.io, github tags/releases) keep the native soak and are not gated by
pr-cooldown.Consuming-repo wiring (per ADR 0005)
workflow-templates/renovate-pr-cooldown.yml(triggers:pull_request,schedule,workflow_dispatch).pr-cooldownto the branch ruleset's required status checks.Validation
actionlint,zizmor(no findings),yamllint,yamlfmt -lint,dprint checkall clean (viaconfig-sync/filesconfigs); JSON5 presets parse; embedded github-scriptnode --check+ a mocked decision matrix (gated-old→success, gated-new→pending, docker.io→pass, human→pass) all correct.Caveat
docker.io images that also lack a timestamp (e.g. dozzle/cloudflared/mongo) are intentionally not gated here, per "only the registries we know are unreliable." They can be added to
gated-branch-prefixes+ the packageRule later if desired.Refs DevSecNinja/truenas-apps#115