From 7e46ef86902591a210ccfb815895733e089ce451 Mon Sep 17 00:00:00 2001 From: Renovate Date: Fri, 30 Oct 2026 06:01:21 +0000 Subject: [PATCH 1/3] :arrow_up: chore(deps): update helm to v4 --- .github/actions/kind-e2e-setup/action.yml | 2 +- .github/workflows/ci.yaml | 4 ++-- .github/workflows/release.yaml | 2 +- Taskfile.yml | 2 +- hack/install-helm.sh | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/kind-e2e-setup/action.yml b/.github/actions/kind-e2e-setup/action.yml index 5819cd66..c4cdeae9 100644 --- a/.github/actions/kind-e2e-setup/action.yml +++ b/.github/actions/kind-e2e-setup/action.yml @@ -78,7 +78,7 @@ runs: - name: Install kind and helm shell: bash env: - HELM_VERSION: v3.22.1 + HELM_VERSION: v4.3.1 run: | set -euo pipefail source "${GITHUB_WORKSPACE}/hack/lib/fetch.sh" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 122e594a..e5a0adff 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -342,7 +342,7 @@ jobs: run: bash hack/test/ci_install_helm_hardening_test.sh - name: Install Helm env: - HELM_VERSION: v3.22.1 + HELM_VERSION: v4.3.1 run: bash hack/install-helm.sh - name: Ensure yq is available run: | @@ -835,7 +835,7 @@ jobs: version: 3.54.0 - name: Install Helm env: - HELM_VERSION: v3.22.1 + HELM_VERSION: v4.3.1 run: bash hack/install-helm.sh - name: Install helm-unittest plugin run: helm plugin install https://github.com/helm-unittest/helm-unittest --version v0.5.1 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ca8e6743..a6b8818e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -157,7 +157,7 @@ jobs: - uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1 with: - version: v3.22.1 + version: v4.3.1 - uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0 diff --git a/Taskfile.yml b/Taskfile.yml index 24f983d7..e64b067b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -32,7 +32,7 @@ vars: # renovate: datasource=go depName=github.com/go-gremlins/gremlins GREMLINS_VERSION: v0.6.0 # renovate: datasource=github-releases depName=helm/helm - HELM_VERSION: v3.22.1 + HELM_VERSION: v4.3.1 # renovate: datasource=github-releases depName=norwoodj/helm-docs HELM_DOCS_VERSION: v1.14.2 HELM_DOCS_BIN: "{{.BIN_DIR}}/helm-docs" diff --git a/hack/install-helm.sh b/hack/install-helm.sh index 673cedd8..db07ebba 100755 --- a/hack/install-helm.sh +++ b/hack/install-helm.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # Install a pinned Helm 3 release with SHA256-verified tarball download. # Checksums from https://get.helm.sh/helm-${VERSION}-${OS}-${ARCH}.tar.gz.sha256 -# Usage: HELM_VERSION=v3.22.1 hack/install-helm.sh [install-dir] +# Usage: HELM_VERSION=v4.3.1 hack/install-helm.sh [install-dir] set -euo pipefail -VERSION="${HELM_VERSION:-v3.22.1}" +VERSION="${HELM_VERSION:-v4.3.1}" INSTALL_DIR="${1:-/usr/local/bin}" # CI-HELMDL-01 / CI-FETCHLIB-01. Both fetches below used to be bare `curl -fsSL`. On 2026-09-01 From bb81191e8db79a57a0f92d7a2b14452297929792 Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Thu, 5 Nov 2026 11:18:09 +0100 Subject: [PATCH 2/3] :construction_worker: ci: install helm-unittest under helm v4 verification Helm 4 verifies plugin provenance by default, and a git source cannot be verified, so `helm plugin install --version v0.5.1` fails with "plugin source does not support verification". Upstream's documented fix is `--verify=false`, which leaves the git-clone install hook to download the binary and check it against a checksum file fetched without retry or protocol pinning. Instead, hack/install-helm-unittest.sh fetches the per-platform release tarball through hack/lib/fetch.sh, verifies its SHA256 against the release's checksum file (the trust model every hack/install-*.sh uses), and unpacks it straight into helm's plugin directory. The tarball is a complete plugin, so no install hook runs and nothing is fetched after verification. It works the same under Helm 3 and Helm 4. Supply-chain trade-off: Helm 4's own GPG provenance check is not used, because it needs the maintainer key in a legacy keyring that this repo does not pin. Integrity rests on the same-origin SHA256, as for helm, helm-docs and the other pinned tools. The plugin moves from v0.5.1 to v1.2.1 (the first line with Helm 4 support), pinned once as HELM_UNITTEST_VERSION in Taskfile.yml with a Renovate annotation; CI runs `task tools:helm-unittest`. --- .github/workflows/ci.yaml | 2 +- Taskfile.yml | 7 +++ docs/development/setup.md | 1 + hack/install-helm-unittest.sh | 96 +++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100755 hack/install-helm-unittest.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e5a0adff..12a4510f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -838,7 +838,7 @@ jobs: HELM_VERSION: v4.3.1 run: bash hack/install-helm.sh - name: Install helm-unittest plugin - run: helm plugin install https://github.com/helm-unittest/helm-unittest --version v0.5.1 + run: task tools:helm-unittest - name: Helm lint and unittest run: task helm-test diff --git a/Taskfile.yml b/Taskfile.yml index e64b067b..201c5afd 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -36,6 +36,8 @@ vars: # renovate: datasource=github-releases depName=norwoodj/helm-docs HELM_DOCS_VERSION: v1.14.2 HELM_DOCS_BIN: "{{.BIN_DIR}}/helm-docs" + # renovate: datasource=github-releases depName=helm-unittest/helm-unittest + HELM_UNITTEST_VERSION: v1.2.1 COVERAGE_MIN: "90" MANAGER_BINARY: "{{.BIN_DIR}}/manager" PIPELINE_BINARY: "{{.BIN_DIR}}/kollect-pipeline" @@ -434,6 +436,11 @@ tasks: cmds: - bash hack/install-helm-docs.sh {{.HELM_DOCS_VERSION}} {{.HELM_DOCS_BIN}} + tools:helm-unittest: + desc: Install the pinned helm-unittest plugin ({{.HELM_UNITTEST_VERSION}}) into helm's plugin dir + cmds: + - bash hack/install-helm-unittest.sh {{.HELM_UNITTEST_VERSION}} + helm-docs: desc: Regenerate charts/kollect/README.md from values.yaml deps: [tools:helm-docs] diff --git a/docs/development/setup.md b/docs/development/setup.md index ffd0005e..bf616c71 100644 --- a/docs/development/setup.md +++ b/docs/development/setup.md @@ -347,6 +347,7 @@ task vulncheck # govulncheck (CI vulncheck job) task format # go fmt ./... task format:check # fail if gofmt or goimports would change files task helm-test # helm lint + helm-docs drift + unittest +task tools:helm-unittest # install the pinned helm-unittest plugin (CI does the same) task helm-docs # regenerate charts/kollect/README.md task lint:markdown # markdownlint-cli2 on docs/**/*.md ``` diff --git a/hack/install-helm-unittest.sh b/hack/install-helm-unittest.sh new file mode 100755 index 00000000..3e52b60c --- /dev/null +++ b/hack/install-helm-unittest.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Install a pinned helm-unittest plugin release with SHA256-verified tarball download. +# Usage: hack/install-helm-unittest.sh (e.g. `task tools:helm-unittest`) +# +# WHY NOT `helm plugin install --version ...`: Helm 4 verifies plugin provenance by +# default and a git source cannot be verified, so that form now fails with "plugin source does not +# support verification". Upstream's answer is `--verify=false`, which leaves the git-clone install +# hook to download the binary and check it against a checksum file fetched without retry or +# protocol pinning. Instead this script fetches the per-platform release tarball through the +# shared hardened helper (hack/lib/fetch.sh), verifies its SHA256 against the release's checksum +# file -- the same trust model as every other hack/install-*.sh -- and unpacks it straight into +# Helm's plugin directory. The tarball is a complete plugin (plugin.yaml + binary), so no install +# hook runs and nothing is downloaded after verification. Helm's own GPG provenance check is not +# used: it needs the maintainer's public key in a legacy keyring, which this repo does not pin. +# Works unchanged under Helm 3 and Helm 4 (no `helm plugin install` flag differences involved). +set -euo pipefail + +VERSION="${1:?version required (e.g. the Taskfile HELM_UNITTEST_VERSION)}" +VER="${VERSION#v}" + +case "$(uname -m)" in + x86_64) arch=amd64 ;; + aarch64 | arm64) arch=arm64 ;; + *) + echo "unsupported architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +case "$(uname -s)" in + Linux) os=linux ;; + Darwin) os=macos ;; + *) + echo "unsupported OS: $(uname -s)" >&2 + exit 1 + ;; +esac + +command -v helm >/dev/null 2>&1 || { + echo "helm is not on PATH; install it first (hack/install-helm.sh)" >&2 + exit 1 +} + +asset="helm-unittest-${os}-${arch}-${VER}.tgz" +base_url="https://github.com/helm-unittest/helm-unittest/releases/download/v${VER}" + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${root}/hack/lib/verify-sha256.sh" +source "${root}/hack/lib/fetch.sh" + +plugins_dir="$(helm env HELM_PLUGINS)" +if [[ -z "${plugins_dir}" ]]; then + echo "helm env HELM_PLUGINS returned nothing; cannot locate the plugin directory" >&2 + exit 1 +fi + +installed="$(helm plugin list 2>/dev/null | awk '$1 == "unittest" {print $2}')" +if [[ "${installed}" == "${VER}" ]]; then + echo "helm-unittest ${VER} already installed" + exit 0 +fi + +tmpdir="$(mktemp -d)" +trap 'rm -rf "${tmpdir}"' EXIT + +# helm-unittest-checksum.sha lines read ` *./_dist/`. +fetch_to "${base_url}/helm-unittest-checksum.sha" "${tmpdir}/checksum.sha" "helm-unittest ${VERSION} checksums" +expected="$(awk -v file="./_dist/${asset}" '$2 == "*" file || $2 == file {print $1}' "${tmpdir}/checksum.sha")" +if [[ ! "${expected}" =~ ^[0-9a-f]{64}$ ]]; then + echo "failed to resolve a checksum for ${asset} from ${base_url}/helm-unittest-checksum.sha" >&2 + exit 1 +fi +fetch_to "${base_url}/${asset}" "${tmpdir}/${asset}" "helm-unittest ${VERSION} tarball" +verify_sha256 "${tmpdir}/${asset}" "${expected}" + +mkdir -p "${tmpdir}/plugin" +tar -xzf "${tmpdir}/${asset}" -C "${tmpdir}/plugin" +if [[ ! -f "${tmpdir}/plugin/plugin.yaml" ]]; then + echo "${asset} has no plugin.yaml at its root; the release layout changed" >&2 + exit 1 +fi + +if [[ -n "${installed}" ]]; then + echo "replacing helm-unittest ${installed} with ${VER}" + helm plugin uninstall unittest +fi +mkdir -p "${plugins_dir}" +rm -rf "${plugins_dir}/unittest" +mv "${tmpdir}/plugin" "${plugins_dir}/unittest" + +installed="$(helm plugin list 2>/dev/null | awk '$1 == "unittest" {print $2}')" +if [[ "${installed}" != "${VER}" ]]; then + echo "helm plugin list reports unittest '${installed}' after install, expected ${VER}" >&2 + exit 1 +fi +echo "installed helm-unittest ${VER} (${os}/${arch}) into ${plugins_dir}/unittest" From 8aa2e5f50f8e388fbc22e33f2e657e3fb1c66271 Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Thu, 5 Nov 2026 11:18:09 +0100 Subject: [PATCH 3/3] :page_facing_up: docs: drop the Helm 3 wording from install-helm.sh --- hack/install-helm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/install-helm.sh b/hack/install-helm.sh index db07ebba..90df1144 100755 --- a/hack/install-helm.sh +++ b/hack/install-helm.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Install a pinned Helm 3 release with SHA256-verified tarball download. +# Install a pinned Helm release with SHA256-verified tarball download. # Checksums from https://get.helm.sh/helm-${VERSION}-${OS}-${ARCH}.tar.gz.sha256 # Usage: HELM_VERSION=v4.3.1 hack/install-helm.sh [install-dir] set -euo pipefail