2012-03-08 17 views
15

Il nostro server di build CI Jenkins è configurato su un Mac Mini con OSX Lion (10.7.3) e ho difficoltà a farlo firmare i build iOS in modo che possano essere caricati su a TestFlight.Impossibile firmare build iOS con Jenkins

Il processo è in esecuzione come utente normale denominato jenkins ed è avviato all'avvio utilizzando launchd. (La macchina non è accessibile al mondo esterno, quindi non ci dovrebbero essere problemi di sicurezza con l'esecuzione di questo con un account utente normale.)

Ecco l'errore nell'output console da Jenkins:

[workspace] $ /usr/bin/xcodebuild -target iMobileStCloud -configuration Release clean build 
=== CLEAN NATIVE TARGET MyApp OF PROJECT MyProject WITH CONFIGURATION Release === 
Check dependencies 
[BEROR]Code Sign error: The identity 'iPhone Distribution' doesn't match any valid certificate/private key pair in the default keychain 

Parte del problema sembra essere che solo il portachiavi di sistema è disponibile quando il processo viene avviato da launchd in fase di boot. Ho aggiunto uno script per il processo di generazione di elencare i portachiavi:

[workspace] $ /bin/sh -xe /var/folders/1y/1q3st_ss58z9ffj4dwbkdw8r0000gt/T/hudson8514187812830984272.sh 
+ /usr/bin/security list-keychains 
    "/Library/Keychains/System.keychain" 
    "/Library/Keychains/applepushserviced.keychain" 
    "/Library/Keychains/System.keychain" 
+ /usr/bin/security find-identity 

sono stato in grado di trovare due soluzioni, ma nessuno dei due è davvero fattibile:

  1. Se abbiamo accesso al server e riavviare il processo launchd ogni volta che la macchina viene riavviata jenkins quindi è in grado di caricare il portachiavi di login ed accedere ai certificati per la firma:

    sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist 
    sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist 
    
  2. Possiamo aggiungere i certificati al portachiavi di sistema, ma questo significa che non possiamo usare questa macchina per fare i build della distribuzione dell'app store. (Xcode non ama il portachiavi del sistema).

Qualcun altro ha trovato altri soluzioni alternative? C'è qualcos'altro oltre a launchd che posso usare per eseguire i processi all'avvio su OSX?

+0

Will Xcode hanno ancora problemi se gli stessi tasti sono _both_ nel login- e il portachiavi di sistema? –

+0

L'inserimento delle chiavi in ​​entrambe le posizioni è un'altra soluzione, suppongo, ma dalle esperienze passate so che può davvero causare problemi con il programma Accesso Portachiavi. Sembra confondersi e non cancella le chiavi che esistono in due portachiavi. –

+1

Vedi questa domanda di scambio dello stack per una soluzione possibile: http://stackoverflow.com/questions/6827874/missing-certificates-and-keys-in-thekeykeyin-while-using-jenkins-hudson-as-cont –

risposta

21

Ho risolto questo problema aggiungendo SessionCreate = true al mio file org.jenkins-ci.plist. Questa chiamata inizializza il framework di sicurezza.

Fonte: http://developer.apple.com/library/mac/#technotes/tn2083/_index.html

Vedi miniera nella sua interezza qui di seguito:

<?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>EnvironmentVariables</key> 
<dict> 
    <key>JENKINS_HOME</key> 
    <string>/Users/Shared/Jenkins/Home</string> 
</dict> 
<key>GroupName</key> 
<string>daemon</string> 
<key>KeepAlive</key> 
<true/> 
<key>Label</key> 
<string>org.jenkins-ci</string> 
<key>ProgramArguments</key> 
<array> 
    <string>/bin/bash</string> 
    <string>/Library/Application Support/Jenkins/jenkins-runner.sh</string> 
</array> 
<key>RunAtLoad</key> 
<true/> 
<key>UserName</key> 
<string>jenkins</string> 
<key>SessionCreate</key> 
<true/> 
</dict> 
</plist> 
+2

Anche questo è confermato che funziona anche per me, quindi ho cambiato il segno di spunta nella mia risposta. Questo era l'ultimo pezzo mancante del puzzle. Grazie mille! –

+1

Salve, SessionCreate è posizionato correttamente nel mio file .plist e nella lista di sicurezza-i portachiavi visualizzano il login.keychain di Jenkins, ma continuo a generare lo stesso errore. Qualche idea? – Claus

+0

Hai riavviato o riavviato jenkins? Non sono sicuro, ci sono molte cose che possono andare storte. Assicurati anche che la coppia di certificati/chiavi private sia nel portachiavi dell'utente jenkins. Infine, fare clic con il tasto destro del mouse sulla chiave e, in Access Control, concedere l'accesso a tutte le applicazioni. – markshiz

3

Ho avuto lo stesso problema. Il problema principale è in realtà causato quando launchd lancia un LaunchDaemon. Anche se si specifica che l'utente che si desidera eseguire il processo di avvio sotto di esso non viene eseguito come se si fosse connessi come tale utente. Ecco perché non vedi il portachiavi di accesso nell'elenco dei portachiavi disponibili per Jenkins.

Mi sono imbattuto in un lavoro che riguardava la chiamata su - yourbuilduser -c ./start-jenkins.sh, dove start-jenkins.sh è uno script di avvio personalizzato, da launchd plist (come LaunchDaemon). Questo garantisce l'accesso al portachiavi di login ma rende difficile il controllo da parte di Jenkins. Nello specifico, non puoi fermare Jenkins chiamando lo launctl unload ... e devi uccidere il processo manualmente.

Attualmente stiamo eseguendo il nostro CI iOS utilizzando un plist in LaunchAgents (che inizia Jenkins usando java -jar jenkins.war) piuttosto che in LaunchDaemon. Noiosamente, questo significa che l'utente deve essere connesso al server (non un problema se la tua macchina è all'interno della tua rete privata o in una DMZ configurata correttamente), tuttavia significa anche che il processo di Jenkins può essere controllato da launchctl e che ha accesso al portachiavi dell'utente. È possibile impostare l'utente per l'accesso automatico in modo da ottenere Jenkins all'avvio.

Sono riuscito ad automatizzare quasi ogni aspetto di una pipeline di Continuous Delivery per i binari di iOS, questa è l'unica parte in cui la mia soluzione non sembra giusta (idealmente, sarei solo in grado di usare un LaunchDaemon che avrebbe accesso al portachiavi dell'utente).

+0

Non sono sicuro che io segua tu, ma penso che tu stia dicendo che hai l'utente Jenkins impostato su Login automatico, e poi hai aggiunto uno script di shell come uno degli elementi di login di quell'utente. È corretto? –

+0

OK, non aggiungere il plist a/Library/LaunchDeamons, aggiungerlo a/Users/youruserhere/Library/LaunchAgents quindi impostare tale utente per l'accesso automatico. Questa istanza di jenkins avrà accesso al portachiavi di login dell'utente. Potrebbe essere necessario sbloccarlo durante il lavoro di jenkins che crea il tuo codice. –

+0

Lasciando che l'utente Jenkins abbia effettuato l'accesso non è l'ideale, ma non è un interruttore automatico, e rende completamente automatico il server di compilazione di elementi di configurazione. Grazie per l'aiuto! –

4

Si potrebbe anche provare il mio programma di installazione Jenkins alternativo che esegue Jenkins come applicazione.

Il progetto è https://github.com/stisti/jenkins-app. Download sono https://github.com/stisti/jenkins-app/downloads

Jenkins deve essere eseguito nel contesto dell'utente per poter accedere ai portachiavi.

+1

Vorrei aver saputo di questo progetto un paio di mesi fa. –

+0

Questo è davvero facile da configurare e utilizzare. Molto meglio di come Jenkins è impostato di default per i miei scopi. –

Problemi correlati