Files
dsh/android/build.sh
T

111 lines
3.8 KiB
Bash

#!/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" <<EOF
{
"version": "$VERSION",
"version_code": $CODE,
"sha256": "$SHA",
"size_bytes": $SIZE,
"built_at": "$BUILT",
"application_id": "com.dsh.sync",
"min_sdk": 24,
"target_sdk": 34
}
EOF
echo
echo "APK : $DIST/dsh-sync.apk"
echo "size : $SIZE bytes"
echo "sha256 : $SHA"
echo "version : $VERSION ($CODE)"
echo
echo "Install page: http://<server>:8020/apk"