#!/usr/bin/env bash # Build dsh-sync.apk and publish it into the server's data/dist directory. # # bash android/build.sh # # Toolchain (override with env vars if yours differs): # JAVA_HOME JDK 17 # ANDROID_HOME Android SDK with build-tools + platform 34 # GRADLE gradle 8.7 launcher # # First run needs network access: Gradle downloads the Android Gradle Plugin and # androidx dependencies into ~/.gradle. Later builds work offline. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ANDROID_DIR="$ROOT/android" DIST="$ROOT/data/dist" TOOLS="${ANDROID_TOOLS:-/c/Users/12914/Desktop/android-tools}" # Windows path form for the JVM. `cygpath -w` when available, else a manual # /c/ -> C:\ rewrite, because the -w call itself is what fails here. win_path() { if command -v cygpath >/dev/null 2>&1; then cygpath -w "$1"; return; fi local p="$1" if [[ "$p" =~ ^/([a-zA-Z])/(.*)$ ]]; then printf '%s:\\%s\n' "${BASH_REMATCH[1]^^}" "${BASH_REMATCH[2]//\//\\}" else printf '%s\n' "$p" fi } # The ambient JAVA_HOME/ANDROID_HOME on this machine point at an unrelated # project, so ours wins unless the caller explicitly overrides via the # ANDROID_TOOLS/GRADLE_BIN knobs. A stale ANDROID_HOME fails the build with # "SDK location not found". export JAVA_HOME="$(win_path "$TOOLS/jdk17/jdk-17.0.20+8")" export ANDROID_HOME="$(win_path "$TOOLS/sdk")" unset ANDROID_SDK_ROOT GRADLE_BIN="${GRADLE_BIN:-$TOOLS/gradle-8.7/bin/gradle}" if [ ! -x "$GRADLE_BIN" ] && [ ! -f "$GRADLE_BIN.bat" ]; then echo "gradle not found at $GRADLE_BIN (set GRADLE_BIN)" >&2 exit 1 fi echo "JAVA_HOME = $JAVA_HOME" echo "ANDROID_HOME = $ANDROID_HOME" # AGP reads sdk.dir from here; it survives a shell with no ANDROID_HOME and is # the authoritative answer when the ambient env points somewhere stale. # Forward slashes on purpose: a Java .properties file treats `\U` in a Windows # path as a unicode escape and silently mangles it. echo "sdk.dir=$TOOLS/sdk" | tr -d '\r' > "$ANDROID_DIR/local.properties" # Release keystore, generated once. Committed nowhere: this is a private LAN # tool, and a stable key matters only so app updates install over each other. KEYSTORE="$ANDROID_DIR/app/dsh-release.jks" KEYTOOL="$(dirname "$JAVA_HOME")/bin/keytool" [ -x "$KEYTOOL" ] || KEYTOOL="$JAVA_HOME/bin/keytool" if [ ! -f "$KEYSTORE" ]; then echo ">> generating release keystore" "$KEYTOOL" -genkeypair -v \ -keystore "$KEYSTORE" \ -alias dsh -keyalg RSA -keysize 2048 -validity 10000 \ -storepass dshsync -keypass dshsync \ -dname "CN=dsh-sync, OU=team, O=dsh, L=, S=, C=CN" >/dev/null 2>&1 fi echo ">> building" cd "$ANDROID_DIR" "$GRADLE_BIN" --no-daemon -q assembleRelease APK_SRC="$ANDROID_DIR/app/build/outputs/apk/release/app-release.apk" if [ ! -f "$APK_SRC" ]; then APK_SRC="$ANDROID_DIR/app/build/outputs/apk/release/app-release-unsigned.apk" fi [ -f "$APK_SRC" ] || { echo "build produced no APK" >&2; exit 1; } echo ">> publishing" mkdir -p "$DIST" cp "$APK_SRC" "$DIST/dsh-sync.apk" # The version metadata the server hands to /apk, so the page can show what it # is offering without unpacking the artifact. VERSION="$(grep -oP 'versionName\s+"\K[^"]+' "$ANDROID_DIR/app/build.gradle" | head -1)" CODE="$(grep -oP 'versionCode\s+\K[0-9]+' "$ANDROID_DIR/app/build.gradle" | head -1)" SHA="$(sha256sum "$DIST/dsh-sync.apk" | cut -d' ' -f1)" SIZE="$(stat -c %s "$DIST/dsh-sync.apk")" BUILT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" cat > "$DIST/dsh-sync.json" <:8020/apk"