fastlane 是 iOS 平台的一个自动传包工具,非常好用。
fastlane 使用过程中有个痛点是:在和 CI 工具集成的时候总是需要输入验证码,起因是苹果账号目前是强制开启二次验证的,系统会向信任的机器或者手机号发验证码,这时候就需要人手动输入,但是 CI 是没有交互环境的,所以就没办法顺利传包。
# 身份验证方式
官方提供了几种身份验证的方式如下,文档地址在这里 (opens new window)
# 两步身份验证。
传包的时候进行手动验证,即我们上面提到的情况,CI 是不支持的。
如果能在有交互的命令行上完成输入验证码这个过程的话,系统会将会话信息缓存在 ~/.fastlane/spaceship/[email]/cookie
这里。
不过 fastlane 还提供了一种直接生成 AppleID 登录会话的机制:
fastlane spaceauth -u user@email.com //替换为自己的苹果账号
执行命令后会在命令行尝试登录操作,然后生成一段变量值,大致如下
--\n- !ruby/object:HTTP::Cookie\n name: myacinfo\n value: …. created_at: &2 2023-07-13 19:00:55.561831000 +08:00\n accessed_at: *2\n
生成的变量值必须存储在 CI 系统上的 FASTLANE_SESSION
环境变量中。每次 fastlane 与 Apple 的 API 通信时,该会话将被重用,而不是触发新的登录(下面会有设置 fastlane 环境变量的介绍)
理论上这种方式也能用于 CI 的自动化,避免每次输验证码。但其中是有一个严重缺陷的,即会话有效期,最长也就一个月。 即至少每个月你都得为 CI 生成一次新的会话。有可能一两天就得来一次,非常麻烦。Session 过期时间的长短取决于很多因素,并不是可控的。
一个小技巧是可以通过 -check_session 判断 session 是否有效。 (opens new window)
# 应用程序专用密码(Application-specific passwords)
如果您想将构建上传到 App Store Connect(upload_to_app_store
和 deliver
)或 TestFlight(操作 upload_to_testflight
、 pilot
或 testflight
)。我们可以生成应用程序特定密码:
- 访问 appleid.apple.com/account/manage (opens new window)
- 生成新的应用程序特定密码。
- 使用环境变量
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
提供应用程序特定密码
后续如果上传的话就直接用应用专用密码,就避免每次输验证码了。但是这种方式也有个限制,即如果做除了上传二进制文件之外的其他操作,则应用程序特定密码将不起作用,官方的这个限制其实说的很笼统,理论上我执行 upload_to_testflight 是不涉及到别的操作的。
其实不仅要设置 FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
也要设置 FASTLANE_USER
的环境变量。
但是重点来了,我按照上面的说明,配置好 FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
环境变量后,依然让我输入验证码,似乎这个配置并没有生效,有人遇到类似的问题 → Github ISSUE-2FA code still required for pilot even with FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD set) (opens new window),不过官方没有回应。
排查了半天之后发现一个解决方案 (opens new window),可能还是 Fastfile 里面的 upload_to_testflight
这个操作缺少一些参数,于是将 Fastfile 里面的 upload_to_testflight
加了俩参数
upload_to_testflight(skip_waiting_for_build_processing: true, apple_id: " 12345")
这里 apple_id 就是 AppleStore 后台为应用自动生成的 Apple ID,可以在 AppleStore 后台看。
skip_waiting_for_build_processing
如果设置为 true,则该 distribute_external
选项将不起作用,并且不会将任何生成分发给测试人员。而 distribute_external
选项又会用到 groups
选项,似乎 groups
选项对后台进行了二进制外的额外操作,导致没能使 fastlane 正确使用应用程序专用密码。
这时候再执行上传操作就没有问题了,基本上是完美解决。
# App Store Connect API 密钥
这个本文不涉及。
# 设置环境变量
有几种不同的方式可以设置 fastlane 的环境变量
通过 Fastfile 预定义的方式。**不推荐使用这种方式,主要是出于安全原因。**如果工程是 git 管理的话,你的苹果账号专用密码就会暴露。
ENV["FASTLANE_USER"] = "user@email.com" ENV["FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"] = "xxxyyy" lane :beta do upload_to_testflight end
通过在 bashfile 中定义。如果终端使用的 zsh,则使用 ~/.zshrc 文件进行定义。定义完记得 source 一下让改动生效。这种定义方式是在本地,相对安全,但有的 CI 的环境是不支持加载这些环境变量的。
export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD = "xxxyyy" export FASTLANE_USER = "user@email.com"
通过 dotenv (opens new window) 方式进行定义。 dotenv 用于将环境存储在特定于项目的文件中。这里你需要创建一个
.env.default
文件。内容如下FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD="xxxyyy" FASTLANE_USER="user@email.com"
大家可以根据自己的情况选择合适的设置变量的方式。
参考地址:
- fastlane » spaceship doc » Authentication.md (opens new window) #身份验证相关文档
- Docs » Best Practices » Continuous Integration (opens new window) #CI 集成相关的文档
- Docs » Best Practices » Keys (opens new window) #fastlane 设置环境变量方式
关注我的微信公众号,我在上面会分享我的日常所思所想。