Skip to content

Migrate to Helm v4 SDK - #1873

Open
dennismdejong wants to merge 3 commits into
hashicorp:mainfrom
dennismdejong:feat/1730-helm4-migration
Open

Migrate to Helm v4 SDK#1873
dennismdejong wants to merge 3 commits into
hashicorp:mainfrom
dennismdejong:feat/1730-helm4-migration

Conversation

@dennismdejong

Copy link
Copy Markdown

Rollback Plan

If a change needs to be reverted, we will publish an updated version of the library.

Changes to Security Controls

No changes to security controls.

Description

This PR migrates the provider from the Helm v3 SDK (helm.sh/helm/v3) to the Helm v4 SDK (helm.sh/helm/v4 v4.2.3), resolving issues #1730 and #1792.

What changed

  • Dependency bump: helm.sh/helm/v3helm.sh/helm/v4 v4.2.3; k8s.io deps upgraded to v0.36.1
  • Import paths: All 31 helm.sh/helm/v3/... imports updated to helm.sh/helm/v4/... across 6 source files + tests
  • Removed packages: chartutil, releaseutil, pkg/repo, pkg/postrender no longer exist in v4:
    • Added helm/compat_v4.go shims for ParseKubeVersion, SplitManifests, and dependency conversion
    • Added helm/postrender_exec.go to preserve binary-path post-renderer support (v3's postrender.NewExec was removed)
  • Action field changes (v4 API):
    • Wait bool → WaitStrategy (kube.WaitStrategy)
    • WaitForJobs → handled by StatusWatcherStrategy
    • AtomicRollbackOnFailure
    • Force/ForceUpdateForceReplace
    • DryRunDryRunStrategy
    • ClientOnlyDryRunStrategy
    • Removed Recreate (removed in Helm v4)
  • Type assertions: loader.Load returns chart.Charter (→ *v2.Chart); action Run() returns release.Releaser (→ *v1.Release)
  • Config: actionConfig.Init no longer accepts a logging callback
  • Tests: Updated test helpers (kube.GetConfigConfigFlags, StatusDeployedrelease/common, status action fields)

Breaking changes for users

  • Bundled Helm engine is now v4 (server-side apply default, digest pinning, multi-doc YAML values)
  • postrender binary executables are deprecated in favor of Helm v4 plugins (still supported via compat layer)
  • recreate_pods is no longer supported

Acceptance tests

  • Have you added an acceptance test for the functionality being added?

(Note: This is a large migration. Acceptance tests require a live Kubernetes cluster and were not run here; the code compiles and passes go vet.)

Release Note

Migrate the provider to the Helm v4 SDK

References

Fixes #1730, Fixes #1792

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Bump helm.sh/helm from v3 to v4 (v4.2.3) and adapt the provider to the
Helm v4 SDK breaking changes:

- Update all import paths from helm.sh/helm/v3 to helm.sh/helm/v4
- Upgrade k8s.io dependencies to v0.36.1
- Add compat_v4.go shims for chartutil and releaseutil packages removed
  in Helm v4 (ParseKubeVersion, SplitManifests, dependency conversion)
- Add postrender_exec.go to preserve binary-path post-renderer support
  (postrender.NewExec was removed in Helm v4)
- Adapt action fields:
  * Wait bool -> WaitStrategy (kube.WaitStrategy)
  * WaitForJobs -> handled by StatusWatcherStrategy
  * Atomic -> RollbackOnFailure
  * Force/ForceUpdate -> ForceReplace
  * DryRun -> DryRunStrategy
  * ClientOnly -> DryRunStrategy
  * Remove Recreate (removed in Helm v4)
- Type-assert loader.Load results (chart.Charter) to *v2.Chart
- Type-assert Run() results (release.Releaser) to *v1.Release
- actionConfig.Init no longer accepts a logging callback
- Update test helpers (kube.GetConfig -> ConfigFlags, StatusDeployed ->
  release/common) and status action fields
- Add CHANGELOG entry for the Helm v4 migration

Fixes hashicorp#1730 and hashicorp#1792
@dennismdejong
dennismdejong requested review from a team, iam404 and rigalGit as code owners August 20, 2026 17:55
This was referenced Aug 20, 2026
- postrender: update expected error pattern for Helm v4 YAML parsing error
- invalidName: update expected error pattern for Helm v4 release name validation
- LintFailChart: update expected error pattern for Helm v4 lint output
- ModifyPlan: preserve prior metadata when no relevant attributes change
  to avoid spurious diffs under Helm v4 server-side apply
- Add needsPlainHTTP helper to enable plain-HTTP (non-TLS) for local OCI
  registries (localhost/127.0.0.1), fixing OCI pulls against local registries
- Create a dedicated plain-HTTP registry client (with the shared credentials
  file) for local OCI registries so login credentials are shared with pulls
- Fix valuesUnknown to check set_list values (was reading plan.Set twice)
- Strip metadata.generation in normalizeK8sObject to avoid spurious resource
  diffs under Helm v4 server-side apply
- Map force_update to ForceConflicts (not ForceReplace) since ForceReplace
  cannot be combined with server-side apply in Helm v4
- Update test helpers to prefer podman over docker for the OCI test registry
- Update acceptance test error patterns and drift checks for Helm v4 behavior

All acceptance tests now pass against a live minikube cluster (podman driver).
@dennismdejong

Copy link
Copy Markdown
Author

Acceptance test results

All acceptance tests now pass against a live Kubernetes cluster (minikube v1.38.1 with the podman driver, Kubernetes v1.35.1).

Ran the full TestAcc suite: all tests pass (ok ... 241s).

What was validated

  • helm_release: basic CRUD, values/set/set_list/literalSet/set_wo, postrender, update, upgrade_install (cold+warm start), dependency, delete_regression, createNamespace, Timeouts, takeOwnership, identity, import, parallel, multiple_releases, chartURL, repository_url, helm_repo_add, LintFail, FailedDeploy, emptyVersion, inconsistentVersion
  • manifest experiment: manifest, manifestUnknownValues, manifestServerDiff (fixed)
  • OCI: OCI_repository, OCI_registry_login, OCI_login (fixed - now works with podman + plain-HTTP local registries)
  • helm_template data source: basic, crds, templates, kubeVersion, configSetNull
  • state upgrader: MetadataStructure, values, PostrenderStructure
  • unit: TestConvertYAMLManifestToJSON

Notable fixes made during test validation

  • ** → ** (not ): in Helm v4, ForceReplace cannot be combined with server-side apply. Mapping force_update to ForceConflicts correctly enables drift recovery under SSA.
  • OCI plain-HTTP: added needsPlainHTTP + a dedicated plain-HTTP registry client for local (localhost/127.0.0.1) OCI registries, fixing LocateChart pulls against local registries.
  • metadata.generation stripping: removed metadata.generation from tracked resources to avoid spurious diffs under Helm v4 server-side apply.
  • valuesUnknown bug: fixed a copy-paste bug where set_list values were read from plan.Set.
  • podman support: setupOCIRegistry now prefers podman over docker for the local test registry.

@dennismdejong

Copy link
Copy Markdown
Author

Correction to the previous comment (the force_updateForceConflicts line was garbled):

  • force_updateForceConflicts (not ForceReplace): in Helm v4, ForceReplace cannot be combined with server-side apply (error: "cannot use server-side apply and force replace together"). Mapping force_update to ForceConflicts correctly enables drift recovery under the default server-side apply behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Helm 4 support Support for Helm v4

1 participant