8881241fd8
runs dist.sh inside that local image via a bind mount, andcupload-image.sh pushes the already-built image. The Dockerfile also warms the Gradle dependency cache in a throwaway build stage, and pre-installs the pinned CMake version, so `run-image.sh` doesn't re-download the same Maven dependencies on every run. dist.sh now strips the -pre+meta suffix before writing package.json's version, since Pebble's build tooling parses it strictly as X.Y.Z integers and was rejecting suffixed versions.
124 lines
5.5 KiB
Bash
Executable File
124 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Builds release artifacts for both apps and drops them in dist/, named
|
|
# schwert-und-magie-<version>.{aab,apk,pbw}.
|
|
#
|
|
# Version comes from the current git tag (vX.Y.Z) by default — push a tag to
|
|
# drive a release. Override with VERSION=1.2.3 ./dist.sh, or just run it
|
|
# untagged for a local dev build (gets a 0.0.0-dev+<sha> placeholder version).
|
|
#
|
|
# Android output requires a release signing config — see docs/publish.md §2.1-2.3
|
|
# (keystore.properties + release.keystore in SchwertUndMagieOnPebbleCompanionApp/).
|
|
# Without it, Gradle still produces an unsigned/debug-signed build; that's not
|
|
# fatal (useful for local testing) so it's a warning, not a hard stop.
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
|
ROOT="$(pwd)"
|
|
DIST="$ROOT/dist"
|
|
COMPANION="$ROOT/SchwertUndMagieOnPebbleCompanionApp"
|
|
WATCH="$ROOT/SchwertUndMagieOnPebbleWatchApp"
|
|
GRADLE_KTS="$COMPANION/app/build.gradle.kts"
|
|
WATCH_PKG_JSON="$WATCH/package.json"
|
|
|
|
fail() { echo "PREFLIGHT FAIL: $*" >&2; exit 1; }
|
|
warn() { echo "WARNING: $*" >&2; }
|
|
|
|
echo "== Preflight checks =="
|
|
|
|
command -v pebble >/dev/null 2>&1 \
|
|
|| fail "pebble CLI not found in PATH (needed to build the watch app)"
|
|
|
|
[ -x "$COMPANION/gradlew" ] \
|
|
|| fail "$COMPANION/gradlew missing or not executable"
|
|
|
|
SDK_DIR="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}"
|
|
if [ -f "$COMPANION/local.properties" ]; then
|
|
LOCAL_SDK="$(sed -n 's/^sdk\.dir=//p' "$COMPANION/local.properties")"
|
|
[ -n "$LOCAL_SDK" ] && SDK_DIR="$LOCAL_SDK"
|
|
fi
|
|
[ -n "$SDK_DIR" ] && [ -d "$SDK_DIR" ] \
|
|
|| fail "Android SDK not found (checked local.properties sdk.dir, \$ANDROID_SDK_ROOT, \$ANDROID_HOME)"
|
|
|
|
NDK_VERSION="$(sed -n 's/.*ndkVersion *= *"\(.*\)".*/\1/p' "$GRADLE_KTS")"
|
|
[ -n "$NDK_VERSION" ] \
|
|
|| fail "could not read ndkVersion from app/build.gradle.kts"
|
|
[ -d "$SDK_DIR/ndk/$NDK_VERSION" ] \
|
|
|| fail "NDK $NDK_VERSION not installed under $SDK_DIR/ndk (Android Studio > SDK Manager > SDK Tools > NDK side by side)"
|
|
|
|
[ -f "$COMPANION/res/vice-3.8.tar.gz" ] \
|
|
|| fail "$COMPANION/res/vice-3.8.tar.gz missing (VICE source tarball required by the buildVice Gradle task)"
|
|
compgen -G "$COMPANION/res/nibtools-*.tar.gz" >/dev/null \
|
|
|| fail "$COMPANION/res/nibtools-*.tar.gz missing (nibtools source tarball required by the buildNibtools Gradle task)"
|
|
|
|
# Signing config: missing/broken keystore.properties still builds (unsigned),
|
|
# so warn here and rely on the post-build apksigner check for the real answer.
|
|
if [ ! -f "$COMPANION/keystore.properties" ]; then
|
|
warn "keystore.properties not found — release build will likely be unsigned (see docs/publish.md §2.1-2.3)"
|
|
else
|
|
STORE_FILE="$(sed -n 's/^storeFile=//p' "$COMPANION/keystore.properties")"
|
|
if [ -z "$STORE_FILE" ] || [ ! -f "$COMPANION/$STORE_FILE" ]; then
|
|
warn "keystore.properties found but its storeFile ('$STORE_FILE') does not exist — release build will likely be unsigned"
|
|
fi
|
|
fi
|
|
|
|
echo "== Resolving version =="
|
|
|
|
if [ -z "${VERSION:-}" ]; then
|
|
if TAG="$(git describe --tags --exact-match --match 'v[0-9]*.[0-9]*.[0-9]*' 2>/dev/null)"; then
|
|
VERSION="${TAG#v}"
|
|
else
|
|
VERSION="0.0.0-dev+$(git rev-parse --short HEAD)"
|
|
warn "HEAD is not on a vX.Y.Z tag — building placeholder version $VERSION (push a tag to drive a real release version)"
|
|
fi
|
|
fi
|
|
[[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]] \
|
|
|| fail "VERSION '$VERSION' is not a semantic version (expected X.Y.Z, optionally with a -pre+meta suffix)"
|
|
VERSION_CODE=$(( ${BASH_REMATCH[1]} * 10000 + ${BASH_REMATCH[2]} * 100 + ${BASH_REMATCH[3]} ))
|
|
echo "Version: $VERSION (Android versionCode $VERSION_CODE)"
|
|
|
|
# Patch versions into the tracked source files for this build only, then
|
|
# restore them — dist.sh must never leave the working tree dirty.
|
|
restore_version_files() {
|
|
git -C "$ROOT" checkout -- "$GRADLE_KTS" "$WATCH_PKG_JSON" 2>/dev/null || true
|
|
}
|
|
trap restore_version_files EXIT
|
|
|
|
sed -i \
|
|
-e "s/versionCode = [0-9]\+/versionCode = $VERSION_CODE/" \
|
|
-e "s/versionName = \"[^\"]*\"/versionName = \"$VERSION\"/" \
|
|
"$GRADLE_KTS"
|
|
# Pebble's own build tooling parses package.json's version strictly as
|
|
# X.Y.Z integers — it rejects the -pre+meta suffix dist.sh otherwise allows
|
|
# (including the default "0.0.0-dev+<sha>" placeholder), so strip it here.
|
|
PEBBLE_VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
|
|
sed -i -e "s/\"version\": \"[^\"]*\"/\"version\": \"$PEBBLE_VERSION\"/" "$WATCH_PKG_JSON"
|
|
|
|
mkdir -p "$DIST"
|
|
|
|
echo "== Android companion app =="
|
|
cd "$COMPANION"
|
|
./gradlew bundleRelease assembleRelease
|
|
|
|
cp -f app/build/outputs/bundle/release/app-release.aab "$DIST/schwert-und-magie-$VERSION.aab"
|
|
cp -f app/build/outputs/apk/release/app-release.apk "$DIST/schwert-und-magie-$VERSION.apk"
|
|
|
|
echo "== Pebble watch app =="
|
|
cd "$WATCH"
|
|
pebble build
|
|
|
|
cp -f build/SchwertUndMagieOnPebbleWatchApp.pbw "$DIST/schwert-und-magie-$VERSION.pbw"
|
|
|
|
echo "== Verifying APK signature =="
|
|
APK="$DIST/schwert-und-magie-$VERSION.apk"
|
|
APKSIGNER="$(compgen -G "$SDK_DIR/build-tools/*/apksigner" | sort -V | tail -1 || true)"
|
|
if [ -z "$APKSIGNER" ]; then
|
|
warn "apksigner not found under $SDK_DIR/build-tools — could not verify APK signature"
|
|
elif ! "$APKSIGNER" verify "$APK" >/dev/null 2>&1; then
|
|
warn "$APK is UNSIGNED (failed apksigner verification) — not installable/publishable as-is"
|
|
elif "$APKSIGNER" verify --print-certs "$APK" 2>/dev/null | grep -qi "CN=Android Debug"; then
|
|
warn "$APK is signed with the Android debug cert, not the release keystore"
|
|
fi
|
|
|
|
echo "== Done =="
|
|
ls -la "$DIST"
|