#!/bin/sh # Creates (or updates) the Gitea release for a tag and uploads what deploy/build.sh made. # # TOKEN= deploy/publish-release.sh v0.2.0 # # In Gitea Actions GITHUB_SERVER_URL and GITHUB_REPOSITORY are already set. Safe to # re-run: an existing release is reused and assets with the same name are replaced. set -eu TAG=${1:?usage: publish-release.sh } : "${TOKEN:?set TOKEN to a Gitea access token that can write releases}" SERVER=${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-https://git.veillax.com}} REPO=${GITHUB_REPOSITORY:-Veillax/Spinner} API="$SERVER/api/v1/repos/$REPO" AUTH="Authorization: token $TOKEN" # a JSON helper without needing jq: any python will do PY=python3 python3 -c 'pass' > /dev/null 2>&1 || PY=python json() { "$PY" -c "$1"; } # release notes: the commit subjects since the previous tag prev=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null || true) if [ -n "$prev" ]; then notes=$(git log --pretty='format:- %s' "$prev..$TAG") else notes=$(git log --pretty='format:- %s' "$TAG") fi prerelease=false case "$TAG" in *-*) prerelease=true ;; esac body=$(NOTES="$notes" TAG="$TAG" PRE="$prerelease" json ' import json, os print(json.dumps({"tag_name": os.environ["TAG"], "name": os.environ["TAG"], "body": os.environ["NOTES"], "draft": False, "prerelease": os.environ["PRE"] == "true"}))') # reuse the release when a failed job is re-run id=$(curl -fsS -H "$AUTH" "$API/releases/tags/$TAG" 2>/dev/null | json 'import sys, json; print(json.load(sys.stdin)["id"])' 2>/dev/null || true) if [ -z "$id" ]; then echo "creating release $TAG" id=$(curl -fsS -X POST -H "$AUTH" -H 'Content-Type: application/json' -d "$body" "$API/releases" | json 'import sys, json; print(json.load(sys.stdin)["id"])') else echo "release $TAG already exists (id $id): replacing its files" fi # the ids of the release's assets with a given name (a failed upload can leave a partial one behind) asset_ids() { curl -fsS -H "$AUTH" "$API/releases/$id/assets" | "$PY" -c 'import sys, json for a in json.load(sys.stdin): if a["name"] == sys.argv[1]: print(a["id"])' "$1" } for f in dist/*.tar.gz dist/*.zip dist/SHA256SUMS; do [ -f "$f" ] || continue name=$(basename "$f") n=1 while :; do for aid in $(asset_ids "$name"); do curl -fsS -X DELETE -H "$AUTH" "$API/releases/$id/assets/$aid" > /dev/null done echo "uploading $name (attempt $n)" if curl -fsS --max-time 1200 -X POST -H "$AUTH" -F "attachment=@$f" "$API/releases/$id/assets?name=$name" > /dev/null; then break fi # large uploads can hit a proxy timeout (HTTP 502); try again [ "$n" -lt 5 ] || { echo "giving up on $name after $n attempts" >&2; exit 1; } n=$((n + 1)) sleep $((n * 10)) done done echo "published $SERVER/$REPO/releases/tag/$TAG"