Skip to content

fix: restore diff/ tarball layout so existing installs can update - #1077

Merged
yxxhero merged 1 commit into
masterfrom
fix/plugin-update-layout-1076
Sep 26, 2026
Merged

yxxhero merged 1 commit into
masterfrom
fix/plugin-update-layout-1076

Conversation

@yxxhero

@yxxhero yxxhero commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

What

Fixes #1076 (without regressing #1071).

Root cause

helm plugin update runs the already installed copy of install-binary.sh (platformHooks.update → ${HELM_PLUGIN_DIR}/install-binary.sh -u). Every hook released so far (checked v3.5.0 → v3.15.13) extracts the downloaded release tarball and copies "$HELM_TMP/diff/bin/diff" into the plugin dir. v3.15.14 (#1072) wrapped the release archives in a directory named after the archive (helm-diff-<os>-<arch>/) instead of diff/, so every pre-3.15.14 install now fails to update:

cp: cannot stat '/tmp/helm-diff-XXXX/diff/bin/diff': No such file or directory
Error: Failed to update plugin diff, got error (plugin update hook for "diff" exited with error)

Why not simply revert, or simply keep the new layout

  • Reverting the wrap to diff/ alone regresses Offline install not working in helm 4 unless you --verify=false #1071: helm 4's LocalInstaller derives the directory it expects inside a locally installed tarball from the tarball file name (stripPluginName strips a trailing -<version> component, then it requires <name>/plugin.yaml).
  • Keeping helm-diff-<os>-<arch>.tgz can never satisfy that flow: the name carries no version component to strip, so helm 4 looks for helm-diff-<os>-<arch>/plugin.yaml.
  • Producing one tarball that embeds both layouts (new dir + legacy diff/ sibling) is not expressible in goreleaser (files cannot escape the wrap directory) and would double every archive's size.

Fix

Wrap all archives in diff/ again — the layout every released hook expects — and publish each platform a second time under a versioned name, diff-<version>-<os>-<arch>.tgz:

helm-diff-linux-amd64.tgz        # historical name, diff/ wrap → old/new hooks update again
diff-3.15.15-linux-amd64.tgz     # byte-identical, versioned name → stripPluginName("diff-3.15.15-…") == "diff"

This satisfies, simultaneously:

flow consumes works
pre-3.15.14 helm plugin update diff (#1076) legacy asset, expects diff/bin/diff ✅
3.15.14 hooks updating to the next release legacy asset, basename dir missing → existing diff/ fallback ✅
fresh installs (any historical tag) tagged legacy asset ✅
HELM_DIFF_BIN_TGZ offline flow legacy or 3.15.14-style files ✅
helm 4 local tarball install + provenance verify (#1071) versioned asset, expects diff/ derived from file name ✅
helm 4 URL install either asset (detectPluginRoot) ✅

Each asset gets its own .prov (goreleaser signs all archives; helm verification matches file names against the checksums in the .prov).

Changes

  • .goreleaser.yml: wrap_in_directory: diff; new versioned archive with diff-{{ .Version }}-… name template
  • Makefile: dist-package wraps in diff/ and emits both asset names (byte-identical copies)
  • install-binary.sh / install-binary.ps1: no behavior change (they already support both layouts — basename dir first, then diff/ fallback); comments updated to document the layout history
  • .github/workflows/release.yaml:
  • README.md: offline/helm 4 install docs updated to the versioned asset name

Verification (all local, on top of this branch)

  • reproduced the exact v3.15.14 tarball layout change (diff/ → helm-diff-<os>-<arch>/) breaks helm plugin update diff for existing installs #1076 failure with the real v3.15.14 helm-diff-macos-arm64.tgz and the v3.15.13 hook
  • goreleaser release --snapshot --clean --skip=sign (v1.26.2): 12 legacy + 12 versioned archives, all diff/-wrapped (.exe on windows), byte-identical per platform
  • v3.15.13 hook and v3.15.14 hook both complete -u updates from the new archives; bin/diff version runs
  • helm 4 (v4.2.3) provenance-verified install of the versioned snapshot tarball: Plugin Hash Verified, helm diff version works
  • make dist macro (single platform) emits both names with the diff/ layout
  • shellcheck clean, YAML valid

Note: takes effect with the next release; users already broken on 3.15.14 can either wait for it (helm plugin update will start working again) or reinstall once.

helm plugin update runs the already-installed copy of install-binary.sh,
which extracts the freshly downloaded release tarball and copies
$HELM_TMP/diff/bin/diff into the plugin dir. The 3.15.14 layout change
(wrapping content in a directory named after the archive, helm-diff-<os>-
<arch>/) therefore broke helm plugin update on every pre-3.15.14 install
with:

  cp: cannot stat '/tmp/helm-diff-*/diff/bin/diff': No such file or directory

Fixes #1076.

- .goreleaser.yml/Makefile: wrap archives in "diff/" again (the layout
  every released install/update hook expects) and, to keep the helm 4
  local-tarball flow from #1071 working, publish each platform a second
  time under a versioned name, diff-<version>-<os>-<arch>.tgz. Helm 4
  derives the directory it expects inside a locally installed tarball
  from its file name (it strips a -<version> component), so the
  versioned name resolves to diff/ while the historical name cannot.
  Both assets are byte-identical and each gets its own .prov signature
  (helm's verification matches file names against the checksums).
- install-binary.sh/.ps1: no behavior change needed (they already support
  both layouts); comments updated to document the layout history.
- release.yaml: smoke tests assert the diff/ layout and the two asset
  names; the helm 4 offline test installs the versioned archive; new
  regression test runs the exact v3.15.13 and v3.15.14 install hooks in
  update mode against the built archives (issue #1076).
- README.md: offline/helm 4 install docs updated for the versioned asset.

Verified locally: reproduced the #1076 failure with the real 3.15.14
asset, then confirmed both the v3.15.13 and v3.15.14 hooks update
successfully from the new archives, and helm 4 installs + provenance-
verifies the versioned tarball (Plugin Hash Verified).

Signed-off-by: yxxhero <aiopsclub@163.com>
@yxxhero
yxxhero merged commit c43e3e4 into master Sep 26, 2026
26 checks passed
@yxxhero
yxxhero deleted the fix/plugin-update-layout-1076 branch September 26, 2026 01:47
@yxxhero yxxhero mentioned this pull request Sep 26, 2026
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.

v3.15.14 tarball layout change (diff/ → helm-diff-<os>-<arch>/) breaks helm plugin update diff for existing installs

1 participant