1. 为什么需要自动化发布流水线作为一个经历过手动打包发布折磨的Android开发者我深刻理解每次发布新版本时的手忙脚乱。记得有一次凌晨两点紧急修复bug结果因为忘记更新版本号导致用户收不到更新推送那种挫败感至今难忘。这就是为什么我们需要建立自动化发布流水线。GitHub Actions作为GitHub原生支持的CI/CD工具与代码仓库无缝集成特别适合中小团队使用。它能帮我们实现版本号自动管理每次发布自动递增版本号避免人为失误代码签名安全存储将敏感的签名密钥存放在私有仓库通过加密方式调用构建过程标准化确保每次构建环境一致避免在我机器上能跑的问题发布流程自动化从代码提交到应用上架全流程无人值守实测下来原本需要30分钟的手动操作现在只需点击一个按钮就能完成而且出错率为零。下面我就详细分享这套经过实战检验的自动化方案。2. 环境准备与基础配置2.1 创建密钥存储仓库安全永远是第一位的。我们首先需要创建一个私有仓库专门存放签名密钥新建一个名为android-keystore的私有仓库准备两个关键文件key.jksAndroid签名密钥文件keystore.properties包含以下内容storePasswordyour_store_password keyPasswordyour_key_password keyAliasyour_key_alias storeFile../keystore/key.jks建议使用子模块方式引入密钥仓库既安全又方便更新git submodule add gitgithub.com:yourname/android-keystore.git keystore2.2 配置版本管理文件在项目根目录创建version.properties文件versionName1.0.0 versionCode1然后在build.gradle中添加读取逻辑def versionProps new Properties() file(version.properties).withInputStream { versionProps.load(it) } defaultConfig { versionCode versionProps[versionCode].toInteger() versionName versionProps[versionName] }3. 构建自动化工作流3.1 基础Workflow配置在.github/workflows/android-ci.yml中配置基础触发器name: Android CI on: push: tags: - v* workflow_dispatch: # 允许手动触发这个配置会在两种情况下运行当推送v开头的tag时如v1.0.0在GitHub Actions界面手动点击运行3.2 密钥安全获取通过GitHub Secrets保护敏感信息- name: Checkout Keystore uses: actions/checkoutv3 with: repository: yourname/android-keystore token: ${{ secrets.KEYSTORE_TOKEN }} path: keystore需要在仓库Settings Secrets中配置KEYSTORE_TOKEN有权限访问密钥仓库的Personal Access TokenKEYSTORE_PASSWORD密钥库密码KEY_PASSWORD密钥密码3.3 构建与签名配置完整的构建步骤示例- name: Build with Gradle run: ./gradlew assembleRelease env: ORG_GRADLE_PROJECT_storePassword: ${{ secrets.KEYSTORE_PASSWORD }} ORG_GRADLE_PROJECT_keyPassword: ${{ secrets.KEY_PASSWORD }}对应的build.gradle配置signingConfigs { release { storeFile file(keystoreProperties[storeFile]) storePassword System.getenv(ORG_GRADLE_PROJECT_storePassword) keyPassword System.getenv(ORG_GRADLE_PROJECT_keyPassword) keyAlias keystoreProperties[keyAlias] } }4. 高级自动化技巧4.1 自动版本递增创建Gradle任务自动处理版本更新task bumpVersion { doLast { def versionFile file(version.properties) def versionProps new Properties() versionFile.withInputStream { versionProps.load(it) } // 版本号1逻辑 versionProps[versionCode] (versionProps[versionCode].toInteger() 1).toString() def versionNameParts versionProps[versionName].tokenize(.) versionNameParts[2] (versionNameParts[2].toInteger() 1).toString() versionProps[versionName] versionNameParts.join(.) versionFile.withWriter { versionProps.store(it, null) } } }4.2 自动创建GitHub Release使用官方Action上传APK- name: Upload Release Asset uses: actions/upload-release-assetv1 with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: app/build/outputs/apk/release/app-release.apk asset_name: App-v${{ steps.get_version.outputs.version }}.apk asset_content_type: application/vnd.android.package-archive4.3 多环境构建支持通过矩阵策略支持不同构建变体strategy: matrix: variant: [prod, staging] steps: - name: Build ${{ matrix.variant }} run: ./gradlew assemble${{ matrix.variant }}Release5. 常见问题排查5.1 权限问题处理如果遇到权限错误检查Personal Access Token是否具有repo权限工作流文件是否在默认分支(.github/workflows目录下)密钥文件权限是否正确(建议644)5.2 构建缓存优化添加缓存配置加速构建- name: Cache Gradle uses: actions/cachev3 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: gradle-${{ runner.os }}-${{ hashFiles(**/*.gradle*) }}5.3 构建耗时分析通过以下命令生成构建报告./gradlew assembleRelease --profile --scan这会生成详细的HTML报告帮助定位耗时最长的任务。这套自动化方案已经在多个项目中稳定运行超过一年最大的感受就是再也不用担心深夜发布时的手抖问题。特别是自动版本管理功能让我们的版本号再也没出现过混乱。现在团队的新成员第一天就能独立完成发布操作这才是工程化应该有的样子。