Résumé:
La configuration de Jenkins sur OS X a été considérablement simplifiée avec le dernier programme d'installation (à partir de 1.449 - 9 mars 2012 ), mais la gestion du processus de signature de code est toujours très difficile sans réponse simple.
Motivation:
Exécutez un serveur CI sans tête qui suit les meilleures pratiques courantes pour exécuter des services sur OS X (dont certains sont expliqués ici en langage clair ).
Contexte:
- 12 octobre 2009 - Comment automatiser les builds de votre application iPhone avec Hudson
- 15 juin 2011 - Jenkins sur Mac OS X; git w / ssh clé publique
- 23 juin 2011 - Déploiement continu des applications iOS avec Jenkins et TestFlight
- 26 juillet 2011 - Certificats et clés manquants dans le trousseau lors de l'utilisation de Jenkins / Hudson comme intégration continue pour le développement iOS et Mac
- 30 août 2011 - Fichier d'approvisionnement Xcode introuvable avec Jenkins
- 20 septembre 2011 - Comment configurer Jenkins CI sur un Mac
- 14 septembre 2011 - Faire fonctionner Jenkins sur un Mac
- 12 novembre 2011 - Howto: Installez Jenkins sur OS X et faites-le construire des trucs Mac
- 23 janvier 2012 - Modifications à venir du programme d'installation de Jenkins OSX
- 7 mars 2012 - Merci d'utiliser le programme d'installation OSX
Processus:
Installez Jenkins CI via OS X package d'installation . Pour l'étape «Type d'installation», cliquez sur le bouton Personnaliser et choisissez «Démarrer au démarrage en tant que« jenkins »».
Discussion:
L'attente naïve à ce stade était qu'un projet de style libre avec le script de construction xcodebuild -target MyTarget -sdk iphoneos
devrait fonctionner. Comme l'indique le titre de cet article, il ne fonctionne pas et échoue avec:
Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain
Ce qui doit se passer est assez évident: vous devez ajouter un certificat de signature de code valide et une clé privée dans le trousseau par défaut. En recherchant comment y parvenir, je n'ai pas trouvé de solution qui n'ouvre pas le système à un certain niveau de vulnérabilité.
Problème 1: pas de trousseau par défaut pour le démon jenkins
sudo -u jenkins security default-keychain
... renvoie "Un trousseau par défaut est introuvable"
Comme indiqué ci-dessous par Ivo Dancet , le UserShell est défini sur / usr / bin / false pour le démon jenkins par défaut (je pense que c'est une fonctionnalité, pas un bogue); suivez sa réponse pour changer le UserShell en bash. Vous pouvez ensuite utiliser sudo su jenkins
pour vous connecter en tant qu'utilisateur jenkins et obtenir une invite bash.
sudo su jenkins
cd ~/Library
mkdir Keychains
cd Keychains
security create-keychain <keychain-name>.keychain
security default-keychain -s <keychain-name>.keychain
D'accord! Super. Nous avons maintenant un trousseau par défaut; allons-y, non? Mais d'abord pourquoi avons-nous même pris la peine de créer un trousseau par défaut?
Presque toutes les réponses, suggestions ou conversations que j'ai lues tout au long de la recherche suggèrent qu'il suffit de jeter leurs certificats et clés de signature de code dans le trousseau du système. Si vous exécutez en security list-keychains
tant que projet de style libre dans Jenkins, vous voyez que le seul trousseau disponible est le trousseau système; Je pense que c'est là que la plupart des gens ont eu l'idée d'y mettre leur certificat et leur clé. Mais cela semble être une très mauvaise idée - d'autant plus que vous devrez créer un script en texte brut avec le mot de passe pour ouvrir le trousseau .
Problème 2: Ajout de certificats de signature de code et de clé privée
C'est là que je commence vraiment à être dégoûté. J'ai le sentiment instinctif que je devrais créer une nouvelle clé publique / privée unique à utiliser avec Jenkins. Mon processus de réflexion est que si le démon jenkins est compromis, je peux facilement révoquer le certificat dans le portail de provisionnement d'Apple et générer une autre clé publique / privée. Si j'utilise la même clé et le même certificat pour mon compte utilisateur et Jenkins, cela signifie plus de tracas (dommage?) Si le service jenkins est attaqué.
En indiquant la réponse de Simon Urbanek, vous déverrouillerez le trousseau à partir d'un script avec un mot de passe en texte brut. Il semble irresponsable de garder autre chose que des certificats et des clés «jetables» dans le trousseau du démon jenkins.
Je suis très intéressé par toute discussion à l'effet contraire. Suis-je trop prudent?
Pour créer un nouveau CSR en tant que démon jenkins dans Terminal, j'ai fait ce qui suit ...
sudo su jenkins
certtool r CertificateSigningRequest.certSigningRequest
Vous serez invité à fournir ce qui suit (la plupart d'entre eux, j'ai fait des suppositions éclairées sur la bonne réponse; avez-vous un meilleur aperçu? Veuillez partager.) ...- Entrez la clé et l'étiquette du certificat:
- Sélectionnez l'algorithme:
r
(pour RSA) - Entrez la taille de la clé en bits:
2048
- Sélectionnez l'algorithme de signature:
5
(pour MD5) - Entrez la chaîne de défi:
- Puis un tas de questions pour RDN
- Soumettez le fichier CSR généré (CertificateSigningRequest.certSigningRequest) au portail de provisioning d'Apple sous un nouvel identifiant Apple
- Approuvez la demande et téléchargez le fichier .cer
security unlock-keychain
security add-certificate ios_development.cer
Cela nous rapproche un peu plus ...
Problème 3: profil de provisionnement et déverrouillage du trousseau
J'ai créé un profil de provisionnement spécial dans le portail de provisionnement juste pour une utilisation avec CI dans l'espoir que si quelque chose de mauvais se produit, j'ai réduit un peu l'impact. Meilleure pratique ou trop prudent?
sudo su jenkins
mkdir ~/Library/MobileDevice
mkdir ~/Library/MobileDevice/Provisioning\ Profiles
- Déplacez le profil de provisioning que vous avez configuré dans le portail de provisioning dans ce nouveau dossier. Nous sommes maintenant à deux pas de la possibilité d'exécuter xcodebuild à partir de la ligne de commande en tant que jenkins, ce qui signifie que nous sommes également sur le point de pouvoir obtenir les builds en cours d'exécution de Jenkins CI.
security unlock-keychain -p <keychain password>
xcodebuild -target MyTarget -sdk iphoneos
Maintenant, nous obtenons une construction réussie à partir d'une ligne de commande lorsque nous nous connectons en tant que démon jenkins, donc si nous créons un projet de style libre et ajoutons ces deux dernières étapes (n ° 5 et n ° 6 ci-dessus), nous pourrons automatiser la construction de notre projet iOS!
Ce n'est peut-être pas nécessaire, mais je me suis senti mieux en remettant jenkins UserShell à / usr / bin / false après avoir réussi à obtenir toute cette configuration. Suis-je paranoïaque?
Problème 4: le trousseau par défaut n'est toujours pas disponible!
( EDIT: j'ai publié les modifications de ma question, redémarré pour m'assurer que ma solution était à 100%, et bien sûr, j'avais laissé de côté une étape )
Même après toutes les étapes ci-dessus, vous devrez modifier le plist de lancement du démon à /Library/LaunchDaemons/org.jenkins-ci.plist comme indiqué dans cette réponse . Veuillez noter qu'il s'agit également d'un bogue openrdar .
Ça devrait ressembler à ça:
<?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>
<!-- **NEW STUFF** -->
<key>SessionCreate</key>
<true />
</dict>
</plist>
Avec cette configuration, je recommanderais également le plugin Xcode pour Jenkins , ce qui facilite un peu la configuration du script xcodebuild. À ce stade, je vous recommande également de lire les pages de manuel de xcodebuild - vous êtes arrivé jusqu'ici dans Terminal, non?
Cette configuration n'est pas parfaite et tout conseil ou aperçu est grandement apprécié.
J'ai eu du mal à choisir une réponse «correcte» car ce que j'ai fini par utiliser pour résoudre mon problème était une collection d'entrées de presque tout le monde. J'ai essayé de donner à tout le monde au moins une voix positive, mais attribuez la réponse à Simon parce qu'il a principalement répondu à la question initiale. De plus, Sami Tikka mérite beaucoup de crédit pour ses efforts pour que Jenkins fonctionne via AppleScript comme une application OS X simple. Si vous êtes seulement intéressé par la mise en service rapide de Jenkins dans votre session utilisateur (c'est-à-dire pas en tant que serveur sans tête), sa solution ressemble beaucoup plus à Mac.
J'espère que mes efforts susciteront de nouvelles discussions et aideront la prochaine pauvre âme qui arrivera en pensant pouvoir installer Jenkins CI pour ses projets iOS en un week-end à cause de toutes les choses merveilleuses dont elle a entendu parler.
Mise à jour: 9 août 2013
Avec tant de votes positifs et de favoris, j'ai pensé que j'y reviendrais 18 mois plus tard avec quelques brèves leçons apprises.
Leçon 1: N'exposez pas Jenkins à l'Internet public
Lors de la WWDC 2012, j'ai posé cette question aux ingénieurs de Xcode et OS X Server. J'ai reçu une cacophonie de "ne fais pas ça!" de quiconque j'ai demandé. Ils ont tous convenu qu'un processus de construction automatisé était excellent, mais que le serveur ne devrait être accessible que sur le réseau local. Les ingénieurs d'OS X Server ont suggéré d'autoriser l'accès à distance via VPN.
Leçon 2: Il existe maintenant de nouvelles options d'installation
J'ai récemment donné une conférence CocoaHeads sur mon expérience Jenkins, et à ma grande surprise, j'ai trouvé de nouvelles méthodes d'installation - Homebrew et même une version Bitnami Mac App Store . Celles-ci valent vraiment le détour. Jonathan Wright a une idée générale du fonctionnement de Homebrew Jenkins .
Leçon 3: Non, sérieusement, n'exposez pas votre boîte de construction à Internet
Il est assez clair d'après l'article original que je ne suis ni un administrateur système ni un expert en sécurité. Le bon sens concernant les trucs privés (porte-clés, informations d'identification, certificats, etc.) m'a laissé assez mal à l'aise pour mettre ma boîte Jenkins sur Internet. Nick Arnott de Neglected Potential a pu confirmer assez facilement mes heebie-jeebies dans cet article .
TL; DR
Ma recommandation aux autres qui cherchent à automatiser leur processus de construction a changé au cours de la dernière année et demie. Assurez-vous que votre machine Jenkins est derrière votre pare-feu. Installez et configurez Jenkins en tant qu'utilisateur Jenkins dédié soit en utilisant le programme d'installation, la version Bitnami Mac App Store, AppleScript de Sami Tikka, etc. cela résout la plupart des maux de tête que je détaille ci-dessus. Si vous avez besoin d'un accès à distance, la configuration des services VPN dans OS X Server prend dix minutes maximum. J'utilise cette configuration depuis plus d'un an et j'en suis très content. Bonne chance!