@@ -329,8 +329,13 @@ jobs:
329329
330330 # Verify the published release matches expectations: not a draft, not a
331331 # prerelease (GoReleaser's prerelease:auto must classify a non-rc tag as a
332- # final release), exactly 5 assets (4 archives + checksums.txt), and that
333- # vX.Y.Z is the repo's latest release.
332+ # final release), that vX.Y.Z is the repo's latest release, and that the
333+ # required signing and checksum assets are attached. The presence checks
334+ # assert assets by name (checksums.txt plus its cosign .bundle and GPG
335+ # .asc signatures) and require at least four archive tarballs, rather than
336+ # a brittle exact asset count. GoReleaser also attaches per-archive SBOMs,
337+ # so the total asset count grows over time; asserting the load-bearing
338+ # assets by name keeps this gate stable as the artifact set expands.
334339 - name : Verify published release
335340 if : steps.idem.outputs.skip != 'true'
336341 env :
@@ -344,29 +349,55 @@ jobs:
344349 --json isDraft,isPrerelease,assets)
345350 IS_DRAFT=$(printf '%s' "$DATA" | jq -r '.isDraft')
346351 IS_PRERELEASE=$(printf '%s' "$DATA" | jq -r '.isPrerelease')
347- ASSET_COUNT=$(printf '%s' "$DATA" | jq -r '.assets | length')
352+ ARCHIVE_COUNT=$(printf '%s' "$DATA" | jq -r \
353+ '[.assets[] | select(.name | endswith(".tar.gz"))] | length')
348354
349355 LATEST=$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" \
350356 --jq '.tag_name')
351357
358+ # Named assets that a signed final release must carry: the checksum
359+ # manifest plus the cosign (.bundle) and GPG (.asc) signatures over it.
360+ REQUIRED_ASSETS="checksums.txt checksums.txt.bundle checksums.txt.asc"
361+ MIN_ARCHIVES=4
362+
363+ has_asset() {
364+ printf '%s' "$DATA" | jq -e --arg n "$1" \
365+ '.assets | any(.name == $n)' >/dev/null
366+ }
367+
368+ fail=0
369+
352370 {
353371 echo "## Auto-promote: $BASE_VERSION"
354372 echo ""
355373 echo "| Check | Value | Expected |"
356374 echo "|---|---|---|"
357375 echo "| draft | $IS_DRAFT | false |"
358376 echo "| prerelease | $IS_PRERELEASE | false |"
359- echo "| assets | $ASSET_COUNT | 5 |"
377+ } >> "$GITHUB_STEP_SUMMARY"
378+
379+ for name in $REQUIRED_ASSETS; do
380+ if has_asset "$name"; then
381+ present="yes"
382+ else
383+ present="no"
384+ echo "::error::$BASE_VERSION is missing required asset $name."
385+ fail=1
386+ fi
387+ echo "| asset: $name | $present | present |" >> "$GITHUB_STEP_SUMMARY"
388+ done
389+
390+ {
391+ echo "| archive tarballs (*.tar.gz) | $ARCHIVE_COUNT | >= $MIN_ARCHIVES |"
360392 echo "| latest release | $LATEST | $BASE_VERSION |"
361393 } >> "$GITHUB_STEP_SUMMARY"
362394
363- fail=0
364395 [ "$IS_DRAFT" = "false" ] || { echo "::error::$BASE_VERSION is a draft."; fail=1; }
365396 [ "$IS_PRERELEASE" = "false" ] || { echo "::error::$BASE_VERSION is marked prerelease; GoReleaser misclassified a non-rc tag."; fail=1; }
366- [ "$ASSET_COUNT" = "5 " ] || { echo "::error::$BASE_VERSION has $ASSET_COUNT assets , expected 5 ."; fail=1; }
397+ [ "$ARCHIVE_COUNT" -ge "$MIN_ARCHIVES " ] || { echo "::error::$BASE_VERSION has $ARCHIVE_COUNT archive tarballs , expected at least $MIN_ARCHIVES ."; fail=1; }
367398 [ "$LATEST" = "$BASE_VERSION" ] || { echo "::error::latest release is $LATEST, expected $BASE_VERSION."; fail=1; }
368399
369400 if [ "$fail" -ne 0 ]; then
370401 exit 1
371402 fi
372- echo "::notice::$BASE_VERSION published as latest, non-prerelease, with 5 assets."
403+ echo "::notice::$BASE_VERSION published as latest, non-prerelease, with the required checksum and signature assets and $ARCHIVE_COUNT archive tarballs ."
0 commit comments