用 fastlane match
管理 iOS 证书和描述文件
iOS 签名最常见的麻烦是:证书只在某个人的 Mac 上,换机器、加同事、上 CI 都要重新折腾。fastlane match 把证书和描述文件加密存进一个私有仓库,团队和构建机都从这里同步。这篇讲初始化、生成、CI 中只读拉取,以及配合 App Store Connect API Key 免登录 Apple ID 的写法。
match 解决什么问题
一张签名证书由公钥证书和私钥组成,私钥只存在于生成 CSR 的那台 Mac 的钥匙串里。团队里每人各建证书,很快会碰到名额上限和“这台机器签不了”的问题。match 的做法是:整个团队共用一套证书和描述文件,加密后存放在一个私有存储中(Git 仓库、Google Cloud Storage、S3 等),任何一台机器用密码解密后安装到钥匙串。
对于远程或租用的 Mac 尤其合适:机器换了、重装了,执行一条命令就能恢复签名环境,私钥也不会只留在某台退租的机器上。
初始化:准备私有仓库
先新建一个空的私有 Git 仓库,专门存放证书(不要和代码仓库混用)。在项目目录执行:
gem install fastlane # 或在 Gemfile 中加入 fastlane 后 bundle install
fastlane match init选择 git 存储并填写仓库地址,会生成 fastlane/Matchfile,可以手动补充常用配置:
git_url("git@github.com:your-org/ios-certificates.git")
storage_mode("git")
type("development")
app_identifier(["com.example.myapp", "com.example.myapp.widget"])
team_id("ABCDE12345")app_identifier 要包含 App 扩展(小组件、通知扩展等)的 Bundle ID,否则这些 target 签名时会缺描述文件。
生成并上传证书
由一位有管理权限的成员在 Mac 上执行一次,按需生成不同类型:
fastlane match development
fastlane match appstore
# 需要 Ad Hoc 分发时
fastlane match adhoc首次运行会要求设置加密密码(即 MATCH_PASSWORD),请保存到团队的密码管理器。之后 match 会在开发者账号中创建证书和描述文件,加密后提交到仓库。新增测试设备后,执行 fastlane match development --force_for_new_devices 刷新描述文件。
其他成员和新的构建机只需要克隆项目、拿到 MATCH_PASSWORD,执行 fastlane match development --readonly 就能装好开发证书,不再需要互相传 .p12 文件。在 Xcode 中,对应 target 应关闭 Automatically manage signing,手动选择 match 生成的描述文件(名称形如 match AppStore com.example.myapp),否则 Xcode 可能自行创建新的证书。
提醒:fastlane match nuke 会吊销账号中对应类型的全部证书,影响团队里所有人,只在确实要重建时使用。
在 CI 中只读拉取
构建机只需要读取,不应创建或修改证书。在 Fastfile 中使用 readonly: true,并在 CI 环境调用 setup_ci 创建临时钥匙串,避免钥匙串弹窗卡住构建:
lane :beta do
setup_ci if ENV["CI"]
match(type: "appstore", readonly: true)
build_app(scheme: "MyApp", export_method: "app-store")
upload_to_testflight(skip_waiting_for_build_processing: true)
end构建机访问证书仓库可以用只读的部署密钥(Deploy Key),或者设置 MATCH_GIT_BASIC_AUTHORIZATION(用户名:令牌 的 Base64 编码)走 HTTPS。MATCH_PASSWORD 和这些凭据都放在 CI 的 Secrets 里,以环境变量传入。
配合 App Store Connect API Key
在 App Store Connect 的「用户和访问 → 集成」中创建 API Key,记下 Key ID、Issuer ID 并下载 .p8 文件(只能下载一次)。在 lane 开头加载后,match 和上传操作都会使用它,不需要 Apple ID 密码和双重认证:
app_store_connect_api_key(
key_id: ENV["ASC_KEY_ID"],
issuer_id: ENV["ASC_ISSUER_ID"],
key_content: ENV["ASC_KEY_BASE64"],
is_key_content_base64: true
)把这段放在 match 之前即可。完整的 runner 配置见 iOS 构建机配置指南,上架流程见 没有 Mac 怎么上架 App Store。
常见问题
MATCH_PASSWORD 丢了怎么办?
仓库里的证书和描述文件是用这个密码加密的,丢失后无法解密。只能用 fastlane match nuke 吊销并清空旧证书,再重新生成。吊销分发证书不会影响已经上架的 App,但会让对应的描述文件失效,需要重新生成。
已有手动创建的证书,能导入 match 吗?
可以。fastlane 提供 match import 命令,按提示指定 .cer、.p12 和描述文件即可加密存入仓库。也可以选择让 match 新建一套证书,团队成员之后都从仓库同步。
开发者账号能创建的证书数量有限,match 会不会用完?
match 的设计正是让整个团队共用一套证书,而不是每人各建一张,因此通常比手动管理更节省名额。证书数量上限由 Apple 规定,如果名额已满,可以先在开发者网站清理不再使用的证书。
扫码加微信客服手机上长按二维码识别