Intégration continue iOS avec Xcode Server expliquée
Publié: 2022-03-11introduction
Avant Xcode 9, l'utilisation des outils d'intégration continue d'Apple était un processus fastidieux et complexe qui nécessitait l'achat et l'installation d'une application macOS Server supplémentaire. Cela a conduit de nombreux développeurs à abandonner l'idée d'une intégration continue pour leurs projets iOS ou à recourir à des solutions tierces, avec des niveaux de succès très variables.
Cependant, après la sortie de Xcode 9.0 en septembre 2017, le processus a été considérablement simplifié, y compris l'option de signature de code automatisée, et est maintenant complètement intégré à Xcode. Par conséquent, il ne nécessite aucune application ou outil supplémentaire.
Alors que des solutions tierces comme Fastlane, Bluepill, etc. sont d'une grande aide et peuvent faire beaucoup de travail pour vous, cet article explorera les capacités d'utilisation des outils Xcode et Apple seuls pour vos besoins d'intégration continue. Nous utiliserons également la signature de code manuelle car cela semble souvent être un problème pour beaucoup de gens, et la signature automatique a également tendance à ne pas être la solution optimale lorsqu'il s'agit de plusieurs configurations de construction.
Remarque : cet article est basé sur Xcode 9.4.1 et se concentre sur le développement d'applications iOS, mais une grande partie s'applique à Xcode 10 (actuellement disponible en tant que version bêta 5) et au développement d'applications macOS.
Configuration du serveur Xcode
En plus de simplifier le processus d'intégration proprement dit, Xcode 9 a également simplifié le processus de configuration du serveur Xcode.
Lancez l'application Xcode sur votre machine macOS qui a été désignée comme votre serveur CI et ouvrez les Préférences.
Accédez au dernier onglet, appelé Server & Bots .
Activez les fonctionnalités de Xcode Server en cliquant sur le commutateur dans le coin supérieur droit. Ensuite, il vous sera demandé de sélectionner un utilisateur pour exécuter et exécuter des scripts de construction sur cette machine. C'est probablement une bonne idée d'avoir un utilisateur dédié uniquement à cette fin, au lieu d'utiliser un utilisateur préexistant.
Notez que cet utilisateur doit être connecté au système pour que tout bot Xcode puisse s'exécuter. Une fois connecté, vous devriez voir un cercle vert à côté du nom d'utilisateur.
C'est ça! Examinons de plus près les bots Xcode.
Comment configurer les robots Xcode
Vous êtes maintenant prêt à commencer à configurer les bots Xcode pour qu'ils s'exécutent sur ce serveur. Cela peut être fait sur n'importe quelle machine de développement connectée au même réseau que le serveur.
Ouvrez Xcode sur votre ordinateur de développement et cliquez sur Xcode > Préférences dans le menu du haut. Ensuite, allez dans l'onglet Comptes et cliquez sur l'icône + dans le coin inférieur gauche. Sélectionnez Xcode Server dans la boîte de dialogue qui s'affiche.
Pour créer un bot, ouvrez simplement votre projet dans Xcode et choisissez l'option Produit > Créer un bot… dans le menu du haut. La configuration du bot comporte un certain nombre d'étapes et nous les explorerons dans les sections à venir.
Automatisation de la distribution des applications
L'une des applications les plus fréquentes de l'automatisation de la création d'applications iOS consiste à configurer un bot pour télécharger une application sur une plate-forme de distribution iOS telle que TestFlight, Fabric, etc.
Comme je l'ai expliqué précédemment, cet article n'explorera que le téléchargement sur App Store Connect et le téléchargement directement depuis votre serveur Xcode, car ce sont les outils natifs d'Apple pour la distribution d'applications iOS.
App Store Connect Distribution à l'aide de Xcode
Avant de configurer un bot, assurez-vous que vous disposez d'un enregistrement d'application App Store Connect qui correspond à l'ID de groupe de votre projet de développement d'application. Il convient également de noter que chaque build doit avoir un identifiant unique composé de la version de build et du numéro de build. Nous verrons comment nous assurer que ces conditions sont remplies lorsque nous discuterons plus tard des paramètres du bot Xcode.
Étape 1 : Configurer la bonne configuration de construction est l'étape cruciale pour obtenir ce que vous voulez. Assurez-vous de sélectionner le schéma et la configuration qui produisent l'application que vous souhaitez télécharger sur App Store Connect. Cela inclut de s'assurer que la configuration de construction utilise l'identifiant de bundle approprié qui est enregistré dans le portail Apple Developer de votre équipe (ceci est utilisé pour la signature de code) ainsi que dans votre portail App Store Connect (ceci est utilisé pour télécharger automatiquement l'application) .
Étape 2 : Toujours dans l'onglet "Configuration", nous devons spécifier les options d'exportation. Nous allons explorer la liste des propriétés des options d'exportation, alors assurez-vous que "Utiliser la liste des options d'exportation personnalisées" est sélectionné.
Étape 3 : Il est maintenant temps de créer notre liste de propriétés d'options d'exportation. Une liste complète des clés à utiliser dans ce fichier est disponible si vous entrez xcodebuild --help
, mais nous allons explorer celles utilisées dans cette configuration de bot ici :
-
compileBitcode
– Bitcode est le format de sortie provisoire d'Apple pour le code source de l'application. En d'autres termes, c'est le format dans lequel votre code source est converti avant d'être compilé en code machine pour une architecture spécifique. Il vise à disposer d'un seul conteneur de code qui puisse être encore optimisé si une optimisation est faite dans le jeu d'instructions, et aussi de pouvoir le compiler vers les futures architectures à partir de ce même format. Cependant, cela n'a aucun effet sur votre candidature. C'est à vous de décider si vous voulez l'activer ou non. -
method
– Cet argument spécifie le type de produit que vous exportez. Apple distingue les produits en fonction de leur public désigné : le développement ne vous permet de l'installer que sur les appareils spécifiés dans le profil d'approvisionnement, l'entreprise permet à tout le monde de l'installer, mais ils doivent explicitement faire confiance à ce profil de développement avant d'exécuter l'application, et l' app-store est pour en le distribuant sur l'App Store ou l'App Store Connect, nous allons donc utiliser cette valeur. -
provisioningProfiles
- Ceci est explicite. Mais il y a quelques points à noter ici : Les profils d'approvisionnement dans la liste des propriétés des options d'exportation sont un dictionnaire où une clé correspond à l'identifiant de bundle d'un produit et la valeur correspond au nom du profil d'approvisionnement utilisé pour le signer en code. -
signingCertificate
– Un autre argument qui s'explique de lui-même. La valeur de ce champ peut être un nom de certificat complet ou un hachage SHA-1. -
teamID
– Un autre argument explicite. Il s'agit de l'identifiant de 10 caractères qu'Apple a attribué à votre organisation lorsque vous vous êtes inscrit au programme Apple Developer. -
uploadBitcode
– Indique s'il faut ou non télécharger le bitcode (si vous avez choisi de le compiler) afin qu'il puisse être utilisé dans AppStore Connect pour générer de nouvelles versions optimisées ou des versions pour de futures architectures. -
uploadSymbols
– Télécharge vos symboles de débogage afin que vous puissiez obtenir un rapport de plantage significatif plutôt qu'un simple vidage de mémoire et une pile d'assemblage.
Alors maintenant, votre liste de propriétés d'options d'exportation pourrait ressembler à ceci :
<?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>compileBitcode</key> <false/> <key>method</key> <string>app-store</string> <key>provisioningProfiles</key> <dict> <key>com.bundle.id</key> <string>ProvisioningProfileName</string> </dict> <key>signingCertificate</key> <string>Signing Certificate Exact Name or SHA-1 hash value</string> <key>teamID</key> <string>??????????</string> <key>uploadBitcode</key> <false/> <key>uploadSymbols</key> <true/> </dict> </plist>
Étape 4 : Choisissez le .plist que vous avez créé comme liste de propriétés des options d'exportation.
Étape 5 : La prochaine étape est l'onglet "Planification" - configurez-le selon vos préférences.
Étape 6 : Dans l'onglet Signature, assurez-vous de décocher l'option « Autoriser le serveur Xcode à gérer mes certificats et mes profils » et de télécharger vous-même un certificat de signature et un profil d'approvisionnement correspondants, sur la page Certificats et profils .
Étape 7 : L'onglet Appareils doit rester tel quel, car nous téléchargeons l'application plutôt que de la tester.
Étape 8 : L'onglet Arguments vous permet de définir explicitement des arguments xcodebuild ou des variables d'environnement pouvant être utilisés dans vos scripts de génération ou de pré-intégration et de post-intégration.
Étape 9 : Enfin, nous atteignons l'onglet Triggers , qui est également le dernier onglet de la configuration du bot d'intégration continue Xcode. C'est l'outil le plus puissant de l'arsenal Xcode Server. Pour commencer, j'aime ajouter les deux commandes suivantes en tant que script de pré-intégration :
#!/bin/sh set printenv
Le premier imprime toutes les variables utilisées par Xcode Server et leurs valeurs dans l'exécution d'intégration en cours. Le second imprime toutes les variables d'environnement et leurs valeurs. Comme prévu, cela peut être utile pour déboguer vos scripts, donc je l'appelle à juste titre "informations de débogage".

N'oubliez pas que nous avons mentionné que nous devons nous assurer que chaque version téléchargée sur App Store Connect doit avoir une version de version et une paire de numéros de version uniques. Nous pouvons utiliser l'outil PlistBuddy intégré, mais nous avons également besoin d'un moyen d'avoir un numéro de build unique. Une chose qui est toujours présente lors de l'intégration de Xcode Server - et qui est également unique - est le numéro d'intégration, car il est automatiquement incrémenté. Nous allons créer un autre script de pré-intégration, nommé "set build number" avec le contenu suivant pour nous assurer que nous avons un numéro de build unique à chaque fois :
#!/bin/sh buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") buildNumber=$XCS_INTEGRATION_NUMBER /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
Si vous utilisez CocoaPods et que vous avez choisi de ne pas valider le répertoire Pods dans votre DVCS, vous devez également inclure un script de pré-intégration avec le contenu suivant :
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install
Étape 10 : Nous avons presque terminé, mais nous n'avons spécifié nulle part que nous souhaitons télécharger la version sur AppStore Connect ou sur quel compte. À cette fin, nous ajouterons un script de post-intégration et un autre outil intégré, appelé Application Loader. Mettez ce qui suit dans le script :
#!/bin/sh /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --upload-app -f $XCS_PRODUCT -u $TESTFLIGHT_USERNAME -p $TESTFLIGHT_PASSWORD
Le $XCS_PRODUCT
est une variable Xcode Server et il contient le chemin d'accès à l'application qui a été créée dans l'exécution d'intégration en cours. Cependant, $TESTFLIGHT_USERNAME
et $TESTFLIGHT_PASSWORD
ne sont ni des variables système ni Xcode Server. Ceux-ci doivent être configurés par vous et avoir la valeur de votre identifiant Apple et de votre mot de passe. Malheureusement, Apple a interrompu la prise en charge de la génération d'une clé API pour le téléchargement de builds AppStore Connect. Comme il s'agit d'informations confidentielles, il est recommandé de les configurer directement sur le serveur Mac (en supposant qu'il s'agit du vôtre) en tant que variable d'environnement plutôt que dans la configuration du bot Xcode Server.
Distribution du serveur Xcode
Le bot de distribution Xcode Server utilise en fait la même configuration que celle de la distribution App Store Connect, à l'exception des scripts de post-intégration. Cependant, le téléchargement de l'application et son installation peuvent toujours être délicats. Vous devez toujours vous assurer que le profil d'approvisionnement avec lequel vous avez signé votre application permet à l'application d'être installée sur l'appareil que vous utilisez.
Une fois cela en place, vous devrez ouvrir Safari sur votre appareil iOS et accéder au tableau de bord Web Xcode Server de votre serveur. Par exemple, si le nom de votre serveur est "serveur Mac", vous pouvez le trouver sur "nom-serveur-mac.local/xcode" si vous êtes sur le même réseau que le serveur. Vous y trouverez une liste de tous vos bots Xcode et les statistiques de leurs intégrations les plus récentes.
Sélectionnez celui qui a créé l'application que vous souhaitez télécharger. Sur l'écran suivant, vous aurez deux boutons— Installer et Profil . S'il s'agit de votre premier téléchargement à partir de ce serveur, vous devez cliquer sur Profil pour ajouter son certificat à la liste des sources fiables. Ensuite, cliquez sur le bouton Installer sur la même page et vous serez accueilli par la boîte de dialogue de confirmation iOS « Êtes-vous sûr de vouloir installer * sur votre appareil ? » Confirmez-le en cliquant sur Oui et votre application sera installée et exécutable depuis l'écran d'accueil.
Pour iOS 10.3 et versions ultérieures , une raison pour laquelle il peut échouer avec "Impossible de se connecter à * .local" est que le certificat auto-signé doit être approuvé manuellement dans les paramètres de l'appareil de test.
Suivez ces étapes:
Étape 1 : Installez le(s) certificat(s) auto-signé(s) à partir de la page des bots du serveur Xcode sur votre iPhone.
Étape 2 : Accédez aux paramètres de l'iPhone > Général > À propos > Paramètres de confiance du certificat .
Étape 3 : Recherchez le ou les certificats auto-signés de votre serveur dans la section ACTIVER LA CONFIANCE TOTALE POUR LES CERTIFICATS RACINES et activez le commutateur.
Étape 4 : Revenez à la page d'intégration du bot sur Xcode Server, cliquez sur Installer .
Test automatique de l'application Xcode Server
Une autre grande utilisation de Xcode Server est le test automatique des applications, qu'il s'agisse de tests unitaires ou d'interface utilisateur. Pour ce faire, vous devez avoir la cible appropriée configurée pour votre projet. Autrement dit, vous devez disposer d'une cible qui exécute des tests unitaires ou d'interface utilisateur, en fonction de votre objectif.
Le processus de configuration est le même que le précédent, mais nous sélectionnerons différentes options. La première différence majeure se trouve dans l'onglet Configuration . Évidemment, nous allons cocher les cases « Analyser » et « Tester » puisque c'est notre objectif principal. Je conseillerais également de ne pas archiver ni exporter le produit avec ce bot. Il est possible de réaliser à la fois les tests et la distribution avec la même configuration de bot. Cependant, ces deux scénarios diffèrent dans leur sortie ainsi que dans leur calendrier. La distribution est souvent effectuée en fin de cycle.
Que vous travailliez dans Scrum ou Kanban ou dans un autre cadre, il devrait y avoir un cycle prédéfini piloté par le temps ou par les événements à la fin duquel vous devriez avoir un produit exporté et utilisable. D'autre part, vous devez exécuter votre bot de test à chaque commit, car c'est votre première ligne de défense contre les régressions. Étant donné que le bot de test est évidemment exécuté plus souvent, la fusion de ces deux bots en un seul pourrait rapidement utiliser l'espace disque sur votre serveur. Et cela prendrait également plus de temps à chaque intégration.
Avec cela à l'écart, nous passons à l'onglet "Planification", et nous en avons déjà parlé dans le paragraphe précédent. Ainsi, le prochain sujet d'intérêt est la signature de code. Notez que, même si votre cible de test peut indiquer qu'elle n'a pas besoin de profil d'approvisionnement dans la page des paramètres de votre projet, vous devez la configurer pour utiliser la même équipe et le même certificat de signature que l'application hôte. Ceci est nécessaire si vous souhaitez tester votre application sur un appareil iOS plutôt que simplement sur un simulateur. Si tel est votre cas, vous devez également vous assurer que l'appareil iOS utilisé pour les tests ne sera pas verrouillé en raison d'une inactivité, car cela pourrait entraîner le blocage indéfini de votre exécution d'intégration sans vous en informer.
Nous sommes maintenant sur l'onglet "Périphériques" qui ne nécessite aucune explication spécifique. Sélectionnez simplement un, plusieurs ou tous les appareils (iOS et simulateur) sur lesquels vous souhaitez tester votre code. Vous pouvez également vérifier s'il faut exécuter des tests sur plusieurs appareils en parallèle ou séquentiellement. Pour configurer cela, vous devez tenir compte des besoins de votre projet (que vous cibliez un ensemble spécifique d'appareils ou tous les appareils iOS pris en charge) ainsi que les ressources matérielles du serveur.
Dans l'onglet Arguments . il n'est pas nécessaire de spécifier quoi que ce soit explicitement, car nous n'utiliserons que des variables d'environnement intégrées.
Enfin, dans l'onglet Déclencheurs , nous présenterons un script de pré-intégration et un script de post-intégration. Le premier est juste là pour nous aider à déboguer au cas où nous rencontrions des problèmes. C'est en fait celui que nous avons déjà utilisé :
#!/bin/sh set printenv
Le second est celui qui nous avertira en cas d'échec d'un ou plusieurs de nos tests dans l'intégration en cours. Assurez-vous qu'il est configuré pour s'exécuter uniquement sur les échecs de test. Et entrez ce qui suit :
#!/bin/sh echo "$XCS_TEST_FAILURE_COUNT test(s) failed for $XCS_BOT_NAME bot on build $XCS_INTEGRATION_NUMBER" echo "You can see bot integration at:" echo "https://$HOSTNAME/xcode/bots/$XCS_BOT_TINY_ID/integrations/$XCS_INTEGRATION_TINY_ID"
Il y a quelques choses qui devraient être expliquées ici. Tout d'abord, les variables $HOSTNAME stockent la valeur au format suivant : nom-ordinateur.local. Évidemment, le lien ne fonctionnera que si vous pouvez atteindre ce serveur via le réseau local. De plus, vous recevrez très probablement un avertissement de sécurité de votre navigateur lorsque vous visiterez ce lien, car il s'agit d'une connexion https vers une destination qui n'est pas fiable. Enfin, ce n'est qu'un point de départ pour votre script "Echec du test". Vous pouvez envoyer un e-mail à toute l'équipe de développement, ou ouvrir un problème JIRA via une requête API ou toute autre chose que vous jugez la plus appropriée et la plus productive.
Emballer
J'espère que cet article vous a encouragé à prendre votre temps pour explorer les fonctionnalités de Xcode Server en dehors de la simple création d'une application. Bien que cet article ne vous ait peut-être pas aidé exactement comme vous le souhaitiez ou l'attendiez, l'objectif était de vous présenter une manière ouverte d'utiliser les environnements intégrés et les variables Xcode Server pour atteindre un niveau d'automatisation plus élevé.
Il existe de nombreux services tiers qui permettent plus de fonctionnalités et peuvent faire beaucoup plus de travail pour vous, notamment Fabric, Bluepill et Fastlane. Mais, inévitablement, s'appuyer sur un tiers introduit une nouvelle dépendance à votre projet et nécessite une installation et une configuration parfois simples, parfois complexes. Les techniques décrites ici ne nécessitent que des outils déjà installés sur chaque Mac, elles ne nécessitent donc aucun temps d'installation en plus de la configuration des bots qui exécuteront vos builds automatisés !