Skip to content

build(gradle): 优化版本代码和名称的环境变量读取逻辑 #34

build(gradle): 优化版本代码和名称的环境变量读取逻辑

build(gradle): 优化版本代码和名称的环境变量读取逻辑 #34

Workflow file for this run

# 工作流名称
name: 创建 Release 并上传 APK
# 工作流触发条件
on:
push:
tags:
- 'v*' # 当一个以 'v' 开头的标签被推送到仓库时触发 (例如 v1.0, v2.1.0)
workflow_dispatch: # 支持手动触发工作流
inputs:
version_code:
description: '版本号 (versionCode,如:1),留空则使用 version.properties 中的值'
required: false
type: string
default: ''
version_name:
description: '版本名称 (versionName,如:1.0.0),留空则使用 version.properties 中的值'
required: false
type: string
default: ''
# 定义一个或多个作业
jobs:
# 作业ID
build-and-release:
# 指定运行此作业的虚拟机环境
runs-on: ubuntu-latest
# 定义作业中的各个步骤
steps:
# 第1步:检出代码
# actions/checkout 是一个官方的 action,用于检出你的仓库代码,以便工作流可以访问它。
- name: 检出代码
uses: actions/checkout@v4
# 第2步:设置 Java 环境
# actions/setup-java 用于配置 Java 环境。
- name: 设置 JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'gradle' # 缓存 Gradle 依赖,加快构建速度
# 第3步:解码签名文件
# 从 GitHub Secrets 中获取 Base64 编码的签名文件内容,并解码还原成 .jks 文件。
- name: 解码签名文件 (Keystore)
id: decode_keystore
run: |
echo "从 Secrets 中解码签名文件..."
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > app/release.jks
echo "签名文件已成功解码到 app/release.jks"
# 第4步:创建签名配置
# 创建一个临时的 gradle.properties 文件,并写入从 Secrets 获取的签名信息。
- name: 为签名创建 gradle.properties
run: |
echo "为签名创建 app/gradle.properties 文件..."
echo "StoreFile=release.jks" > app/gradle.properties
echo "StorePassword=${{ secrets.STORE_PASSWORD }}" >> app/gradle.properties
echo "KeyAlias=${{ secrets.KEY_ALIAS }}" >> app/gradle.properties
echo "KeyPassword=${{ secrets.KEY_PASSWORD }}" >> app/gradle.properties
echo "gradle.properties 文件创建成功。"
# 第5步:为 gradlew 添加执行权限
# 在 Linux/macOS 系统中,需要给 gradlew 脚本添加执行权限。
- name: 授予 gradlew 执行权限
run: chmod +x gradlew
# 第6步:构建 Release 版本的 APK
# 运行 Gradle 命令来编译和打包带签名的 APK。
- name: 构建 Release APK
run: ./gradlew :app:assembleRelease --stacktrace
env:
GRADLE_OPTS: -Xmx8g -Dfile.encoding=UTF-8
# 手动触发时传递版本参数,留空则使用 version.properties 中的值
APP_VERSION_CODE: ${{ github.event.inputs.version_code }}
APP_VERSION_NAME: ${{ github.event.inputs.version_name }}
# 调试步骤(暂时保留,用于确认构建是否生成目录)
- name: 调试:列出构建输出
run: ls -R build/app/outputs
# 第6.5步:生成 appConfig.json
# 运行自定义任务生成 appConfig.json 文件
- name: 生成 appConfig.json
run: ./gradlew :app:printReleaseAppConfig
# 第7步:获取版本信息
# 从 version.properties 文件中读取版本信息,如果有手动输入则优先使用手动输入的值。
- name: 获取版本名称
id: get_version
run: |
# 读取 version.properties 中的值作为默认值
VERSION_NAME=$(grep 'versionName=' version.properties | cut -d'=' -f2)
VERSION_CODE=$(grep 'versionCode=' version.properties | cut -d'=' -f2)
# 如果提供了手动输入的版本名称,则使用手动输入的值
if [ -n "${{ github.event.inputs.version_name }}" ]; then
VERSION_NAME="${{ github.event.inputs.version_name }}"
fi
# 如果提供了手动输入的版本号,则使用手动输入的值
if [ -n "${{ github.event.inputs.version_code }}" ]; then
VERSION_CODE="${{ github.event.inputs.version_code }}"
fi
echo "version=$VERSION_NAME" >> $GITHUB_OUTPUT
echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
echo "::notice::Building with versionName=$VERSION_NAME, versionCode=$VERSION_CODE"
# 第8步:获取 APK 路径
# 从输出目录中找到构建生成的 APK 文件。
- name: 获取 APK 路径
id: get_apk_path
run: |
APK_PATH=$(find build/app/outputs/apk/release -type f -name "*.apk" | head -n 1)
if [ -z "$APK_PATH" ]; then
echo "错误:在 build/app/outputs/apk/release 目录中找不到 APK 文件。" >&2
exit 1
fi
# 获取文件名(不带扩展名),用于 Artifact 命名
APK_NAME=$(basename "$APK_PATH" .apk)
echo "apk_path=$APK_PATH" >> $GITHUB_OUTPUT
echo "apk_name=$APK_NAME" >> $GITHUB_OUTPUT
APP_CONFIG_PATH=$(find build/app/outputs/apk/release -type f -name "appConfig.json" | head -n 1)
if [ -z "$APP_CONFIG_PATH" ]; then
echo "错误:在 build/app/outputs/apk/release 目录中找不到 appConfig.json 文件。" >&2
else
echo "app_config_path=$APP_CONFIG_PATH" >> $GITHUB_OUTPUT
fi
# 第9步:上传 APK 为 Artifact(仅手动触发时)
# 手动触发工作流时,将 APK 上传为 artifact,方便下载测试
- name: 上传 APK 为 Artifact
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: ${{ steps.get_apk_path.outputs.apk_name }}
path: |
${{ steps.get_apk_path.outputs.apk_path }}
${{ steps.get_apk_path.outputs.app_config_path }}
retention-days: 30
# 第10步:创建 GitHub Release(仅 tag 触发时)
# 使用 softprops/action-gh-release 这个 action 来创建 Release 并上传 APK。
- name: 创建 GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
# 上传的文件路径
files: |
${{ steps.get_apk_path.outputs.apk_path }}
${{ steps.get_apk_path.outputs.app_config_path }}
# Release 的标题
name: "Release ${{ github.ref_name }}"
# Release 的描述内容
body: |
**版本:** ${{ steps.get_version.outputs.version }}
此版本由 GitHub Actions 自动构建和发布。
# 是否为预发布版本
prerelease: false
env:
# 需要 GITHUB_TOKEN 才能有权限创建 Release
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 第11步:清理工作区
# 删除生成的签名文件和配置文件,确保它们不会被意外泄露。
- name: 清理签名文件和配置
if: always() # 保证无论之前的步骤成功或失败,此步骤都会执行
run: |
echo "清理工作区..."
rm -f app/release.jks
rm -f app/gradle.properties
echo "清理完成。"