dist: add Forgejo release helper and F-Droid instructions
Some checks are pending
Deploy to GitHub Pages / deploy (push) Waiting to run
Some checks are pending
Deploy to GitHub Pages / deploy (push) Waiting to run
This commit is contained in:
parent
65914144d1
commit
383ff8a5cf
3 changed files with 137 additions and 6 deletions
|
|
@ -66,18 +66,33 @@ The Android project is generated by Capacitor and intentionally not committed,
|
|||
so the prebuild steps must be verified in the F-Droid build environment before
|
||||
submitting to F-Droid main.
|
||||
|
||||
IzzyOnDroid submission details, when you want to send it:
|
||||
|
||||
- App ID: `org.skatespots.app`
|
||||
- Source: `https://git.skate-spots.org/skatespots/SkateSpots`
|
||||
- APK: the signed asset on the latest Forgejo release
|
||||
- License: `AGPL-3.0-only`
|
||||
- Category: Sports
|
||||
- Summary: `Local-first skate map, crews, events and marketplace`
|
||||
- Keep the developer signature; do not ask users to replace an existing install
|
||||
with an F-Droid-main-signed build.
|
||||
|
||||
No GitHub account is used anywhere in this path.
|
||||
|
||||
## Release checklist
|
||||
|
||||
1. `npm test`
|
||||
2. `scripts/release.sh patch --yes --deploy` (Zapstore + web)
|
||||
3. Push the release tag and `main` to Forgejo.
|
||||
4. Attach `android/app/build/outputs/apk/release/app-release.apk` and its
|
||||
`.sha256` to the Forgejo release.
|
||||
5. Copy the signed APK into the F-Droid repo on the relay host, update the
|
||||
metadata changelog and run `fdroid update`; sync `repo/` to
|
||||
`/var/www/fdroid/repo/`.
|
||||
4. Upload the APK through the helper:
|
||||
`FORGEJO_TOKEN=... scripts/publish-forgejo.sh <version>`
|
||||
(or set `FORGEJO_TOKEN` before `release.sh`; the APK upload is then automatic)
|
||||
5. Copy the signed APK into the F-Droid repo on the relay host, add a
|
||||
`metadata/org.skatespots.app.yml` changelog entry, run `fdroid update`, and
|
||||
sync `repo/` to `/var/www/fdroid/repo/`.
|
||||
6. Verify the public latest-release page contains the new `.apk`, and that
|
||||
`https://fdroid.skate-spots.org/repo/index-v2.json` still lists the app.
|
||||
`https://fdroid.skate-spots.org/repo/index-v2.json` lists the new
|
||||
`versionCode`.
|
||||
7. Update the static download page if the displayed version/checksum changes:
|
||||
`public/download/index.html`.
|
||||
|
||||
|
|
|
|||
108
scripts/publish-forgejo.sh
Executable file
108
scripts/publish-forgejo.sh
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Publish a built APK to the self-hosted Forgejo release page.
|
||||
#
|
||||
# Usage:
|
||||
# FORGEJO_TOKEN=... scripts/publish-forgejo.sh 1.7.62 [path/to.apk]
|
||||
# FORGEJO_PASSWORD=... FORGEJO_USER=skatespots scripts/publish-forgejo.sh 1.7.62
|
||||
#
|
||||
# This uploads the APK and its .sha256 file. It does not push the git tag or
|
||||
# source; do that separately (the Forgejo repo is a mirror, not an auto-push
|
||||
# remote). Keep credentials in your shell/environment, never in this repo.
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${1:?usage: publish-forgejo.sh <version> [apk]}"
|
||||
APK="${2:-android/app/build/outputs/apk/release/app-release.apk}"
|
||||
TAG="${FORGEJO_TAG:-v$VERSION}"
|
||||
BASE="${FORGEJO_URL:-https://git.skate-spots.org}"
|
||||
OWNER="${FORGEJO_OWNER:-skatespots}"
|
||||
REPO="${FORGEJO_REPO:-SkateSpots}"
|
||||
API="$BASE/api/v1/repos/$OWNER/$REPO"
|
||||
|
||||
command -v curl >/dev/null || { echo "curl is required" >&2; exit 1; }
|
||||
command -v python3 >/dev/null || { echo "python3 is required" >&2; exit 1; }
|
||||
[ -f "$APK" ] || { echo "APK not found: $APK" >&2; exit 1; }
|
||||
|
||||
AUTH=()
|
||||
if [ -n "${FORGEJO_TOKEN:-}" ]; then
|
||||
AUTH=(-H "Authorization: token $FORGEJO_TOKEN")
|
||||
elif [ -n "${FORGEJO_PASSWORD:-}" ]; then
|
||||
AUTH=(-u "${FORGEJO_USER:-skatespots}:$FORGEJO_PASSWORD")
|
||||
else
|
||||
echo "set FORGEJO_TOKEN (preferred) or FORGEJO_PASSWORD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmpdir"' EXIT
|
||||
|
||||
sha="$(sha256sum "$APK" | awk '{print $1}')"
|
||||
body="$tmpdir/release.md"
|
||||
cat >"$body" <<EOF
|
||||
## SkateSpots $VERSION
|
||||
|
||||
Signed Android release. SHA-256: \`$sha\`
|
||||
|
||||
- Source: $BASE/$OWNER/$REPO
|
||||
- APK signing key: same as the Zapstore release.
|
||||
EOF
|
||||
|
||||
python3 - "$TAG" "$VERSION" "$body" >"$tmpdir/payload.json" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
tag, version, body_path = sys.argv[1:]
|
||||
print(json.dumps({
|
||||
"tag_name": tag,
|
||||
"name": version,
|
||||
"body": Path(body_path).read_text(),
|
||||
"draft": False,
|
||||
"prerelease": False,
|
||||
}))
|
||||
PY
|
||||
|
||||
create_code="$(curl -sS -o "$tmpdir/release.json" -w '%{http_code}' \
|
||||
"${AUTH[@]}" -H 'Content-Type: application/json' \
|
||||
-X POST "$API/releases" --data-binary @"$tmpdir/payload.json" || true)"
|
||||
|
||||
if [ "$create_code" = "201" ]; then
|
||||
release_id="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["id"])' "$tmpdir/release.json")"
|
||||
elif [ "$create_code" = "409" ] || [ "$create_code" = "422" ]; then
|
||||
curl -fsS "${AUTH[@]}" "$API/releases/tags/$TAG" -o "$tmpdir/release.json"
|
||||
release_id="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["id"])' "$tmpdir/release.json")"
|
||||
else
|
||||
echo "Forgejo release creation failed (HTTP $create_code)" >&2
|
||||
cat "$tmpdir/release.json" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sha_file="$tmpdir/SkateSpots-$VERSION.apk.sha256"
|
||||
printf '%s SkateSpots-%s.apk\n' "$sha" "$VERSION" >"$sha_file"
|
||||
|
||||
existing_assets="$(python3 - "$tmpdir/release.json" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(open(sys.argv[1]))
|
||||
print("\n".join(asset["name"] for asset in data.get("assets", [])))
|
||||
PY
|
||||
)"
|
||||
|
||||
for file in "$APK" "$sha_file"; do
|
||||
name="$(basename "$file")"
|
||||
if printf '%s\n' "$existing_assets" | grep -Fqx "$name"; then
|
||||
echo "already present: $name"
|
||||
continue
|
||||
fi
|
||||
code="$(curl -sS -o "$tmpdir/asset.json" -w '%{http_code}' \
|
||||
"${AUTH[@]}" -X POST "$API/releases/$release_id/assets?name=$name" \
|
||||
-F "attachment=@$file" || true)"
|
||||
case "$code" in
|
||||
201|202) echo "uploaded $name" ;;
|
||||
*) echo "warning: upload of $name returned HTTP $code" >&2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "release: $BASE/$OWNER/$REPO/releases/tag/$TAG"
|
||||
echo "latest: $BASE/$OWNER/$REPO/releases/latest"
|
||||
|
|
@ -126,6 +126,14 @@ for _ in 1 2 3 4 5 6; do
|
|||
done
|
||||
[ "$FOUND" -eq 1 ] || log "warning: the release event did not appear on the relay yet (it usually propagates shortly)"
|
||||
|
||||
if [ -n "${FORGEJO_TOKEN:-}" ] || [ -n "${FORGEJO_PASSWORD:-}" ]; then
|
||||
log "publishing the APK to the self-hosted Forgejo release page…"
|
||||
scripts/publish-forgejo.sh "$VERSION" "$APK" || \
|
||||
log "warning: Forgejo upload failed — the Zapstore release is still valid"
|
||||
else
|
||||
log "Forgejo: skipped (set FORGEJO_TOKEN or FORGEJO_PASSWORD to publish there)"
|
||||
fi
|
||||
|
||||
log "committing the release…"
|
||||
git add package.json package-lock.json release-notes.txt
|
||||
git commit -m "release: $VERSION" >/dev/null
|
||||
|
|
|
|||
Loading…
Reference in a new issue