Search code examples
iosxcodecontinuous-integrationprovisioning-profileios-app-extension

How to resign an app with app store provisioning profile to add beta-reports-active key?


In order to distribute apps via Apple's new Test Flight service the beta-reports-active key needs to be present. Currently I'm using Apple's bot server to distribute to the old Test Flight system with and Ad Hoc distribution profile. Using a post build trigger I want to take the archive that is created and build an App Store Distribution ipa that I can upload to iTunes Connect. I've written a script that does this. I use the xcrun command to build:

/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "${APP_STORE_IPA}" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"

The SIGNING_IDENTITY and PROVISIONING_PROFILE are both app store distribution certificates/profiles. So the provisioning profile is getting embedded in the ipa and it contains the beta-reports-active flag. However, when I look at the ipa to verify its entitlements it is not present.

What am I doing wrong? All information I've seen on this has just suggested regenerating the provisioning profile. I've done this and know the key is present. It is not getting added to the entitlements. I have a widget that gets bundled in the ipa as well. I am not resigning that.


Solution

  • Alright so I think I've finally got this figured out. It seems as though the Bot Server may have a few kinks that Apple needs to iron out. I noticed that the Distribution IPA that is generated by the Bot Server lacks any of the required entitlements of my Application. I did a little searching and found other people are having the same problem. Here's a question that explains the issue really well: IPA created via Xcode bot fails to run for APNS but runs if built manually via Xcode itself or built as an archive by Xcode

    So with this in mind I created and added an entitlement file to my project with the minimum entitlements I needed. I also did the same for the widget that is in my project. Then during my post integration trigger I read both entitlement files and add the necessary entitlements to it.

    # Copy the Entitlements file out of the payload so we can update it
    APP_ENTITLEMENTS="/tmp/distributionEntitlements.plist"
    rm -rf ${APP_ENTITLEMENTS}
    codesign -d --entitlements :${APP_ENTITLEMENTS} "/tmp/Payload/MyAppName.app"
    
    WIDGET_ENTITLEMENTS="/tmp/widgetDistributionEntitlements.plist"
    rm -rf ${WIDGET_ENTITLEMENTS}
    codesign -d --entitlements :${WIDGET_ENTITLEMENTS} "/tmp/Payload/MyAppName.app/Plugins/${WIDGET_NAME}"
    
    # Copy over the latest build the bot just created
    echo "Copying latest Archive to /tmp/...";
    cp -Rp "${XCS_ARCHIVE}" "/tmp/"
    
    APP="/tmp/Archive.xcarchive/Products/Applications/MyAppName.app"
    
    echo "Updating entitlements file"
    /usr/libexec/PlistBuddy -c "Add :beta-reports-active bool true" ${APP_ENTITLEMENTS}
    /usr/libexec/PlistBuddy -c "Add :aps-environment string production" ${APP_ENTITLEMENTS}
    cat ${APP_ENTITLEMENTS}
    
    echo "Updating widget entitlements file"
    /usr/libexec/PlistBuddy -c "Add :beta-reports-active bool true" ${WIDGET_ENTITLEMENTS}
    cat ${WIDGET_ENTITLEMENTS}
    

    Then of course you have to codesign these apps again:

    echo "Codesign the widget"
    cp "${WIDGET_PROVISIONING_PROFILE}" "${APP}/Plugins/${WIDGET_NAME}/embedded.mobileprovision"
    codesign -fv -s "${FULL_SIGNING_IDENTITY}" "${APP}/Plugins/${WIDGET_NAME}" --entitlements "${WIDGET_ENTITLEMENTS}" --preserve-metadata=resource-rules,requirements
    
    echo "Codesign the app"
    codesign -fv -s "${FULL_SIGNING_IDENTITY}" "${APP}" --entitlements "${APP_ENTITLEMENTS}" --preserve-metadata=resource-rules,requirements
    
    echo "Creating .ipa"
    # Remove any whitespace
    FILENAME=${XCS_BOT_NAME// /}
    echo "Filename: ${FILENAME}"
    APP_STORE_IPA="/tmp/${FILENAME}_AppStore_${VERSION_NUMBER}.ipa"
    rm "${APP_STORE_IPA}"
    /usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "${APP_STORE_IPA}" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"
    

    After all this, I can upload this IPA to Apple and distribute it using their new TestFlight beta distribution tool.