Search code examples
iosxcodeazure-devopsxcode11

xcodebuild strips CFBundleVersion and CFBundleShortVersionString from Info.plist


I am building an iOS app in Azure DevOps. The build and export of the *.ipa works fine, but the upload to the App Store fails with the following message:

2020-10-05T14:02:27.9260830Z [14:02:27]: [Transporter Error Output]: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:27.9268950Z [14:02:27]: [Transporter Error Output]: ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.1474570Z [14:02:28]: Transporter transfer failed.
2020-10-05T14:02:28.1475590Z [14:02:28]: 
2020-10-05T14:02:28.1477810Z [14:02:28]: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.1480380Z ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2737090Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> DBG-X:   parameter ShouldUseRESTAPIs = false
2020-10-05T14:02:28.2741670Z 
2020-10-05T14:02:28.2743710Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> ERROR: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.2745220Z 
2020-10-05T14:02:28.2746740Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> ERROR: ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2747600Z 
2020-10-05T14:02:28.2748330Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> DBG-X: The error code is: 1102
2020-10-05T14:02:28.2748700Z 
2020-10-05T14:02:28.2749420Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main>  INFO: Done performing authentication.
2020-10-05T14:02:28.2749760Z 
2020-10-05T14:02:28.2749950Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750120Z 
2020-10-05T14:02:28.2750310Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750480Z 
2020-10-05T14:02:28.2750660Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750830Z 
2020-10-05T14:02:28.2751070Z [14:02:28]: [iTMSTransporter] Package Summary:
2020-10-05T14:02:28.2751270Z 
2020-10-05T14:02:28.2751460Z [14:02:28]: [iTMSTransporter]  
2020-10-05T14:02:28.2751630Z 
2020-10-05T14:02:28.2751950Z [14:02:28]: [iTMSTransporter] 1 package(s) were not uploaded because they had problems:
2020-10-05T14:02:28.2752240Z 
2020-10-05T14:02:28.2753070Z [14:02:28]: [iTMSTransporter]  /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/d20201005-1299-rww8bj/1454404673.itmsp - Error Messages:
2020-10-05T14:02:28.2753450Z 
2020-10-05T14:02:28.2754860Z [14:02:28]: [iTMSTransporter]      ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.2755720Z 
2020-10-05T14:02:28.2757000Z [14:02:28]: [iTMSTransporter]      ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2757770Z 
2020-10-05T14:02:28.2758440Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:28 UTC] <main> DBG-X: Returning 1

Sure enough, when I extract the ipa file and look in "Payload/MyApp.app/Info.plist", CFBundleVersion and CFBundleShortVersionString are missing.

However, those values are included in the original, pre-compilation Info.plist and are also set during the build phase using GitVersion and PlistBuddy. I have checked that the variables are correctly set and also tried to just use the hard-coded versions, which did not change the result.

> echo 'iOsBundleVersion: $(iOsBundleVersion)'
iOsBundleVersion: 1.2.21
> echo 'iOsMarketingVersion: $(iOsMarketingVersion)'
iOsMarketingVersion: 1.2

azure-pipelines.yml (extract):

- task: InstallAppleCertificate@2
  displayName: 'Install certificates'
  inputs:
    certSecureFile: $(certSecureFile)
    certPwd: '$(certPwd)'
    keychain: 'temp'

- task: InstallAppleProvisioningProfile@1
  displayName: 'Install provisioning profile'
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: $(provProfileSecureFile)

- task: CocoaPods@0
  displayName: 'Install CocoaPods'
  inputs:
    workingDirectory: '$(appRoot)'
    forceRepoUpdate: true
    projectDirectory: 'ios'

- task: Bash@3
  displayName: 'Set bundle version'
  inputs:
    targetType: 'inline'
    script: |
      /usr/libexec/PlistBuddy -c "Set CFBundleVersion $(iOsBundleVersion)" ./Info.plist
      /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $(iOsMarketingVersion)" ./Info.plist
    workingDirectory: '$(appRoot)'

- task: Xcode@5
  displayName: 'Build project'
  inputs:
    actions: 'archive'
    configuration: 'Release'
    sdk: 'iphoneos'
    xcWorkspacePath: '$(appRoot)/MyApp.xcworkspace'
    scheme: '$(appName)'
    packageApp: true
    exportPath: '$(appRoot)/ios/build'
    xcodeVersion: 'default'
    signingOption: 'manual'
    signingIdentity: '$(APPLE_CERTIFICATE_SIGNING_IDENTITY)'
    provisioningProfileUuid: '$(APPLE_PROV_PROFILE_UUID)'
    args: '-UseModernBuildSystem=0'
    workingDirectory: '$(appRoot)'
    useXcpretty: true

which results in the following commands:

xcodebuild -workspace /Users/runner/work/1/s/MyApp.xcworkspace -scheme MyApp archive -sdk iphoneos -configuration Release -archivePath /Users/runner/work/1/s/MyApp CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY=Apple Distribution: xxxxxxxx (xxxxxxxxx) PROVISIONING_PROFILE=xxxxxxxx PROVISIONING_PROFILE_SPECIFIER= -UseModernBuildSystem=0 | /usr/local/lib/ruby/gems/2.6.0/bin/xcpretty --no-color

and

xcodebuild -exportArchive -archivePath /Users/runner/work/1/s/MyApp.xcarchive -exportPath /Users/runner/work/1/s/ios/build -exportOptionsPlist _XcodeTaskExportOptions.plist | /usr/local/lib/ruby/gems/2.6.0/bin/xcpretty --no-color

Info.plist (extract):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.2</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.2.20</string>
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.utilities</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>

Solution

  • I'm afraid the solution for this specific problem is almost completely unrelated to everything I included in the in my description of the problem.

    It was entirely an error in the way I created the pipelines in Azure DevOps. I have used global vars to set the version numbers in one job and read them in another job, which is not possible. In the end, $(iOsBundleVersion) and $(iOsMarketingVersion) were not set. Unfortunately, none of the build scripts failed with any sensible error message. A gradle-build for the Android version of the app actually completed just fine.

    There are probably no new lessons to learn from this issue. I checked the values of $(iOsBundleVersion) and $(iOsMarketingVersion) in another context, which made me believe that they were correctly set - so maybe this issue is just a reminder to always make sure to be in the correct context when "debugging" any code.