From 2fb1448234fb3a16a31fb89716b0730f6980627d Mon Sep 17 00:00:00 2001 From: Derek Date: Wed, 14 Oct 2026 15:58:51 +1100 Subject: [PATCH] fix: key the linux tarball upload on the tarball hyperi-ci's release tail writes /macbash-linux-.sha256 for the raw binary before Package runs. The linux tarball job used that same file as its write-once marker, so on the next release it would have found it, skipped, and never published the linux tarballs or the tarball line the Homebrew formula reads. The marker is now the tarball, which only this job writes, and it goes up after the .sha256. --- .github/workflows/package.yml | 12 +++++++----- docs/release.md | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 8ba35b2..3b237ea 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -153,9 +153,11 @@ jobs: aws configure set aws_access_key_id "$R2_ACCESS_KEY_ID" aws configure set aws_secret_access_key "$R2_SECRET_ACCESS_KEY" aws configure set region auto - # Versioned paths are write-once: the formula and install.sh pin these - # bytes by sha256. The .sha256 goes up last, so it marks a full upload. - marker="macbash/${TAG}/macbash-linux-${ARCH}.sha256" + # Versioned paths are write-once: the formula pins the tarball by sha256. + # hyperi-ci has already written /macbash-linux-.sha256 for the + # raw binary and this job adds the tarball line, so the tarball, which + # only this job writes, is the marker and goes up last. + marker="macbash/${TAG}/macbash-linux-${ARCH}.tar.gz" published=$(aws s3api list-objects-v2 --endpoint-url "$R2_ENDPOINT" --bucket "$R2_BUCKET" \ --prefix "$marker" --query "length(Contents || \`[]\`)" --output text) case "$published" in @@ -164,10 +166,10 @@ jobs: *) echo "::error::unexpected R2 listing for ${marker}: ${published}"; exit 1 ;; esac for dest in "s3://${R2_BUCKET}/macbash/${TAG}/" "s3://${R2_BUCKET}/macbash/latest/"; do - aws s3 cp --endpoint-url "$R2_ENDPOINT" \ - "dist/macbash-linux-${ARCH}.tar.gz" "$dest" aws s3 cp --endpoint-url "$R2_ENDPOINT" \ "dist/macbash-linux-${ARCH}.sha256" "$dest" + aws s3 cp --endpoint-url "$R2_ENDPOINT" \ + "dist/macbash-linux-${ARCH}.tar.gz" "$dest" done deb-rpm: diff --git a/docs/release.md b/docs/release.md index 01b42e0..a2af431 100644 --- a/docs/release.md +++ b/docs/release.md @@ -91,7 +91,7 @@ A Cross-build that refuses a run concludes `skipped`, and Package only follows a ## Versioned paths are write-once -The Homebrew formula and `install.sh` pin the bytes at `//` by SHA-256, so nothing overwrites them. Each upload checks R2 for the file it writes last (its `.sha256`, or `/install.sh` for the manifests), and when that exists it writes nothing, `latest/` included. The root `install.sh` is the exception: it is re-rendered from the default branch on every Package run. A re-run, or a CI run that published nothing new, therefore leaves the release alone. Replacing a published artefact means deleting it from R2 by hand first. +The Homebrew formula and `install.sh` pin the bytes at `//` by SHA-256, so nothing overwrites them. Each upload checks R2 for a file only it writes, uploaded last, and when that exists it writes nothing, `latest/` included. That file is the `.sha256` for the darwin, windows and package uploads, the tarball for the linux tarballs (hyperi-ci writes the linux `.sha256` first), and `/install.sh` for the manifests. The root `install.sh` is the exception: it is re-rendered from the default branch on every Package run. A re-run, or a CI run that published nothing new, therefore leaves the release alone. Replacing a published artefact means deleting it from R2 by hand first. The binaries carry no build clock either: `build.rs` stamps `SOURCE_DATE_EPOCH` when it is set, else the commit time of HEAD.