From b20b6b5f143e2e0fa12d88a0c406951f3af8f255 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Apr 2026 01:06:27 +0000 Subject: [PATCH] fix: restrict --output-dir + --post-renderer workaround to Helm 3 only Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/229b14e2-b1ad-4f19-bd00-b8f7821383cd Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --- pkg/helmexec/exec.go | 5 +++-- pkg/helmexec/exec_test.go | 18 +++++++++++++----- test/integration/test-cases/issue-2515.sh | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index ec1454fb..acc73fc6 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -658,9 +658,10 @@ func (helm *execer) TemplateRelease(name string, chart string, flags ...string) } } - if outputToFile && hasPostRenderer { - // Helm does not apply --post-renderer to files written by --output-dir. + if outputToFile && hasPostRenderer && helm.IsHelm3() { + // Helm 3 does not apply --post-renderer to files written by --output-dir. // It writes pre-post-renderer content to files and sends post-renderer output to stdout. + // Helm 4 handles this correctly, so the workaround is only needed for Helm 3. // Workaround: run without --output-dir, capture stdout (with post-renderer applied), // and write the output to the output directory ourselves. var outputDir string diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 760315a8..109c6b30 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -21,8 +21,9 @@ import ( // Mocking the command-line runner type mockRunner struct { - output []byte - err error + output []byte + versionOutput []byte // if set, returned for "helm version --short" probe; overrides default Helm 4 fallback + err error } func (mock *mockRunner) ExecuteStdIn(cmd string, args []string, env map[string]string, stdin io.Reader) ([]byte, error) { @@ -30,8 +31,13 @@ func (mock *mockRunner) ExecuteStdIn(cmd string, args []string, env map[string]s } func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string, enableLiveOutput bool) ([]byte, error) { - if len(mock.output) == 0 && strings.Join(args, " ") == "version --short" { - return []byte("v4.0.1+g12500dd"), nil + if strings.Join(args, " ") == "version --short" { + if mock.versionOutput != nil { + return mock.versionOutput, nil + } + if len(mock.output) == 0 { + return []byte("v4.0.1+g12500dd"), nil + } } return mock.output, mock.err } @@ -1260,7 +1266,9 @@ func Test_Template_PostRendererWithOutputDir(t *testing.T) { var buffer bytes.Buffer logger := NewLogger(&buffer, "debug") - runner := &mockRunner{} + // Use Helm 3 version for the version probe so the Helm 3 workaround is applied. + // The workaround is not needed for Helm 4, which natively applies --post-renderer to --output-dir output. + runner := &mockRunner{versionOutput: []byte("v3.20.0")} helm, err := New("helm", HelmExecOptions{}, logger, "config", "dev", runner) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/test/integration/test-cases/issue-2515.sh b/test/integration/test-cases/issue-2515.sh index c99023f8..b18b2ee3 100644 --- a/test/integration/test-cases/issue-2515.sh +++ b/test/integration/test-cases/issue-2515.sh @@ -2,7 +2,7 @@ issue_2515_case_dir="$(cd "${cases_dir}/issue-2515" && pwd)" issue_2515_tmp=$(mktemp -d) if [ "${HELMFILE_HELM4}" = "1" ]; then - info "Skipping issue-2515 test for Helm 4 (post-renderer requires plugin)" + info "Skipping issue-2515 test for Helm 4 (Helm 4 natively applies --post-renderer to --output-dir output)" test_start "issue-2515 post-renderer with output-dir-template (skipped for Helm 4)" test_pass "issue-2515 post-renderer with output-dir-template (skipped for Helm 4)" else