Lorsqu’une équipe extrait son projet sur un Mac dans le cloud, le problème le plus souvent sous-estimé n’est pas une erreur de compilation. Il arrive plutôt que le pipeline ne trouve pas le schéma attendu, ou qu’un schéma portant le même nom exécute des cibles différentes dans l’environnement distant. Xcode en local lit les réglages utilisateur du répertoire du développeur, tandis qu’un espace de travail CI vierge ne connaît que les fichiers présents dans le dépôt. Pour garantir un point d’entrée de build stable, le schéma doit être versionné et validé au même titre que les scripts et les fichiers de verrouillage des dépendances.
Traiter d’abord le schéma comme une interface CI
Un schéma destiné à être appelé par un pipeline définit au minimum quatre éléments : les Target à compiler, la Build Configuration à utiliser, les Test Bundle à exécuter et la configuration appliquée lors de l’Archive. Le simple fait que son nom apparaisse dans les menus de Xcode ne garantit pas que ces informations ont été ajoutées au dépôt.
Commencez par vérifier la présence d’un fichier partagé :
find . \( -path "*/xcshareddata/xcschemes/*.xcscheme" \
-o -path "*/xcuserdata/*/xcschemes/*.xcscheme" \) -print
Un schéma situé dans xcuserdata relève de la configuration utilisateur et ne peut pas servir de point d’entrée CI. Activez Shared dans Manage Schemes sous Xcode, puis vérifiez que le fichier apparaît dans l’un des emplacements suivants :
App.xcodeproj/xcshareddata/xcschemes/App.xcscheme
App.xcworkspace/xcshareddata/xcschemes/App.xcscheme
Utilisez ensuite git status et git check-ignore -v pour confirmer que le fichier est suivi et qu’il n’est pas exclu par erreur à cause d’une règle trop large visant *.xcuser* ou xcshareddata.
« Visible en local » signifie seulement que la configuration existe dans le répertoire de l’utilisateur actuel. Pour être « utilisable par la CI », elle doit être confirmée par le résultat d’une commande exécutée depuis une extraction propre.
Fixer le Workspace, le Scheme et la configuration
Le pipeline ne doit pas laisser Xcode choisir automatiquement le projet. En présence de CocoaPods, d’un projet agrégé ou d’un Package local, ouvrir le fichier .xcodeproj ou le fichier .xcworkspace peut produire des résultats différents. Déclarez explicitement les trois valeurs d’entrée dans les variables de CI :
WORKSPACE="App.xcworkspace"
SCHEME="App"
CONFIGURATION="Release"
xcodebuild \
-workspace "$WORKSPACE" \
-scheme "$SCHEME" \
-configuration "$CONFIGURATION" \
-list
La sortie de -list doit contenir le schéma attendu. Effectuez ensuite une vérification automatisée à partir de la sortie JSON, plutôt que de vous fier uniquement à une lecture manuelle des journaux :
xcodebuild -workspace "$WORKSPACE" -list -json > xcode-list.json
python3 - <<'PY'
import json
data = json.load(open("xcode-list.json"))
schemes = data.get("workspace", {}).get("schemes", [])
if "App" not in schemes:
raise SystemExit("Required Xcode scheme is missing")
PY
Si le dépôt conserve des points d’entrée distincts pour le développement, la préproduction et la production, leur nom doit indiquer leur usage, par exemple App-Dev, App-Staging et App-Release. Ne demandez pas au script de sélectionner le premier schéma de la liste : l’ajout d’une dépendance peut en modifier l’ordre.
Valider séparément Build, Test et Archive
Le partage du schéma résout uniquement le problème de visibilité ; il ne prouve pas encore que ses actions sont correctes. Il est recommandé d’organiser la validation en trois niveaux.
Examiner les réglages de build résolus
Exportez d’abord les réglages finaux, puis vérifiez en priorité PRODUCT_BUNDLE_IDENTIFIER, CONFIGURATION, SDKROOT, SUPPORTED_PLATFORMS et le répertoire de sortie :
xcodebuild \
-workspace "$WORKSPACE" \
-scheme "$SCHEME" \
-configuration "$CONFIGURATION" \
-showBuildSettings > build-settings.txt
grep -E "PRODUCT_BUNDLE_IDENTIFIER|CONFIGURATION =|SDKROOT|SUPPORTED_PLATFORMS" \
build-settings.txt
Ces valeurs correspondent au résultat obtenu après fusion du schéma, de la configuration du projet et des paramètres de ligne de commande. Elles reflètent donc mieux l’exécution réelle qu’une inspection directe de project.pbxproj.
Valider le point d’entrée des tests
Lors de la phase de test, commencez par compiler les artefacts testables avant d’exécuter les tests. Cela permet de distinguer un point d’entrée de compilation défectueux d’un échec survenu pendant l’exécution des tests :
xcodebuild \
-workspace "$WORKSPACE" \
-scheme "$SCHEME" \
-destination "platform=iOS Simulator,name=iPhone 16" \
build-for-testing
Le nom du simulateur doit provenir de la sortie de xcrun simctl list devices available sur la machine concernée. Ne codez pas en dur un appareil disponible uniquement sur l’ordinateur personnel d’un développeur. Si l’équipe doit imposer un runtime précis, consignez également la version de Xcode et la version du système d’exploitation cible.
Vérifier séparément l’action d’archivage
Archive peut utiliser une configuration différente de Run et Test. Vérifiez d’abord la configuration d’ArchiveAction dans le fichier .xcscheme, puis lancez un véritable archivage dans une tâche contrôlée :
xcodebuild \
-workspace "$WORKSPACE" \
-scheme "$SCHEME" \
-configuration Release \
-destination "generic/platform=iOS" \
-archivePath "$PWD/artifacts/App.xcarchive" \
archive
Ne considérez pas la réussite d’un simple build comme une validation de l’Archive. Le traitement des ressources, les phases de script et les réglages d’archivage ne révèlent souvent leurs problèmes qu’à cette étape.
Supprimer l’état local avant une seconde validation
La vérification la plus fiable ne consiste pas à supprimer DerivedData, mais à cloner de nouveau le dépôt dans un autre répertoire. Cette méthode met simultanément en évidence les schémas non validés, les liens symboliques locaux, les configurations non suivies et les dépendances implicites :
ROOT="$(mktemp -d)"
git clone --no-local . "$ROOT/repo"
cd "$ROOT/repo"
git submodule update --init --recursive
xcodebuild -workspace App.xcworkspace -scheme App -list
Si le projet dépend d’une étape de génération, placez la commande correspondante avant le build et vérifiez que son résultat est reproductible. N’indiquez pas dans la procédure qu’il faut « ouvrir une première fois le projet dans Xcode » : une telle étape ne peut pas être automatisée sans surveillance et masque les fichiers manquants.
La validation en environnement propre doit au minimum couvrir les points suivants :
| Élément vérifié | Critère de réussite |
|---|---|
| Visibilité du schéma | xcodebuild -list -json renvoie le nom spécifié |
| Emplacement du fichier | Le schéma se trouve dans xcshareddata et est suivi par Git |
| Configuration de build | Les valeurs résolues en ligne de commande correspondent aux attentes du pipeline |
| Point d’entrée des tests | build-for-testing produit les artefacts de test |
| Point d’entrée de l’archivage | Une cible iOS générique permet de produire un fichier .xcarchive |
| Exécution non interactive | Il n’est pas nécessaire d’ouvrir Xcode ni de lire un répertoire utilisateur |
Bloquer la dérive des points d’entrée avant la fusion
Un schéma est un fichier XML. Ses conflits de fusion sont souvent traités comme de simples conflits de texte, au risque de conserver son nom tout en supprimant un Testable ou un BuildActionEntry. Ajoutez une vérification légère aux demandes de fusion : confirmez la présence du fichier partagé, interdisez l’ajout de xcuserdata et exécutez xcodebuild -list -json.
Examinez également les Pre-actions et Post-actions du schéma. Si un script fait référence à un chemin absolu, à une configuration Shell interactive ou à un outil installé uniquement sur la machine d’un développeur, son exécution distante échouera malgré tout. Les scripts doivent localiser leurs fichiers à partir de variables de build telles que SRCROOT et s’arrêter avec une erreur explicite lorsqu’une dépendance est absente.
Le critère de validation final est simple : à partir d’un répertoire vide, il doit être possible d’extraire le dépôt puis, avec uniquement la version de Xcode et les commandes indiquées dans la documentation, d’énumérer les schémas, de résoudre les réglages, de compiler les artefacts de test et de terminer l’archivage. Une fois ce résultat obtenu, le Mac cloud de G-Mini exécute bien le point d’entrée défini par le dépôt, au lieu de reproduire l’état accidentel de l’ordinateur d’un développeur.
Questions fréquentes
Pourquoi la CI Mac cloud ne trouve-t-elle pas un schéma utilisable en local ?
Le schéma se trouve probablement dans xcuserdata et n'est donc pas inclus dans un clone propre. Enregistrez-le dans xcshareddata/xcschemes, puis ajoutez ce fichier au dépôt Git.
Un schéma Xcode partagé garantit-il que l'action Archive réussira ?
Non. Le partage garantit seulement sa visibilité. Il faut aussi vérifier la configuration Release, la cible d'archivage, les pré-actions et effectuer au moins un archivage réel depuis un clone propre.
Préparez un Mac dans le cloud pour votre prochaine file de build
Comparez deux configurations M4 sur cinq nœuds et choisissez une location à la journée, à la semaine, au mois ou au trimestre selon votre rythme de travail.