Xcode13.4.1升级后Fastlane deliver版本号读取异常排查
问题背景
近期对iOS构建环境做调整:将构建机Xcode版本从13.1升级至13.4.1、关闭bitcode编译配置、应用版本从2.10.x迭代至2.11.x,Fastlane版本相关逻辑未做修改,但CI流水线运行时出现deliver阶段版本识别异常问题。
问题现象
- 流水线执行过程中,agvtool已成功执行版本设置操作,将项目
CFBundleShortVersionString设置为目标版本2.11.1,对应执行日志如下:
[16:34:28]: $ cd /Users/****/appname && agvtool new-marketing-version 2.11.1 [16:34:28]: ▸ Setting CFBundleShortVersionString of project appname to: [16:34:28]: ▸ 2.11.1. [16:34:28]: ▸ Updating CFBundleShortVersionString in Info.plist(s)... [16:34:28]: ▸ Updated CFBundleShortVersionString in "appname.xcodeproj/../Info.plist" to 2.11.1
- 后续执行到deliver阶段时,deliver 2.207.0的执行摘要中
app_version错误显示为9.9.9,对应摘要日志如下:
+--------------------------------------+-----------------------------------+ | deliver 2.207.0 Summary | +--------------------------------------+-----------------------------------+ | ipa | ./build/appname.ipa | | precheck_include_in_app_purchases | false | | submit_for_review | false | | force | true | | metadata_path | .fastlane/metadata | | api_key | ******** | | screenshots_path | ./.fastlane/screenshots | | app_version | 9.9.9
- 此时lane上下文变量中
LATEST_TESTFLIGHT_VERSION、VERSION_NUMBER均为正确值2.11.1,ipa打包路径正常,但上传阶段Transporter抛出ITMS-90189错误,提示版本号9.9.9下build号为1的构建包已存在,属于重复二进制上传,对应上下文与报错日志如下:
| LATEST_TESTFLIGHT_VERSION | 2.11.1 | | BUILD_NUMBER | 1 | | VERSION_NUMBER | 2.11.1 | | IPA_OUTPUT_PATH | /Users/****/build/appname.ipa | | XCODEBUILD_ARCHIVE | ./archive/appname2022-07-12 16.35.38.xcarchive | | +------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ [16:42:44]: Error uploading ipa file: [Transporter Error Output]: ERROR ITMS-90189: Redundant Binary Upload. You've already uploaded a build with build number '1' for version number '9.9.9'.
- 当前使用的Fastlane lane配置如下,未修改版本相关逻辑:
increment_build_number_from_appstore( app_version: options[:app_version], asc_key_id: options[:asc_key_id], asc_issuer_id: options[:asc_issuer_id], asc_key: options[:asc_key]) increment_version_number( version_number: options[:app_version], xcodeproj: @xcode_project) build_app( scheme: @scheme, export_method: "app-store", export_options: { provisioningProfiles: { "com.xxxxx" => "match AppStore com.xxxxx" } }, configuration: "Release", include_symbols: true, project: @xcode_project, build_path: @archive_directory, output_directory: @output_directory, cloned_source_packages_path: options[:cloned_source_packages_path], output_name: "appname") deliver( ipa: @ipa, precheck_include_in_app_purchases: false, submit_for_review: false, force: true, metadata_path: ".fastlane/metadata")
已验证结论
将构建机Xcode版本回退至13.1后,版本识别逻辑完全恢复正常。
问题根因
这是Xcode 13.3+和旧版Fastlane的适配问题,和构建机其他配置无关:
- Xcode 13.3开始调整了Info.plist生成规则:如果项目Build Settings中开启了
GENERATE_INFOPLIST_FILE = YES,打包时的版本号CFBundleShortVersionString、构建号CFBundleVersion会优先读取Build Settings中的MARKETING_VERSION、CURRENT_PROJECT_VERSION字段,磁盘上存放的Info.plist内容不会被打包进最终ipa。 - 当前环境下的agvtool只会修改磁盘上的Info.plist值,不会同步更新Build Settings中的
MARKETING_VERSION,导致打包出来的ipa内实际写入的是Xcode默认占位值9.9.9。 - 你用的deliver 2.207.0没有适配这个逻辑变化,会直接解包ipa读取内部Info.plist的版本号,没有优先取lane上下文中已经正确赋值的
VERSION_NUMBER,最终把错误的9.9.9传给Transporter触发报错。
回退Xcode到13.1后恢复正常,是因为旧版Xcode没有调整plist生成优先级,agvtool修改的磁盘plist值会被正常打包。
解决方案
按落地成本从低到高排序:
- 显式传参指定版本(5分钟修复,无需改项目配置)
给build_app加两个参数强制指定打包时的版本和构建号,同时给deliver加参数指定上传用的版本号,绕过自动读取逻辑,修改后的配置片段如下:build_app( scheme: @scheme, export_method: "app-store", marketing_version: options[:app_version], # 新增:强制指定营销版本 build_number: lane_context[BUILD_NUMBER], # 新增:强制指定构建号 export_options: { provisioningProfiles: { "com.xxxxx" => "match AppStore com.xxxxx" } }, configuration: "Release", include_symbols: true, project: @xcode_project, build_path: @archive_directory, output_directory: @output_directory, cloned_source_packages_path: options[:cloned_source_packages_path], output_name: "appname") deliver( ipa: @ipa, app_version: options[:app_version], # 新增:强制指定上传用的版本号 precheck_include_in_app_purchases: false, submit_for_review: false, force: true, metadata_path: ".fastlane/metadata") - 升级Fastlane版本
把Fastlane升级到2.210.0及以上版本,该版本之后deliver已经修复了Xcode 13.3+的版本读取逻辑,会优先使用lane上下文中的VERSION_NUMBER变量,不会错误读取ipa内的占位值。 - 调整版本修改逻辑
弃用agvtool修改版本的方式,直接通过Fastlane的版本管理action修改Build Settings中的MARKETING_VERSION和CURRENT_PROJECT_VERSION字段,适配新版Xcode的plist生成规则。
验证方法
打包完成后执行以下命令,直接读取ipa包内的实际版本号,确认写入正确:
# 解包ipa到临时目录 unzip -q ./build/appname.ipa -d ./build/ipa_verify # 读取包内Info.plist的版本号 /usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ./build/ipa_verify/Payload/appname.app/Info.plist
如果输出为你指定的2.11.1,说明版本写入正确,上传不会再触发ITMS-90189错误。
内容的提问来源于stack exchange,提问作者Michael Harper
相关产品推荐
相关产品推荐

