Un seul fichier de verrouillage, Podfile.lock, permet de conserver les versions de dépendances résolues entre les installations ; la documentation CocoaPods distingue explicitement son rôle de celui de pod update (explication officielle de pod install et pod update). Pour un échec d’installation de CocoaPods sur un Mac CI distant, vérifiez d’abord quel Ruby, quel Bundler et quel exécutable pod le Runner utilise. Ensuite, isolez la panne entre sources Specs, accès privé, verrouillage et téléchargement des dépendances. Gardez le verrouillage en place pour reproduire le problème avant de modifier ou nettoyer quoi que ce soit.
Cet article s’adresse aux équipes qui maintiennent une chaîne d’intégration continue macOS et doivent comprendre l’écart entre leur poste de travail et le Runner.
Il concerne aussi les équipes utilisant des Pods privés, qui doivent vérifier les accès du compte CI sans exposer de secrets.
Enfin, il aide les responsables de build à valider une correction sur le même commit et avec les mêmes versions verrouillées.
Distinguer l’environnement local du processus CI
Un pod install réussi localement ne prouve pas que le Runner exécute les mêmes outils. Une session interactive peut charger un fichier de configuration du shell ou compléter le PATH, alors que le processus CI utilise un shell non interactif, un autre compte et un répertoire de travail différent. La comparaison doit porter sur les commandes effectivement exécutées par le travail automatisé, pas sur une session ouverte manuellement sur la machine.
Commencez par récupérer, dans le journal du Runner, la commande complète et le répertoire de travail au moment de l’échec. Notez le compte qui exécute le processus, puis relevez les chemins et versions de ruby, gem, bundle et pod. which ruby et which pod montrent quels exécutables sont trouvés dans le PATH courant ; ruby -v, gem env et pod env donnent des éléments complémentaires sur l’environnement utilisé. La référence officielle des commandes CocoaPods décrit les commandes disponibles et leur usage.
Comparez ensuite ces informations avec celles du poste où l’installation fonctionne. Un écart de chemin vers Ruby peut expliquer qu’un pod global soit lancé au lieu de celui prévu par le projet. Un mauvais répertoire peut, lui, faire ignorer le Podfile ou le Podfile.lock attendus. Si la commande ne démarre même pas, cherchez d’abord un problème d’exécutable, de chargement du shell ou de droits d’exécution : les journaux de résolution des Pods ne sont pas encore pertinents.
Fixer Ruby et Bundler plutôt que corriger le mauvais exécutable
Une chaîne CI devient difficile à reproduire lorsque la dépendance à CocoaPods n’est installée qu’au niveau global du Runner. Chaque projet peut avoir ses propres dépendances Ruby et ses propres contraintes ; une installation globale ne garantit pas qu’un processus automatisé utilise la version attendue. La documentation CocoaPods sur Gemfile et Bundler explique comment déclarer les gems du projet et exécuter les commandes dans cet environnement.
Vérifiez si le dépôt contient un Gemfile et un Gemfile.lock. Si c’est le cas, assurez-vous que le CI les utilise depuis le bon répertoire et installe les gems déclarées avant d’appeler CocoaPods. La commande de travail devrait alors prendre la forme bundle exec pod install, afin que Bundler fournisse le contexte Ruby prévu pour le projet. Si la chaîne lance seulement pod install, elle peut sélectionner un autre exécutable via le PATH, même si la bonne version de CocoaPods est installée ailleurs.
Procédez sans masquer les preuves :
- relevez
which ruby,ruby -v,which bundle,bundle -vetwhich poddans le travail CI ; - vérifiez la présence de
Gemfileet deGemfile.lockdans le répertoire réellement utilisé ; - comparez la commande du Runner à celle qui réussit localement ;
- conservez les journaux de résolution, sans y imprimer de variables contenant des secrets ;
- après correction, relancez l’installation avec l’environnement du projet, plutôt qu’avec un
podglobal choisi implicitement.
Le dépôt CocoaPods indique que le projet est en mode maintenance ; cette information ne signifie pas qu’une panne donnée soit inévitable ou que toutes les erreurs proviennent de l’outil. Elle invite plutôt à établir un diagnostic à partir de la configuration et des journaux observés (état du dépôt officiel CocoaPods). N’attribuez donc pas un échec au statut général du projet sans avoir identifié l’étape précise qui échoue.
Séparer les erreurs de Specs des problèmes de réseau
La formule « Pod introuvable » ne suffit pas à conclure que le CDN est indisponible. La panne peut survenir pendant la résolution des spécifications, lors d’une requête HTTP, pendant la négociation TLS ou au moment de télécharger le code source. Ces causes appellent des vérifications différentes. La documentation décrit la configuration des sources et la syntaxe du Podfile ; confrontez-la aux sources effectivement déclarées dans le dépôt.
Repérez dans le journal la première erreur, puis classez-la selon l’opération interrompue. Un problème de connexion ou de certificat appelle un contrôle réseau depuis le Runner. Une réponse HTTP doit être lue avec son contexte, sans la réduire à « le CDN ne marche pas ». Un nom de Pod ou une version non résolue impose de vérifier le Podfile, les sources configurées et les contraintes de version. Quand l’erreur mentionne un dépôt Specs, comparez les sources attendues par le projet à celles disponibles dans l’environnement CI.
La vérification doit être réalisée depuis le Runner et sous le compte qui exécute le travail. Une connexion réussie depuis votre poste n’établit pas que le processus CI a le même accès réseau, le même magasin de certificats ou la même configuration proxy. De même, une défaillance isolée ne justifie pas le remplacement immédiat d’une source amont : une telle modification peut changer le comportement de résolution sans traiter la cause. La documentation officielle de dépannage CocoaPods peut compléter l’examen, mais les journaux de la tentative concernée restent la preuve de ce qui s’est passé dans votre environnement.
Une erreur TLS, une réponse HTTP et une spécification absente sont des indices différents. Gardez la première erreur complète et son contexte ; ne partagez jamais dans un ticket les en-têtes ou paramètres qui contiennent des identifiants.
Vérifier séparément la source et les droits des Pods privés
Pour une dépendance privée, la présence d’une référence dans le Podfile ne garantit ni que le Runner connaisse la source Specs correspondante, ni que son compte puisse lire le dépôt du code. Traitez ces deux vérifications séparément. La documentation CocoaPods sur les Pods privés décrit le modèle des sources privées et les éléments à configurer.
Commencez par confirmer la source attendue dans le Podfile et dans la configuration effective de l’environnement CocoaPods. Ensuite, vérifiez l’accès en lecture au dépôt de spécifications privé, puis au dépôt qui héberge le code du Pod. Une installation peut résoudre la spécification et échouer seulement plus tard au téléchargement du code : un résultat positif pour la première étape ne valide donc pas la seconde.
Effectuez les contrôles sous l’identité du travail automatisé. Une authentification réussie dans le terminal d’un administrateur ne démontre pas que le compte CI possède les mêmes droits. Si les identifiants sont injectés par des variables ou un mécanisme de secrets, vérifiez leur présence et leur portée sans afficher leur valeur. Utilisez des formes masquées comme <IDENTIFIANT_CI> ou <URL_DEPOT_PRIVE> dans les scripts d’exemple et les tickets. En cas d’échec, la trace doit permettre de distinguer l’absence d’identifiants, un refus d’accès et une adresse de dépôt incorrecte sans divulguer de secret.
Préserver Podfile.lock avant toute mise à jour
pod install et pod update n’ont pas la même intention. Lorsqu’un Podfile.lock est présent et utilisé dans le bon répertoire, pod install sert à installer les dépendances du projet en respectant les versions déjà verrouillées. pod update cherche au contraire à mettre à jour les dépendances concernées, ce qui peut modifier le résultat et rendre la comparaison avec le build initial moins utile. La documentation officielle détaille cette différence dans son guide consacré à pod install et pod update.
Vérifiez que Podfile.lock est bien suivi par le système de gestion de versions, que le Runner a récupéré le commit attendu et que la commande part du répertoire contenant les fichiers du projet. Examinez également les scripts d’installation : une option ou une commande distincte peut conduire le CI à ne pas suivre le verrouillage attendu. Comparez le Podfile.lock du poste local avec celui présent dans l’espace de travail CI, sans régénérer le fichier pour « faire disparaître » une différence.
Si une mise à jour de dépendances est nécessaire, traitez-la comme une modification explicite du projet : créez un changement séparé, examinez le diff du fichier de verrouillage et validez le build avec ce nouvel état. Ne faites pas de pod update la réparation réflexe d’un échec d’installation. Cela pourrait modifier les versions utilisées sans résoudre un défaut d’accès réseau, de compte ou d’environnement Ruby.
Comparer les symptômes et choisir le prochain contrôle
Le tableau ci-dessous relie le point d’échec au contrôle suivant. Il sert à choisir une vérification discriminante, et non à attribuer une cause certaine à un message isolé.
| Symptôme observé dans le Runner | Contrôle prioritaire | Élément de preuve à conserver |
|---|---|---|
pod introuvable ou commande Ruby indisponible |
Examiner le compte, le PATH, les chemins Ruby et le répertoire de travail |
Chemins des exécutables et versions relevés dans le même travail CI |
| Résolution des Specs interrompue | Comparer le Podfile et les sources CocoaPods effectives | Première erreur complète et source concernée |
| Erreur HTTP, TLS ou connexion | Vérifier l’accès réseau depuis le Runner et son compte d’exécution | Résultat du contrôle réseau sans identifiants sensibles |
| Pod privé résolu, mais code non téléchargé | Contrôler l’accès au dépôt Specs puis au dépôt du code | Identité utilisée et résultat de chaque contrôle d’accès |
| Versions différentes de celles attendues | Vérifier le commit, le répertoire et l’emploi de Podfile.lock |
Diff du fichier de verrouillage et commande exécutée |
| Installation terminée, build Xcode en échec | Séparer la génération et l’intégration des Pods de la compilation | Fin de l’installation CocoaPods et première erreur Xcode |
À chaque reprise, conservez le même commit et le même état de verrouillage. Changez une seule cause candidate à la fois ; si l’environnement est modifié simultanément avec le fichier de dépendances, vous ne saurez pas quelle intervention a résolu le problème. L’objectif est de confirmer l’étape qui échoue, puis de faire réussir une nouvelle exécution avec des preuves comparables.
Valider l’installation avant d’attribuer l’échec à Xcode
Une commande CocoaPods qui se termine correctement ne garantit pas encore que la compilation Xcode réussira. Inversement, un message d’erreur Xcode ne démontre pas que l’installation des dépendances a échoué. Vérifiez séparément que les dépendances ont été obtenues, que le projet Pods a été généré et que l’intégration attendue est présente dans l’espace de travail du projet. Consultez la référence officielle des commandes CocoaPods pour interpréter la commande et son résultat, puis passez aux journaux de compilation.
Pour la validation, relancez le même commit sur le Runner après la correction, avec le même Podfile.lock et la même commande d’installation. Consignez le compte exécutant, le répertoire de travail, la commande, les versions Ruby/Bundler/CocoaPods et la première erreur éventuelle. Si l’installation passe mais que Xcode échoue, repartez du premier message pertinent de la phase de build ; ne reconstruisez pas le Runner avant d’avoir vérifié la configuration du projet et l’intégration générée.
Utilisez cette liste avant de déclarer l’incident résolu :
- [ ] La commande CocoaPods et son répertoire de travail correspondent au dépôt et au commit examinés.
- [ ] Les chemins et versions de Ruby, Bundler et CocoaPods ont été relevés dans le processus CI.
- [ ] Le
Gemfile, leGemfile.locket lePodfile.lockattendus sont présents et utilisés. - [ ] Les sources Specs et l’accès aux dépôts privés ont été contrôlés sous le compte CI.
- [ ] Les secrets restent masqués dans les journaux, les extraits de commande et les tickets.
- [ ] Une nouvelle exécution sur le même commit confirme l’installation et, séparément, le résultat de la compilation Xcode.
Choisir une remédiation selon la preuve disponible
Les deux tableaux suivants aident à éviter les corrections qui changent trop de variables à la fois. Prenez comme critère la preuve recueillie dans le Runner, et non une supposition fondée sur le poste local.
| Preuve observée | Action adaptée | À éviter |
|---|---|---|
Le Runner sélectionne un autre Ruby ou un autre pod |
Stabiliser l’environnement du projet avec Bundler et vérifier la commande lancée | Modifier les dépendances avant d’avoir corrigé l’appel d’outil |
| Le compte CI ne lit pas un dépôt privé | Corriger la portée des identifiants ou les droits du compte | Réafficher les secrets dans la trace pour « voir s’ils sont bons » |
| Une source Specs ou une connexion échoue | Tester l’accès depuis le Runner et examiner la configuration de source | Déclarer le CDN indisponible sur la base d’un seul échec |
| Le verrouillage attendu n’est pas utilisé | Corriger le checkout, le répertoire ou la commande | Lancer pod update pour contourner la différence |
| CocoaPods finit, mais Xcode échoue ensuite | Diagnostiquer la phase Xcode avec les journaux de compilation | Traiter l’erreur de compilation comme un échec de téléchargement |
| État recherché | Commande ou fichier à examiner | Résultat à consigner |
|---|---|---|
| Ruby et Bundler identifiés | ruby -v, which ruby, bundle -v, which bundle |
Versions et chemins vus par le travail CI |
| CocoaPods appelé depuis le contexte prévu | which pod, puis bundle exec pod install si le projet utilise Bundler |
Commande réellement lancée et résultat de l’installation |
| Dépendances préservées | Podfile.lock et historique du commit |
Identité du fichier utilisé et éventuelles différences |
| Sources et accès vérifiés | Podfile, configuration CocoaPods, compte du Runner | Source attendue et contrôles de lecture, sans secret |
| Compilation vérifiée séparément | Journaux de génération des Pods et journaux Xcode | Dernière étape réussie et première erreur de build |
Cette méthode limite les faux correctifs : changer de source peut modifier la résolution, vider des caches peut effacer des indices et mettre à jour les Pods peut changer l’ensemble des versions testées. Ces actions peuvent être justifiées après diagnostic, mais elles ne remplacent pas une reproduction contrôlée.
FAQ sur les échecs CocoaPods en CI
Pourquoi pod install passe-t-il en local mais échoue sur le Mac du CI ?
Le poste local et le Runner peuvent appeler des installations Ruby différentes, charger des PATH distincts ou s’exécuter sous des comptes différents. Comparez la commande exacte, le répertoire de travail, l’identité du processus et les premières lignes utiles du journal. Si ces éléments concordent, poursuivez vers l’accès aux Specs, aux dépôts privés et aux sources des dépendances.
Comment le Runner peut-il utiliser la bonne version de Ruby et de pod ?
Vérifiez le chemin renvoyé par which ruby, which bundle et which pod, puis comparez les versions et l’environnement du processus CI avec votre poste. Si le dépôt contient un Gemfile et son fichier de verrouillage, installez les dépendances Ruby du projet et lancez CocoaPods avec bundle exec pod install, plutôt qu’avec un exécutable global choisi par le PATH.
Comment distinguer une panne CDN CocoaPods d’une erreur de configuration des sources ?
Lisez l’étape qui échoue au lieu de déduire la cause du seul message final. Une erreur de résolution de nom, un refus HTTP, un échec TLS et un Pod introuvable ne désignent pas le même problème. Vérifiez la source déclarée dans le Podfile et les traces réseau disponibles depuis le Runner, puis reproduisez l’accès avant de modifier la configuration.
Quels accès contrôler quand un Pod privé est introuvable en CI ?
Confirmez que la source Specs privée attendue est déclarée et que le compte exécutant le travail peut lire à la fois le dépôt de spécifications et le dépôt du code source. Vérifiez le mécanisme d’injection des identifiants et leur portée sans imprimer de secret dans les journaux. Testez l’accès sous l’identité du processus CI, pas seulement depuis une session interactive.
Si le diagnostic confirme que le projet et ses dépendances sont correctement configurés, mais que l’équipe ne dispose pas d’un environnement macOS stable pour reproduire et exécuter la chaîne, un Mac distant peut compléter le CI existant. Un Runner Linux ne remplace pas les outils de build propres à macOS ; un poste local dépend, lui, de sa disponibilité et de son environnement. Pour un besoin temporaire de validation ou de build, examinez les modalités d’accès à un Mac distant et évaluez-les selon le cycle de votre projet, les exigences de votre chaîne et la durée d’utilisation. Si un équipement Mac dédié correspond mieux à une utilisation continue, consultez également les options Mac mini disponibles avant de choisir entre location et achat.