xcodebuild无法使用配置文件?GitHub Actions构建失败排查
问题背景
我配置了GitHub Action用于自动构建应用并上传至TestFlight,但添加Notification Service扩展后出现构建问题。原本使用Fastlane,现已简化为执行以下命令:
xcodebuild archive -scheme Yeshivat\ Torat\ Shraga -project ./Yeshivat\ Torat\ Shraga.xcodeproj
该命令在本地笔记本电脑上运行正常,但在GitHub Actions CI机器上执行时出现如下错误:
error: "NotificationModifier" requires a provisioning profile with the App Groups feature. Select a provisioning profile in the Signing & Capabilities editor. (in target 'NotificationModifier' from project 'Yeshivat Torat Shraga')
error: "Yeshivat Torat Shraga" requires a provisioning profile with the Associated Domains, App Groups, App Attest, and Push Notifications features. Select a provisioning profile in the Signing & Capabilities editor. (in target 'Yeshivat Torat Shraga' from project 'Yeshivat Torat Shraga')
使用gym时已指定正确证书,但CI机器上仍出现上述错误。
核心疑问
- 为何该命令在本地正常但CI机器上失败?
- 如何配置本地环境匹配CI以方便调试?
- 如何成功自动化该构建流程(直接用
xcodebuild或优先用Fastlane)?
问题分析与解决方案
一、本地正常CI失败的原因及调试方法
原因
本地环境通常会自动从Xcode的Accounts中拉取匹配的配置文件,或缓存了符合能力要求的签名资产;而CI环境是全新的干净环境,无本地缓存的签名文件,若签名配置未明确指定,xcodebuild会尝试自动选择,但可能选到不包含所需Capabilities的配置文件。
本地模拟CI环境调试步骤
- 清理本地签名缓存:删除
~/Library/MobileDevice/Provisioning Profiles下的所有配置文件,同时在Xcode的Preferences > Accounts > 你的Apple ID > Manage Certificates中,暂时移除除CI用证书外的其他证书(记得备份)。 - 关闭Xcode自动签名:在项目的Signing & Capabilities中,关闭
Automatically manage signing,手动指定与CI使用相同的配置文件和证书。 - 在终端执行相同的
xcodebuild命令,观察是否复现错误。若复现,说明本地之前依赖自动签名缓存,可针对性调整签名配置。
二、自动化构建流程的修复方案
方案1:使用Fastlane gym明确指定签名参数
在Fastfile中配置gym时,不仅要指定证书,还要明确主应用和扩展目标的配置文件ID,避免CI自动选择错误配置:
lane :build_for_testflight do gym( scheme: "Yeshivat Torat Shraga", project: "./Yeshivat Torat Shraga.xcodeproj", export_method: "app-store", # 主应用签名配置 signing_identity: "iPhone Distribution: Your Team Name (XXXXXX)", provisioning_profile_specifier: "YeshivatToratShraga_AppStore", # 为扩展目标单独指定配置文件 export_options: { provisioningProfiles: { "com.yourdomain.YeshivatToratShraga" => "YeshivatToratShraga_AppStore", "com.yourdomain.YeshivatToratShraga.NotificationModifier" => "YeshivatToratShraga_NotificationModifier_AppStore" } } ) end
注意:provisioning_profile_specifier是配置文件名称(非UUID),需确保主应用和扩展的配置文件都包含对应Capabilities(扩展需App Groups,主应用需Associated Domains、App Groups等)。
方案2:直接用xcodebuild指定签名参数
若不用Fastlane,执行xcodebuild时需明确指定签名标识和配置文件:
xcodebuild archive \ -scheme "Yeshivat Torat Shraga" \ -project "./Yeshivat Torat Shraga.xcodeproj" \ -configuration Release \ -archivePath "./build/YeshivatToratShraga.xcarchive" \ CODE_SIGN_IDENTITY="iPhone Distribution: Your Team Name (XXXXXX)" \ PROVISIONING_PROFILE_SPECIFIER="YeshivatToratShraga_AppStore" \ OTHER_CODE_SIGN_FLAGS="--keychain login.keychain" \ TARGETED_DEVICE_FAMILY="1,2" \ # 扩展目标的签名配置 NotificationModifier_CODE_SIGN_IDENTITY="iPhone Distribution: Your Team Name (XXXXXX)" \ NotificationModifier_PROVISIONING_PROFILE_SPECIFIER="YeshivatToratShraga_NotificationModifier_AppStore"
额外注意事项
- 在GitHub Action中,使用
apple-actions/import-codesign-certs或Fastlane的match工具导入正确的证书和配置文件,避免手动管理遗漏。 - 使用
match可统一管理签名资产,确保本地和CI使用完全相同的配置文件,减少环境差异:
lane :setup_signing do match( type: "appstore", app_identifier: [ "com.yourdomain.YeshivatToratShraga", "com.yourdomain.YeshivatToratShraga.NotificationModifier" ] ) end
在build lane中调用setup_signing,gym会自动使用match下载的签名资产。
内容的提问来源于stack exchange,提问作者benjixinator

