Skip to content

feat: support --labels on helm install and helm upgrade #277

@JonathanCrt

Description

@JonathanCrt

Background

Helm 3.14 added -l, --labels stringToString on helm install and helm upgrade. Labels are attached to the release record (and copied onto the Secret/ConfigMap storing release state), useful for filtering and for org/billing tagging.

Helm SDK exposes this as (*action.Install).Labels map[string]string and (*action.Upgrade).Labels map[string]string (install.go:101).

Acceptance criteria

  • InstallCommand.withLabel(String key, String value) adds a single label; multiple calls accumulate
  • Same on UpgradeCommand (helm 3.14+ supports it there too)
  • Labels reach the underlying helm Release record (verifiable in the storage Secret)
  • Integration test confirms install/upgrade succeeds with labels and surfaces no errors

Proposed Java API

helm.install()
    .withName("r")
    .withLabel("env", "prod")
    .withLabel("team", "platform")
    .withKubeConfig(kc)
    .call();

Implementation guide

The codebase already passes Map<String,String> over JNA as a URL-encoded string. Copy this pattern for labels — see how Values flows.

Java side (InstallCommand.java, UpgradeCommand.java)

  • Add private final Map<String,String> labels = new LinkedHashMap<>(); field.
  • Add withLabel(String key, String value) (append into the map; return this).
  • In call(), pass urlEncode(labels) as the new labels argument (helper already exists in HelmCommand).

JNA (InstallOptions.java, UpgradeOptions.java)

  • Add public String labels; field; update @Structure.FieldOrder (append at the end) and the constructor signature.

CGO bridge (native/main.go)

  • Add char* labels; to struct InstallOptions and struct UpgradeOptions. The field order must match the Java @Structure.FieldOrder exactly.
  • Pass through: Labels: C.GoString(options.labels).

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

  • Add Labels string field to the Go options struct (URL-encoded; decoded inside Install/Upgrade).
  • Decode with url.ParseQuery(options.Labels) (same pattern as mergeValues in install.go:289 for Values).
  • Convert url.Valuesmap[string]string (take the first value per key).
  • Set client.Labels = ....

Tests

  • Add to HelmKubernetesTest.Install and HelmKubernetesTest.Upgrade nested classes. Labels persist in the release Secret, so client-only mode won't exercise them — needs the real KinD container.
  • Scenarios:
    • Install with a single label — no exception, release lands as deployed
    • Install with multiple labels — same
    • Upgrade adding a label to a release that had none — succeeds
  • Optionally: fetch the release Secret with the Fabric8 / k8s client (already on the test classpath via Testcontainers/KinD) and assert the metadata.labels block contains the expected entries. If too heavy, omit and trust the SDK.

Contributor checklist

  • Java 8 syntax only
  • Apache 2.0 header
  • @author Javadoc tag
  • DCO sign-off
  • make build-native && ./mvnw test -pl helm-java -Dtest=HelmKubernetesTest 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