I\'m using xcodebuild
to compile my iPhone app from the command line. Is there a way to pass in some sort of option to set the provisioning profile? There seems to
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.
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.
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`
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:
Setup the Xcode build as a regular OSX user first; get it building your distributable from there, fixing any provisioning profile issues through Xcode;
Get the command line build working using xcodebuild, as a regular OSX user;
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.