ci: run helm from a checksum-pinned binary, not a container
ci / lint (push) Successful in 23s
ci / types (push) Successful in 1m29s
ci / unit (push) Successful in 1m31s
ci / dockerfile (push) Successful in 38s
ci / security (push) Successful in 1m22s
ci / chart (push) Successful in 45s
ci / integration (push) Successful in 1m21s
ci / image (api) (push) Successful in 5m26s
ci / image (worker) (push) Failing after 7m34s
ci / image (reconciler) (push) Successful in 6m0s
ci / bump (push) Has been skipped

The chart gate failed with 'stat deploy/chart/Chart.yaml: no such file or
directory' while the file plainly existed in the checkout. `docker run -v
"$PWD:/repo"` is interpreted by the dind sidecar's daemon rather than by the
job container, so the bind source has to exist on the daemon's side of that
boundary. Downloading the binary removes the boundary entirely.

Pinned by sha256 for the same reason every image here is pinned by digest.
This commit is contained in:
Nguyen Minh Phuc
2026-07-18 12:20:16 +00:00
parent c76154aeaa
commit a51227d952
+25 -8
View File
@@ -199,15 +199,34 @@ jobs:
runs-on: ubuntu-latest
needs: [lint]
env:
# Pinned by digest like gitleaks and trivy, and the same helm the worker and
# reconciler images carry — CI renders with the version that ships.
HELM: alpine/helm:3.21.3@sha256:35da09ba0716fc7c3cd63b6b31ee380a9c7662e95f29ab0e4ae962420afd315b
# The same helm version the worker and reconciler images carry, so CI renders with
# the version that ships.
HELM_VERSION: "3.21.3"
# sha256 of helm-v3.21.3-linux-arm64.tar.gz, from https://get.helm.sh/*.sha256sum.
# Pinned for the same reason every image here is pinned by digest: a tarball fetched
# over HTTPS is still a tarball whoever controls the bucket chose to serve.
HELM_SHA256: "67f58155079ff9ffab98ba5c88daff0ed9b542f3a4732f5dd426dde7dd0f5244"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: install helm
# A downloaded binary rather than `docker run alpine/helm`. The container form
# cannot see the checkout: `docker run -v "$PWD:/repo"` is interpreted by the dind
# SIDECAR's daemon, and the chart path resolved to nothing inside it —
# "stat deploy/chart/Chart.yaml: no such file or directory" while the file plainly
# exists in the job. A binary on PATH has no such boundary to cross.
run: |
set -euo pipefail
curl -fsSL -o /tmp/helm.tgz \
"https://get.helm.sh/helm-v${HELM_VERSION}-linux-arm64.tar.gz"
echo "${HELM_SHA256} /tmp/helm.tgz" | sha256sum -c -
tar -xzf /tmp/helm.tgz -C /tmp
install -m 0755 /tmp/linux-arm64/helm /usr/local/bin/helm
helm version --short
- name: helm lint
run: |
docker run --rm -v "$PWD:/repo" -w /repo "$HELM" lint deploy/chart
helm lint deploy/chart
- name: helm template (rejects unbumped digests)
# values.yaml ships all-zeros placeholders, so a bare `helm template` MUST fail.
@@ -215,8 +234,7 @@ jobs:
# what stops the guard silently regressing into a prefix check again.
run: |
set -euo pipefail
if docker run --rm -v "$PWD:/repo" -w /repo "$HELM" \
template svcforge deploy/chart >/dev/null 2>&1; then
if helm template svcforge deploy/chart >/dev/null 2>&1; then
echo "FAIL: chart rendered against the placeholder digests in values.yaml." >&2
echo "The digest guard in _helpers.tpl is not guarding." >&2
exit 1
@@ -231,8 +249,7 @@ jobs:
A="sha256:$(printf 'a%.0s' $(seq 64))"
B="sha256:$(printf 'b%.0s' $(seq 64))"
C="sha256:$(printf 'c%.0s' $(seq 64))"
docker run --rm -v "$PWD:/repo" -w /repo "$HELM" \
template svcforge deploy/chart \
helm template svcforge deploy/chart \
--set image.api.digest="$A" \
--set image.worker.digest="$B" \
--set image.reconciler.digest="$C" \