CI runs with -o pipefail, so 'yes | sdkmanager --licenses' fails
with exit code 141 when sdkmanager closes stdin. Wrapped with
{ yes || true; } | ... || true to handle this gracefully.
172 lines
5.7 KiB
Bash
Executable File
172 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ── build-apk.sh ──────────────────────────────────────────────────────────────
|
|
# Builds the Meal Tracker Android APK from the android/ directory.
|
|
#
|
|
# Usage:
|
|
# ./build-apk.sh # Build debug APK (default)
|
|
# ./build-apk.sh release # Build release APK (unsigned)
|
|
#
|
|
# Prerequisites (auto-installed if missing):
|
|
# - Java 17+ (OpenJDK)
|
|
# - Android SDK command-line tools
|
|
# - Gradle (via wrapper)
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ANDROID_DIR="$SCRIPT_DIR/android"
|
|
OUTPUT_DIR="$ANDROID_DIR/app/build/outputs/apk"
|
|
SDK_ROOT="${ANDROID_SDK_ROOT:-$HOME/android-sdk}"
|
|
CMDLINE_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
|
|
BUILD_TOOLS_VER="34.0.0"
|
|
PLATFORM_VER="34"
|
|
GRADLE_VER="8.7"
|
|
GRADLE_URL="https://services.gradle.org/distributions/gradle-${GRADLE_VER}-bin.zip"
|
|
|
|
BUILD_TYPE="${1:-debug}"
|
|
|
|
# ── Colors ──
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
|
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
err() { echo -e "${RED}[ERR]${NC} $*"; }
|
|
|
|
# ── Detect package manager ──
|
|
if command -v apt-get &>/dev/null; then
|
|
PM="apt"
|
|
elif command -v yum &>/dev/null; then
|
|
PM="yum"
|
|
elif command -v dnf &>/dev/null; then
|
|
PM="dnf"
|
|
else
|
|
PM=""
|
|
fi
|
|
|
|
# ── Install Java if needed ──
|
|
install_java() {
|
|
info "Installing Java 17..."
|
|
case "$PM" in
|
|
apt)
|
|
apt-get update -qq && apt-get install -y -qq openjdk-21-jdk-headless ;;
|
|
yum)
|
|
yum install -y java-17-openjdk-headless ;;
|
|
dnf)
|
|
dnf install -y java-17-openjdk-headless ;;
|
|
*)
|
|
err "Cannot install Java automatically. Please install Java 17+ manually."
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
if ! command -v java &>/dev/null; then
|
|
if [ "$PM" != "" ]; then
|
|
install_java
|
|
else
|
|
err "Java is required but not found. Install Java 17+ (OpenJDK)."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
JAVA_VER=$(java -version 2>&1 | head -1 | grep -oP '\d+' | head -1 || echo "0")
|
|
if [ "$JAVA_VER" -lt 17 ] 2>/dev/null; then
|
|
warn "Java $JAVA_VER detected. Java 17+ is recommended."
|
|
fi
|
|
info "Java: $(java -version 2>&1 | head -1)"
|
|
|
|
# ── Install Android SDK if needed ──
|
|
install_sdk() {
|
|
info "Installing Android SDK command-line tools to $SDK_ROOT..."
|
|
mkdir -p "$SDK_ROOT"
|
|
tmp_zip="/tmp/cmdline-tools.zip"
|
|
tmp_dir="/tmp/cmdline-tools-tmp"
|
|
|
|
if command -v wget &>/dev/null; then
|
|
wget -q --show-progress "$CMDLINE_URL" -O "$tmp_zip"
|
|
elif command -v curl &>/dev/null; then
|
|
curl -L --progress-bar "$CMDLINE_URL" -o "$tmp_zip"
|
|
else
|
|
err "Need wget or curl to download Android SDK."
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf "$tmp_dir"
|
|
mkdir -p "$tmp_dir"
|
|
unzip -qo "$tmp_zip" -d "$tmp_dir"
|
|
mkdir -p "$SDK_ROOT/cmdline-tools"
|
|
rm -rf "$SDK_ROOT/cmdline-tools/latest"
|
|
mv "$tmp_dir/cmdline-tools" "$SDK_ROOT/cmdline-tools/latest"
|
|
rm -f "$tmp_zip"
|
|
rm -rf "$tmp_dir"
|
|
info "Android SDK command-line tools installed."
|
|
}
|
|
|
|
if [ ! -f "$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then
|
|
install_sdk
|
|
fi
|
|
|
|
export ANDROID_SDK_ROOT="$SDK_ROOT"
|
|
|
|
# Accept SDK licenses (avoid SIGPIPE under -o pipefail)
|
|
{ yes 2>/dev/null || true; } | "$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null 2>&1 || true
|
|
|
|
# ── Install required SDK packages ──
|
|
info "Checking Android SDK packages..."
|
|
"$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" \
|
|
"platform-tools" \
|
|
"build-tools;${BUILD_TOOLS_VER}" \
|
|
"platforms;android-${PLATFORM_VER}" \
|
|
> /dev/null 2>&1 || true
|
|
|
|
# Create local.properties
|
|
cat > "$ANDROID_DIR/local.properties" <<EOF
|
|
sdk.dir=$SDK_ROOT
|
|
EOF
|
|
|
|
# ── Download Gradle if needed ──
|
|
GRADLE_DIR="$ANDROID_DIR/.gradle-home"
|
|
GRADLE_BIN="$GRADLE_DIR/gradle-${GRADLE_VER}/bin/gradle"
|
|
if [ ! -f "$GRADLE_BIN" ]; then
|
|
info "Downloading Gradle ${GRADLE_VER}..."
|
|
gradle_zip="/tmp/gradle-${GRADLE_VER}.zip"
|
|
if command -v wget &>/dev/null; then
|
|
wget -q --show-progress "$GRADLE_URL" -O "$gradle_zip"
|
|
else
|
|
curl -L --progress-bar "$GRADLE_URL" -o "$gradle_zip"
|
|
fi
|
|
rm -rf "$GRADLE_DIR"
|
|
mkdir -p "$GRADLE_DIR"
|
|
unzip -qo "$gradle_zip" -d "$GRADLE_DIR"
|
|
rm -f "$gradle_zip"
|
|
info "Gradle ${GRADLE_VER} ready."
|
|
fi
|
|
|
|
# Generate wrapper in the android dir so gradlew works
|
|
if [ ! -f "$ANDROID_DIR/gradlew" ]; then
|
|
info "Generating Gradle wrapper..."
|
|
cd "$ANDROID_DIR"
|
|
"$GRADLE_BIN" wrapper --gradle-version "$GRADLE_VER" --no-daemon 2>&1 | tail -3
|
|
cd "$SCRIPT_DIR"
|
|
fi
|
|
|
|
# ── Build ──
|
|
info "Building $BUILD_TYPE APK..."
|
|
cd "$ANDROID_DIR"
|
|
./gradlew "assemble${BUILD_TYPE^}" --no-daemon --warning-mode=all
|
|
|
|
# ── Report ──
|
|
APK_FILE=$(find "$OUTPUT_DIR" -name "*.apk" -type f | head -1)
|
|
if [ -f "$APK_FILE" ]; then
|
|
APK_SIZE=$(du -h "$APK_FILE" | cut -f1)
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo -e " ${GREEN}✓ BUILD SUCCESSFUL${NC}"
|
|
echo " APK: $APK_FILE"
|
|
echo " Size: $APK_SIZE"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
else
|
|
err "APK not found in $OUTPUT_DIR"
|
|
exit 1
|
|
fi
|