renovate: exclude the two legacy qbittorrent tags

linuxserver/qbittorrent still carries 14.3.9 and 20.04.1 from earlier tagging
schemes. Docker versioning sorts both above every real release, so Renovate
offers them as major updates - PRs #152 and #153 are exactly those, and they
would have to be closed by hand again after every lookup.

They cost more than the noise. Renovate fills the major bucket once, so while a
stray occupies it the genuine major is never offered at all: measured from
currentValue 4.6.4, the unconstrained lookup returns 4.6.7 and 20.04.1, and
never mentions 5.2.3.

Both are excluded by name. A bound such as "<10" would reject a genuine major
sooner or later, whereas two finished artifacts cannot grow and so cannot mask
a release that does not exist yet. A shape-based filter was tried first and
measured out: requiring a non-padded minor drops 20.04.1 and simply promotes
14.3.9 into its place.

Verified with renovate 44.41.0 (dry-run=lookup) against the live registry:
  currentValue 5.2.1 -> [5.2.3 (patch)], both strays gone
  currentValue 4.6.4 -> [4.6.7 (patch), 5.2.3 (major)]
The second fixture is the guard the nginx rule taught us to run - it proves the
filter does not silently empty the update list. A full run over the real
repository with the real config confirms it in place: qbittorrent offers 5.2.3
only, nginx is unchanged, and no docker dependency carries a skipReason or a
warning.
This commit is contained in:
jklein committed 2026-08-24 15:45:57 +02:00
1 parent 9c81061f92
commit f5da9ce126
2 files changed
+34 -1

No files matched your search

+3 -1
View File
@@ -74,7 +74,9 @@ Each chart renders its main image as `<repo>:{{ .Chart.AppVersion }}` — reposi
A consequence of pinning every tag in `values.yaml`: `ci/renovate-bump-chart.sh` sees an unchanged `appVersion` and bumps the chart **patch**. That holds for all nine images alike — none of them is special — and it is the intended outcome, since `appVersion` here is the chart's own marker rather than a tracked upstream version. A consequence of pinning every tag in `values.yaml`: `ci/renovate-bump-chart.sh` sees an unchanged `appVersion` and bumps the chart **patch**. That holds for all nine images alike — none of them is special — and it is the intended outcome, since `appVersion` here is the chart's own marker rather than a tracked upstream version.
One dependency is constrained beyond its versioning: **nginx** (the Synapse delegation sidecar) is limited to **even minors** via `allowedVersions`. nginx numbers its release branches by minor — even is stable, odd is mainline — and the chart belongs on stable. Patch updates inside the stable branch still flow through normally. The constraint tolerates a variant suffix (`1.30.4-alpine`) on purpose: docker versioning only ever offers candidates carrying the current tag's suffix, so a suffix-blind constraint would silently freeze nginx the day the sidecar moves to a slimmer base image — a switch to `1.30.4-alpine` that #84 has commissioned a check on — with no error and no warning. Two dependencies are constrained beyond their versioning. **nginx** (the Synapse delegation sidecar) is limited to **even minors** via `allowedVersions`. nginx numbers its release branches by minor — even is stable, odd is mainline — and the chart belongs on stable. Patch updates inside the stable branch still flow through normally. The constraint tolerates a variant suffix (`1.30.4-alpine`) on purpose: docker versioning only ever offers candidates carrying the current tag's suffix, so a suffix-blind constraint would silently freeze nginx the day the sidecar moves to a slimmer base image — a switch to `1.30.4-alpine` that #84 has commissioned a check on — with no error and no warning.
**linuxserver/qbittorrent** (freesailarr) excludes two tags by name, `14.3.9` and `20.04.1`. They are leftovers from earlier linuxserver tagging schemes, and docker versioning sorts both above every real release, so Renovate offers them as major updates — PRs #152 and #153 were exactly that. They are named rather than cut off with an upper bound like `<10`, because a bound would eventually reject a genuine major, while two finished artifacts cannot grow and therefore cannot hide a future release. The same guard as for nginx applies and was run: a lookup from `currentValue 4.6.4` still offers `5.2.3` as a **major**, so the filter does not silently empty the update list. That fixture also shows the cost of leaving it alone — without the rule the very same lookup offers `20.04.1` and never mentions the real `5.2.3`, since Renovate fills the major bucket only once.
Not managed: `ci/**` (install-test fixtures pin throwaway infrastructure to major lines on purpose) and `template-chart/**` (placeholder image). A consequence worth knowing: `ci/matrix-synapse/fixtures.yaml` pins a Synapse image that Renovate will not follow — bump it by hand when the chart moves a major. Not managed: `ci/**` (install-test fixtures pin throwaway infrastructure to major lines on purpose) and `template-chart/**` (placeholder image). A consequence worth knowing: `ci/matrix-synapse/fixtures.yaml` pins a Synapse image that Renovate will not follow — bump it by hand when the chart moves a major.
+31
View File
@@ -119,6 +119,37 @@
// "updates": [] and "warnings": []. // "updates": [] and "warnings": [].
allowedVersions: "/^\\d+\\.\\d*[02468]\\.\\d+(-.+)?$/", allowedVersions: "/^\\d+\\.\\d*[02468]\\.\\d+(-.+)?$/",
}, },
{
description: [
"linuxserver/qbittorrent carries two historic tags from earlier tagging schemes,",
"14.3.9 and 20.04.1, which docker versioning sorts above every real release and",
"offers as major updates — PRs #152 and #153 are exactly those. Both are excluded",
"by name.",
],
matchDatasources: ["docker"],
matchPackageNames: [
"linuxserver/qbittorrent",
"docker.io/linuxserver/qbittorrent",
],
// Excluded by name rather than by a bound such as "<10": the strays are
// finished artifacts that cannot grow, so naming them can never block a
// release that does not exist yet, while any upper bound would sooner or
// later reject a genuine major. Shape-based filters were measured and
// rejected too: requiring a non-padded minor removes 20.04.1 and leaves
// 14.3.9 (verified, the lookup then offers 14.3.9 instead).
//
// Verified with renovate 44.41.0 (dry-run=lookup, real registry), two
// fixtures against the live tag list:
// currentValue 5.2.1 -> updates [5.2.3 (patch)]; both strays gone.
// currentValue 4.6.4 -> updates [4.6.7 (patch), 5.2.3 (major)].
// The second fixture is the guard the nginx rule taught us to run: it
// proves a genuine major still comes through instead of the filter
// silently emptying the update list. It also shows what the strays cost
// today — without the rule that same lookup offers 20.04.1 as the major
// candidate and never mentions the real 5.2.3, because Renovate fills
// the major bucket once.
allowedVersions: "!/^(14\\.3\\.9|20\\.04\\.1)$/",
},
], ],
customManagers: [ customManagers: [