fix: strip OCI chart pull progress from rendered manifests (#1040) - #1041
Merged
Conversation
yxxhero
force-pushed
the
fix/oci-three-way-merge-1040
branch
2 times, most recently
from
August 1, 2026 07:26
450c302 to
7acd90a
Compare
When templating an OCI-hosted chart (or a chart with OCI subcharts),
Helm writes the chart pull progress to stdout before the rendered
manifests:
Pulled: public.ecr.aws/karpenter/karpenter:1.9.0
Digest: sha256:8e3952caafd208cb888fbf97467cd04a4a024a3fba64c84af73039040cc6a371
---
# Source: ...
These progress lines leaked into the manifest buffer returned by the
`helm template` code paths and got parsed as a YAML document lacking a
Kind, breaking the downstream three-way-merge and take-ownership
`kubeclient.Build()` calls:
unable to decode "": Object 'Kind' is missing in
'{"Digest":"...","Pulled":"..."}'
This affected `helm diff upgrade --three-way-merge`/`--take-ownership`
(the regular diff and `helm diff local` paths were not broken because
`manifest.Parse()` already skips documents without apiVersion/kind).
Strip the OCI pull progress lines ("Pulled:", "Digest:", and
defensively "Pulling:") from the `helm template` output in both places
that capture it:
* cmd/helm.go `template()` -> upgrade (three-way-merge / take-ownership)
* cmd/local.go `renderChart()` -> local diff
Stripping at the source ensures `manifest.Generate()` (three-way-merge),
the take-ownership `Build()` call, and `manifest.Parse()` all receive
clean manifests, and keeps both `helm template` callers symmetric.
The lines are matched at the start of a line (column 0), which is safe
because top-level Kubernetes manifest keys are apiVersion/kind/metadata/
spec and never "Pulled"/"Digest"/"Pulling"; any homonymous keys nested
inside a manifest are indented and therefore not matched.
Fixes #1040
Signed-off-by: yxxhero <aiopsclub@163.com>
yxxhero
force-pushed
the
fix/oci-three-way-merge-1040
branch
from
August 1, 2026 07:47
7acd90a to
93dce5f
Compare
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
helm diff upgrade --three-way-merge(and--take-ownership) fails with OCI-hosted charts because Helm writes the chart pull progress to stdout before the rendered manifests:The
helm templatecode path in helm-diff used a no-op filter, so these lines leaked into the manifest buffer and got parsed as a YAML document lacking aKind, breakingkubeclient.Build():This only affects the
helm templatepath. TheHELM_DIFF_USE_UPGRADE_DRY_RUN=truepath works becauseextractManifestFromHelmUpgradeDryRunOutputonly keeps theMANIFEST:/HOOKS:sections, discarding the leading progress output.Fixes #1040.
Fix
Strip Helm's OCI chart pull progress lines (
Pulled:,Digest:,Pulling:) from thehelm templateoutput before it is returned, fixing the leak at the source. This benefits bothmanifest.Generate()(three-way-merge) and the--take-ownershipBuild()call, which bothkubeclient.Build()the templated manifest.Why is the regex safe?
The lines are matched at the start of a line (column 0). Top-level Kubernetes manifest keys are
apiVersion/kind/metadata/specand are neverPulled/Digest/Pulling. Any homonymous keys nested inside a manifest (e.g. underdata:ormetadata:) are indented and therefore not matched.Verification
go build ./...go vet ./...golangci-lint run ./cmd/→ 0 issuesgo test ./...→ all passTestStripOCIPullProgresscovering: progress prepended to manifests, all three line variants, no-op on clean output, indented keys preserved, progress-only input, and empty input.Checklist
helm templatefilter), so it covers three-way-merge and take-ownership paths.