All checks were successful
Forgejo Android APK / Build signed APK (push) Successful in 2m27s
--push ran `git push origin HEAD`, but this repo's only remote is named forgejo — so the flag failed after the script had already committed and tagged, leaving the release half-done. Resolve the remote instead: prefer forgejo, fall back to origin, else use the only remote present, and fail with a clear message if there is none. Also corrects the header comment, which claimed the script does not build the APK and pointed at --gh / gh CLI. Forgejo CI builds the APK on every branch push and attaches it to a Forgejo release on a v* tag push, which is what Obtainium tracks. --gh is a leftover from the GitHub era. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
138 lines
4.7 KiB
Bash
Executable file
138 lines
4.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# ============================================================
|
|
# PedScribe release helper — one command to tag a new version.
|
|
#
|
|
# Usage:
|
|
# scripts/release.sh 6.1.1 # bump to 6.1.1
|
|
# scripts/release.sh 6.1.1 --push # also git push + tag push
|
|
# scripts/release.sh 6.2.0 --push --gh # also create GitHub release
|
|
#
|
|
# What it does:
|
|
# 1. Updates version in root package.json
|
|
# 2. Updates version in mobile/package.json
|
|
# 3. Updates versionName + bumps versionCode in Android build.gradle
|
|
# 4. Commits the version bump
|
|
# 5. (optional) git push + push the new tag
|
|
# 6. (optional) create a GitHub release via gh CLI
|
|
#
|
|
# It does NOT:
|
|
# - Build the Docker image (run `docker compose build`/`up -d` yourself
|
|
# or wire it to a deploy script / CI hook)
|
|
# - Build the Android APK itself. Forgejo CI does that
|
|
# (.forgejo/workflows/android-apk.yml): any branch push builds a signed
|
|
# APK as a 30-day workflow artifact, and a v* tag push additionally
|
|
# attaches it to a Forgejo release, which is what Obtainium tracks for
|
|
# updates. So --push is normally all you need; --gh is a leftover from
|
|
# the GitHub era and is not how releases are published here.
|
|
# ============================================================
|
|
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:-}"
|
|
PUSH=false
|
|
DO_RELEASE=false
|
|
for arg in "${@:2}"; do
|
|
case "$arg" in
|
|
--push) PUSH=true ;;
|
|
--gh) DO_RELEASE=true ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$VERSION" ]]; then
|
|
echo "usage: $0 <version> [--push] [--gh]"
|
|
echo " example: $0 6.1.1 --push --gh"
|
|
exit 1
|
|
fi
|
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "ERROR: version must be semver X.Y.Z (e.g. 6.1.1). got: $VERSION" >&2
|
|
exit 1
|
|
fi
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
if [[ -n "$(git status --porcelain)" ]]; then
|
|
echo "ERROR: working tree has uncommitted changes. commit or stash first." >&2
|
|
git status --short >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Bumping to v$VERSION"
|
|
|
|
# Bump a package.json "version" field without needing node/jq.
|
|
# Only touches the first top-level "version": "…" line, which is the
|
|
# canonical location npm puts it. Fragile only if someone hand-wrote
|
|
# a nested "version" ABOVE the top-level one.
|
|
bump_pkg_version() {
|
|
local file="$1" new="$2"
|
|
sed -i -E "0,/(\"version\"[[:space:]]*:[[:space:]]*\")[^\"]+(\")/ s//\1${new}\2/" "$file"
|
|
}
|
|
|
|
bump_pkg_version package.json "$VERSION"
|
|
echo " updated package.json"
|
|
bump_pkg_version mobile/package.json "$VERSION"
|
|
echo " updated mobile/package.json"
|
|
|
|
# Android build.gradle
|
|
# versionCode: encode X.Y.Z as X*100000 + Y*1000 + Z (room for 999 patches)
|
|
IFS='.' read -r MAJ MIN PAT <<< "$VERSION"
|
|
ANDROID_CODE=$(( MAJ * 100000 + MIN * 1000 + PAT ))
|
|
sed -i -E \
|
|
-e "s/versionCode +[0-9]+/versionCode ${ANDROID_CODE}/" \
|
|
-e "s/versionName +\"[^\"]+\"/versionName \"${VERSION}\"/" \
|
|
mobile/android/app/build.gradle
|
|
echo " updated mobile/android/app/build.gradle (code=$ANDROID_CODE, name=$VERSION)"
|
|
|
|
# Commit
|
|
git add package.json mobile/package.json mobile/android/app/build.gradle
|
|
git commit -m "Release v${VERSION}"
|
|
echo " committed"
|
|
|
|
# Tag
|
|
git tag -a "v${VERSION}" -m "Release v${VERSION}"
|
|
echo " tagged v${VERSION}"
|
|
|
|
if $PUSH; then
|
|
# This repo's remote is "forgejo", not "origin". Prefer forgejo, fall back
|
|
# to origin, otherwise use the only remote there is — so this keeps working
|
|
# if the remote is ever renamed. Pushing the tag is what makes CI attach the
|
|
# signed APK to a Forgejo release for Obtainium; the branch push alone only
|
|
# builds it as a 30-day workflow artifact.
|
|
REMOTE=""
|
|
for candidate in forgejo origin; do
|
|
if git remote get-url "$candidate" >/dev/null 2>&1; then REMOTE="$candidate"; break; fi
|
|
done
|
|
if [[ -z "$REMOTE" ]]; then
|
|
REMOTE=$(git remote | head -1)
|
|
fi
|
|
if [[ -z "$REMOTE" ]]; then
|
|
echo "ERROR: no git remote configured — cannot push. Commit and tag are still local." >&2
|
|
exit 1
|
|
fi
|
|
git push "$REMOTE" HEAD
|
|
git push "$REMOTE" "v${VERSION}"
|
|
echo " pushed to $REMOTE"
|
|
fi
|
|
|
|
if $DO_RELEASE; then
|
|
if ! command -v gh >/dev/null; then
|
|
echo "WARN: gh CLI not installed, skipping GitHub release creation" >&2
|
|
else
|
|
APK="mobile/android/app/build/outputs/apk/release/app-release.apk"
|
|
if [[ -f "$APK" ]]; then
|
|
gh release create "v${VERSION}" "$APK" \
|
|
--title "PedScribe ${VERSION}" \
|
|
--notes "Release ${VERSION}" \
|
|
--latest
|
|
echo " created GitHub release with APK"
|
|
else
|
|
gh release create "v${VERSION}" \
|
|
--title "PedScribe ${VERSION}" \
|
|
--notes "Release ${VERSION}" \
|
|
--latest
|
|
echo " created GitHub release (no APK attached — run gradle first then gh release upload)"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "==> Done. v$VERSION."
|