Wardrobe/scripts/build-apk.sh
jif2.zhang 38b5e3190a init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD
- 响应式项目首页 (Landing, 含 R2 APK 下载) + 路由 /home 调整
- OTA 升级: tauri-plugin-hotswap (lib.rs/main.rs 拆分, 客户端热替换)
- OTA 服务端 (check/bundle/manifest-web) + build-ota/genkey/upload 脚本
- 密钥/凭据统一存配置中心 (signing + ota + cloudflare 分组)
- Android CI (android-* 分支) + OTA CI (手动触发), 产物上传 R2
- 修复 tsc/构建阻塞问题
2026-09-11 15:46:42 +08:00

130 lines
3.9 KiB
Bash

#!/usr/bin/env bash
# Wardrobe Android APK 本地打包脚本 (WSL 内运行)
# 用法: bash scripts/build-apk.sh [debug|release]
# 参考: D:\workbench\iboard\scripts\wsl\build-apk.sh
# 尽量复用本机已装的 Android SDK / NDK, 不重复下载
set -euo pipefail
WIN_PROJECT='/mnt/d/workbench/Wardrobe'
cd "$WIN_PROJECT"
VARIANT="${1:-debug}"
echo "构建变体: $VARIANT"
# ---- 复用已有 Android SDK / NDK (不重复安装) ----
# 优先用 ANDROID_HOME 环境变量, 找不到再探测常见路径
if [ -z "${ANDROID_HOME:-}" ] || [ ! -d "$ANDROID_HOME/platforms" ]; then
for cand in "$HOME/android-sdk" "/opt/android-sdk" "/usr/lib/android-sdk"; do
if [ -d "$cand/platforms" ]; then
export ANDROID_HOME="$cand"
break
fi
done
fi
if [ -z "${ANDROID_HOME:-}" ] || [ ! -d "$ANDROID_HOME/platforms" ]; then
echo "ERROR: 未找到可复用的 Android SDK (ANDROID_HOME)" >&2
exit 1
fi
echo "复用 SDK: $ANDROID_HOME"
# NDK: 复用已装的 27.2.x, 找不到报错
export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}"
NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then
echo "ERROR: NDK toolchain 不存在: $NDK_TOOLCHAIN_BIN, 请确认已安装 NDK 27.2.x" >&2
exit 1
fi
echo "复用 NDK: $ANDROID_NDK_HOME"
export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH"
# ---- 0. 首次需要 android 工程 ----
cd src-tauri
if [ ! -d "gen/android" ]; then
echo "=== 0. 初始化 Android 工程 (一次性) ==="
npx tauri android init --ci
fi
cd "$WIN_PROJECT"
# ---- 1. 构建前端 ----
echo "=== 1. 构建前端 ==="
npm run build
# ---- 1.5 拷贝 dist/ 到 Android 工程 assets/ ----
ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets"
mkdir -p "$ANDROID_ASSETS"
find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} +
cp -r dist/. "$ANDROID_ASSETS/"
echo "前端 bundle 已拷贝到 $ANDROID_ASSETS"
# ---- 2. 构建 ----
cd src-tauri
if [ "$VARIANT" = "release" ]; then
# release: 手工 cargo 编 4 ABI, gradle 只跑打包
RUST_BUILD_TASKS=(
":app:rustBuildArm64Release"
":app:rustBuildArmRelease"
":app:rustBuildX86_64Release"
":app:rustBuildX86Release"
)
SKIP_ARGS=()
for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done
ANDROID_TARGETS=(
"aarch64-linux-android"
"armv7-linux-androideabi"
"x86_64-linux-android"
"i686-linux-android"
)
echo "[release] 手工 cargo 编 lib (4 个 ABI)..."
for target in "${ANDROID_TARGETS[@]}"; do
echo " [cargo] build lib release for $target ..."
cargo build \
--target "$target" \
--features custom-protocol \
--lib \
--release
done
echo " [gradle] assembleRelease -x rustBuild* ..."
cd gen/android
./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}"
APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release"
SIGNED_APK="$APK_DIR/app-universal-release.apk"
UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk"
if [ -f "$SIGNED_APK" ]; then
APK_PATH="$SIGNED_APK"
APK_STATUS="已签名"
elif [ -f "$UNSIGNED_APK" ]; then
APK_PATH="$UNSIGNED_APK"
APK_STATUS="未签名"
else
APK_PATH=""
APK_STATUS="未找到"
fi
echo
echo "=== 产物 ($APK_STATUS) ==="
if [ -n "$APK_PATH" ]; then
ls -lh "$APK_PATH"
else
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
fi
if [ "$APK_STATUS" = "已签名" ]; then
echo
echo "安装: adb install -r $APK_PATH"
fi
else
echo "[debug] 直接走 Tauri CLI"
npx tauri android build --apk
APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug"
echo
echo "=== 产物 ==="
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
fi