如查看解决流程、可直接翻到总结处
前言(可忽略)
项目在测试阶段,已经配置完成远程Jenkins+Fastlane自动化打包AdHoc包,并且完善了各个实用功能:
- convert命令更改App图标,添加版本号、build号、打包时间等相关内容,方便QA人员区分包版本
- Jenkins多参数化构建,构建时可设置版本号、build号、选择git分支、选择钉钉通知人员等功能,并处理好各个参数的默认值
- 接入Jenkins DingTalk插件,实现构建失败等意外情况发生时,可钉钉通知开发人员查看日志并解决
- Shell脚本实现打包完成后,自动上传ipa包至Fir或蒲公英平台
- Shell脚本实现包上传至三方平台后,钉钉通知QA人员下载安装新包进行测试
- 接入Fastlane send_email插件,实现打包完成后,邮件通知开发人员(个人空闲邮箱)
后续会将以上实现的功能进行总结
- AdHoc包的自动化已经趋近完善,但是正式包还是一直由我手动去打包并手动上传至AppStore的。
- 之前我一直不建议正式包使用自动化的方式去构建,原因是我认为正式包不会去经常构建,且出于
包大小(比如fastlane ShenZhen会影响ipa包大小)、包安全性(之前有小伙伴用不同Xcode打出来的包运行起来会导致闪退)
考虑还是手动更放心一些。但是因为版本的快速迭代,而且会出现各个版本穿插发布的情况,自动化被迫(被现实打败)提上了日程。 - 考察了下,发现市面上其实有很多都有介绍正式包自动化的文章,说明我之前担心的问题其实是多余的,所以就放手去做了这个事
一、前期准备
还是采用Jenkins+Fastlane的方案,前期为了将AdHoc包和正式包区分开来,所以在Jenkins上,对此分别构建了两个Item,一个专门构建AdHoc包,一个专门构建正式包。后期其实可以合并为一个Item,用Jenkins的多参数构建加以区分
二、配置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部分常用的配置项及说明。
配置项 | 说明 | 备注 |
---|---|---|
ipa | ipa压缩包文件所在路径 | |
pkg | pkg压缩包文件所在路径 | 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_number | build号 | 默认是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
注意:
- 生成的FASTLANE_SESSION,真正的实体要从第一个value处开始到第一个value结束,不要全部一股脑全部配置到环境变量文件中,否则会因为格式问题导致变量设置失败
- 如官网提示,使用application specific password的情况下,deliver不要做上传二进制之外的其他操作,比如设置元数据等,否则可能会导致方案失效
六、上传二进制文件至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重设钥匙串对应的开发者账号密码。步骤如下:
可以看到官网上也是说这种方案会对持续集成的情况下有效
注意:application specific password和FASTLANE_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_SESSION、FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD变量,使得CI情况下正常登录双重认证账号
- 使用CredentialsManager重设钥匙串对应的开发者账号密码为application specific password,使得CI情况下可以正常上传二进制包到双重认证账号的后台中