84 lines
4.2 KiB
Bash
Executable file
84 lines
4.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Cut a RELEASE of TVAnarchy and publish it to forge.black (Forgejo).
|
|
#
|
|
# Two-tier distribution: day-to-day `./build-install.sh` builds are ephemeral
|
|
# (tmp, install-to-/Applications, gone). A release is the durable, shareable
|
|
# artifact — built once here, tagged, and uploaded to the Forgejo repo so any
|
|
# node on the mesh can install/update from it WITHOUT the Xcode toolchain or
|
|
# source. Nodes pull with `tools/update.sh` (or the documented curl one-liner).
|
|
#
|
|
# Usage: tools/release.sh [vX.Y.Z] # tag defaults to v<MARKETING_VERSION>
|
|
# Auth: FORGEJO_TOKEN env, or ~/.config/tv-anarchy/forgejo-token (mode 600).
|
|
# Mint one at the Forgejo web UI → Settings → Applications → Tokens
|
|
# (scopes: write:repository). Required — the script will not guess.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
[ "$(uname -s)" = "Darwin" ] || { echo "✗ releases are cut on the macOS build box (xcodebuild); this is $(uname -s)." >&2; exit 1; }
|
|
|
|
API="${FORGEJO_API:-http://10.9.0.4:3000}" # overlay IP: mesh-stable (LAN addr flaps)
|
|
|
|
# --- auth (fail loud; never publish anonymously) ---------------------------
|
|
TOKEN="${FORGEJO_TOKEN:-}"
|
|
TOKEN_FILE="$HOME/.config/tv-anarchy/forgejo-token"
|
|
[ -z "$TOKEN" ] && [ -f "$TOKEN_FILE" ] && TOKEN="$(tr -d '[:space:]' < "$TOKEN_FILE")"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "✗ no Forgejo token. Set FORGEJO_TOKEN, or write one to $TOKEN_FILE (chmod 600)." >&2
|
|
echo " Mint: Forgejo → Settings → Applications → Generate Token (scope: write:repository)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- repo owner/name from the git remote ------------------------------------
|
|
remote="$(git remote get-url origin)" # forge-wg:lilith/tv-anarchy.git
|
|
path="${remote##*:}"; path="${path%.git}" # lilith/tv-anarchy
|
|
OWNER="${path%%/*}"; REPO="${path##*/}"
|
|
|
|
# --- build (ephemeral tmp) + install, reusing build-install.sh --------------
|
|
DD="$(mktemp -d "${TMPDIR:-/tmp}/tvanarchy-release.XXXXXX")"
|
|
trap 'rm -rf "$DD"' EXIT
|
|
echo "→ building release into $DD"
|
|
TVANARCHY_DD="$DD" ./build-install.sh
|
|
|
|
# Same destination resolution as build-install.sh (which we just ran) — both
|
|
# read tools/platform.sh, the single source of truth — so we zip the app it
|
|
# actually installed.
|
|
. tools/platform.sh
|
|
APP="$(tva_resolve_dest mac)"
|
|
[ -d "$APP" ] || { echo "✗ build-install did not produce $APP" >&2; exit 1; }
|
|
VER="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$APP/Contents/Info.plist")"
|
|
BUILD="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$APP/Contents/Info.plist" 2>/dev/null || echo 0)"
|
|
SHA="$(sed -n 's/.*sha = "\(.*\)"/\1/p' Sources/TVAnarchyCore/BuildStamp.swift)"
|
|
TAG="${1:-v$VER}"
|
|
|
|
# --- refuse to ship a dirty tree (a release must be reproducible) -----------
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "✗ working tree is dirty — commit before cutting release $TAG (a release must be reproducible)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- zip the .app (ditto preserves bundle symlinks/resources) ---------------
|
|
ZIP="$DD/TVAnarchy-$TAG.zip"
|
|
echo "→ packaging $ZIP"
|
|
ditto -c -k --sequesterRsrc --keepParent "$APP" "$ZIP"
|
|
|
|
# --- tag + push (over forge-wg ssh) -----------------------------------------
|
|
if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
|
|
echo "✗ tag $TAG already exists — bump MARKETING_VERSION or pass a new tag." >&2
|
|
exit 1
|
|
fi
|
|
echo "→ tagging $TAG @ $SHA and pushing"
|
|
git tag -a "$TAG" -m "TVAnarchy $TAG (build $BUILD · $SHA)"
|
|
git push origin "$TAG"
|
|
|
|
# --- create the Forgejo release + upload the zip ----------------------------
|
|
api() { curl -fsSL -H "Authorization: token $TOKEN" "$@"; }
|
|
echo "→ creating Forgejo release $TAG on $OWNER/$REPO"
|
|
rel="$(api -X POST "$API/api/v1/repos/$OWNER/$REPO/releases" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{\"tag_name\":\"$TAG\",\"name\":\"TVAnarchy $TAG\",\"body\":\"Build $BUILD · $SHA\"}")"
|
|
rid="$(printf '%s' "$rel" | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')"
|
|
echo "→ uploading asset (release id $rid)"
|
|
api -X POST "$API/api/v1/repos/$OWNER/$REPO/releases/$rid/assets?name=TVAnarchy-$TAG.zip" \
|
|
-F "attachment=@$ZIP;type=application/zip" >/dev/null
|
|
|
|
echo "✓ released $TAG → $API/$OWNER/$REPO/releases/tag/$TAG"
|
|
echo " nodes update with: tools/update.sh"
|