Setting a provisioning profile from within xcodebuild when making iPhone apps

佐手、 提交于 2019-12-02 13:51:39

Documentation

It seems from the doc, you can't set the provisioning file BUT you can specify the target:

[-target targetname]

So, if you create a target for each provisioning file, you could select the proper target from the command line.

This would basically accomplish what your asking.

Actually, you should be able to just add it to the XCode command line setting.

xcodebuild [whatever other options you have] PROVISIONING_PROFILE="[Your profile Unique ID here]"

Build Settings from the command line are supposed to override everything, so this should win out over anything defined in the project or target.

jkp

My solution isn't elegant but it does do the job and let me automate everything on the build server:

#!/bin/bash

TARGET="Your App"
CONFIGURATION="Release"
SDK="iphoneos"
PROFILE_PATH="/Users/jkp/Desktop/foo.mobileprovision"
IDENTITY="iPhone Distribution: Your Company Ltd"
KEYCHAIN="/Users/jkp/Desktop/keychain"
PASSWORD="foobar"

open "${PROFILE_PATH}"
sleep 5
osascript -e "tell application \"Xcode\" to quit"
security unlock-keychain -p ${PASSWORD} ${KEYCHAIN}
xcodebuild \
  -target "${TARGET}" \
  -configuration ${CONFIGURATION} \
  -sdk iphoneos \
  CODE_SIGN_IDENTITY="${IDENTITY}" \    
  OTHER_CODE_SIGN_FLAGS="--keychain ${KEYCHAIN}"

The key thing here is that I didn't need to install the provisioning profile first. I actually have another script that uses mechanize to download the latest copy of the provisioning profile before each build which means we can update the profile (adding new devices for example) remotely and have those changes picked up by our CI server without any extra work.

Note: I've since found a way to install or update a provisioning profile without needing to involve Xcode at all - much cleaner! See here for full details.

BitByteDog

The provisioning profile has to be provided by UUID, in my case the provisioning profiles are checked in to the source control system, and are therefore checked out with the code by the developer/build server/CI system. In the source tree the profiles have human readable names such as MyApp.mobileprovison and are located in a directory called "ProvisioningProfiles". To create an xcode archive, the profiles have to be renamed and copied to the ~/Library/MobileDevice/Provisioning Profiles directory before xcodebuild will recognize them. This is a code snippet that can be used in a CI build script.

# The keychain needs to be unlocked for signing, which requires the keychain
# password. This is stored in a file in the build account only accessible to
# the build account user
if [ ! -f $HOME/.pass ] ; then
    echo "no keychain password file available"
    exit 1
fi

case `stat -L -f "%p" $HOME/.pass`
in
    *400) ;;
    *)
        echo "keychain password file permissions are not restrictive enough"
        echo "chmod 400 $HOME/.pass"
        exit 1
        ;;
esac

#
# unlock the keychain, automatically lock keychain on script exit
#
security unlock-keychain -p `cat $HOME/.pass` $HOME/Library/Keychains/login.keychain
trap "security lock-keychain $HOME/Library/Keychains/login.keychain" EXIT

#
# Extract the profile UUID from the checked in Provisioning Profile.
#
uuid=`/usr/libexec/plistbuddy -c Print:UUID /dev/stdin <<< \
        \`security cms -D -i ProvisioningProfiles/MyApp.mobileprovision\``

#
# Copy the profile to the location XCode expects to find it and start the build,
# specifying which profile and signing identity to use for the archived app
#
cp -f ProvisioningProfiles/MyApp.mobileprovision \
        "$HOME/Library/MobileDevice/Provisioning Profiles/$uuid.mobileprovision"
xcodebuild -workspace MyApp.xcworkspace -scheme MyScheme \
        -archivePath build/MyApp.xcarchive archive \
        PROVISIONING_PROFILE="$uuid" CODE_SIGN_IDENTITY="iOS Distribution"

The keychain must be unlocked and the "/usr/bin/codesign" tool must be allowed access to the private key associated with signing identity for this to work - The following references were used https://stackoverflow.com/a/21327591/2351246 and Add codesign to private key ACL without Keychain for unlocking and adding keychain access for codesign respectively.

If the archive is to be subsequently exported to an IPA using xcodebuild then the following issue must be taken into account (xcodebuild not copying file from .app). The provisioning profile needs to be supplied again. The script snippet to create an IPA is

profileName=`/usr/libexec/plistbuddy -c Print:Name /dev/stdin <<< \
        \`security cms -D -i ProvisioningProfiles/MyApp.mobileprovision\``

xcodebuild \
        -exportArchive \
        -exportFormat IPA \
        -archivePath build/MyApp.xcarchive \
        -exportPath $IPADIR/MyApp.ipa \
        -exportProvisioningProfile "$profileName"

The keychain will have to be unlocked while this command is running.

UPDATE

On OSX Mavericks (v10.9.5) and OSX Yosemite we started seeing code signing errors:

Codesign check fails : ...../MyApp.app: resource envelope is obsolete

Check this posting here for the cause xcodebuild - codesign -vvvv says"resource envelope is obsolete"

To implement the change suggested by Apple Support in the referenced post, run the following command:

 sudo perl -pi.bak -e 's/--verify"./--verify", "--no-strict",/ if /codesign.*origApp/;' `xcrun -sdk iphoneos -f PackageApplication`
Tim Fulmer

I realize this is probably a little off OP topic, but this question comes up first when searching for how to get Xcode builds working on Jenkins. Posting some additional information here for posterity. And points. If you found this useful, please give points :)

Anyway, went several rounds on this one a couple times lately. Found this:

http://code-dojo.blogspot.co.uk/2012/09/fix-ios-code-signing-issue-when-using.html

Seems to work. Make sure to:

  1. Setup the Xcode build as a regular OSX user first; get it building your distributable from there, fixing any provisioning profile issues through Xcode;

  2. Get the command line build working using xcodebuild, as a regular OSX user;

  3. Then follow the instructions in the post above to the letter, copying all iOS certs from Login Keychain to System and copying ~/Library/MobileDevice/Provisioning Profiles to the Jenkins user's ~jenkins/Library/MobileDevice/Provisioning Profiles folder.

The next Jenkins build, using the commands in step 2 above, should work flawlessly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!