iboard/.gitea/workflows/android-build.yml
cheney 5822a01ed7
All checks were successful
Android Build & Publish / build-android (push) Successful in 18m36s
fix rust env
2026-08-08 10:40:33 +08:00

178 lines
7.2 KiB
YAML

name: Android Build & Publish
# 仅在 android-* 分支 push 时触发 (如 android/release, android-1.0)
# 构建 release APK (keystore 签名) 并上传到 Gitea Generic Package Registry
on:
push:
branches:
- 'android-*'
jobs:
build-android:
runs-on: ubuntu-latest
# 需要写权限: 上传 packages
permissions:
contents: read
packages: write
env:
# 固定工具链版本, 便于 actions/cache 命中
# Android 后端地址 (bake 进 APK); 与 scripts/wsl/build-apk.sh 保持一致
VITE_API_BASE: http://bh.vps.honor3.com:3001
steps:
- name: Checkout
uses: https://gitea.com/actions/checkout@v4
- name: Setup Node
uses: https://gitea.com/actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- name: Setup JDK 17
uses: https://gitea.com/actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
# ---------- 缓存: 命中后跳过下面的安装 ----------
- name: Cache Android SDK & NDK
id: cache-android
uses: https://gitea.com/actions/cache@v4
with:
path: ~/android-sdk
key: android-sdk-ndk-27.2-${{ runner.os }}
- name: Cache Rust toolchain
id: cache-rust
uses: https://gitea.com/actions/cache@v4
with:
path: |
~/.cargo
~/.rustup
# 工具链升级时 bump 版本号使缓存失效重装 (含 cargo-ndk)
key: rust-android-v1-${{ runner.os }}
- name: Cache Tauri cargo target
uses: https://gitea.com/actions/cache@v4
with:
path: src-tauri/target
key: tauri-target-android-${{ runner.os }}
# ---------- 安装工具链 (仅缓存未命中时) ----------
- name: Install Rust + Android targets
if: steps.cache-rust.outputs.cache-hit != 'true'
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
. "$HOME/.cargo/env"
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
cargo install cargo-ndk --locked
- name: Install Android SDK & NDK
if: steps.cache-android.outputs.cache-hit != 'true'
run: |
export ANDROID_HOME="$HOME/android-sdk"
sudo apt-get update
sudo apt-get install -y --no-install-recommends unzip
mkdir -p "$ANDROID_HOME/cmdline-tools"
wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O /tmp/cmdline-tools.zip
unzip -q /tmp/cmdline-tools.zip -d /tmp/
mv /tmp/cmdline-tools "$ANDROID_HOME/cmdline-tools/latest"
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
yes | sdkmanager --licenses >/dev/null || true
sdkmanager --install \
"platforms;android-36" \
"build-tools;36.0.0" \
"platform-tools" \
"ndk;27.2.12479018" \
"cmake;3.22.1"
- name: Install frontend deps
run: npm ci --no-audit --no-fund
# ---------- 全局 Android 环境 (对后续所有 step 生效, 无论缓存是否命中) ----------
- name: Set Android env
run: |
echo "ANDROID_HOME=$HOME/android-sdk" >> "$GITHUB_ENV"
echo "ANDROID_NDK_HOME=$HOME/android-sdk/ndk/27.2.12479018" >> "$GITHUB_ENV"
echo "$HOME/android-sdk/cmdline-tools/latest/bin" >> "$GITHUB_PATH"
echo "$HOME/android-sdk/platform-tools" >> "$GITHUB_PATH"
# ---------- 构建 ----------
- name: Init Android project
run: |
# tauri android init 需要 cargo (运行 cargo metadata)。
# Rust 工具链缓存命中时 "Install Rust" 步骤被跳过, 不会把 cargo 加进全局 PATH,
# 因此这里显式加载 cargo 环境 (与 Build release APK 步骤保持一致)。
. "$HOME/.cargo/env"
cd src-tauri
npx tauri android init --ci
- name: Inject release signing config
run: bash scripts/ci/android-signing.sh
env:
ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
- name: Build release APK
run: |
export ANDROID_HOME="$HOME/android-sdk"
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.2.12479018"
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH"
export CARGO_HOME="$HOME/.cargo"
. "$HOME/.cargo/env"
cd src-tauri
npx tauri android build --apk
# 断言签名配置仍在且 release 块实际引用了它 (防止 tauri 重新生成 gen/android 或正则未命中)
if ! grep -q 'create("release")' gen/android/app/build.gradle.kts || ! grep -q 'signingConfig = signingConfigs.getByName("release")' gen/android/app/build.gradle.kts; then
echo "ERROR: 构建后签名配置丢失/未生效, APK 未签名" >&2
exit 1
fi
- name: Locate APK
id: apk
run: |
# 优先 universal 已签名 APK, 找不到再回退到其他已签名 APK
APK=""
UNIVERSAL=$(find src-tauri/gen/android/app/build/outputs/apk/universal/release -name '*.apk' ! -name '*unsigned*' 2>/dev/null | head -1)
if [ -n "$UNIVERSAL" ]; then
APK="$UNIVERSAL"
else
APK=$(find src-tauri/gen/android/app/build/outputs/apk -name '*.apk' ! -name '*unsigned*' | head -1)
fi
if [ -z "$APK" ]; then
echo "ERROR: 未找到已签名 APK" >&2
exit 1
fi
echo "path=$APK" >> $GITHUB_OUTPUT
ls -lh "$APK"
# ---------- 上传到 Gitea Generic Package ----------
- name: Publish APK to Gitea packages
env:
# 注意: 不能用 GITEA_TOKEN (内置 job token, 无组织 packages 写权限, 且命名规则禁止 GITEA_ 前缀)
# 用一个自定义名 secret 存放有 packages 写权限的 user token
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
APK_PATH: ${{ steps.apk.outputs.path }}
run: |
set -euo pipefail
# 包版本: 用分支名去掉 android- 前缀 + 短 SHA, 保证每次 push 唯一
BRANCH="${GITHUB_REF_NAME#android-}"
PKG_VERSION="${BRANCH}-${GITHUB_SHA:0:8}"
FILE_NAME="iboard-$(basename "$APK_PATH")"
OWNER="${GITHUB_REPOSITORY_OWNER}"
PKG_NAME="iboard"
# Gitea Generic Package Registry 上传端点 (PUT)
# 注意: GITHUB_SERVER_URL 是仓库 web 根地址, 例如 http://git.honor3.com
URL="${GITHUB_SERVER_URL}/api/packages/${OWNER}/generic/${PKG_NAME}/${PKG_VERSION}/${FILE_NAME}"
echo "上传到: ${URL}"
curl -sS --fail-with-body \
-H "Authorization: token ${PACKAGE_TOKEN}" \
--upload-file "$APK_PATH" \
"${URL}"
echo ""
echo "已发布: ${URL}"