weirdness when packaging with xcrun (codesign fails when using variable) - ios

I try to parameterize my application build script when running into this behaviour:
the app already has been build (with 'cordova build ios --release') and is available.
when calling:
$ xcrun ... -sign "iPhone Developer: XXX" -embed ...
everything goes fine. so far so good :)
now i instead want to use a variable in the call like:
$ identity="iPhone Developer: XXX"
$ xcrun ... -sign $identity -embed ...
where i later pass the $identity parameter to my build script
doing the 'xcrun ...' like above logically results in the fact that the 'codesign' command only gets "iPhone" as parameter and fails (of course:)
thus i'm trying to mask the $identity
closest call for success is to use
$ xcrun ... -sign \""$identity"\" -embed ...
which results into a 'codesign' call by the xcrun like
$ xcrun ... -sign \""$identity"\" -embed ...
[...]
/usr/bin/codesign ... --sign "iPhone Developer: XXX" ...
Program /usr/bin/codesign returned 1 : ["iPhone Developer: XXX": no identity found
]
interestingly enough executing the command directly from shell (/bin/bash) works okay !!?
i tried as well to define $identity already having double-quotes but that runs into the initial behaviour with no quotation at all. using single-quotes in various combinations didn't help either so far.
any idea why xcrun is getting it wrong ? ... or, how to do it differently?
like said: the goal is to have a parameterized build script
-------- system parameters ---------
$ uname -a
Darwin allianz 13.0.0 Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27 PDT 2013; root:xnu-2422.1.72~6/RELEASE_X86_64 x86_64
$ xcrun -version
xcrun version 22.

Okay, this weirdness seems to be due to the fact that I assembled the command line like
xcrun -sdk iphoneos PackageAppliction $package -o $ipafile -sign \"$identity
\" -embed $profile
doing it the way to assemble the parts (option1 $variable1 option2 $variable2 ... etc.) to just one string first, like
assembledstring="-sdk iphoneos PackageAppliction $package -o $ipafile -sign \"$identity
\" -embed $profile"
and only then doing a
sh -c "xcrun $assemledstring"
sorts the issue.

Related

codesign --keychain gets ignored

I am exporting App archives using the command line tools (xcodebuild). Essentially this is what I running:
xcodebuild -workspace "${WORKSPACE_PATH}" \
-scheme "${SCHEME_NAME}" \
-archivePath "${PROJECT_ARCHIVE}" \
-configuration "${CONFIGURATION}" \
-sdk "${TARGET_SDK}" \
DEVELOPMENT_TEAM="XXXXXXXX" \
OTHER_CODE_SIGN_FLAGS="--keychain /Users/user/Library/Keychains/jenkins.keychain" \
archive
And this is the result:
Check dependencies
No signing certificate "iOS Development" found: No "iOS Development" signing certificate matching team ID "XXXXXXX" with a private key was found.
Code signing is required for product type 'Application' in SDK 'iOS 10.2'
** ARCHIVE FAILED **
The following build commands failed:
Check dependencies
(1 failure)
$ echo $?
65
The code signing fails because codesign ignores the --keychain parameter. Now here is the interesting part. The keychain I want to use is jenkins.keychain-db (as specified above). That certainly does not work. Here is my keychain search list:
$ security list-keychains
"/Users/user/Library/Keychains/login.keychain-db"
"/Library/Keychains/System.keychain"
Obviously jenkins.keychain-db is not in there as it should be. If I am adding the jenkins.keychain-db in the search list it starts working.
Unfortunately this is not a solution for me because I do have multiple keychains with the same private keys and certificates. That leads xcodebuild to pick up the first right certificate that it can find which will fails because the keychain is probably not unlocked.
You can make codesign prefer using your custom keychain with the following commands:
security list-keychains -d user -s jenkins.keychain
security default-keychain -s jenkins.keychain
# to unlock the kechain:
security unlock-keychain -p $PW jenkins.keychain
Put this right before xcodebuild ...
You can omit the -db extension. It's not necessary to use it and will lead to confusing behavior.
You might want to clean this up after the build has finished:
security list-keychains -d user -s login.keychain
security default-keychain -s login.keychain

Using xcodebuild to install application on iPhone

I am working on a shell script that builds and install our xcodeproj directly to the first found and connected iDevice. This is the script
#!/bin/bash
cd ../../cordova/platforms/ios
deviceName=$(ideviceinfo | grep -i DeviceName)
deviceName=${deviceName//DeviceName: /} #This is the device name you set in Settings->General->Info->Name on your iDevice
deviceUdid=$(system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}')
if [ -n "deviceUdid" ]; then
echo 'Found device "'${deviceName}'" with UUID "'${deviceUdid}'", process...'
xcodeProject=$(ls | grep -i *.xcodeproj)
if [ -n "$xcodeProject" ]; then
echo "Is xCode project dir, start building..."
################### Not working command ###################
eval "xcodebuild -scheme AppScheme -destination 'platform=iOS,id=$deviceUdid' install" #This line is not really working
################### Not working command ################
else
echo "Directory is not an xCode project directory!"
fi
else
echo 'It looks like there is no iDevice connected!'
fi
Everything works, except installing it on my iPhone. I get the correct device name, it looks like as if it finds the device, but I don't see the app on my iPhone. The strange thing is, that everything works well if I install it from xCode.
Does anyone know how to fix this issue?
I use this following commands to build and run my Application in Simulator:
xcodebuild -sdk iphonesimulator8.4 -arch i386 -workspace MyApp.xcworkspace -scheme MyApp install DSTROOT=~/MyApp
xcrun instruments -w "iPhone 5s (8.4 Simulator)"
xcrun simctl install booted ~/MyApp/Applications/MyApp.app
if you want to run in another Simulator try see available simulators with:
xcrun instruments -s

Error when export archive

I have problem with using Export function in Xcode ("Your account already have distribution certificate") so I used solution with xcodebuild. It produce IPA file but I see this in console:
### Checking original app
+ /usr/bin/codesign --verify -vvvv /.../My.app
Program /usr/bin/codesign returned 1 : [/.../My.app: resource envelope is obsolete
]
Codesign check fails : /.../My.app: resource envelope is obsolete
Is it a problem from my side and how to solve it?
If you are using Mac OSX 10.9.5 or later, then there is an issue with OS codesigning with V2 signature.
So, use --no-strict flag with codesign --verify to getover this error.
If you're using PackageApplication to create an .ipa file, then
Edit the PackageApplication perl script tool using vi PackageApplication command and update codesign function occurrences to pass "--no-strict" parameter.
Example:
my $result = runCmd("/usr/bin/codesign", "--verify", "--no-strict",
"-vvvv", , $plugin );
I was facing same and got following response from Apple Dev Team. The issue is resolved for me.
The command line tool “codesign” has changed in 10.9.5 and 10.10, you need to pass “--no-strict” option to the command, (the problem has been reported and will be fixed).
To workaround the problem, please save a copy and modify PackageApplication to pass “—no-strict” to codesign, you can locate PackageApplication by running the following:-
xcrun -sdk iphoneos -f PackageApplication

Failed to generate release build of cordova ios app

I am using phonegap CLI 3.1 and XCode5. I am trying to generate the build for release mode through Phonegap CLI and Xcrun. I don't want to use Phonegap Build to upload the mobileprovision or whatever the process of them. I want to do it by xcrun to assign the mobileprovison to release build.
1) cordova build ios --release
Compiling app on platform "ios" via command
"/Applications/MAMP/htdocs/MyTest/MyTestApp/platforms/ios/cordova/build" --release
Platform "ios" compiled successfully.
2) sudo xcrun -sdk iphoneos PackageApplication -v "ios/build/emulator/MyTestApp.app" -o "/Users/mymac/Desktop/Testnew/MyTestApp.ipa" --sign "iPhone Distribution: NAME (TEAM_ID)" --embed "MyTestApp_Dis.mobileprovision"
Packaging application: 'ios/build/emulator/MyTestApp.app'
Arguments: embed=MyTestApp_Dis.mobileprovision verbose=1 output=/Users/mymac/Desktop/Testnew/MyTestApp.ipa sign=iPhone Distribution: NAME (TEAM_ID)
Environment variables:
HOME = /Users/mymac
SUDO_GID = 20
SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk
VERSIONER_PERL_PREFER_32_BIT = no
MAIL = /var/mail/root
SSH_AUTH_SOCK = /tmp/launch-zsBMC8/Listeners
LANG = en_US.UTF-8
USER = root
LOGNAME = root
__CF_USER_TEXT_ENCODING = 0x0:0:0
USERNAME = root
PATH = /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin
SUDO_USER = mymac
SHELL = /bin/bash
TERM = xterm-256color
SUDO_COMMAND = /usr/bin/xcrun -sdk iphoneos PackageApplication -v ios/build/emulator/MyTestApp.app -o /Users/mymac/Desktop/Testnew/MyTestApp.ipa --sign iPhone Distribution: NAME (TEAM_ID) --embed MyTestApp_Dis.mobileprovision
SUDO_UID = 501
VERSIONER_PERL_VERSION = 5.12
Output directory: '/Users/mymac/Desktop/Testnew/MyTestApp.ipa'
Temporary Directory: '/tmp/W81FhZ9VAH' (will NOT be deleted on exit when verbose set)
+ /bin/cp -Rp ios/build/emulator/MyTestApp.app /tmp/W81FhZ9VAH/Payload
Program /bin/cp returned 0 : []
Checking original app
/usr/bin/codesign --verify -vvvv ios/build/emulator/MyTestApp.app
Program /usr/bin/codesign returned 1 : [ios/build/emulator/MyTestApp.app: code object is not signed at all
In architecture: i386
]
Codesign check fails : ios/build/emulator/MyTestApp.app: code object is not signed at all
In architecture: i386
Done checking the original app
Embedding 'MyTestApp_Dis.mobileprovision'
/bin/rm -rf /tmp/W81FhZ9VAH/Payload/MyTestApp.app/embedded.mobileprovision
Program /bin/rm returned 0 : []
/bin/cp -rp MyTestApp_Dis.mobileprovision /tmp/W81FhZ9VAH/Payload/MyTestApp.app/embedded.mobileprovision
Program /bin/cp returned 0 : []
/usr/bin/codesign -d --entitlements /tmp/W81FhZ9VAH/entitlements_rawixGWnKhi /tmp/W81FhZ9VAH/Payload/MyTestApp.app
Program /usr/bin/codesign returned 1 : [/tmp/W81FhZ9VAH/Payload/MyTestApp.app: code object is not signed at all
]
error: Failed to read entitlements from '/tmp/W81FhZ9VAH/Payload/MyTestApp.app'
Hmmh, I'm having a similar problem like Shashi.
When running 'cordova buld ios [--release]' from shell and then doing a 'xcrun ...' afterwards it works for me okay.
BUT: When running this sequence from within a script, I receive a "Codesign check fails ..." error too ...
If I insert (like) a "wait" cycle inside my script between the cordova and the xcrun call, it works.
So - to me - it seems, as if cordova returns to shell while it isn't completely finished (?)
Fact is if I code my script like
#!/bin/bash
cordova build ios --release
sleep 5
sh -c "xcrun ..."
it's working for me.
Question: Is it a bug in cordova/phonegap ???
So, finally I got everything to work okay ... :D
The problem of Jenkins complaining about a failed 'codesign ...' run is a MacOS (configuration) issue
The crucial thing is to allow the Jenkins access to the keychain of the system. The allowed access for the Login-shell of the Jenkins user is different from the Jenkins server process running under the Jenkins user account (!)
For now I realize this by running the unlock of the login.keychain within the Jenkins job before running my build script
like: in the Jenkins job for "execute shell"
security unlock-keychain -p password /Users/Shared/Jenkins/Library/Keychains/login.keychain
echo ##### building now ######################
./buildit.sh ios --release -v
This may not be the 100% nicest solution - but for now it works :P
See as well: [1]: Keychain won't unlock from Jenkins script unless user logged in
Meanwhile I found:
Fact is, that - when cordova exits and returns to shell - cordova related activities are NOT completed yet!
It takes a while after the cordova exit, for the 'platforms/ios/AppName/_CodeSignature/CodeResources' file to show up. This file obviously is essential for the 'codesign' which is started by xcrun command to succeed.
So I do in my script (which i call 'buildit.sh')
#!/bin/bash
[...]
cordova build ios --release
signaturefile="platforms/ios/build/device/$appname/_CodeSignature/CodeResources"
echo DEBUG:signatur file is $signaturefile
while [ ! -f $signaturefile ]
do
echo waiting
sleep 1
done
xcrun ...
Then the whole build/packaging process in one script succeeds.
However: Running the script from my ContinuousIntegration server Jenkins, I observe that this criteria may be essential, but not enough. From the CI I still get a
/usr/bin/codesign --verify -vvvv [...]
Program /usr/bin/codesign returned 1 : [...] code object is not signed at all
error!??
EDIT (05.12.2013): This is due to the fact that the Jenkins service couldn't access the keychain. E.g. doing in the Jenkins job an unlock of the keychain prior running the build script sorts it. (May not be the most elegant solution, but at least it prooves the problem not to be in the scripting :)
In order to skip the code signing you can perform a manual build from the console like this:
xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
Use additionally the -configuration, -target and -sdk parameters in order to define your build settings.
To Disable Code Signing:
*Go to /Applications.
Right click on XCode and select 'Show Package Contents'.
Copy Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/SDKSettings.plist to your desktop. (Make sure to actually copy and paste. No drag and drop)
Open it and under DefaultProperties set CODE_SIGNING_REQUIRED to NO.
Copy it back and replace the original file.
Restart XCode.
Open your project.
In Project Navigator select your project and open Build Settings section of your porject (and not any particular target)
Under Code Signing find Code Signing Identity and for both Debug and Release modes set Any iOS SKD to Don't Code Sign.
Now you should be able to build your project without any errors.*
To make an IPA:
In 'Project Navigator' select Products
Right click on [NameOfYourProject].app and select 'Show in Finder'.
Create a folder and name it Payload
Move [NameOfYourProject].app to Payload.
Compress Payload and rename it to [NameOfYourProject].ipa

PackageApplication fails because app does not Satisfy its Designated Requirement

I'm having trouble packaging an app as an IPA with PackageApplication. Codesign verification fails with "does not satisfy its designated Requirement":
+ /usr/bin/codesign --verify -vvvv -R=anchor apple generic and (certificate 1[field.1.2.840.113635.100.6.2.1] exists and (certificate leaf[field.1.2.840.113635.100.6.1.2] exists or certificate leaf[field.1.2.840.113635.100.6.1.4] exists)) /var/folders/8j/n5d5y1bj6wz3l8gs_djqn3400000gn/T/8xonyTiAuP/Payload/Planner.app
Program /usr/bin/codesign returned 3 : [/var/folders/8j/n5d5y1bj6wz3l8gs_djqn3400000gn/T/8xonyTiAuP/Payload/Planner.app: valid on disk
/var/folders/8j/n5d5y1bj6wz3l8gs_djqn3400000gn/T/8xonyTiAuP/Payload/Planner.app: does not satisfy its designated Requirement
/var/folders/8j/n5d5y1bj6wz3l8gs_djqn3400000gn/T/8xonyTiAuP/Payload/Planner.app: explicit requirement satisfied
What requirement is designated here?!?
I'm building with xcodebuild:
xcodebuild -workspace MyWorkspace.xcworkspace -scheme Planner -ask iphoneos clean build archive
which creates an Xcode archive for me inside ~/Library/Developer/Xcode/Archives So far so good.
Then I've read that people use PackageApplication but that fails for me:
xcrun -sdk iphoneos PackageApplication -v path/to/Planner.app -o Planner.ipa --sign 9990807058544973D70EA9A9F3BB3949D51C0983 --embed my_profile.mobileprovision
with the above error.
What part am I missing here? Is there another way to do this?
This is Xcode 4.5.
You can check what the designated requirements for your .app file are by running the following command:
codesign -d -r- path/to/file.app
Your output should include a line that starts with designated =>. What follows after are your designated requirements. An example of this output would be:
designated => identifier "com.organization.project" and certificate root = H"abcdef0123456789abcdef0123456789abcdef12"
The -d flag displays information and the -r- flag writes the requirements to stdout.
You can use Apple's page on Code Signing Requirement Language to interpret what these requirements mean.
If you want to narrow down which particular requirement is failing, you can run the tests individually by entering the following command:
codesign -v -R="certificate root = H\"abcdef0123456789abcdef0123456789abcdef12\"" /path/to/file.app
The -v flag performs verification on your app and the -R flag passes in an explicit requirement to test.

Resources