103 lines
3.5 KiB
Bash
103 lines
3.5 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# Publish an Archipelago OTA release to a Gitea remote and verify downloads.
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
VERSION="${1:-}"
|
||
|
|
REMOTE="${2:-gitea-vps2}"
|
||
|
|
|
||
|
|
if [ -z "$VERSION" ]; then
|
||
|
|
echo "Usage: $0 VERSION [remote]"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
|
|
VERSION_DIR="$PROJECT_ROOT/releases/v${VERSION}"
|
||
|
|
BACKEND="$VERSION_DIR/archipelago"
|
||
|
|
FRONTEND="$VERSION_DIR/archipelago-frontend-${VERSION}.tar.gz"
|
||
|
|
|
||
|
|
fail() { echo "Error: $*" >&2; exit 1; }
|
||
|
|
|
||
|
|
[ -f "$PROJECT_ROOT/releases/manifest.json" ] || fail "releases/manifest.json missing"
|
||
|
|
[ -f "$BACKEND" ] || fail "backend artifact missing: $BACKEND"
|
||
|
|
[ -f "$FRONTEND" ] || fail "frontend artifact missing: $FRONTEND"
|
||
|
|
|
||
|
|
"$SCRIPT_DIR/check-release-manifest.sh"
|
||
|
|
|
||
|
|
remote_url=$(git -C "$PROJECT_ROOT" remote get-url "$REMOTE")
|
||
|
|
case "$remote_url" in
|
||
|
|
http://*@*) ;;
|
||
|
|
*) fail "$REMOTE must be an authenticated http:// Gitea remote URL for API uploads" ;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
auth=${remote_url#http://}
|
||
|
|
auth=${auth%@*}
|
||
|
|
host_path=${remote_url#http://$auth@}
|
||
|
|
host=${host_path%%/*}
|
||
|
|
repo_path=${host_path#*/}
|
||
|
|
repo_path=${repo_path%.git}
|
||
|
|
api="http://$host/api/v1/repos/$repo_path"
|
||
|
|
release_url="$api/releases/tags/v${VERSION}"
|
||
|
|
|
||
|
|
echo "Pushing main and v${VERSION} to $REMOTE..."
|
||
|
|
git -C "$PROJECT_ROOT" push "$REMOTE" main "refs/tags/v${VERSION}"
|
||
|
|
|
||
|
|
release_json=$(curl -fsS -u "$auth" "$release_url" || true)
|
||
|
|
if [ -z "$release_json" ]; then
|
||
|
|
echo "Creating Gitea release v${VERSION}..."
|
||
|
|
release_body=$(python3 - "$VERSION" <<'PY'
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
|
||
|
|
version = sys.argv[1]
|
||
|
|
print(json.dumps({
|
||
|
|
"tag_name": f"v{version}",
|
||
|
|
"target_commitish": "main",
|
||
|
|
"name": f"v{version}",
|
||
|
|
"body": f"Archipelago v{version} release artifacts for OTA updates.",
|
||
|
|
"draft": False,
|
||
|
|
"prerelease": True,
|
||
|
|
}))
|
||
|
|
PY
|
||
|
|
)
|
||
|
|
release_json=$(curl -fsS -u "$auth" -H 'Content-Type: application/json' -d "$release_body" "$api/releases")
|
||
|
|
fi
|
||
|
|
|
||
|
|
release_id=$(printf '%s' "$release_json" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
|
||
|
|
|
||
|
|
asset_names=$(curl -fsS -u "$auth" "$api/releases/$release_id/assets" | python3 -c 'import json,sys; print("\n".join(a["name"] for a in json.load(sys.stdin)))')
|
||
|
|
upload_asset() {
|
||
|
|
local path="$1"
|
||
|
|
local name="$2"
|
||
|
|
if printf '%s\n' "$asset_names" | grep -Fxq "$name"; then
|
||
|
|
echo "Asset $name already exists; leaving it in place."
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
echo "Uploading $name..."
|
||
|
|
curl --fail --show-error --silent --http1.1 --connect-timeout 20 --max-time 900 \
|
||
|
|
-u "$auth" \
|
||
|
|
-F "attachment=@$path" \
|
||
|
|
"$api/releases/$release_id/assets?name=$name" >/dev/null
|
||
|
|
asset_names=$(printf '%s\n%s\n' "$asset_names" "$name")
|
||
|
|
}
|
||
|
|
|
||
|
|
upload_asset "$BACKEND" "archipelago"
|
||
|
|
upload_asset "$FRONTEND" "archipelago-frontend-${VERSION}.tar.gz"
|
||
|
|
|
||
|
|
echo "Verifying public download URLs from manifest..."
|
||
|
|
python3 - "$PROJECT_ROOT/releases/manifest.json" <<'PY' | while read -r url size; do
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
|
||
|
|
manifest = json.load(open(sys.argv[1]))
|
||
|
|
for component in manifest["components"]:
|
||
|
|
print(component["download_url"], component["size_bytes"])
|
||
|
|
PY
|
||
|
|
headers=$(curl -fsSI -L --max-time 60 "$url") || fail "download URL failed: $url"
|
||
|
|
actual_size=$(printf '%s\n' "$headers" | awk 'tolower($1)=="content-length:" { size=$2 } END { gsub("\r", "", size); print size }')
|
||
|
|
[ "$actual_size" = "$size" ] || fail "download size mismatch for $url (expected $size, got ${actual_size:-missing})"
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "Release v${VERSION} published and verified on $REMOTE."
|