From ef78be403580bd53a8003e65edbe99d6cda04a40 Mon Sep 17 00:00:00 2001 From: Sirius DevOps Date: Thu, 10 Sep 2026 14:20:45 -0400 Subject: [PATCH] fix(release): refuse to publish 0-byte assets + log on-disk sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run 309 reported success but uploaded 0 bytes for both aarch64 assets (a 0.85s 'upload' of an 18MB file). The Pack step had just listed 18258736 bytes and sha256sum -c'd OK, so the failure is in the handoff, not the build. - publish-release.sh now fails loudly on a 0-byte asset instead of publishing a release that silently breaks every download - the workflow logs pwd, GITHUB_WORKSPACE, ls -l dist/ and the byte count of each dist file immediately before publishing Ruled out: the api_curl retry wrapper. Reproduced from inside a node:20-bullseye container (curl 7.74, same as CI) — wrapper and plain curl both uploaded 994 bytes correctly through Cloudflare. --- .forgejo/workflows/release.yml | 3 +++ scripts/publish-release.sh | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 5748373..ac4d184 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -98,6 +98,9 @@ jobs: run: | set -euo pipefail cd "${GITHUB_WORKSPACE}" + echo "pwd=$PWD workspace=$GITHUB_WORKSPACE" + ls -l dist/ 2>&1 || true + for f in dist/*; do printf 'on disk: %s %s bytes\n' "$f" "$(wc -c < "$f")"; done tag="${INPUT_TAG:-$REF}" # Only a tag push may create the tag; a re-publish must not move it. if [ "$EVENT_NAME" = "push" ]; then export TARGET_COMMITISH="$EVENT_SHA"; fi diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index a7732e3..3368eec 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -75,7 +75,15 @@ echo "publish: release id $rid ($tag)" # Replace same-named assets so re-runs are clean. for f in "$@"; do [ -f "$f" ] || { echo "publish: missing asset $f" >&2; exit 1; } + # Never publish an empty asset: a 0-byte binary/checksum looks like a + # successful release and silently breaks everyone who downloads it. + bytes=$(wc -c < "$f") + if [ "$bytes" -eq 0 ]; then + echo "publish: refusing to upload empty asset $f (0 bytes, cwd=$PWD)" >&2 + exit 1 + fi asset=$(basename "$f") + echo "publish: asset $asset is $bytes bytes on disk" api_curl -s -H "Authorization: Bearer $FORGEJO_TOKEN" "$api/releases/$rid/assets" \ | python3 -c " import json,sys