Skip to content

feat: support --post-renderer (exec a binary) on install / upgrade / template #269

@nightink

Description

@nightink

Background

Helm's --post-renderer flag runs an external binary that receives rendered YAML on stdin and outputs modified YAML on stdout. Typical use cases: kustomize patches, sealed-secrets transforms, security policy injection.

Helm SDK exposes this via the postrender.PostRenderer interface, and ships postrender.NewExec(binaryPath, args...) (upstream) — exactly the CLI behavior.

Scope — external binary only

A Java-callback PostRenderer (where Java code transforms the YAML in-process) requires JNA callbacks back into Java from Go and is out of scope for this issue. Stick to the exec-binary path that matches helm CLI's --post-renderer. If the callback path is wanted later, file a separate issue.

Acceptance criteria

  • withPostRenderer(Path binary, String... args) on InstallCommand, UpgradeCommand, and TemplateCommand
  • When set, helm executes the binary, pipes rendered YAML in, and uses the transformed output
  • If the binary is missing / not executable / exits non-zero, surface a meaningful error to the Java caller
  • Integration tests with a tiny shell script that mutates the output, asserting the change shows up in the rendered manifest

Proposed Java API

helm.template()
    .withPostRenderer(Paths.get("/usr/local/bin/my-transform.sh"), "--arg1", "--arg2")
    .call();

Implementation guide

Go (native/internal/helm/install.go, upgrade.go, template.go)

  • Add PostRenderer string (binary path) and PostRendererArgs []string to each options struct.
  • When PostRenderer != "":
    pr, err := postrender.NewExec(options.PostRenderer, options.PostRendererArgs...)
    if err != nil { return "", err }
    client.PostRenderer = pr

CGO bridge (native/main.go)

  • Add char* postRenderer; and char* postRendererArgs; to the install/upgrade/template structs.
  • For args: pass as a single string with a separator (e.g. \n); split Go-side. Avoid , since arg values may legitimately contain it.

JNA + Java

  • Add public String postRenderer; and public String postRendererArgs; to each *Options.java. Update @Structure.FieldOrder and constructors.
  • Add withPostRenderer(Path binary, String... args) to the three commands. Join args with the same separator the Go side splits on.

Tests

  • Add to HelmInstallTest, HelmUpgradeTest, HelmTemplateTest.
  • Use @TempDir to write a tiny test renderer script per test. Skip on Windows (@DisabledOnOs(OS.WINDOWS)) — no POSIX shell.
  • Sample renderer:
    #!/bin/sh
    sed 's/replicas: 1/replicas: 99/g'
  • After running with the post-renderer set, assert the rendered output contains replicas: 99.
  • Also cover: missing binary path → exception with a clear message.

Contributor checklist

  • Java 8 syntax only
  • Apache 2.0 header
  • @author Javadoc tag
  • DCO sign-off
  • make build-native && ./mvnw test -pl helm-java green

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions