Issue
I'm trying to improve Hudson CI for iOS and start Hudson as soon as system starts up. To do this I'm using the following launchd script:
<?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>Label</key>
<string>Hudson CI</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/java</string>
<string>-jar</string>
<string>/Users/user/Hudson/hudson.war</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>user</string>
</dict>
</plist>
This works OK but when xcodebuild, which is started by Hudson, tries to sign an app it fails because it cant find the proper key/certificate in the keychain. However key/certificate pair is there since it's working correct if I start Hudson from command line.
Do you have any ideas why it happens?
Solution
After spending hours and days with this issue I found a fairly easy solution to this. It doesn't matter if you have a distinct username in your launchd configuration as stated above:
<key>UserName</key>
<string>user</string>
The missing certificates and keys have to be on the system keychain (/Library/Keychains/System.keychain
). I found this after I setup a jenkins job which executes several security
shell calls. The one which's interesting is security list-keychains
:
+ security list-keychains
"/Library/Keychains/System.keychain"
"/Library/Keychains/applepushserviced.keychain"
"/Library/Keychains/System.keychain"
That are the keychains jenkins will search the certificates and keys for so they should be there. After I moved my certs there it works. Make sure you also copy the »Apple Worldwide Developer Relations Certification Authority« certificate to the system keychain, otherwise you will see a CSSMERR_TP_NOT_TRUSTED
error from codesign
.
It is also possible to register more keychains with security list-keychains -s [path to additional keychains]
. I haven't tried it but something like security list-keychains -s $HOME/Library/Keychains/login.keychain
as a pre-build shell execution in jenkins might work.
EDIT: I've tried to add a user keychain to the search path with -s
but I wasn't able to get it to work. So for now, we have to copy our certs and keys into the system keychain.
EDIT^2: Read and use joensson' solution instead of mine, he managed it to access the users keychain instead of just the system keychain.
Answered By - Jens Kohl
Answer Checked By - Senaida (JavaFixing Volunteer)