Skip to content

fix: make release tarballs installable offline by helm 4 - #1072

Open
yxxhero wants to merge 1 commit into
masterfrom
fix/offline-tarball-install-helm4
Open

fix: make release tarballs installable offline by helm 4#1072
yxxhero wants to merge 1 commit into
masterfrom
fix/offline-tarball-install-helm4

Conversation

@yxxhero

@yxxhero yxxhero commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

What

Fixes #1071

Helm 4's LocalInstaller (used for helm plugin install <local>.tgz) extracts the tarball and requires plugin.yaml inside a top-level directory derived from the tarball filename (helm-diff-linux-amd64.tgzhelm-diff-linux-amd64/plugin.yaml). Our release archives wrapped their content in a diff/ directory instead, so a verified offline install failed with:

Error: plugin.yaml not found in expected directory /tmp/helm-plugin-extract-.../helm-diff-linux-amd64

Since provenance verification additionally requires keeping the original tarball filename (the .prov checksums are keyed by filename), the only workaround was --verify=false.

This changes release archives to wrap content in a directory named after the archive itself — exactly what helm 4 expects.

Changes

  • .goreleaser.yml: wrap_in_directory: difftrue (goreleaser then wraps in a directory named after the archive, e.g. helm-diff-linux-amd64/)
  • Makefile: dist target rewritten with a dist-package macro producing the same per-platform wrapped layout
  • install-binary.sh / install-binary.ps1: derive the extracted binary path from the tarball's own basename, with a fallback to the legacy diff/ layout so older releases still install/update correctly; HELM_DIFF_BIN_TGZ copies keep their original filename (the wrap dir depends on it)
  • .github/workflows/release.yaml: smoke tests updated for the new layout, plus a new "Helm 4 offline tarball install test" that signs a snapshot tarball with a disposable key and installs it with helm 4 with provenance verification enabled (regression test for Offline install not working in helm 4 unless you --verify=false #1071)
  • README.md: offline install docs updated; documents the helm plugin install <tarball> --keyring ... flow incl. the "keep the original tarball filename" requirement

Compatibility

  • Helm 4 tarball URL installs: still work — the HTTP installer detects the plugin root one level deep (detectPluginRoot)
  • Helm 3: unaffected — it installs from the git repo (URL tarball installs never worked with either layout, as its HTTP installer requires plugin.yaml at the archive root)
  • Older releases: the install hooks keep a legacy diff/ fallback, so updates from / installs of pre-layout-change tarballs keep working

Verification

  • Reproduced the exact error from Offline install not working in helm 4 unless you --verify=false #1071 with the real v3.15.13 release artifacts on helm v4.3.0
  • Full offline verified install (disposable GPG key + scripts/sign-provenance.sh) now succeeds on helm v4.3.0 for both Makefile- and goreleaser-built tarballs; helm diff version runs the installed binary
  • Helm 4 URL install and extracted-directory install still work
  • install-binary.sh tested against a new-layout tarball (HELM_DIFF_BIN_TGZ) and against the real latest (old-layout) release download; shellcheck clean
  • go test ./..., gofmt, go vet pass

Note: the fix takes effect with the next release — existing published tarballs keep the old layout.

Helm 4 installs plugins from local tarballs by deriving the expected
plugin directory from the tarball filename (helm-diff-linux-amd64.tgz ->
helm-diff-linux-amd64/) and requires plugin.yaml to live there. Our
release archives wrapped everything in a diff/ directory instead, so a
verified offline install failed with:

    Error: plugin.yaml not found in expected directory .../helm-diff-linux-amd64

and users had to fall back to --verify=false, since provenance
verification also requires keeping the original tarball filename.

Wrap each release archive in a directory named after the archive itself
(wrap_in_directory: true), which is exactly what helm 4 expects. Helm 4
tarball installs from URLs keep working (its HTTP installer detects the
plugin root one level deep), and helm 3 is unaffected (it installs from
the git repo and the install hooks, which are updated here to handle
both the new and the legacy diff/ layout).

Also update make dist to produce the same layout and add a CI smoke test
that installs a locally signed snapshot tarball with helm 4, with
verification enabled.

Fixes #1071

Signed-off-by: yxxhero <aiopsclub@163.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Update the documented PowerShell filename workflow or make installers discover the archive’s actual wrapper directory.

Pull request overview

Updates release archives and installers so Helm 4 can install verified offline tarballs.

Changes:

  • Uses filename-derived archive directories.
  • Updates Makefile and installers with legacy-layout support.
  • Adds Helm 4 verification tests and documentation.
File summaries
File Summary
README.md Documents the updated offline installation workflow.
Makefile Produces filename-wrapped platform archives.
install-binary.sh Resolves new and legacy archive layouts.
install-binary.ps1 Resolves new and legacy Windows layouts.
.goreleaser.yml Enables filename-based archive wrapping.
.github/workflows/release.yaml Adds layout and Helm 4 regression tests.
Review details

Suppressed comments (3)

README.md:68

  • The HELM_DIFF_BIN_TGZ PowerShell example above still uses helm-diff-bin.tgz. With the new installer, the archive basename determines the wrapper directory, so following that example with a release archive wrapped as helm-diff-windows-amd64/ makes the script look under helm-diff-bin/ and fail to find diff.exe. Please update that example (or explicitly state that the path must retain the exact release filename) consistently with this new requirement.
For offline/airgapped environments with Helm 4, transfer the release tarball **together with its `.prov` file** (and keep the original tarball file name — provenance verification matches the file name against the checksums recorded in the `.prov` file) and install directly from the tarball:

install-binary.ps1:108

  • This now assumes that every HELM_DIFF_BIN_TGZ path preserves the release asset's canonical basename. The existing offline-install documentation shows a renamed PowerShell path (helm-diff-bin.tgz), so using that documented path with a new-layout archive makes $wrapDir point at helm-diff-bin and Copy-Item fails. Either update that documented workflow to require the original basename or detect the extracted top-level directory instead of deriving it solely from the temporary filename.
    $archiveName = [System.IO.Path]::GetFileName($env:HELM_DIFF_BIN_TGZ)

install-binary.sh:122

  • HELM_DIFF_BIN_TGZ is now copied under its original basename, and installFile derives the new wrapper directory from that basename. The existing PowerShell instructions still use helm-diff-bin.tgz; a real Windows release archive renamed that way contains helm-diff-windows-amd64/, so this lookup misses it and the legacy diff/ fallback also misses, causing the documented offline install to fail. Update that example and state the filename requirement for this flow, or make the installer discover the top-level directory from the archive.
    PLUGIN_TMP_FILE="${HELM_TMP}/$(basename "$HELM_DIFF_BIN_TGZ")"
    cp "$HELM_DIFF_BIN_TGZ" "$PLUGIN_TMP_FILE"
  • Files reviewed: 6/6 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

Offline install not working in helm 4 unless you --verify=false

2 participants