Android CI 概述:从概念到选型
大家好,我是老张,在移动 DevOps 这行摸爬滚打了快十年。今天开始咱们聊 Android CI 的失败案例和排查方法,第一章先打个底——把 CI/CD 的基本概念、Android 的特殊坑、还有几个主流平台怎么选,掰扯清楚。
一句话核心:CI/CD 不是“搭个流水线就完事”,Android 的编译、签名、多 flavor 等特性,会让同一套流程变得格外脆弱。提前理解这些特殊性,能省掉你未来至少一半的排查时间。
1.1 CI/CD 基本概念
CI(持续集成)就是频繁地把代码合并到主干,每次合并都自动构建、自动测试。CD(持续交付/部署)则是让那个构建产物能快速、安全地推到测试环境甚至用户手里。
说白了,就是“别攒一堆改动最后一天集,崩到怀疑人生”。我亲历过一个项目,团队两周才合一次代码,结果冲突花了一天,编译又花了一天,测试还没跑完,发布延期三天。从那以后,我坚持所有 MR 必须附带自动化构建和单元测试,哪怕慢点,也比最后一刻炸掉强。
- 持续集成(CI):代码合并 → 自动构建 → 自动测试 → 反馈结果
- 持续交付(CD):构建产物 → 自动部署到测试/预发布环境
- 持续部署(CD):通过测试后,自动推送到生产环境(Android 通常走到内测分发)
我的个人习惯:哪怕项目再小,也至少配一个最简的 CI 流水线——lint 检查 + 单元测试 + assembleDebug。别等出问题时才后悔。
1.2 Android CI 的特殊性
同样是写代码,Android CI 的麻烦程度比后端高了一个数量级。你想想看,后端代码编译完就是一个 jar/war,放服务器上就能跑。但 Android 呢?
- 构建环境复杂:需要特定版本的 JDK、Gradle、Android SDK、Build Tools、NDK。版本稍微不对,编译就挂。我遇到过因为 CI 机器上 Build Tools 33.0.0 和本地 34.0.0 不一致导致 resource 合并失败的案例,查了两天才定位到。
- 多 flavor / 多 module:项目稍大就会有 productFlavors、buildTypes,组合起来几十个 variant。CI 如果不按需过滤,光编译就能跑一小时。
- 签名与证书:调试签名和发布签名不同,密钥不能明文放在仓库,但 CI 里又需要动态注入。弄错一次,apk 就装不上。
- 测试环境:UI 测试需要模拟器或真机,而 CI 里的模拟器经常因为 HAXM、GPU、版本等兼容问题闪退。我曾经在 GitLab CI 上折腾了三天,才发现是模拟器镜像版本和宿主机 CPU 不匹配。
- 产物管理与分发:apk/aab 需要上传到 Firebase App Distribution、蒲公英或者自建服务器,涉及版本号、build number 统一管理。
曾经踩过的坑:有一次我忘了在 CI 的 gradle.properties 里设置 android.useAndroidX=true,结果第三库和 support 库冲突,编译成功但运行时疯狂崩溃。所以 CI 环境配置一定要和本地保持一致,最好用 docker 或者统一的 gradle wrapper。
1.3 常见 CI 平台对比
目前主流的 Android CI 平台有三个:Jenkins、GitLab CI、GitHub Actions。我用过前两个,第三个也帮客户迁移过。咱们用表格直观对比:
| 维度 | Jenkins | GitLab CI | GitHub Actions |
|---|---|---|---|
| 配置难度 | 高(需要维护 master/slave、插件) | 中(.gitlab-ci.yml 定义,较简洁) | 低(YAML 定义,市场有大量 Action 可用) |
| 易用性 | 低(界面老,调试麻烦) | 中(与仓库深度集成) | 高(生态丰富,社区活跃) |
| Android 支持 | 强(通过 Gradle 插件 + 自定义脚本) | 强(直接使用 gradle 镜像) | 强(有官方 setup-android 和 gradle-build-action) |
| 扩展性 | 极高(任意插件、分布式构建) | 中(共享 Runner 有限,自建需维护) | 中(只能使用 GitHub 提供的 runner 或自托管) |
| 成本 | 免费开源,但服务器硬件+维护人力高 | 免费额度有限,自建 runner 免费 | 公共仓库免费,私有仓库每月有限分钟 |
| 适合团队 | 大型团队、需要深度定制 | 中型团队,使用 GitLab 做 git 托管 | 小型/快速迭代团队,GitHub 用户 |
我个人习惯:如果团队本身就用的 GitLab,那直接上 GitLab CI 是最省事的,仓库和流水线绑定,MR 状态一目了然。如果你的项目托管在 GitHub,想快速跑起来,GitHub Actions 最合适,尤其是它内置的 secrets 管理,对签名密钥等敏感信息处理比 Jenkins 友好。
Jenkins 虽然老了,但它的 Pipeline as Code 配合共享库,做复杂场景(比如多分支并行发布、蓝绿部署)还是最灵活的。我曾经帮一个金融 App 客户用 Jenkins 搭了一套自动化签名+多渠道分发流水线,每天跑几十个 flavor 的构建,运行了一年没出大问题。
给新手的建议:别一开始就上 Jenkins,它的学习曲线太陡。如果团队小于10人,优先考虑 GitHub Actions。如果已经用 GitLab,就先用 GitLab CI 试试。等业务复杂到需要定制并行策略、自定义节点时,再考虑 Jenkins。
1.4 本章知识体系总览
下面这张图总结了 CI/CD 基本流程、Android 的特殊挑战,以及三大平台的定位关系。你可以把它当成后续章节的“地图”。
这张图从上到下分三层:最顶上是标准的 CI/CD 流程,中间是 Android 独有的那些“地雷”,底部是我们常选的三个平台。你再看后续章节关于构建失败、签名失败、测试失败等案例时,就可以往回关联——是环境问题?是多 flavor 没处理好?还是平台选择带来的限制?这样知识就串起来了。
1.5 小结与下一步思路
这一章我们聊了:
- CI/CD 是什么、为什么需要
- Android CI 的五个核心特殊性
- Jenkins、GitLab CI、GitHub Actions 的优缺点对比
注意:别只盯着平台的功能列表看。实际项目中,选哪个平台往往取决于你的基础设施、团队习惯、以及预算。我见过不少公司 Jenkins 用了五年舍不得换,也有团队从 GitHub Actions 切到 GitLab CI 因为需要更多私有 runner 的控制权。没有银弹,只有最适合你的方案。