flux manager: OCI HelmRelease with HelmRepository in a separate file rebases its branch on every run #45438
Replies: 5 comments
|
Your analysis checks out against the source at 44.40.0. I re-read the three files you cited and they behave exactly as you describe, and all three are byte-identical on current main (44.44.0 was tagged today), so no released version fixes this yet. Confirmed from source:
That places the failure between two extraction paths inside the flux manager, which config cannot reconcile properly. With a minimal repro plus the pipeline-volume numbers, this looks worth promoting to an issue. Of the threads you linked, #20906 is the closest relative, but its cause (post-upgrade tasks) is distinct, so it does not cover this behavior. Until a fix lands, your two workarounds are the practical options. One addition on I have not executed your repro repo myself; the above comes from reading the linked files at the 44.40.0 tag and diffing them against main. |
|
Thanks for the detailed source review — that matches what we see, and I can add a data point on newer releases. Our bot is not pinned to a chart version, so it has been picking up releases on its own while this thread was open. It has moved The behavior is unchanged on So the loop reproduces on Two more notes that may be useful when this becomes an issue:
Happy to run anything specific against the reproduction repo if it would help. |
|
Hi! Just catching up on this thread. @aschyolkin, your release sweep turned my source read into something much harder to argue with, thanks for doing it. One thing your notes clarify for me: if The namespace finding feels like the strongest argument for fixing this in the manager rather than documenting a |
|
Happy to write those up — one small thing first: #45441 is a On The seven excluded pairsAll seven are Flux Because that comparison already fails during the full extraction, these pairs get They fall into two shapes: Shape A — # HelmRelease
metadata:
namespace: flux-system
spec:
chart:
spec:
sourceRef:
kind: HelmRepository
name: some-chart
namespace: team-ns # <- overrides the comparison
---
# HelmRepository, separate file
metadata:
name: some-chart
namespace: flux-system # <- matches the HelmRelease, but not sourceRef.namespaceShape B — the HelmRepository has no namespace at all (5 pairs) # HelmRelease
metadata:
namespace: team-ns
spec:
chart:
spec:
sourceRef:
kind: HelmRepository
name: some-chart # no namespace -> falls back to team-ns
---
# HelmRepository, separate file
metadata:
name: some-chart # no namespace -> undefinedWhy this shape exists at allThese manifests are not broken at runtime. The Flux That is the part I would flag for any routing change: the namespace in the manifest is not authoritative when a parent For a fix in the manager, a regression test with both shapes above (asserting that full and single-file extraction agree, whatever the outcome) would cover the edge. The property that matters is not "the chart resolves" but "both paths agree", which also holds for the deliberately unresolvable cases. We are keeping these seven out of our |
|
@aschyolkin You are right, my mistake on the number: #45441 is the component-prefixed tags fix and unrelated to the flux rebase loop. Thanks for writing the seven pairs up here instead. I searched the issue tracker just now and found nothing tracking the OCI HelmRepository rebase loop, so there is no number to hand you yet. This thread seems like a candidate for a tracking issue once someone from the team picks it up; it has a confirmed reproduction spanning 44.40 through 44.45.4 plus a dedicated repro repository. Your image-branch split is a useful constraint either way: three extra loops, all in package files that also carry an unresolvable chart, none where the chart resolves. That fits the per-file signature reading even without a test isolating it. |
Uh oh!
There was an error while loading. Please reload this page.
What is the problem?
When a Flux
HelmReleasegets its chart from an OCIHelmRepositorythat is defined in a separate file, Renovate re-creates and force-pushes the existing update branch on every run.The new commit has a byte-identical diff to the previous one — only the parent and the SHA change. Because every push starts a new merge request pipeline, this produces an endless stream of pipelines and CI comments. In our repository this rebuilds 23 branches every 15 minutes; the oldest affected MR has accumulated roughly 500 pipelines and 1000 CI comments.
The debug log shows the branch is not conflicted and reuse was intended, yet the branch is rebuilt anyway:
Minimal reproduction
https://github.com/aschyolkin/renovate-flux-oci-repro
reloader.Analysis
extractAllPackageFilescallscollectHelmRepos(manifests)over all files, so it finds the neighbouringhelmrepository.yaml. Fortype: oci,resolveHelmRepositorysetsdatasource=dockerandpackageName=ghcr.io/stakater/charts/reloader— flux/extract.ts#L122-L170.checkBranchDepsMatchBaseDepsre-extracts the branch content through the single-fileextractPackageFile, wherecollectHelmRepos([manifest])only seeshelmrelease.yaml.matchingRepositoriesis empty, so the dependency falls through toskipReason: 'unknown-registry'with nopackageName— auto-replace.ts#L173-L186.getDepsSignaturecomparesdepName + packageName, so the two extraction paths can never agree, andget-updated.tsunconditionally falls back toreuseExistingBranch: false, rebuilding the branch from the base branch — get-updated.ts#L253-L257.A plain HTTP
HelmRepositoryis unaffected:packageNameis left unset in both extraction paths andregistryUrlsis not part of the signature, so the signatures match. That is why only OCI repositories loop.Note that
rebaseWhen: "never"does not help — it only affectsshouldReuseExistingBranchhigher up the stack, while the reset inget-updated.tsis unconditional.Expected behavior
A branch whose package file has not changed should be reused rather than rebuilt. The branch-reuse check should either extract with cross-file context, the way
extractAllPackageFilesdoes, or compare a dependency identity that is stable across both extraction paths.Workarounds
Both make the single-file extraction produce the same
packageName:registryAliaseskeyed bysourceRef.name. Note that the example in the flux manager readme uses"matchDatasources": ["helm"], which does not apply here: after full extraction the dependency is alreadydatasource=docker, so the filter has to be omitted.{ "packageRules": [ { "matchManagers": ["flux"], "registryAliases": { "reloader": "oci://ghcr.io/stakater/charts" } } ] }Merging the
HelmRepositoryand theHelmReleaseinto a single multi-document YAML file.Version
Reproduced on 44.40.0. The same implementation is present in current
main.Possibly related but with different root causes: #20906, #10358, #19835.
All reactions