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 呢?

  1. 构建环境复杂:需要特定版本的 JDK、Gradle、Android SDK、Build Tools、NDK。版本稍微不对,编译就挂。我遇到过因为 CI 机器上 Build Tools 33.0.0 和本地 34.0.0 不一致导致 resource 合并失败的案例,查了两天才定位到。
  2. 多 flavor / 多 module:项目稍大就会有 productFlavors、buildTypes,组合起来几十个 variant。CI 如果不按需过滤,光编译就能跑一小时。
  3. 签名与证书:调试签名和发布签名不同,密钥不能明文放在仓库,但 CI 里又需要动态注入。弄错一次,apk 就装不上。
  4. 测试环境:UI 测试需要模拟器或真机,而 CI 里的模拟器经常因为 HAXM、GPU、版本等兼容问题闪退。我曾经在 GitLab CI 上折腾了三天,才发现是模拟器镜像版本和宿主机 CPU 不匹配。
  5. 产物管理与分发: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 的特殊挑战,以及三大平台的定位关系。你可以把它当成后续章节的“地图”。

Android CI/CD 知识体系总览 代码提交 自动构建 自动测试 部署/分发 Android CI 特殊性(常见失败来源) 构建环境版本不一致 多 flavor 组合爆炸 签名/密钥管理 模拟器兼容问题 常见CI平台 Jenkins · 高定制化 · 插件丰富 · 自建服务器 · 维护成本高 GitLab CI · 仓库集成好 · YAML 易配置 · 共享 Runner · 适合中团队 GitHub Actions · 生态丰富 · 上手简单 · 免费额度 · 小团队首选 提示:本章是理解后续失败案例的“地基”,重点关注 Android 特殊性和平台选型依据。

这张图从上到下分三层:最顶上是标准的 CI/CD 流程,中间是 Android 独有的那些“地雷”,底部是我们常选的三个平台。你再看后续章节关于构建失败、签名失败、测试失败等案例时,就可以往回关联——是环境问题?是多 flavor 没处理好?还是平台选择带来的限制?这样知识就串起来了。

1.5 小结与下一步思路

这一章我们聊了:

  • CI/CD 是什么、为什么需要
  • Android CI 的五个核心特殊性
  • Jenkins、GitLab CI、GitHub Actions 的优缺点对比

注意:别只盯着平台的功能列表看。实际项目中,选哪个平台往往取决于你的基础设施、团队习惯、以及预算。我见过不少公司 Jenkins 用了五年舍不得换,也有团队从 GitHub Actions 切到 GitLab CI 因为需要更多私有 runner 的控制权。没有银弹,只有最适合你的方案。