Running xcodebuild from a forked terminal

Viewed 51128

I'm trying to setup an automated build server for an iPhone application. I'd like to be able to have nightly adhoc beta builds so that testers can follow the development.

I've setted up xcode successfully xcode to perform adhoc builds and I can also launch the build from the command line:

xcodebuild -configuration AdHoc -sdk iphoneos2.2 clean build

The problem I'm having is that the following line doesn't work from a forked terminal (using nohup or screen) and failed with the following

CodeSign error: Code Signing Identity 'iPhone Distribution: XXXXX' does not match any code-signing certificate in your keychain. Once added to the keychain, touch a file or clean the project to continue.

I've checked my environment variables in my shell and in nohup or screen and didn't found a clue. I guess my problem is that the forked terminal can't access to the keychain but I have no clue on how to allow it.

Thanks for your help

13 Answers

I had te error User interaction is not allowed and solved it by unlocking the keychain first

security unlock-keychain /Users/yannooo/Library/Keychains/login.keychain

I've also tried to put my certs in the System's keychain and it was working. My final solution was to put all my iPhone related certs in a dedicated keychain named iPhone.keychain using the Keychain Access application

security list-keychains -s /Users/yannooo/Library/Keychains/iPhone.keychain 
security unlock-keychain -p keychainpassword /Users/yannooo/Library/Keychains/iPhone.keychain 

Could you use security list-keychains -s ${HOME}/Library/Keychains/login.keychain inside the build process to explicitly add your login keychain to the search list? It seems like from the forked Terminal, the build process doesn't see your user keychain. That could make sense if the keychain search list is based on your current security session - a forked terminal session would leave the login session just as if you ssh over the loopback connection.

update for people running into similar issues with Jenkins:

If you set up your Mac to launch jenkins via LaunchDaemons, you need to make sure to add

<key>SessionCreate</key>
<true />

So the whole ci.plist would look like so:

<?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>Jenkins</string>
 <key>UserName</key>
 <string>user</string>
 <key>GroupName</key>
 <string>staff</string>
 <key>ProgramArguments</key>
 <array>
 <string>/usr/bin/java</string>
 <string>-Xmx512m</string>
 <string>-jar</string>
 <string>/path/to/jenkins/jenkins.war</string>
 </array>
 <key>RunAtLoad</key>
 <true/>
 <key>KeepAlive</key>
 <true/>
 <key>EnvironmentVariables</key>
   <dict>
     <key>JENKINS_HOME</key>
     <string>/path/to/jenkins/home</string>
   </dict>
 <key>SessionCreate</key>
 <true />
</dict>
</plist>

I've been stuck wit the same issue as many people above have. Specifically I experienced the issue when running from a Jenkins shell script I got the same ** User interaction is not allowed ** error. When running from an ssh shell, my script worked fine.

The difference that most people have also seen is that if you run security list-keychain you'd get:

$ security list-keychain
  "/Library/Keychains/System.keychain"
  "/Library/Keychains/System.keychain"

But when running in the ssh shell, I'd get:

$ security list-keychain
    "/Users/<i>user_account_name</i>/Library/Keychains/login.keychain"
    "/Library/Keychains/System.keychain"

And most people will have all their keys/certs etc. in the user account keychain. Like some folks suggested it's easy to make a new key chain that is distinct from the user key chain, and reseve it for your XCode signing stuff. I ended up putting mine here: /Library/Keychains/sysiphone.keychain

I think the issue is that for my setup (and possibly for yours too), you're running in a different security preference domain (system vs. user). Finally -- here is how I got my sysiphone.keychain to show up:

$ sudo security list-keychains -d system -s "/Library/Keychains/sysiphone.keychain"
Password: *****
$ security list-keychains -d system
    "/Library/Keychains/sysiphone.keychain"

... and magically things started to build in Jenkins. Wow... that was about 4 hours down the drain for me. Sigh.

As another poster says,

security list-keychains -s  "~/Library/Keychains/login.keychain"

But I think you only have access to the login.keychain when you are logged in, in the GUI context (I just tested on a system via SSH and screen, but which I also happen to be logged into via VNC).

It is apparently possible to use launchctl to select the GUI context and run the program, but I suspect that only works for the "logged in user" too.

If you try 'security show-keychain-info keychain-file' then you'll get the following error:

User interaction is not allowed

And that's a phrase to search with for some more info. The other solution is to put the certificate into your System keychain!

I've looked at the security command an it appears that the keychains assigned to my terminal are not the same when forked. If I launched the security command in terminal I have:

$ security list-keychains
  "/Users/yannooo/Library/Keychains/login.keychain"
  "/Library/Keychains/System.keychain"

whereas when using screen I have the following output:

$ security list-keychains
    "/Library/Keychains/System.keychain"
    "/Library/Keychains/System.keychain"

Since my build certificates are stored in the login keychain, the code sign error I have looks normal.

Does anyone know how I could assign a keychain to a terminal? I've tried this without success

security login-keychain -s /Users/yannooo/Library/Keychains/login.keychain

Any ideas?

If you're executing xcodebuild as root (which you are when you sudo), you need to log in as root and put your signing certificates in root's keychain. Then unlock the keychain with security as above.

I did:

  • delete login.keychain from list

  • create own keychain in $HOME/Library/Keychains/

  • add it to keychain list (I did not specify any specific domain)

  • set it as default

  • call security unlock-keychain on it

  • add global signing certificate (WWDRCA) to it

  • import private key and both Development and Distribution certificates to it

If there's login.keychain, I still get "User interaction not allowed" error. Thus deleting login.keychain using security delete-keychain finally helped!

Related