Skip to content

ci(workflow): 优化 Release 构建流程与签名参数传递方式 #41

ci(workflow): 优化 Release 构建流程与签名参数传递方式

ci(workflow): 优化 Release 构建流程与签名参数传递方式 #41

Workflow file for this run

name: 创建 Release 并上传 APK
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version_code:
description: '版本号 (versionCode),留空则使用 version.properties 中的值'
required: false
type: string
default: ''
version_name:
description: '版本名称 (versionName),留空则使用 version.properties 中的值'
required: false
type: string
default: ''
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-release:
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
contents: write
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 JDK 21
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
- name: 设置 Gradle
uses: gradle/actions/setup-gradle@v4
- name: 授予 gradlew 执行权限
run: chmod +x gradlew
- name: 验证签名 Secrets
run: |
missing=""
[ -z "${{ secrets.KEYSTORE_BASE64 }}" ] && missing="$missing KEYSTORE_BASE64"
[ -z "${{ secrets.STORE_PASSWORD }}" ] && missing="$missing STORE_PASSWORD"
[ -z "${{ secrets.KEY_ALIAS }}" ] && missing="$missing KEY_ALIAS"
[ -z "${{ secrets.KEY_PASSWORD }}" ] && missing="$missing KEY_PASSWORD"
if [ -n "$missing" ]; then
echo "::error::以下 Secrets 未配置:$missing"
exit 1
fi
- name: 准备签名文件
run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > app/release.jks
- name: 构建 Release APK 并生成构建清单
run: |
./gradlew :app:assembleRelease :app:printReleaseAppConfig --stacktrace \
-PStoreFile=release.jks \
-PStorePassword="${{ secrets.STORE_PASSWORD }}" \
-PKeyAlias="${{ secrets.KEY_ALIAS }}" \
-PKeyPassword="${{ secrets.KEY_PASSWORD }}"
env:
GRADLE_OPTS: -Xmx2g -Dfile.encoding=UTF-8
APP_VERSION_CODE: ${{ github.event.inputs.version_code || '' }}
APP_VERSION_NAME: ${{ github.event.inputs.version_name || '' }}
- name: 读取构建清单
id: manifest
run: |
MANIFEST_PATH="app/build/outputs/build-manifest.json"
if [ ! -f "$MANIFEST_PATH" ]; then
echo "::error::build-manifest.json 未找到,请确保构建步骤执行成功。"
echo "预期路径: $MANIFEST_PATH"
exit 1
fi
echo "=== 构建清单内容 ==="
cat "$MANIFEST_PATH"
APK_PATH=$(jq -r '.apkPath' "$MANIFEST_PATH")
APK_NAME=$(jq -r '.apkName' "$MANIFEST_PATH")
APP_CONFIG_PATH=$(jq -r '.appConfigPath' "$MANIFEST_PATH")
VERSION_NAME=$(jq -r '.versionName' "$MANIFEST_PATH")
if [ ! -f "$APK_PATH" ]; then
echo "::error::APK 文件不存在: $APK_PATH"
exit 1
fi
echo "apk_path=$APK_PATH" >> $GITHUB_OUTPUT
echo "apk_name=$APK_NAME" >> $GITHUB_OUTPUT
echo "app_config_path=$APP_CONFIG_PATH" >> $GITHUB_OUTPUT
echo "version_name=$VERSION_NAME" >> $GITHUB_OUTPUT
echo "::notice::构建成功 — $APK_NAME (v$VERSION_NAME)"
- name: 上传 APK 为 Artifact
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: ${{ steps.manifest.outputs.apk_name }}
path: |
${{ steps.manifest.outputs.apk_path }}
${{ steps.manifest.outputs.app_config_path }}
if-no-files-found: error
retention-days: 30
- name: 创建 GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: |
${{ steps.manifest.outputs.apk_path }}
${{ steps.manifest.outputs.app_config_path }}
name: "Release ${{ github.ref_name }}"
body: |
**版本:** ${{ steps.manifest.outputs.version_name }}
此版本由 GitHub Actions 自动构建和发布。
prerelease: false
fail_on_unmatched_files: true
- name: 清理敏感文件
if: always()
run: rm -f app/release.jks app/gradle.properties app/build/outputs/build-manifest.json