移动端发布和 Web 完全不同:构建一次、分发到无数设备、还要过商店审核、出问题不能像 Web 一样秒回滚。Mobile CD(移动端持续交付)就是把这些特殊性工程化:统一的 CI 构建矩阵、证书与签名管理、TestFlight/内部分发、商店灰度与全量、以及"热修复兜底 + 质量门禁"。本指南帮你把移动端的发布从"手工打包上传"推进到"自动化、可控、可回退"的流水线。
目录
- 1. 移动端发布的特殊性
- 2. CI 构建矩阵:iOS / Android 并行构建
- 3. 签名与证书管理
- 4. 测试分发:内测、TestFlight 与 TestFlight 流程
- 5. 应用商店发布与灰度
- 6. 回滚与紧急修复
- 7. 移动端质量门禁
- 8. 移动端发布的避坑
- 9. 最佳实践清单
1. 移动端发布的特殊性:与 Web 的差异
1.1 为什么移动端 CD 更难
移动端发布的特殊性:
1. 客户端代码不可热替换(除热修)
2. 每个版本要过商店审核(时间不可控)
3. 用户设备千差万别(版本/机型/网络)
4. 出问题回滚很慢(用户还在老版本)
5. 有不同渠道/商店(iOS App Store / Android 多个商店)
结果:发布必须"慢而稳",需要专门工程化手段
1.2 移动端 CD 的目标
目标:
- 自动化构建(拉分支→编译→打包→签名→分发)
- 每个提交/PR 可测(内部渠道分发给 QA/产品)
- 发布流程可审计(版本号、build、变更记录)
- 灰度可控(按渠道/按比例/按地区)
- 紧急时有兜底(热修/强制升级/快速回退通道)
2. CI 构建矩阵:iOS / Android 并行构建
2.1 构建矩阵设计
# 一个 PR/提交触发两个平台的构建矩阵
matrix:
platform: [ios, android]
flavor: [dev, staging, prod] # 按环境打不同配置
构建任务:
- iOS:xcodebuild / fastlane build(真机证书 + 模拟器)
- Android:gradle assemble(debug/release + 多渠道)
- 产物:apk / ipa + 签名 + 版本号注入
并行好处:
- 一次提交两端同时构建 → 反馈快
- 两端构建失败立刻知道,不用等发布时才炸
2.2 版本号与构建号
版本号策略:
- 语义化:major.minor.patch(对外版本)
- build 号:每次 CI 构建自动递增(对内唯一标识)
- 从 Git 提交信息/CI 流水号生成 → 可追踪
注入到应用:
- 版本号显示在关于页 → 内测定位问题必靠它
- build 号写入构建信息 → 支持查询"这个包是哪个提交"
3. 签名与证书管理
3.1 iOS / Android 签名的区别
iOS:
- 证书(.cer)+ 私钥 + Provisioning Profile
- 真机调试/发布分别要 profile(device id 绑定)
- 过期/失效 → 无法安装/上架
Android:
- 用 keystore 签名(release 必须)
- 签名密钥必须长期保存(丢了没法更新已装应用)
核心痛点:签名/证书/私钥是"敏感 + 必须一致 + 有有效期"
3.2 用 CI Secrets 管理证书
正确做法:
- 私钥/证书/keystore 放 CI Secrets(加密存储)
- 在 CI 里解密 → 用于构建 → 用完即删
- profile/keystore 版本化(标记有效期)
避坑:
- 私钥别放代码仓库 / 别手工共享
- 证书快过期要提前预警(失效会导致线上事故)
- 自动化续期(fastlane match 管理 iOS 证书)
4. 测试分发:内测、TestFlight 与第三方
4.1 内测渠道
内测分发:
- iOS:TestFlight(苹果官方,最多 100 内测用户/版本)
- Android:Firebase App Distribution / 蒲公英 / 自建 APK 托管
- 作用:PR/提测版本即时给 QA、产品、设计师安装验证
CI 集成:
构建完 → 自动上传内测渠道 → 通知测试人员
→ 二维码/链接直达安装(Android 尤其方便)
4.2 TestFlight 流程
TestFlight 流程:
- CI 上传 ipa → 苹果审核(几小时~一天)
- 添加测试用户(内测/公开测试)
- 测试人员装 TestFlight → 安装 → 反馈
- 正式发布前先在 TestFlight 放一轮
好处:发布前"真实设备 + 真实网络"验证,还收集崩溃/反馈
5. 应用商店发布与灰度
5.1 发布到商店的流程
商店发布要点:
- 过商店审核(内容、合规、隐私说明)
- 发布窗口:避开节假日/大促前
- 版本号对齐:商店里的版本 = 应用内版本
- 元数据(标题/描述/截图/隐私)配好
自动化的边界:
- 上传、元数据、审核状态跟踪可自动化
- 最终"上架动作"留人工确认(不可逆)
5.2 灰度(分阶段发布)
iOS App Store:
- 分阶段发布(Phased Release)——按比例 1%→100%
- 苹果控制节奏,可暂停/停止
Android Play:
- 渠道/地区/百分比灰度
- 先用"内部测试→封闭测试→开放测试"分层
自建渠道/企业分发:
- 服务端控制开关:按版本/地区/白名单
- 客户端启动时查版本策略 → 决定可见性
灰度注意:
- 看崩溃率/核心指标,达标才继续放量
- 灰度期间不关机,随时可停止
6. 回滚与紧急修复
6.1 为什么移动端回滚难
移动端回滚的无奈:
- 无法撤回已安装的版本(用户还在跑旧包)
- 商店"下架"很重、影响所有用户
- 唯一解法是"再发一个版本",要过审核
所以移动端要有"兜底三件套"
6.2 兜底三件套:热修 / 强制升级 / 开关
方案一:热修复(Hotfix)
动态下发补丁(JSPatch/Tinker/CodePush 类)
适用:紧急 bug,秒级修复,不重新发版
风险:绕过审核、兼容性/安全需评估 → 慎用
方案二:强制升级(Force Update)
服务端下发"最低版本号",低于则拦截使用
用于:旧版本有致命 bug 时必须引导升级
方案三:功能开关/远端配置
不修代码,先关闭坏功能(特性开关)
把"坏功能"从用户视线移走,争取发版时间
组合策略:小 bug → 热修;致命 → 强制升级;功能问题 → 开关
7. 移动端质量门禁
7.1 构建时质量检查
CI 里的移动端质量门禁:
- 单元测试 + UI 测试(关键路径)
- 静态分析(lint / SonarQube)——代码质量
- 包体积检查(超标 → 告警/阻断)
- 崩溃/ANR 静态风险扫描
只有通过质量门的提交,才允许进入"发布候选"
7.2 发布候选(Release Candidate)门禁
发布候选流程:
1. 冻结分支 → 跑全套测试
2. 冒烟包 → 内测渠道分发给测试
3. 过质量门禁(崩溃率/关键指标)→ 才可提审
4. 提审后监控 TestFlight/商店审核状态
关键:发布候选"测试通过"才提交商店,
而不是"代码写完就提审"
8. 移动端发布的避坑
常见坑:
1. 签名证书泄露/丢失 → 线上事故
2. 版本号混乱 → 用户/客服分不清
3. 提审内容不合规 → 审核被拒延期
4. 灰度没监控 → 崩溃率飙了才知道
5. 热修滥用 → 绕过审核风险
6. 只发不测 → 用户就是测试
对治:
- 证书走 Secrets + 有效期预警
- 版本号 CI 自动注入、可追踪
- 提审前自查清单(隐私/合规)
- 灰度看崩溃率/关键指标,随时停
- 热修分级审批、慎用
- 发布候选必须过质量门禁
9. 最佳实践清单
□ 统一 CI 构建矩阵(iOS/Android 并行 + 环境 flavor)
□ 版本号 + build 号自动注入、可追踪
□ 证书/keystore 走 CI Secrets,有效期预警
□ 每次提测/发布自动分发内测渠道
□ TestFlight/商店发布前先一轮真机验证
□ 商店发布窗口、元数据、审核状态跟踪
□ 灰度按比例/地区/渠道 + 监控指标
□ 兜底三件套:热修 / 强制升级 / 功能开关
□ 发布候选过质量门禁(测试 + 静态 + 体积)
□ 发布流程可审计、可追溯
一句话原则
移动端 CD = 把"构建、签名、分发、灰度、回滚"都变成可控的流水线,
让发布"慢而稳",事故"快而小"。
小结
移动端持续交付的核心是尊重移动端的特殊性:构建不可热替换、审核不可控、回滚极慢,所以要在构建、签名、分发、灰度、回滚、质量门禁六个环节都做工程化。落地记住五件事:CI 并行构建 + 版本号可追踪、证书走 Secrets 防丢失、内测分发让每次提交可测、灰度按比例 + 监控随时停、热修/强制升级/开关三件套兜底。当移动端发布从"手忙脚乱打包上传"变成"自动构建、可控灰度、随时可回退"的流水线,产品迭代的速度和稳定性就真正被工程化解放了。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。