From f0e418026a07e36ba2a6d59366d062ffdc5a09c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 00:06:08 +0000 Subject: [PATCH 1/2] Initial plan From d38b67fed1fb45e00de80b6a74e15f151d446f28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 00:15:55 +0000 Subject: [PATCH 2/2] Fix empty render crash: treat no-output helm template as no-op When helm template --output-dir produces an empty directory (e.g. all templates are gated behind a falsy conditional), ReplaceWithRendered now removes the chart's content dirs and returns successfully with an empty file list instead of crashing with an assertion error. Adds test chart testdata/charts/emptychart and integration test 'empty render no op' to cover this scenario. Closes #206 --- integration_test.go | 15 +++++++++++++++ replace.go | 17 +++++++++++++++++ testdata/charts/emptychart/Chart.yaml | 6 ++++++ .../charts/emptychart/templates/configmap.yaml | 8 ++++++++ testdata/charts/emptychart/values.yaml | 3 +++ .../testcases/empty_render_no_op/want | 1 + 6 files changed, 50 insertions(+) create mode 100644 testdata/charts/emptychart/Chart.yaml create mode 100644 testdata/charts/emptychart/templates/configmap.yaml create mode 100644 testdata/charts/emptychart/values.yaml create mode 100644 testdata/integration/testcases/empty_render_no_op/want diff --git a/integration_test.go b/integration_test.go index 8b24b9c..49d881e 100644 --- a/integration_test.go +++ b/integration_test.go @@ -265,6 +265,21 @@ func TestIntegration(t *testing.T) { chart: "./testdata/charts/importvalues", }) + // SAVE_SNAPSHOT=1 go1.25 test -run ^TestIntegration/empty_render_no_op$ ./ + // Tests that a chart whose templates all render to nothing (e.g. gated behind a falsy + // conditional) is treated as a no-op rather than causing an assertion error. + // See https://github.com/helmfile/chartify/issues/206 + runTest(t, integrationTestCase{ + description: "empty render no op", + release: "myapp", + chart: "./testdata/charts/emptychart", + opts: ChartifyOpts{ + // OverrideNamespace ensures ReplaceWithRendered is called even though + // no Patches/Injectors are configured, exercising the empty-render path. + OverrideNamespace: "test-ns", + }, + }) + // // Kubernets Manifests // diff --git a/replace.go b/replace.go index d83cfd2..04a3304 100644 --- a/replace.go +++ b/replace.go @@ -132,6 +132,23 @@ func (r *Runner) ReplaceWithRendered(name, chartName, chartPath string, o Replac return nil, fmt.Errorf("unable to read helm output dir entries: %w", err) } + // When the chart renders no resources, helm template --output-dir produces an empty + // directory. Treat this as a no-op: remove original content dirs so that subsequent + // helm processing also sees no resources, clean up the temp output dir, and return + // an empty file list with no error. + if len(helmOutputDirEntries) == 0 { + if err := os.RemoveAll(helmOutputDir); err != nil { + return nil, fmt.Errorf("cleaning up empty helm output dir: %v", err) + } + for _, d := range ContentDirs { + origDir := filepath.Join(chartPath, d) + if err := os.RemoveAll(origDir); err != nil { + return nil, err + } + } + return nil, nil + } + // This directory contains templates/ and charts/SUBCHART/templates var chartOutputDir string diff --git a/testdata/charts/emptychart/Chart.yaml b/testdata/charts/emptychart/Chart.yaml new file mode 100644 index 0000000..2613056 --- /dev/null +++ b/testdata/charts/emptychart/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: emptychart +description: A Helm chart whose templates are all conditionally disabled, used to test empty render handling +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/testdata/charts/emptychart/templates/configmap.yaml b/testdata/charts/emptychart/templates/configmap.yaml new file mode 100644 index 0000000..a5668cd --- /dev/null +++ b/testdata/charts/emptychart/templates/configmap.yaml @@ -0,0 +1,8 @@ +{{- if .Values.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cm +data: + hello: world +{{- end }} diff --git a/testdata/charts/emptychart/values.yaml b/testdata/charts/emptychart/values.yaml new file mode 100644 index 0000000..5cb6585 --- /dev/null +++ b/testdata/charts/emptychart/values.yaml @@ -0,0 +1,3 @@ +# When enabled is false (the default), this chart renders no resources, +# which exercises the empty-render code path in chartify. +enabled: false diff --git a/testdata/integration/testcases/empty_render_no_op/want b/testdata/integration/testcases/empty_render_no_op/want new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/testdata/integration/testcases/empty_render_no_op/want @@ -0,0 +1 @@ +