From 5eceac79edbfe08e6af74998b054e27cbcfe2c1e Mon Sep 17 00:00:00 2001 From: xiajiid Date: Sun, 8 Feb 2026 21:23:51 +0800 Subject: [PATCH] Add signing configuration for Huawei compatible release builds --- .github/workflows/build-and-sign.yml | 71 ++++++++++++++++++++++++++++ GITHUB_SECRETS.md | 69 +++++++++++++++++++++++++++ app/build.gradle | 10 ++++ 3 files changed, 150 insertions(+) create mode 100644 .github/workflows/build-and-sign.yml create mode 100644 GITHUB_SECRETS.md diff --git a/.github/workflows/build-and-sign.yml b/.github/workflows/build-and-sign.yml new file mode 100644 index 0000000..9185dee --- /dev/null +++ b/.github/workflows/build-and-sign.yml @@ -0,0 +1,71 @@ +name: Android CI with Release Signing + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build-and-sign: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Create signing properties file + run: | + cat > app/signing.properties << EOF + storeFile=../keystore.jks + storePassword=${{ secrets.KEYSTORE_PASSWORD }} + keyAlias=${{ secrets.ALIAS }} + keyPassword=${{ secrets.KEY_PASSWORD }} + EOF + + - name: Restore signing key + run: | + echo "${{ secrets.SIGNING_KEY }}" | base64 --decode > keystore.jks + ls -la keystore.jks + + - name: Set up signing environment + run: | + echo "KEYSTORE_PATH=../keystore.jks" >> $GITHUB_ENV + echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV + echo "ALIAS=${{ secrets.ALIAS }}" >> $GITHUB_ENV + echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV + echo "Signing environment variables set" + + - name: Build release APK + run: ./gradlew assembleRelease + + - name: Sign APK (alternative method) + uses: r0adkll/sign-android-release@v1 + with: + releaseDirectory: app/build/outputs/apk/release + signingKeyBase64: ${{ secrets.SIGNING_KEY }} + alias: ${{ secrets.ALIAS }} + keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }} + keyPassword: ${{ secrets.KEY_PASSWORD }} + + - name: Upload signed APK + uses: actions/upload-artifact@v4 + with: + name: app-release-signed + path: app/build/outputs/apk/release/app-release-signed.apk + + - name: Upload debug APK as fallback + if: always() + uses: actions/upload-artifact@v4 + with: + name: app-debug + path: app/build/outputs/apk/debug/app-debug.apk \ No newline at end of file diff --git a/GITHUB_SECRETS.md b/GITHUB_SECRETS.md new file mode 100644 index 0000000..1b5afa9 --- /dev/null +++ b/GITHUB_SECRETS.md @@ -0,0 +1,69 @@ +# GitHub Secrets 配置说明 + +## 生成的签名文件信息 +- **签名文件**: `logcam-release.jks` +- **别名 (ALIAS)**: `logcam-release-key` +- **密钥库密码 (KEYSTORE_PASSWORD)**: `android123` +- **密钥密码 (KEY_PASSWORD)**: `android123` + +## Base64 字符串 (SIGNING_KEY) + +将以下整个字符串(包含 `===` 结束符)复制为 `SIGNING_KEY` 的值: + +``` +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 +``` + +## GitHub Secrets 配置步骤 + +1. **访问 Secrets 页面**: + - 打开 https://github.com/xiajid/logcam/settings/secrets/actions + - 点击 "New repository secret" + +2. **创建以下 4 个 Secrets**: + + | 名称 | 值 | 说明 | + |------|-----|------| + | `SIGNING_KEY` | 上面的 Base64 字符串 | 签名文件(整个字符串) | + | `ALIAS` | `logcam-release-key` | 密钥别名 | + | `KEYSTORE_PASSWORD` | `android123` | 密钥库密码 | + | `KEY_PASSWORD` | `android123` | 密钥密码 | + +3. **保存并触发构建**: + - 保存所有 Secrets + - 推送任意更改到 `main` 分支 + - 或手动触发工作流 + +## 工作流说明 + +已创建 `.github/workflows/build-and-sign.yml` 工作流: + +- **触发条件**:push 到 main 分支 +- **构建类型**:release(签名版) +- **输出文件**:`app-release-signed.apk` +- **备用输出**:`app-debug.apk` + +## 本地构建(可选) + +如果你需要在本地构建签名版 APK: + +```bash +# 设置环境变量(Linux/macOS) +export KEYSTORE_PATH=../keystore.jks +export KEYSTORE_PASSWORD=android123 +export ALIAS=logcam-release-key +export KEY_PASSWORD=android123 + +# 复制签名文件到项目根目录 +cp logcam-release.jks keystore.jks + +# 构建发布版 +./gradlew assembleRelease +``` + +## 注意事项 + +1. **密码安全**:建议在生产环境中使用更复杂的密码 +2. **密钥保管**:保管好 `logcam-release.jks` 文件 +3. **更新应用**:签名后,后续版本必须使用相同签名才能升级 +4. **华为兼容**:签名版 APK 更容易通过华为安全检测 \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 5d252cc..dee895c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,6 +17,15 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + signingConfigs { + release { + storeFile file(System.getenv('KEYSTORE_PATH') ?: '../keystore.jks') + storePassword System.getenv('KEYSTORE_PASSWORD') ?: 'android123' + keyAlias System.getenv('ALIAS') ?: 'logcam-release-key' + keyPassword System.getenv('KEY_PASSWORD') ?: 'android123' + } + } + buildTypes { debug { versionNameSuffix "-debug" @@ -24,6 +33,7 @@ android { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release } }