Background
helm rollback reverts a release to a previous revision. Without it, recovering from a bad install/upgrade requires uninstall + re-install, losing release history. See helm rollback docs.
Helm SDK action: action.NewRollback (upstream).
Acceptance criteria
Proposed Java API
Release r = Helm.rollback("my-release")
.toRevision(2)
.cleanupOnFail()
.waitReady()
.withTimeout(300)
.withKubeConfig(kubeConfigPath)
.call();
Implementation guide
Follow AGENTS.md → "Adding a new Helm command" for the 9-step workflow.
Reference impl to copy patterns from: StatusCommand — same shape (keyed by release name, returns Release, uses Release.parseSingle()).
Go (native/internal/helm/rollback.go)
- Build config with
NewCfg(&CfgOptions{ KubeConfig, KubeConfigContents, Namespace }) — same as status.go.
client := action.NewRollback(cfg). Map options: client.Version (= revision; 0 means previous), CleanupOnFail, DryRun, Force, DisableHooks, Wait, Timeout (time.Duration(seconds) * time.Second), MaxHistory.
client.Run(releaseName) returns only an error (no payload).
- After success, fetch state with
action.NewStatus(cfg).Run(name) and return StatusReport(rel, true, options.Debug) — same pattern as status.go.
CGO bridge (native/main.go)
- Add
struct RollbackOptions { ... } next to the other option structs.
- Add
//export Rollback wrapping helm.Rollback(...) via runCommand(func() (string, error) { ... }).
JNA + Java
lib/api/.../RollbackOptions.java: mirror the C struct field order exactly (@Structure.FieldOrder).
- Add
Result Rollback(RollbackOptions options) to HelmLib.
helm-java/.../RollbackCommand.java extends HelmCommand<Release>; call() returns parseSingle(run(hl -> hl.Rollback(...))).
- Add
Helm.rollback(String releaseName) static factory next to Helm.status(...).
Tests
- Add as a nested
Rollback class inside HelmKubernetesTest, not a separate file — the KinD container is shared via @BeforeAll. Use the static kubeConfigFile / kubeConfigContents fields.
- Scenario suggestions:
- Valid:
toPreviousRevision (install → upgrade → rollback → assert revision == "3"), toSpecificRevision, withNamespace, withKubeConfigContents
- Invalid:
nonExistentRelease → assertThatThrownBy(cmd::call).hasMessageContaining("release: not found")
- Skeleton:
@Nested
class Rollback {
@Nested
class Valid {
@Test
void toPreviousRevision() {
helm.install().withKubeConfig(kubeConfigFile).withName("r1").call();
helm.upgrade().withKubeConfig(kubeConfigFile).withName("r1").call();
Release r = Helm.rollback("r1").withKubeConfig(kubeConfigFile).call();
assertThat(r).returns("3", Release::getRevision);
}
}
}
Contributor checklist
References
Background
helm rollbackreverts a release to a previous revision. Without it, recovering from a bad install/upgrade requires uninstall + re-install, losing release history. See helm rollback docs.Helm SDK action:
action.NewRollback(upstream).Acceptance criteria
Helm.rollback("release").call()rolls a release back one revision and returns the resultingRelease.toRevision(int)targets a specific revision;0(or unset) = previous--cleanup-on-fail,--dry-run,--force,--no-hooks,--wait,--timeout,--history-max,--namespace,--debug, kube-config (path + contents)HelmKubernetesTest.Rollback(nested class — shares the KinD container)IllegalStateExceptionProposed Java API
Implementation guide
Follow AGENTS.md → "Adding a new Helm command" for the 9-step workflow.
Reference impl to copy patterns from:
StatusCommand— same shape (keyed by release name, returnsRelease, usesRelease.parseSingle()).Go (
native/internal/helm/rollback.go)NewCfg(&CfgOptions{ KubeConfig, KubeConfigContents, Namespace })— same asstatus.go.client := action.NewRollback(cfg). Map options:client.Version(= revision; 0 means previous),CleanupOnFail,DryRun,Force,DisableHooks,Wait,Timeout(time.Duration(seconds) * time.Second),MaxHistory.client.Run(releaseName)returns only anerror(no payload).action.NewStatus(cfg).Run(name)and returnStatusReport(rel, true, options.Debug)— same pattern asstatus.go.CGO bridge (
native/main.go)struct RollbackOptions { ... }next to the other option structs.//export Rollbackwrappinghelm.Rollback(...)viarunCommand(func() (string, error) { ... }).JNA + Java
lib/api/.../RollbackOptions.java: mirror the C struct field order exactly (@Structure.FieldOrder).Result Rollback(RollbackOptions options)toHelmLib.helm-java/.../RollbackCommand.javaextendsHelmCommand<Release>;call()returnsparseSingle(run(hl -> hl.Rollback(...))).Helm.rollback(String releaseName)static factory next toHelm.status(...).Tests
Rollbackclass insideHelmKubernetesTest, not a separate file — the KinD container is shared via@BeforeAll. Use the statickubeConfigFile/kubeConfigContentsfields.toPreviousRevision(install → upgrade → rollback → assert revision == "3"),toSpecificRevision,withNamespace,withKubeConfigContentsnonExistentRelease→assertThatThrownBy(cmd::call).hasMessageContaining("release: not found")Contributor checklist
var,Path.of, records,Map.of)make license)@authorJavadoc tag on each new classgit commit -s)make build-native && ./mvnw test -pl helm-java -Dtest=HelmKubernetesTestpasses locallyReferences
StatusCommand.java+native/internal/helm/status.go