From 33503cb9927a29ed3eaa843faeabea9202c1b9b3 Mon Sep 17 00:00:00 2001 From: yaroslavmokflmg Date: Wed, 8 Jul 2026 14:22:54 -0400 Subject: [PATCH 1/4] ci(release): fail on incomplete client artifacts instead of silent || true --- .github/workflows/release.yml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fc48b2cd196..90aa66b04cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -246,12 +246,19 @@ jobs: continue-on-error: true - name: Prepare release artifacts + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - set -e + set -euo pipefail mkdir -p final-artifacts/clients - gh release download latest --pattern "*.tar.gz" --pattern "*.zip" --dir final-artifacts/clients || true # macOS + if gh release view latest >/dev/null 2>&1; then + gh release download latest --pattern "*.tar.gz" --pattern "*.zip" --dir final-artifacts/clients + else + echo "No previous 'latest' release yet, skipping carry-forward." + fi + if [ -d "release-artifacts/fleet-mac-universal" ]; then tar -czf "final-artifacts/clients/fleet-macos-universal.tar.gz" \ -C "release-artifacts/fleet-mac-universal" fleet @@ -264,6 +271,20 @@ jobs: ls -lh final-artifacts/clients/ + missing=0 + if [ ! -f final-artifacts/clients/fleet-macos-universal.tar.gz ]; then + echo "::error::fleet-macos-universal.tar.gz missing from release artifacts" + missing=1 + fi + if [ ! -f final-artifacts/clients/fleet-windows-amd64.zip ]; then + echo "::error::fleet-windows-amd64.zip missing from release artifacts" + missing=1 + fi + if [ "$missing" -ne 0 ]; then + echo "::error::Release would ship incomplete client binaries, failing." + exit 1 + fi + - name: Generate release header run: | VERSION="${{ needs.version.outputs.version }}" From 542f20b232759dac993f264b66bebfb04d701ac9 Mon Sep 17 00:00:00 2001 From: yaroslavmokflmg Date: Wed, 8 Jul 2026 14:27:01 -0400 Subject: [PATCH 2/4] ci(release): verify latest image digest matches this release after build --- .github/workflows/release.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 90aa66b04cb..d2184d3e837 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -204,6 +204,26 @@ jobs: DOCKER_PUSH: "true" run: goreleaser release --clean + - name: Verify latest tag points at this release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.version.outputs.version }} + run: | + set -euo pipefail + image="${REGISTRY}/${GITHUB_REPOSITORY}/${BINARY_NAME}" + ver_digest=$(docker buildx imagetools inspect "${image}:${VERSION}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"') + latest_digest=$(docker buildx imagetools inspect "${image}:latest" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"') + echo "version (${VERSION}) digest: ${ver_digest:-}" + echo "latest digest: ${latest_digest:-}" + if [ -z "$ver_digest" ]; then + echo "::error::${image}:${VERSION} was not pushed" + exit 1 + fi + if [ "$ver_digest" != "$latest_digest" ]; then + echo "::error::${image}:latest did not move to this release (${VERSION}); dev pins latest and would keep serving a stale image" + exit 1 + fi + build_helm: name: "Build Helm Chart" From 125a8f84199edd6691ef47a56566c5e7f6979029 Mon Sep 17 00:00:00 2001 From: yaroslavmokflmg Date: Wed, 8 Jul 2026 14:48:00 -0400 Subject: [PATCH 3/4] Revert "ci(release): verify latest image digest matches this release after build" This reverts commit 542f20b232759dac993f264b66bebfb04d701ac9. --- .github/workflows/release.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2184d3e837..90aa66b04cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -204,26 +204,6 @@ jobs: DOCKER_PUSH: "true" run: goreleaser release --clean - - name: Verify latest tag points at this release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - VERSION: ${{ needs.version.outputs.version }} - run: | - set -euo pipefail - image="${REGISTRY}/${GITHUB_REPOSITORY}/${BINARY_NAME}" - ver_digest=$(docker buildx imagetools inspect "${image}:${VERSION}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"') - latest_digest=$(docker buildx imagetools inspect "${image}:latest" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"') - echo "version (${VERSION}) digest: ${ver_digest:-}" - echo "latest digest: ${latest_digest:-}" - if [ -z "$ver_digest" ]; then - echo "::error::${image}:${VERSION} was not pushed" - exit 1 - fi - if [ "$ver_digest" != "$latest_digest" ]; then - echo "::error::${image}:latest did not move to this release (${VERSION}); dev pins latest and would keep serving a stale image" - exit 1 - fi - build_helm: name: "Build Helm Chart" From 9dd6310fcb79c9c084d85beb6c119d81c354086e Mon Sep 17 00:00:00 2001 From: yaroslavmokflmg Date: Wed, 8 Jul 2026 14:53:35 -0400 Subject: [PATCH 4/4] =?UTF-8?q?ci(release):=20fix=20latest-tag=20verify=20?= =?UTF-8?q?=E2=80=94=20split=20push=20(version=3Dlatest)=20vs=20dispatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 90aa66b04cb..5873c37e612 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -204,6 +204,30 @@ jobs: DOCKER_PUSH: "true" run: goreleaser release --clean + - name: Verify latest tag was pushed + env: + VERSION: ${{ needs.version.outputs.version }} + EVENT: ${{ github.event_name }} + run: | + set -euo pipefail + image="${REGISTRY}/${GITHUB_REPOSITORY}/${BINARY_NAME}" + latest_digest=$(docker buildx imagetools inspect "${image}:latest" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) + if [ -z "$latest_digest" ]; then + echo "::error::${image}:latest was not pushed by this release" + exit 1 + fi + if [ "$EVENT" = "workflow_dispatch" ]; then + ver_digest=$(docker buildx imagetools inspect "${image}:${VERSION}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) + if [ -z "$ver_digest" ]; then + echo "::error::${image}:${VERSION} was not pushed" + exit 1 + fi + if [ "$ver_digest" != "$latest_digest" ]; then + echo "::error::${image}:latest did not move to ${VERSION}; dev pins latest and would keep serving a stale image" + exit 1 + fi + fi + build_helm: name: "Build Helm Chart"