furtka/scripts/publish-release.sh
Daniel Maksymilian Syrnicki cf93ef44cb
Some checks failed
Build ISO / build-iso (push) Successful in 26m56s
Deploy site / deploy (push) Successful in 23s
CI / lint (push) Successful in 34s
CI / test (push) Successful in 1m4s
CI / validate-json (push) Successful in 51s
CI / markdown-links (push) Successful in 28s
Release / release (push) Failing after 7m38s
chore: release 26.8-alpha (power actions, supersedes orphan 26.7 tag)
Adds Reboot + Shut down buttons on /settings, backed by a new
POST /api/furtka/power endpoint that kicks a delayed `systemd-run
--on-active=3s systemctl {reboot|poweroff}` so the HTTP response
flushes before the kernel loses network. Both buttons open a native
confirm dialog; after reboot, the page polls /furtka.json until the
box is back and reloads itself.

26.7-alpha was tagged on 5d8ac63 but release.yml never fired for that
tag (Forgejo race with the concurrent main push; re-push of the deleted
tag didn't wake the workflow either). 26.8 supersedes it and carries
the same open_url + Open-button content plus the power actions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 16:00:19 +02:00

111 lines
3.4 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.
ISO="$DIST_DIR/furtka-$VERSION.iso"
if [ -f "$ISO" ]; then
upload_asset "$ISO"
fi
echo "Release $VERSION published: https://$HOST/$REPO/releases/tag/$VERSION"