feat(android): 增加独立Android原生离线工程与GitHub Actions自动化构建
- 原生工程物理隔离:新建 android/ 独立工程,零侵入 Web 端现有源码 - 自动化资产同步:通过 android/copy-web-assets.sh 在构建时复制 Web 静态资产 - 原生体验调优:沉浸式状态栏适配、明文HTTP与DOM存储支持、返回键防误退 - 高清图标生成:基于 icon-512.png 自动生成全套 mipmap 分辨率桌面图标 - 云端CI构建:添加 .github/workflows/build-apk.yml 支持一键/Tag打包输出 APK
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
name: Build Android APK
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_name:
|
||||
description: '版本名称 (例如 1.0.0)'
|
||||
required: false
|
||||
default: '1.0.0'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Release APK
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
- name: Sync Web Assets to Android
|
||||
run: |
|
||||
chmod +x android/copy-web-assets.sh
|
||||
./android/copy-web-assets.sh
|
||||
|
||||
- name: Setup Keystore
|
||||
id: sign_setup
|
||||
run: |
|
||||
mkdir -p android/keystore
|
||||
KEYSTORE_PATH="$GITHUB_WORKSPACE/android/keystore/release.jks"
|
||||
|
||||
if [ -n "${{ secrets.SIGNING_KEY }}" ]; then
|
||||
echo "Using custom signing key from repository secrets..."
|
||||
echo "${{ secrets.SIGNING_KEY }}" | base64 --decode > "$KEYSTORE_PATH"
|
||||
echo "SIGNING_KEY_FILE=$KEYSTORE_PATH" >> $GITHUB_ENV
|
||||
echo "KEY_STORE_PASSWORD=${{ secrets.KEY_STORE_PASSWORD }}" >> $GITHUB_ENV
|
||||
echo "ALIAS=${{ secrets.ALIAS }}" >> $GITHUB_ENV
|
||||
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "No custom signing key provided. Generating self-signed release keystore for this build..."
|
||||
keytool -genkeypair -v \
|
||||
-keystore "$KEYSTORE_PATH" \
|
||||
-alias "workhours" \
|
||||
-keyalg RSA \
|
||||
-keysize 2048 \
|
||||
-validity 10000 \
|
||||
-storepass "workhours123" \
|
||||
-keypass "workhours123" \
|
||||
-dname "CN=WorkHours, OU=OpenClaw, O=WorkHoursTracker, L=Wuhan, ST=Hubei, C=CN"
|
||||
echo "SIGNING_KEY_FILE=$KEYSTORE_PATH" >> $GITHUB_ENV
|
||||
echo "KEY_STORE_PASSWORD=workhours123" >> $GITHUB_ENV
|
||||
echo "ALIAS=workhours" >> $GITHUB_ENV
|
||||
echo "KEY_PASSWORD=workhours123" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
cd android
|
||||
chmod +x gradlew
|
||||
./gradlew assembleRelease --stacktrace
|
||||
|
||||
- name: Prepare APK Artifact
|
||||
id: prepare_apk
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version_name || github.ref_name || '1.0.0' }}"
|
||||
VERSION="${VERSION#v}" # 剥离前缀 v
|
||||
|
||||
OUTPUT_DIR="android/app/build/outputs/apk/release"
|
||||
APK_FILE=$(find "$OUTPUT_DIR" -name "*.apk" | head -n 1)
|
||||
|
||||
if [ -z "$APK_FILE" ]; then
|
||||
echo "Error: APK not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_APK="work-hours-tracker-v${VERSION}.apk"
|
||||
cp "$APK_FILE" "$TARGET_APK"
|
||||
echo "Built APK: $TARGET_APK"
|
||||
echo "apk_path=$TARGET_APK" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload APK to Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: work-hours-tracker-${{ steps.prepare_apk.outputs.version }}
|
||||
path: ${{ steps.prepare_apk.outputs.apk_path }}
|
||||
retention-days: 30
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ steps.prepare_apk.outputs.apk_path }}
|
||||
name: Work Hours Tracker v${{ steps.prepare_apk.outputs.version }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
Reference in New Issue
Block a user