Une pipeline annonce Xcode 26, mais ses journaux montrent un SDK Xcode 27 : votre nœud CI sélectionne probablement l’outil global au lieu de celui prévu par la tâche.
Solution la plus rapide : conservez deux applications Xcode dans des dossiers distincts, puis imposez DEVELOPER_DIR dans chaque pipeline. Ne modifiez pas xcode-select pendant que des tâches parallèles s’exécutent.
Dernière mise à jour : 1er septembre 2026. Les informations relatives à Xcode 27 Beta ont été vérifiées à partir des notes de version Xcode 27, des exigences système Xcode et de la documentation Apple sur les outils de ligne de commande.
Cet article est destiné aux équipes qui doivent encore publier avec Xcode 26 tout en testant des projets avec Xcode 27. Il concerne également les ingénieurs DevOps qui routent plusieurs dépôts vers des chaînes d’outils différentes, ainsi que les responsables de nœuds Mac distants qui gèrent les mises à niveau, le stockage et la récupération après incident.
Le vrai conflit : une version déclarée, une autre version exécutée
La coexistence de Xcode 27 et Xcode 26 est possible sur un même Mac Apple silicon compatible. L’installation des deux applications n’est toutefois que le début. La question importante est de pouvoir prouver, pour chaque tâche, quelle application a fourni xcodebuild, xcrun, le SDK et le compilateur Swift.
Un cas fréquent ressemble à ceci :
- le dépôt de publication contient
XCODE_VERSION=26; - le script appelle
xcodebuildsans chemin explicite ; - le nœud a été redémarré après un essai de Xcode 27 Beta ;
- le journal affiche un SDK ou un chemin de développeur associé à Xcode 27 ;
- l’archive produite semble valide, mais elle ne correspond plus aux conditions de validation habituelles.
Le problème vient de plusieurs niveaux de sélection. xcode-select définit un chemin de développeur global pour l’utilisateur ou le système. Le profil du shell peut ensuite modifier l’environnement. Enfin, l’agent CI peut lancer un processus avec ses propres variables. Une tâche interactive et une tâche non interactive ne lisent donc pas nécessairement le même contexte.
Vous devez enregistrer au début de chaque exécution :
- la version et le numéro de build de Xcode ;
- le chemin du répertoire de développeur ;
- le SDK utilisé ;
- la version du compilateur Swift ;
- le commit, le schéma et la destination demandés.
La documentation Apple sur la configuration des outils de ligne de commande décrit le rôle du choix global. Pour un nœud partagé, cette fonction ne doit pas devenir un routeur dynamique entre deux pipelines.
Xcode 27 Beta et Xcode 26 : choisir entre défaut de nœud et sélection par tâche
Vous pouvez conserver un Xcode par défaut au niveau du nœud si une seule chaîne de production l’utilise de manière stable. Dès que le même hôte sert à la publication et à la validation, la sélection par tâche devient plus sûre.
Comparaison des deux méthodes
Modifier le choix global avec xcode-select est simple à comprendre. C’est aussi une opération à portée large. Elle peut affecter les commandes lancées ensuite par d’autres utilisateurs, les agents persistants et les tâches qui démarrent au même moment.
DEVELOPER_DIR limite au contraire le choix au processus qui reçoit la variable. Dans un script CI, cette portée est plus prévisible. Elle facilite aussi la lecture des journaux : la tâche déclare son outil avant de l’utiliser.
Une machine peut-elle installer simultanément Xcode 27 et Xcode 26 ? Oui, si le Mac et sa version de macOS satisfont les exigences publiées pour les deux versions. Xcode 27 Beta peut imposer des conditions différentes de Xcode 26, notamment concernant l’architecture Apple silicon et le système hôte. Vérifiez toujours les documents correspondant au téléchargement réellement utilisé ; ne forcez pas l’installation en modifiant le paquet ou en employant une méthode non officielle. Les exigences peuvent évoluer pendant la période bêta.
La règle de décision est la suivante :
- Si le nœud est dédié à une seule chaîne stable, vous pouvez définir son Xcode par défaut avec
xcode-select, puis contrôler ce choix à chaque redémarrage. - Si le nœud reçoit plusieurs dépôts ou plusieurs branches, utilisez
DEVELOPER_DIRdans chaque tâche et laissez le réglage global inchangé. - Si les tâches peuvent s’exécuter en parallèle, interdisez toute modification de
xcode-selectdans les scripts. - Si Xcode 27 Beta exige un macOS que le nœud ne peut pas recevoir, revenez à un nœud séparé ; ne tentez pas de contourner la compatibilité.
- Si les composants nécessaires ne sont pas disponibles pour les deux chaînes, suspendez le partage du nœud jusqu’à l’installation et la validation de ces composants.
Dans la pratique, une variable de pipeline peut ressembler à ceci :
export DEVELOPER_DIR="/Applications/Xcode-26.app/Contents/Developer"
Pour la chaîne de validation, utilisez un autre chemin explicitement nommé :
export DEVELOPER_DIR="/Applications/Xcode-27-Beta.app/Contents/Developer"
Les noms sont volontairement explicites. Évitez de conserver deux applications sous le même nom ou dans un emplacement susceptible d’être remplacé par une mise à jour automatique.
Première étape : créer deux installations que personne ne confondra
Avant l’installation, vérifiez l’architecture du Mac distant et la version de macOS. Comparez-les aux exigences de Xcode 26 et de Xcode 27 Beta dans les exigences système officielles. Cette vérification doit être faite sur le nœud réel, pas sur votre poste local.
Conservez ensuite les applications dans des chemins séparés, par exemple :
/Applications/Xcode-26.app
/Applications/Xcode-27-Beta.app
Ces chemins sont des exemples de laboratoire. Remplacez-les par des emplacements contrôlés par votre équipe. Ne stockez pas une version sous Xcode.app et l’autre sous un nom temporaire si un agent ou un script utilise des chemins implicites.
Pour chaque téléchargement, archivez les informations suivantes dans l’inventaire du nœud :
- nom exact de l’application ;
- numéro de version et numéro de build ;
- source du téléchargement ;
- date d’installation ;
- résultat de la première ouverture ;
- composants installés ;
- empreinte ou méthode interne de vérification retenue par votre organisation.
Une couverture de version présente trois risques différents. Une installation initiale peut échouer avant l’initialisation. Une mise à jour par remplacement peut supprimer le chemin attendu. Une mise à jour automatique peut modifier l’application alors qu’une tâche est encore configurée pour l’utiliser. Le chemin déclaré dans le pipeline doit donc être vérifié avant chaque build important.
Après chaque installation, lancez l’initialisation sous le compte qui exécutera réellement l’agent CI. Une ouverture réussie dans votre session graphique ne prouve pas que le compte de service dispose des mêmes accès, licences acceptées ou composants.
Deuxième étape : faire parler le nœud avant de compiler
Le précontrôle doit être en lecture seule. Il ne doit ni changer le choix global, ni installer un composant, ni nettoyer les caches. Son rôle est de refuser rapidement une exécution ambiguë.
Exemple avec des identifiants fictifs :
#!/bin/bash
set -euo pipefail
: "${DEVELOPER_DIR:?DEVELOPER_DIR doit être défini}"
test -d "$DEVELOPER_DIR"
echo "DEVELOPER_DIR=$DEVELOPER_DIR"
xcodebuild -version
xcode-select -p
xcrun --find xcodebuild
xcrun --sdk iphoneos --show-sdk-path
swiftc --version
Comparez les sorties aux valeurs attendues du dépôt. Le simple fait que xcodebuild réponde ne suffit pas. Vous devez contrôler que :
xcodebuildprovient du répertoire de développeur prévu ;- le chemin du SDK correspond à la plateforme ciblée ;
- le compilateur Swift appartient à la même installation ;
- le schéma demandé existe dans cette version ;
- la destination de test est réellement disponible.
La référence Apple des réglages de compilation vous aide à distinguer les réglages du projet, de la configuration et de la ligne de commande. N’utilisez pas un réglage de build pour masquer une sélection de Xcode incorrecte.
Si une vérification échoue, arrêtez la tâche. Ne générez pas une archive « provisoire » dont l’origine ne peut pas être identifiée. Une archive ambiguë peut contaminer un dépôt de distribution, un cache ou un rapport de qualité.
Troisième étape : isoler les composants et les simulateurs
Un Xcode qui s’ouvre est seulement un Xcode installé. Une chaîne CI exploitable doit disposer des plateformes et des simulateurs correspondant à ses tests.
Pour chaque application, contrôlez séparément :
- la plateforme de compilation requise ;
- le runtime de simulateur prévu ;
- les composants supplémentaires ;
- l’état de l’initialisation au premier lancement ;
- les autorisations du compte de service.
L’installation d’un composant doit être attachée au bon chemin de développeur. Avant toute opération, définissez DEVELOPER_DIR vers l’application concernée. La documentation Apple sur les composants supplémentaires précise le principe de cette gestion.
Pour les simulateurs, ne supposez pas que Xcode 27 Beta et Xcode 26 exposent exactement le même ensemble. Vérifiez les destinations avec la commande adaptée, puis utilisez la plateforme réellement demandée par le projet. La documentation Apple explique également comment ajouter des simulateurs supplémentaires.
Les deux versions partagent-elles les simulateurs et DerivedData ? Elles peuvent voir certains emplacements communs, mais cette possibilité ne constitue pas une stratégie d’isolation. Les métadonnées, les runtimes, les index et les produits intermédiaires peuvent évoluer différemment. Un test qui réussit grâce à un état résiduel ne valide pas la reproductibilité.
Pour un nœud destiné uniquement à l’archivage, installez les composants nécessaires à l’archive. Pour un nœud de tests d’interface, ajoutez les runtimes réellement utilisés. Évitez d’installer tous les simulateurs sur un hôte partagé sans vérifier l’espace disponible et la procédure de nettoyage.
Quatrième étape : séparer DerivedData, dépendances et archives
Le mélange des caches est l’une des causes les plus difficiles à diagnostiquer. Une compilation peut sembler rapide parce qu’elle réutilise un produit produit par une autre version. Le résultat n’est alors ni propre ni représentatif.
Associez un chemin distinct à chaque combinaison pertinente de dépôt, branche et version Xcode :
XCODE_LABEL="xcode-26"
PROJECT_LABEL="projet-exemple"
BUILD_ROOT="$HOME/ci-data/$PROJECT_LABEL/$XCODE_LABEL"
mkdir -p "$BUILD_ROOT/derived-data" \
"$BUILD_ROOT/archives" \
"$BUILD_ROOT/logs"
xcodebuild \
-project "ProjetExemple.xcodeproj" \
-scheme "SchemeExemple" \
-derivedDataPath "$BUILD_ROOT/derived-data" \
-archivePath "$BUILD_ROOT/archives/ProjetExemple.xcarchive" \
archive
Pour Xcode 27 Beta, utilisez un autre XCODE_LABEL. Le même principe s’applique aux dépendances Swift Package Manager, aux répertoires de sortie, aux rapports de test et aux journaux. Vous pouvez conserver un cache partagé seulement après avoir démontré qu’il ne change pas la provenance ni le résultat du build.
La signature demande une séparation différente. Il n’est pas nécessaire de copier plusieurs fois les mêmes identités ou profils. En revanche, les deux tâches doivent s’exécuter dans une frontière d’identité maîtrisée, avec les accès strictement nécessaires. Vérifiez que chaque chaîne utilise le trousseau et les profils autorisés par votre politique interne. Ne placez jamais de certificat, de clé privée, de mot de passe ou de jeton dans le dépôt ou dans les commandes affichées.
Réalisez ensuite deux validations :
- une construction propre avec un répertoire DerivedData neuf ;
- une seconde construction contrôlée afin de vérifier que le cache ne change pas la sélection du SDK, la signature ou l’archive.
Ne publiez pas de chiffres de durée issus d’un autre matériel. Les performances dépendent du projet, des dépendances, de la charge du nœud et du stockage. Si vous mesurez une durée, indiquez qu’il s’agit d’une mesure réalisée sur votre propre configuration, avec le commit et la chaîne concernés.
Cinquième étape : choisir un routage qui survive au redémarrage
Votre agent doit recevoir le choix de Xcode depuis une configuration versionnée ou depuis une variable contrôlée par le serveur CI. Il ne doit pas dépendre d’un clic effectué dans une session graphique.
Un routage minimal peut associer :
- le dépôt de publication au chemin Xcode 26 ;
- la branche de validation au chemin Xcode 27 Beta ;
- un identifiant de tâche au répertoire de cache correspondant ;
- une politique d’échec si le chemin n’existe plus.
Après un redémarrage du Mac distant, rejouez le précontrôle. Vérifiez aussi que le compte de service voit les applications, que les variables sont présentes et que les simulateurs répondent. Puis simulez une mise à jour de Xcode 27 Beta dans une fenêtre de maintenance. La chaîne Xcode 26 doit continuer à pointer vers son propre dossier, sans suivre un alias modifié.
Comment conserver un retour arrière avant la mise à niveau de Xcode 27 ? Ne remplacez pas l’application qui sert à la publication. Conservez le dossier Xcode 26 validé, exportez la configuration du pipeline, notez les composants attendus et gardez une copie vérifiable de l’inventaire. Testez ensuite une tâche complète avec Xcode 27 Beta avant d’élargir son routage.
Le retour arrière doit être une opération documentée, pas une improvisation :
- désactiver les tâches routées vers la version expérimentale ;
- restaurer la variable
DEVELOPER_DIRvalidée ; - supprimer ou isoler les sorties produites par la version en échec ;
- relancer le précontrôle ;
- exécuter une construction propre ;
- comparer l’archive et le rapport de signature aux critères habituels.
Les contrôles qui doivent être écrits dans votre runbook
Avant de partager le nœud entre deux chaînes, utilisez les conditions suivantes :
- Si les deux versions satisfont les exigences du macOS installé et de l’architecture du nœud, alors poursuivez l’installation ; sinon, affectez Xcode 27 Beta à un autre Mac.
- Si chaque pipeline définit
DEVELOPER_DIRet journalise le chemin effectif, alors autorisez le routage partagé ; sinon, bloquez les builds parallèles. - Si les composants et destinations de test ont été validés séparément, alors activez les tests concernés ; sinon, limitez la tâche à une étape qui ne les requiert pas.
- Si DerivedData, archives et journaux sont séparés par chaîne, alors autorisez le cache ; sinon, utilisez un répertoire propre.
- Si le redémarrage, la mise à jour bêta et le retour arrière ont été rejoués avec succès, alors vous pouvez élargir l’usage de Xcode 27 ; sinon, conservez-le sur une chaîne de validation.
- Si les tâches concurrentes peuvent modifier le choix global, alors le nœud n’est pas prêt ; sinon, utilisez une sélection explicite par processus.
Trois vues de décision pour votre nœud distant
Le tableau suivant résume la configuration à retenir selon le type de chaîne. Il ne remplace pas le précontrôle : il indique surtout quelle portée de configuration éviter.
| Situation | Sélection recommandée | Caches | Décision opérationnelle |
|---|---|---|---|
| Publication uniquement avec Xcode 26 | xcode-select contrôlé au niveau du nœud ou DEVELOPER_DIR |
Dédiés au projet | Nœud simple, maintenance planifiée |
| Publication Xcode 26 et validation Xcode 27 Beta | DEVELOPER_DIR dans chaque tâche |
Séparés par version | Partage possible après matrice complète |
| Plusieurs dépôts et exécutions parallèles | DEVELOPER_DIR obligatoire |
Séparés par dépôt et version | Interdire toute modification globale |
| Composants incompatibles ou macOS insuffisant | Nœud distinct | Aucun partage entre chaînes | Reporter le partage |
| Besoin de ports, d’accessoires ou de tests persistants | Sélection explicite sur un hôte dédié | Politique propre au nœud | Évaluer une machine indépendante |
La coexistence réduit parfois le besoin d’administrer plusieurs hôtes, mais elle ajoute des coûts de gouvernance. Vous devez maintenir deux inventaires, deux parcours de composants, plusieurs familles de caches et un protocole de retour arrière.
| Poste à prévoir | Nœud partagé | Nœud séparé |
|---|---|---|
| Administration des applications | Deux chemins et deux cycles de validation | Un chemin par nœud |
| Stockage | Applications, composants et caches isolés | Répartition plus simple |
| Risque de collision | Élevé si le choix global est modifié | Limité au nœud concerné |
| Exploitation | Routage obligatoire par tâche | Routage plus direct |
| Retour arrière | Doit préserver les deux chaînes | Peut immobiliser uniquement la chaîne bêta |
| Usage créatif | Adapté à des builds audio, vidéo ou design ponctuels si les composants sont vérifiés | Préférable pour des rendus ou validations qui doivent rester indépendants |
Ne transformez pas un nœud de publication en poste d’expérimentation simplement parce que Xcode 27 Beta démarre. Pour des projets audio, vidéo ou de design utilisant des outils macOS spécifiques, l’état des composants et la stabilité de la session graphique peuvent être aussi importants que la compilation. Un Mac distant accessible par la console de gestion MacHTML peut convenir à une validation ponctuelle, mais vous devez confirmer les besoins d’interface, de stockage et de continuité avant de déplacer une chaîne entière.
| Vérification | Xcode 26 | Xcode 27 Beta | Critère de réussite |
|---|---|---|---|
| Version, build et chemin | Journalisés | Journalisés | Les sorties correspondent au routage |
| SDK et compilateur | Contrôlés par tâche | Contrôlés par tâche | Aucune provenance implicite |
| Archive propre | Validée | Validée pour le projet cible | Produit lisible et reproductible |
| Tests requis | Destinations disponibles | Destinations disponibles | Le runtime attendu répond |
| Signature | Identité contrôlée | Identité contrôlée | Aucun secret copié dans le dépôt |
| Redémarrage | Rejoué | Rejoué | Le routage revient sans intervention graphique |
| Retour arrière | Exécuté | Scénario préparé | La chaîne de publication reste disponible |
Quand un Mac distant indépendant devient le meilleur choix
Un nœud partagé est raisonnable si Xcode 27 Beta sert à une validation limitée, si les tâches sont correctement isolées et si l’équipe accepte de maintenir une matrice de contrôle. Il devient moins pertinent lorsque les deux chaînes ont des fenêtres de publication simultanées, des composants différents ou des exigences de disponibilité incompatibles.
Votre solution actuelle peut être un poste Mac local partagé, une machine virtuelle ou un serveur généraliste. Ces options présentent chacune des défauts concrets : un poste local dépend de la disponibilité d’une personne, une machine virtuelle peut diverger des contraintes d’un Mac réel, et un serveur Linux ne fournit pas les outils macOS nécessaires à Xcode. Une seule machine locale peut aussi devenir un point de panne lors d’une mise à jour ou d’une intervention.
Dans ce contexte, louer un Mac auprès de MacHTML peut offrir un environnement distant réel avec accès SSH, VNC ou console, sans remplacer immédiatement le nœud de publication. Vous pouvez réserver l’hôte à Xcode 27 Beta, conserver Xcode 26 sur votre chaîne stable, puis comparer les résultats avec une frontière opérationnelle plus nette. Consultez les conditions de location d’un Mac distant avant de choisir la durée et le mode d’accès adaptés à vos tests.
La bonne séquence consiste à terminer la matrice d’acceptation, à vérifier les exigences du projet, puis à décider entre trois options : conserver le partage, isoler Xcode 27 sur un nœud dédié, ou suspendre son usage jusqu’à une version officiellement compatible. Si vous avez besoin d’un environnement temporaire pour une validation, une migration ou un cycle de tests audio, vidéo ou design, l’accès à un Mac distant MacHTML peut être plus souple qu’une modification risquée de votre machine de publication. Pour les charges longues et parfaitement stables, ou pour les périphériques physiques spécifiques, l’achat et la gestion d’un Mac dédié restent parfois plus cohérents.
Pour aller plus loin: Résoudre les conflits entre Xcode 27 et Copilot for Xcode Optimiser les performances d’un pipeline CI/CD sur Mac mini M4
Accélérez votre CI avec un Mac distant adapté à Xcode
Avec MacHTML, vous disposez d’un Mac distant pour exécuter séparément vos pipelines Xcode 26 et Xcode 27 Beta sans perturber vos publications. Testez différentes versions de macOS et de Xcode dans un environnement dédié, avec une isolation claire des projets, composants et caches. L’accès distant vous permet de superviser vos validations, d’ajuster vos configurations CI et de revenir rapidement à un environnement stable en cas de régression. Choisissez une configuration MacHTML adaptée à votre équipe et faites évoluer votre capacité de compilation au rythme de vos besoins iOS et macOS.