阅读 628

Fastlane支持苹果双重认证终极解决方案

如查看解决流程、可直接翻到总结

前言(可忽略)

项目在测试阶段,已经配置完成远程Jenkins+Fastlane自动化打包AdHoc包,并且完善了各个实用功能:

  1. convert命令更改App图标,添加版本号、build号、打包时间等相关内容,方便QA人员区分包版本
  2. Jenkins多参数化构建,构建时可设置版本号、build号、选择git分支、选择钉钉通知人员等功能,并处理好各个参数的默认值
  3. 接入Jenkins DingTalk插件,实现构建失败等意外情况发生时,可钉钉通知开发人员查看日志并解决
  4. Shell脚本实现打包完成后,自动上传ipa包至Fir或蒲公英平台
  5. Shell脚本实现包上传至三方平台后,钉钉通知QA人员下载安装新包进行测试
  6. 接入Fastlane send_email插件,实现打包完成后,邮件通知开发人员(个人空闲邮箱)

后续会将以上实现的功能进行总结

  • AdHoc包的自动化已经趋近完善,但是正式包还是一直由我手动去打包并手动上传至AppStore的。
  • 之前我一直不建议正式包使用自动化的方式去构建,原因是我认为正式包不会去经常构建,且出于包大小(比如fastlane ShenZhen会影响ipa包大小)、包安全性(之前有小伙伴用不同Xcode打出来的包运行起来会导致闪退)考虑还是手动更放心一些。但是因为版本的快速迭代,而且会出现各个版本穿插发布的情况,自动化被迫(被现实打败)提上了日程。
  • 考察了下,发现市面上其实有很多都有介绍正式包自动化的文章,说明我之前担心的问题其实是多余的,所以就放手去做了这个事

一、前期准备

还是采用Jenkins+Fastlane的方案,前期为了将AdHoc包和正式包区分开来,所以在Jenkins上,对此分别构建了两个Item,一个专门构建AdHoc包,一个专门构建正式包。后期其实可以合并为一个Item,用Jenkins的多参数构建加以区分

Jenkins Items.webp

二、配置Jenkins

  • 在AdHoc任务项的基础上,去除convert更改图标、钉钉通知、邮箱通知、上传三方平台等QA辅助功能
  • 更新fastlane文件,更改对应的正式包证书与配置文件
  • fastlane添加deliver这个action,上传至AppStore(下面会详细点总结下deliver)

三、Fastlane action之deliver

对于Fastlane最常用的两个action,就是gym和deliver,gym是Shenzhen的进阶,作为App构建使用的工具。deliver是将二进制上传至App Store Connect的工具。其分别有自己对应的配置项,在fastlane官方文档可查,也可以使用fastlane action deliver命令进行查看。

下面是我从网上看到前人文章后二次总结的deliver部分常用的配置项及说明。

配置项说明备注
ipaipa压缩包文件所在路径
pkgpkg压缩包文件所在路径mac应用使用
username上传的苹果邮箱账号默认值为打包机钥匙串存储的账号
app_identifier应用程序的BundleId
team_id如果你在多个团队,你的iTunes Connect团队的ID
team_name如果你在多个团队中,你的iTunes Connect团队的名字
platform使用的平台默认值为ios
metadata_path包含元数据文件夹的路径,元数据中保存的appStore中你应用的具体内容介绍(如标题、描述)
screenshots_path包含屏幕快照文件夹的路径不建议使用,若使用则需遵循AppStoreConnect要求的规则
skip_screenshots不上传屏幕快照默认值为false,建议设置为true
skip_metadata不上传元数据默认值为false,建议设置为true
app_version应该编辑或创建的App版本默认是Xcode中设置的版本号
build_numberbuild号默认是Xcode中设置的build号
force跳过HTML报告文件验证默认值为false,建议设置为true
submit_for_review在上传所有内容后提交新版本进行审核默认值为false
automatic_release审核通过后,是否自动发布默认值false
auto_release_date审核通过后自动发布App Store的以毫秒为单位的日期默认值为false
price_tier元数据相关:价格层级元数据相关的不建议在此使用
subtitle、name 、description 、app_icon 等元数据相关:应用程序副标题、名字、描述、图标等元数据的配置不建议自动化
generate_ipa(typePrefix,options,exportMethod,codeSigningIdentify,matchType)
      deliver(
        ipa: "./build/#{APP_NAME}.ipa",
        skip_screenshots: true,
        skip_metadata: true,
        force: true,
        submit_for_review: false
        ...
      )
  end
复制代码

四、Deliverfile

以上介绍了fastlane的其中一个action deliver的相关配置,可以发现其实deliver的很多配置可以多个应用是通用的,比如说使用的开发者邮箱、是否手动发布等配置项。这时就可以建立一个与Fastfile同目录的名为Deliverfile的文件,其顾名思义,就是deliver的配置文件,deliver的通用配置都可以在此文件中去设置。

app_identifier "com.xxx.xxxxx" # The bundle identifier of your app
username "xxx@xxx.cn" # your Apple ID user
automatic_release false
force true
...
复制代码

注意Deliverfile的优先级要高于fastfile中deliver的配置

这样另外一个App下Fastlane中deliver的一些通用配置就不用设置了,直接复制粘贴过来Deliverfile即可

五、账号登录(双重认证)

做完以上这一切,觉得应该万事大吉了。打包机钥匙串里也存有对应的苹果账号的密码,所以潇洒地按下立即构建。一段时间过后发现构建成功了,但是并没有收到苹果的邮件啊~打开Jenkins的构建日志如下:

Error: Unable to validate your application. Sign in with the app-specific password you generated. 
If you forgot the app-specific password or need to create a new one, go to appleid.apple.com
复制代码

打包虽然成功了,但是因为苹果开发者账号开启了双重认证,所以仅有账号和密码还是不能够成功登录账号的。于是屁颠地跑去fastlane官网寻找解决方案,发现了这个:

fastlane官网针对双重认证情况下给出的deliver解决方案

可以看到官方给出四种方案,前两种方案都是Manual verification(内心MMP),后两种有一个被标记了deprecated,那就只有第三个方案了😓。正好解决了我的选择困难症。下面就介绍一下这个方案的流程:

  • 生成一个不需要进行短信认证的application specific password,这个需要到 苹果开发者中心的账号管理下进行生成。注意生成后将其备份,因为页面一旦关闭将无法再次查看
  • 执行命令 **fastlane spaceauth -u [开发者账号] **,生成FASTLANE_SESSION,将其备份
  • 配置环境变量如下:
export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=[application specific password(替换为你自己的)]
export FASTLANE_SESSION=[FASTLANE_SESSION(替换为你自己的)]
复制代码
  • 执行source ~/.bash_profile使新增的环境变量生效,分别执行以下命令查看环境变量是否设置成功
echo $FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
echo $FASTLANE_SESSION
复制代码

注意:

  1. 生成的FASTLANE_SESSION ,真正的实体要从第一个value处开始到第一个value结束,不要全部一股脑全部配置到环境变量文件中,否则会因为格式问题导致变量设置失败
  2. 如官网提示,使用application specific password的情况下,deliver不要做上传二进制之外的其他操作,比如设置元数据等,否则可能会导致方案失效fastlane官网截图Note.webp

六、上传二进制文件至App Store Connect(双重认证)

做完以上操作后,Jenkins重新构建,一段时间后仍显示成功,却没收到苹果邮件。继续查看Jenkins构建日志如下:

Login to App Store Connect (xxx@xxx.cn)
Login successful
...
Uploading binary to App Store Connect
Going to upload updated app to App Store Connect
[32mThis might take a few minutes. Please don't interrupt the script.[0m
[31mTransporter transfer failed.[0m
[31mSign in with the app-specific password you generated. If you forgot the app-specific password or need to create a new one, go to appleid.apple.com (-22938)
[0m
[31mYour account has 2 step verification enabled[0m
[31mPlease go to [https://appleid.apple.com/account/manage[0m](https://appleid.apple.com/account/manage%1B[0m)
[31mand generate an application specific password for[0m
[31mthe iTunes Transporter, which is used to upload builds[0m
[31mTo set the application specific password on a CI machine using[0m
[31man environment variable, you can set the[0m
[31mFASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD variable[0m
复制代码

可以看到这次账号登录成功了,但是上传二进制到App Store Connect时再次被双重认证拦截,并且fastlane还给出了建议的解决方案,仔细一看,MMP!!!这不就是我解决登录时的解决方案吗?不禁感叹用谎言去验证谎言,得到的一定是谎言。

所幸继续往下看,发现这么两句

[32mPlease provide your Apple Developer Program account credentials[0m
[32mThe login information you enter will be stored in your macOS Keychain
复制代码

这两句给了我灵感,可以把keychain下开发者账号对应的密码改为application specific password,我们可以使用CredentialsManager重设钥匙串对应的开发者账号密码。步骤如下: fastlane官网截图之CredentialsManager重置钥匙串密码.webp 可以看到官网上也是说这种方案会对持续集成的情况下有效

注意 application specific passwordFASTLANE_SESSION的有效期为一个月左右,所以切记要及时对环境变量和钥匙串对应的密码进行更新

后话

最后再次进行重新构建,如愿看到以下日志信息:

[32mSuccessfully exported and compressed dSYM file[0m
[32mSuccessfully exported and signed the ipa file:[0m
...
Login to App Store Connect (xxx@xxx.cn)
Login successful
...
[32mSuccessfully set the version to '3.0.0'[0m
Uploading binary to App Store Connect
Fetching password for transporter from environment variable named `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD`
Going to upload updated app to App Store Connect
[32mThis might take a few minutes. Please don't interrupt the script.[0m
[32miTunes Transporter successfully finished its job[0m
[32m--------------------------------------------------------------------[0m
[32mSuccessfully uploaded package to App Store Connect. It might take a few minutes until it's visible online.[0m
[32m--------------------------------------------------------------------[0m
[32mFinished the upload to App Store Connect[0m
复制代码

大功告成,登录开发者后台可以再次确认一下是否上传成功~

总结

  • 基本的Jenkins+fastlane配置
  • 配置fastlane的deliver、Deliverfile
  • 配置bash_profile环境变量,增加FASTLANE_SESSIONFASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD变量,使得CI情况下正常登录双重认证账号
  • 使用CredentialsManager重设钥匙串对应的开发者账号密码为application specific password,使得CI情况下可以正常上传二进制包到双重认证账号的后台中
文章分类
iOS
文章标签