代码改变世界

在gitlab中使用fastlane编译ios

2025-09-30 15:20  蜡笔小旧  阅读(15)  评论(0)    收藏  举报
## 准备工作

1. 先找apple帐号管理员添加一个app api key, 见app-store-connect-api.png. 然后role设置为 app manager. (注:如何这个账户要自动创建cert可能需要admin)。
他应该给你issue Id, keyId, 然后一个p8文件 AuthKey_{keyId}.p8.

(可选) 1.2 如果是用手动导入证书模式,可以让apple管理员给你生成一个p12证书需要带密码.然后你可以把这个值配置到gitlab ci/cd variables中`CERTIFICATE_BASE64`和`CERTIFICATE_PASSWORD_BASE64`(passwod可能有特殊字符所以base64了).

1.3 添加`KEYCHAIN_PASSWORD`到gitlab ci/cd variables, 值用一个guid就行,后面用于创建keychain解锁.

2. 然后可以在https://gitlab.com/ci-ios-signing/-/settings/integrations中找到Apple App Store Connect点击Configure把对应的值填入,然后上传p8凭证.添加完成后gitlab会在job中自动的把APP_STORE_CONNECT_API_KEY_*注入到环境变量中, 后面如果要使用fastlane可以少写点环境变量注入可以直接用`api_key = app_store_connect_api_key()`直接拿到api_key。

3. 由于gitlab runner默认在macos下运行在daemon环境中. 所以无法拿到gui相关session的东西比如Keychain.
例如你明明在SSH cli中创建了一个keychian然后把它设置为default, 还把加入list, 也unlock了, 但是最后一运行`security find-identity -v -p codesigning`检测可签名的证书返回`0 valid identities found`. 但是在cli中一点问题都没有. 这个就是
daemon上下文的问题. 最后AI没有正确帮助我解决这个问题. 是另外一种思路解决的,见: https://serverfault.com/questions/328785/how-do-i-launch-a-process-as-a-specific-user-at-startup-on-os-x/371252#371252. /Library/LaunchDaemons/gitlab-runner.plist把<key>SessionCreate</key>从false改成true了. 然后重新加载gitlab runner plist就好了, 还是对macos不是很熟悉造成的为什么macos一定基于GUI, linux貌似没有这样的问题. 据说还有另外一种解决办法就是使用~/Library/Keychain/login.keychain-db.但是这个要输入ec2-user的密码, 这个是用证书来做登录的, 所以作罢.

## 流程

1. 新建一个keychain (create_keychain)
2. 把certifacate放入keychain (import_certificate/get_certificates)
3. 导入profile (get_provisioning_profile)
-------------------------
4. 关联profile和项目 (调用update_code_signing_settings配置xcode中use_automatic_signing: false, 其实这一步就是更新pubspec.yaml)
5. 编译ios项目到ipa文件 (build_ios_app)

## 名词

- Profile(mobileprovision): 一个文件包含了证书的信息, app id, 设备相关的信息告诉哪些证书可以用,然后和xcode去关联就可以用这个来生成签名的代码了, 默认会放到/Users/ec2-user/Library/MobileDevice/Provisioning Profiles/{guid}.mobileprovision, 最终这个profile和它的摘要应该会放到ipa里面.

- Certificates: 这个分为两种一种是Developer Certificate(可以有很多个), 另外一种是Distribution Certificate(只允许3个). 以前apple搞了些独立的证书比如ios certificate. 现在搞了个大一统的名字apple certificate, 然后就是分了两种类别了.
有一点比较坑的是见完证书是没有别名的,只有个时间. 但是证书code sign后, 后面就没有地方用了. 所以删掉了也没关系.

- KeyChain: 一组vault. 用于存放Certificates. 用户的keychain位于~/Library/Keychain/**keychain-db.
可以设置默认keychain, 然后设置是个链所以可以设置多个keychains. 程序应该会一个个找到合适的证书, 找之前需要用密码解锁, 如果是login-keychain-db需要用用户登录密码解锁.

- fastlane: ruby写的一个用于cert,sign的程序,可以做很多事也可以build把xcodebuild封装起来了. 也可以自动cert, sign叫做match函数但是证书需要托管到git和s3.这样就只用访问中间媒介不需要都去访问apple的证书了. 用之前需要先安装bundle然后在使用的根目录添加一个Gemfile文件加入一行'gem "fastlane", 然后调用`bundle install`安装fastlane依赖. 然后就可以用bundle execute fastlane init去初始化fastlane, 你可以看到会生成一个fastlane文件夹还有下面的两个文件Appfile, Fastfile, Appfile可以放appple_id, team_id, app_identifier等配置, 一旦这个文件加了配置fastlane里面内置的参数会自动使用,不用传来传去了. 另外Fastlile就可以定义各种lane了, 注意lane名字不要和fastlane内置的action名字冲突,不然调用的时候会死循环. 这里有个doc可以看下:https://docs.fastlane.tools/codesigning/troubleshooting/#keychain. 意思就是要执行`security find-identity -v -p codesigning`确定一定要有一个valid cert.


## REF
- https://docs.fastlane.tools/actions/
- https://medium.com/@lucas.buchalla.sesti/automating-deployment-of-ios-apps-in-flutter-project-with-fastlane-1174a4e235b9