All checks were successful
Build ISO / build-iso (push) Successful in 20m49s
CI / lint (push) Successful in 1m13s
CI / test (push) Successful in 48s
CI / validate-json (push) Successful in 44s
CI / markdown-links (push) Successful in 16s
Release / release (push) Successful in 13m31s
Three small fixes surfaced by the 26.8 QA pass on fresh VM .161: - Landing-page app tiles now open external `open_url` links in a new tab, matching /apps Open-button behaviour. Without this a Kuma click on the home screen replaced Furtka itself. - `scripts/publish-release.sh` treats the ISO upload as best-effort; a Forgejo-proxy 504 no longer kills the whole release after tarball + sha + release.json are already uploaded. - `furtka app list --json` now mirrors /api/apps — includes `description_long`, `open_url`, and `settings` that the previous slim projection dropped.
118 lines
3.8 KiB
Bash
Executable file
118 lines
3.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Publish a Furtka release to the Forgejo releases page.
|
|
#
|
|
# Usage: ./scripts/publish-release.sh <version>
|
|
#
|
|
# Preconditions:
|
|
# - $FORGEJO_TOKEN set (PAT with write:repository)
|
|
# - dist/furtka-<version>.tar.gz + .sha256 + release.json already built
|
|
#
|
|
# Behaviour:
|
|
# 1. Read the [<version>] section from CHANGELOG.md for the release body.
|
|
# 2. Create a release on Forgejo (or fail if one already exists for the tag).
|
|
# 3. Upload the three assets sequentially (Forgejo's release API has been
|
|
# observed to choke on parallel uploads).
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:?usage: $0 <version>}"
|
|
: "${FORGEJO_TOKEN:?FORGEJO_TOKEN must be set}"
|
|
|
|
HOST="${FORGEJO_HOST:-forgejo.sourcegate.online}"
|
|
REPO="${FORGEJO_REPO:-daniel/furtka}"
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
DIST_DIR="$REPO_ROOT/dist"
|
|
TARBALL="$DIST_DIR/furtka-$VERSION.tar.gz"
|
|
SHA_FILE="$TARBALL.sha256"
|
|
RELEASE_JSON="$DIST_DIR/release.json"
|
|
|
|
for f in "$TARBALL" "$SHA_FILE" "$RELEASE_JSON"; do
|
|
[ -f "$f" ] || { echo "missing: $f"; exit 1; }
|
|
done
|
|
|
|
# Extract the changelog section for this version. Matches `## [<version>]`
|
|
# up to (but not including) the next `## [` line.
|
|
BODY="$(awk -v v="$VERSION" '
|
|
BEGIN { inside=0 }
|
|
/^## \[/ {
|
|
if (inside) exit
|
|
if (index($0, "[" v "]") > 0) { inside=1; next }
|
|
}
|
|
inside { print }
|
|
' "$REPO_ROOT/CHANGELOG.md")"
|
|
if [ -z "$BODY" ]; then
|
|
BODY="Release $VERSION"
|
|
fi
|
|
|
|
PRERELEASE=false
|
|
if [[ "$VERSION" == *-alpha* || "$VERSION" == *-beta* || "$VERSION" == *-rc* ]]; then
|
|
PRERELEASE=true
|
|
fi
|
|
|
|
api() {
|
|
curl --silent --show-error --fail-with-body \
|
|
--header "Authorization: token $FORGEJO_TOKEN" \
|
|
"$@"
|
|
}
|
|
|
|
base="https://$HOST/api/v1/repos/$REPO"
|
|
|
|
# 1. Create the release. Python for JSON assembly so we don't depend on jq
|
|
# on the runner — the previous `apt-get install -y jq` step in release.yml
|
|
# hung for 15+ minutes on a slow mirror and stalled the whole publish.
|
|
release_body_json="$(
|
|
VERSION="$VERSION" BODY="$BODY" PRE="$PRERELEASE" python3 -c '
|
|
import json, os
|
|
print(json.dumps({
|
|
"tag_name": os.environ["VERSION"],
|
|
"name": os.environ["VERSION"],
|
|
"body": os.environ["BODY"],
|
|
"prerelease": os.environ["PRE"] == "true",
|
|
}))
|
|
'
|
|
)"
|
|
|
|
echo "==> Creating release $VERSION"
|
|
release_response="$(api --request POST "$base/releases" \
|
|
--header "Content-Type: application/json" \
|
|
--data "$release_body_json")"
|
|
|
|
release_id="$(echo "$release_response" | python3 -c 'import json, sys; print(json.load(sys.stdin).get("id", ""))')"
|
|
if [ -z "$release_id" ] || [ "$release_id" = "null" ]; then
|
|
echo "error: couldn't parse release id from response:"
|
|
echo "$release_response"
|
|
exit 1
|
|
fi
|
|
echo " release id: $release_id"
|
|
|
|
# 2. Upload assets — one at a time.
|
|
upload_asset() {
|
|
local path="$1"
|
|
local name
|
|
name="$(basename "$path")"
|
|
echo "==> Uploading $name"
|
|
api --request POST "$base/releases/$release_id/assets?name=$name" \
|
|
--form "attachment=@$path" > /dev/null
|
|
}
|
|
|
|
upload_asset "$TARBALL"
|
|
upload_asset "$SHA_FILE"
|
|
upload_asset "$RELEASE_JSON"
|
|
|
|
# Optional: attach the live-installer ISO when dist/furtka-<version>.iso
|
|
# exists. Release workflows that want this build the ISO via iso/build.sh
|
|
# and move the output here before calling publish-release. Local runs
|
|
# that skip the ISO step still publish the core release successfully.
|
|
#
|
|
# Soft-fail: the ISO is ~1 GB and Forgejo's reverse proxy has returned
|
|
# 504 on the upload even when the write eventually succeeds. The core
|
|
# tarball (which boxes need for self-update) is already uploaded above,
|
|
# so don't let an ISO transport hiccup fail the whole release.
|
|
ISO="$DIST_DIR/furtka-$VERSION.iso"
|
|
if [ -f "$ISO" ]; then
|
|
if ! upload_asset "$ISO"; then
|
|
echo "warning: ISO upload failed — release published without ISO asset" >&2
|
|
fi
|
|
fi
|
|
|
|
echo "Release $VERSION published: https://$HOST/$REPO/releases/tag/$VERSION"
|