2026 — CI Mac exclusif : CocoaPods + SPM mélangés — caches, isolation concurrente et matrice xcodebuild SSH + FAQ
Sur un Mac CI distant exclusif, un projet qui combine CocoaPods et Swift Package Manager entraîne deux graphes de dépendances, deux familles de caches et des risques de contention disque dès que plusieurs jobs tournent en parallèle. Ce guide fixe les répertoires à sauvegarder, les règles d’isolation et une matrice de paramètres xcodebuild reproductible depuis une session SSH.
1. Pourquoi le mélange Pods + SPM n’est pas « un seul cache »
pod install matérialise des artefacts sous Pods/ et s’appuie sur des caches Rubygems/CocoaPods (souvent sous le répertoire utilisateur du compte CI). SPM, lui, résout et compile via le moteur de packages intégré à Xcode, avec des artefacts typiquement sous Derived Data et le cache utilisateur SPM (SourcePackages, checkouts, etc.). Un pipeline qui ne distingue pas ces couches purge parfois « le mauvais niveau » — build froid inutile — ou laisse plusieurs jobs écrire au même endroit — flakiness.
Pour cadrer d’abord l’orchestration (runner unique, files d’attente, montée en charge), croisez avec
CI iOS/macOS entreprise 2026 : GitLab Runner (macOS) et GitHub Actions en auto-hébergé, puis revenez ici pour aligner chemins Pods/SPM et -derivedDataPath.
2. Cartographie des répertoires (runbook 2026)
Tableau indicatif : adaptez les chemins à votre compte de service CI et à vos montages réseau.
| Couche | Emplacement typique | Ce qu’on met en cache CI |
|---|---|---|
| CocoaPods (projet) | Pods/, Podfile.lock |
Arborescence générée + lock ; invalider si le lock change |
| Caches CocoaPods | Caches gems / specs (souvent ~/.cocoapods, repo specs) |
Accélère pod install ; versionner avec la même version de CocoaPods |
| SPM (résolution) | Checkouts sous Derived Data ou dossier du workspace | Cache « packages » cohérent avec la résolution Xcode ; attention aux URLs Git et aux tags |
| Build Xcode | -derivedDataPath (recommandé explicite en CI) |
Modules Swift, index, produits ; ne pas partager naivement entre jobs concurrents |
3. Isolation concurrente sur un Mac exclusif
Même sur une machine « dédiée », le parallélisme réel se limite souvent par le disque et la thermique. Règles pragmatiques :
- Un job → un
-derivedDataPathdistinct (sous-dossier par build ID) pour éviter les courses sur les modules Swift. - Ne pas partager le même répertoire
Pods/entre deux checkouts concurrents du même dépôt sans mécanisme de verrou ; préférez des workspaces clonés séparés ou une file sérialisée pourpod install. - Plafonner le nombre de
xcodebuildsimultanés en fonction du SSD et de la RAM (les linkers SPM + ObjC peuvent picoter ensemble).
Pour relier durées de build observées et capacité machine, voir aussi Test de performance Xcode 2026 : combien de temps pour un build sur un Mac loué ?.
4. Matrice : paramètres xcodebuild et intention
| Paramètre / env | Rôle en CI mixte Pods/SPM | Note SSH |
|---|---|---|
-workspace + -scheme |
Cible stable pour pipelines ; évite les ambiguïtés multi-projets | Vérifier le chemin absolu depuis le job (pas de dépendance au GUI) |
-derivedDataPath |
Contrôle du cache de compilation ; à isoler par job | Surveiller df -h sur le volume choisi |
-clonedSourcePackagesDirPath (si utilisé) |
Ancre SPM à un dossier prévisible pour cache/backup | Aligner avec la politique de purge entre branches |
CODE_SIGNING_ALLOWED=NO (sélections de build) |
Accélère certaines cibles analyse/tests sans signature | Ne remplace pas une stratégie de signature pour archive store |
-resultBundlePath |
Artefact xcresult pour CI lisible en SSH et export hors machine | Éviter collisions de noms entre jobs parallèles |
5. FAQ — symptômes fréquents
Q : « pod install est rapide en local mais lent en CI. »
R : Vérifier cache specs/CocoaPods du compte utilisateur du runner, la version de Ruby/CocoaPods, et l’accès réseau aux specs ; en SSH, tracer aussi les proxies et DNS.
Q : « Résolution SPM change sans modification apparente du code. »
R : Verrouiller versions (tags/commit) dans le manifeste ; éviter branch flottante pour les dépendances critiques ; invalider le cache Derived/SPM lors d’un bump Xcode majeur.
Q : « Erreurs de modules Swift intermittents seulement avec plusieurs builds. »
R : Forte probabilité de Derived Data partagé ou disque saturé ; séparer les chemins et réduire le parallélisme.
Q : « Dois-je commiter le dossier Pods ? »
R : Choix d’équipe ; en CI, l’important est la reproductibilité (Podfile.lock + même toolchain) et des installs déterministes, pas l’opinion « dogmatique ».
6. Synthèse Ops
Documentez dans le dépôt : version CocoaPods, stratégie de cache (Pods vs SPM vs Derived), nombre max de jobs concurrents, et critères de purge. En incident, distinguer réseau specs, cache SPM et contention disque avant de changer de matériel.
Pourquoi macOS sur Mac mini aide cette stack
La combinaison Xcode, signatures Apple et outillage natif (SwiftPM, outils CLI) est pensée pour macOS ; un nœud physique Mac mini évite la dette d’émulation et simplifie les chemins de cache auditables. L’Apple Silicon offre une mémoire unifiée utile lors des pics de linkage ; le mini reste adapté au 24/7 avec une consommation au repos d’environ 4 W et un fonctionnement silencieux.
Côté sécurité, Gatekeeper, SIP et des options comme FileVault structurent la surface autour des clés et des runners. Sur le coût total, une machine dédiée et prévisible bat souvent un pool opaque pour stabiliser les SLA de build iOS.
Si vous voulez appliquer cette matrice sur un matériel homogène en 2026, le Mac mini M4 reste un point d’entrée très rationnel — découvrez les offres sur la page d’accueil.