pull/31954/merge
Sumit Solanki 3 days ago committed by GitHub
commit 09cde635e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -150,6 +150,19 @@ const (
// "---apiVersion: v1" which is not a valid YAML document separator.
// This function inserts a newline after any "---" at the start of a line
// that is immediately followed by non-whitespace content.
// ensureTrailingNewlineForYAML appends a final newline when the input omits one.
// kyaml's reader does not add a trailing newline to the last YAML document when
// splitting streams (see kio.ByteReader.Read); parsing and re-serializing then
// rewrites literal block scalars from "|" to "|-" (strip chomping). A trailing
// newline at EOF avoids that round-trip change so post-renderer merge/split
// matches direct template output. See https://github.com/helm/helm/issues/31948
func ensureTrailingNewlineForYAML(content string) string {
if content == "" || strings.HasSuffix(content, "\n") {
return content
}
return content + "\n"
}
func fixDocSeparators(content string) string {
var b strings.Builder
remaining := content
@ -198,6 +211,7 @@ func annotateAndMerge(files map[string]string) (string, error) {
// separator. Insert the missing newline so kio.ParseAll can
// parse the content correctly.
content = fixDocSeparators(content)
content = ensureTrailingNewlineForYAML(content)
manifests, err := kio.ParseAll(content)
if err != nil {
@ -221,6 +235,7 @@ func annotateAndMerge(files map[string]string) (string, error) {
// splitAndDeannotate reconstructs individual files from a merged YAML stream,
// removing filename annotations and grouping documents by their original filenames.
func splitAndDeannotate(postrendered string) (map[string]string, error) {
postrendered = ensureTrailingNewlineForYAML(postrendered)
manifests, err := kio.ParseAll(postrendered)
if err != nil {
return nil, fmt.Errorf("error parsing YAML: %w", err)

@ -710,6 +710,40 @@ metadata:
}
}
// Regression: https://github.com/helm/helm/issues/31948 — kyaml parse/serialize
// without a trailing newline rewrites "|" block scalars to "|-" unless we normalize EOF.
func TestAnnotateAndMerge_PreservesLiteralBlockScalarWithoutEOFNewline(t *testing.T) {
files := map[string]string{
"templates/cm.yaml": `apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
data:
value: |
my value
with multiple lines`,
}
merged, err := annotateAndMerge(files)
require.NoError(t, err)
assert.Contains(t, merged, "value: |")
assert.NotContains(t, merged, "value: |-")
// Original behavior: splitAndDeannotate on the merged stream as produced.
reconstructed, err := splitAndDeannotate(merged)
require.NoError(t, err)
out := reconstructed["templates/cm.yaml"]
assert.Contains(t, out, "value: |")
assert.NotContains(t, out, "value: |-")
// New regression coverage: simulate a post-renderer output stream lacking a trailing newline.
mergedNoEOF := strings.TrimSuffix(merged, "\n")
reconstructedNoEOF, err := splitAndDeannotate(mergedNoEOF)
require.NoError(t, err)
outNoEOF := reconstructedNoEOF["templates/cm.yaml"]
assert.Contains(t, outNoEOF, "value: |")
assert.NotContains(t, outNoEOF, "value: |-")
}
func TestSplitAndDeannotate(t *testing.T) {
tests := []struct {
name string

Loading…
Cancel
Save