A tag wai-quantum-cli-v<version> (the crate's version, checked) builds the
wai-quantum binary on the project's own runners and attaches each archive, with its
SHA-256, to the forge release of that tag:
- macOS: aarch64-apple-darwin and x86_64-apple-darwin, with the GPU state vector;
- Linux: x86_64- and aarch64-unknown-linux-musl, static, checked as such, so any
distribution runs them;
- Windows: x86_64-pc-windows-msvc, as a zip.
Each binary runs once before it is packaged (--version, and a did:key from
`key --demo-key`). A last job writes the Homebrew formula and the Scoop manifest
from the attached SHA-256 files, leaving out a platform whose build attached nothing,
and attaches them too.
release/package.sh makes the archive (the binary, README and LICENSE; the same bytes
for the same inputs where GNU tar is there) and its .sha256. release/publish.sh
creates the release if no build has yet, replaces an asset of the same name, and
uploads over the private network, not the public tunnel. release/formulae.py writes
the formula and the manifest. The README says how to install it each way.
Checked here: package.sh on the macOS binary (the archive verifies against its
.sha256, unpacks, and runs); formulae.py against a stand-in release with three of the
five platforms attached (the formula holds those three, Ruby reads it, and the
manifest is the Windows one). The workflow itself runs on its first tag.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit 66fd49edc0)
34 lines
2 KiB
Shell
Executable file
34 lines
2 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# Attach files to the forge release for a tag, creating the release if there is
|
|
# none, and replacing an asset of the same name:
|
|
#
|
|
# FORGE_API=http://host:3400/api/v1 FORGE_REPO=owner/repo FORGE_TOKEN=... \
|
|
# bash release/publish.sh <tag> <title> <file>...
|
|
#
|
|
# Uploads go to FORGE_API directly (over the private network), never through the
|
|
# public tunnel, whose request size cap a large asset would hit.
|
|
set -euo pipefail
|
|
if [ $# -lt 3 ]; then
|
|
echo "usage: bash release/publish.sh <tag> <title> <file>..." >&2
|
|
exit 2
|
|
fi
|
|
TAG="$1"; TITLE="$2"; shift 2
|
|
: "${FORGE_API:?}" "${FORGE_REPO:?}" "${FORGE_TOKEN:?}"
|
|
AUTH="Authorization: token $FORGE_TOKEN"
|
|
BASE="$FORGE_API/repos/$FORGE_REPO/releases"
|
|
release_id() { curl -fsS -H "$AUTH" "$BASE/tags/$TAG" 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin).get("id", ""))' 2>/dev/null || true; }
|
|
ID="$(release_id)"
|
|
if [ -z "$ID" ]; then
|
|
BODY="$(python3 -c 'import json,sys; print(json.dumps({"tag_name": sys.argv[1], "name": sys.argv[2], "body": "The wai-quantum command line for macOS, Linux and Windows. Each archive holds the binary, its README and its licence; each .sha256 file checks its archive (`shasum -a 256 -c`)."}))' "$TAG" "$TITLE")"
|
|
curl -fsS -H "$AUTH" -H 'content-type: application/json' -X POST "$BASE" -d "$BODY" > /dev/null 2>&1 || true
|
|
# Builds run side by side; one of them created it if this did not.
|
|
for _ in 1 2 3 4 5 6; do ID="$(release_id)"; [ -n "$ID" ] && break; sleep 3; done
|
|
fi
|
|
[ -n "$ID" ] || { echo "::error::no release for $TAG"; exit 1; }
|
|
for f in "$@"; do
|
|
name="$(basename "$f")"
|
|
for old in $(curl -fsS -H "$AUTH" "$BASE/$ID/assets" | NAME="$name" python3 -c 'import json,os,sys; print(" ".join(str(a["id"]) for a in json.load(sys.stdin) if a["name"] == os.environ["NAME"]))'); do
|
|
curl -fsS -H "$AUTH" -X DELETE "$BASE/$ID/assets/$old" > /dev/null
|
|
done
|
|
curl -fsS -H "$AUTH" -X POST "$BASE/$ID/assets?name=$name" -F "attachment=@$f;type=application/octet-stream" -o /dev/null -w "uploaded $name: http %{http_code}\n"
|
|
done
|