VPSSpark Blog
← Retour au journal dev

Avant Phone 18 : on a relancé la CI/CD iOS sur Xcode 27, iOS 27, GitHub Actions et runners Apple Silicon — carnet de pièges

Notes serveur · 2026.09.11 · ~12 min

Recherches fréquentes : Xcode 27 · iOS 27 · xcode-27 · Apple Silicon · Phone 18 CI

Bureau développeur avec moniteurs verticaux affichant logs et interface technique
Fixez d’abord l’image runner et simctl — le nom marketing Phone 18 peut attendre.

Une semaine avant le lancement du Phone 18, personne dans la salle ne parlait de focale caméra — tout le monde fixait une liste Actions pleine de pastilles rouges. Xcode 27, le SDK iOS 27, le label hébergé GitHub xcode-27, plus quelques runners Apple Silicon self-hosted tout juste branchés : quatre lignes la même semaine. Si l’une dérive, captures App Store et bêta TestFlight s’arrêtent ensemble. Nous avons refait toute la CI/CD iOS — de « ça passe au vert » à « ça tient la semaine de lancement » — et noté ici les vrais pièges.

L’ancre temporelle est nette : le 10 septembre 2026, GitHub écrit dans le Changelog que l’image runner Xcode 27 tourne désormais sur macOS 27 — labels toujours xcode-27 / xcode-27-xlarge, et arm64 uniquement. Un job encore « vert par chance » la veille sur base macOS 26 peut basculer en masse après le cut d’image : version OS, nom de simulateur, ou niveau disque. Pour la fenêtre GA Golden Gate et le cutoff machines, voir en interne macOS 27 Golden Gate : date de sortie et modèles supportés ; ici, uniquement le côté CI : où ça casse, comment on range.

9.10
GitHub : xcode-27 bascule sur macOS 27
arm64
xcode-27 hébergé : Apple Silicon seulement
4 pièges
Labels · Simulateur · Cache · Disque/file

Pourquoi tout rejouer avant le lancement — pas juste retoucher la matrix

Réflexe courant : passer xcode-version de 26 à 27, destination en iPhone 18. Avant la fenêtre Phone 18, ça explose presque toujours. Trois couches. Première : SDK et image runner ne sortent pas synchrones — en local Xcode 27 GM, l’image hébergée encore en public preview, ou juste passée de base macOS 26 à 27. Deuxième : la table des appareils simulateur change. Le runtime iOS 27 n’a pas forcément votre nom en dur ; name=iPhone 18 finit en Unable to find a device matching the provided destination. Troisième : si les cache keys DerivedData, SwiftPM, CocoaPods restent liés aux chemins « avant le grand saut Xcode », un hit restaure les déchets d’hier dans le compilateur d’aujourd’hui.

Nous séparons l’acceptation : « ça compile » vs « ça tient la semaine de lancement ». L’un : un job PR vert. L’autre : concurrence, disque, certificats et cold start simulateur ne se marchent pas dessus au pic. Côté hébergé, lire d’abord la doc des runners hébergés GitHub ; self-hosted, séparer par labels le feedback PR rapide et les jobs Archive lourds — même logique que GitHub Actions ralentit la CI iOS/Xcode : nouvelle approche, déclencheur Phone 18 cette fois.

Quatre lignes de pièges CI iOS avant Phone 18 : labels, simulateur, cache, disque et file
Ordre : figer runs-on et l’image, choisir le simulateur dynamiquement, invalider les vieux caches — seulement ensuite pool self-hosted et niveau disque.

Piège 1 : encore macos-latest — ou croire que xcode-27 = « n’importe quel Mac »

macos-latest reste correct à l’automne 2026 pour « ça tourne », mais inadapté comme seule surface d’acceptation la semaine Phone 18. Il suit la politique d’image par défaut GitHub — pas « SDK iOS 27 + votre simulateur déjà là ». Pour Xcode 27, écrire explicitement runs-on: xcode-27 (jobs lourds : xcode-27-xlarge), plutôt que compter sur maxim-lobanov/setup-xcode sur une mauvaise base — sans runtime, même le bon Xcode.app ne sauve pas simctl.

Plus sournois : le Changelog insiste sur arm64 uniquement. Si des nœuds Intel self-hosted restent, ou si runs-on: [self-hosted, macOS] signifie « tout Mac prend les jobs Xcode 27 », la matrix devient « parfois vert, parfois rouge » — vert = Apple Silicon, rouge = Intel incapable de la toolchain. Labels = l’ensemble réellement prêt, ex. [self-hosted, macOS, ARM64, xcode27], et retirer du label les nœuds non upgradés.

La dérive de labels est plus dangereuse que celle du code
En semaine de lancement, ce n’est pas l’erreur de compile qui fait peur — c’est un label runner dont le sens a changé sans doc. Qui prend xcode-27, qui la ligne compat macos-26 : dans le runbook, et à croiser chaque semaine sur la page Runners Actions.

Piège 2 : destination figée sur iPhone 18 — l’image n’a pas encore ce « téléphone »

Le Phone 18 marketing et le nom d’appareil simulateur ne sont pas la même table. Dans actions/runner-images, le runtime iOS 27.0 liste aujourd’hui la série iPhone 17, iPhone Air, plusieurs iPad — sans garantie qu’un simulateur nommé iPhone 18 apparaisse le jour J. Un YAML en -destination 'platform=iOS Simulator,name=iPhone 18,OS=27.0' est l’auto-blessure la plus courante avant release.

Reproductible : en tête de job, xcrun simctl list devices available -j, parser le JSON, trier « runtime iOS 27 + nom commence par iPhone », prendre une machine, UDID dans $GITHUB_OUTPUT, puis xcodebuild test uniquement avec id=…. Matrix multi-appareils : intersection liste dispo ∩ whitelist ; manquant → skip + alerte, pas toute la ligne Release au rouge. UI tests : le premier cold start du nouvel OS peut manger plusieurs minutes — timeout encore calé sur les 20 min de l’ère Xcode 26, et l’intermittent devient systématique.

ÉcritureRisque semaine de lancementAlternative plus stable
name=iPhone 18,OS=27.0Nom absent → échecChoix dynamique par UDID
OS=27.0 en durImage peut être 27.0.1Préfixe runtime ou dernière dispo
Seulement macos-latestSDK/simulateur incertainsSurface d’acceptation xcode-27 explicite
Intel + Apple Silicon mélangésMême job, échecs d’arch sporadiquesPools séparés, ligne 27 ARM64 seulement

Piège 3 : cache key pas invalidé avec Xcode 27 — le vert est l’« ancien monde »

Sur une major, la plus belle illusion de « c’est réparé » vient du cache. SourcePackages SwiftPM, Pods CocoaPods, tarballs DerivedData maison : si la key n’a que le branch ou le hash du lockfile, sans $(xcodebuild -version) / version d’image, Actions restaure joyeusement des artefacts Xcode 26. Symptômes : symboles linker manquants, Swift driver qui plante, tests qui buildent mais check de module cache qui échoue.

Nous forçons trois segments dans la key : version courte Xcode, version d’image runner (hébergé : env ou doc), plus Package.resolved / Podfile.lock. Le jour de l’upgrade, changer le préfixe — plutôt 8–12 min de cold start de plus que de debugger en semaine de lancement pourquoi le même commit passe en local et pas en CI. Self-hosted Apple Silicon : DerivedData partagé entre jobs sans dossiers par version Xcode mélange preview et GM.

Critère d’acceptation
Une hit rate cache en hausse n’est pas un succès d’upgrade ; « froid et quand même vert stable » l’est. Avant le lancement, au moins une nightly en miss forcé.

Piège 4 : runners Apple Silicon là — disque et file vous ramènent au point de départ

Xcode 27 + runtime iOS 27 + plusieurs simulateurs : tueurs de disque. L’image hébergée xcode-27 est déjà lourde ; un Mac mini self-hosted qui garde Xcode 26, deux betas et le DerivedData de trois apps explose souvent tard dans l’Archive avec No space left on device. Avant la semaine de lancement : une seule Xcode « acceptation courante », runtimes en whitelist, DerivedData nettoyé par job, cron nocturne df -h et xcrun simctl delete unavailable.

La file ne disparaît pas avec le Silicon. Avant le keynote, la matrix passe de « un SDK » à « compat 26 + acceptation 27 » — concurrence hébergée et slots self-hosted saturés ensemble. Feedback PR rapide et Archive TestFlight doivent avoir des labels distincts : minutes pour l’un, file OK pour l’autre sans bloquer le premier. Qui prend le slot au pic, c’est le design des labels — pas le M-series sur l’affiche.

Comportement toolchain selon la doc Apple Xcode ; quels simulateurs dans l’image, selon le Readme runner-images de la semaine — pas une capture de blog de l’an dernier comme source de config.

Runbook semaine de lancement : comment on a basculé

Jour 1 : job d’acceptation PR prod explicite sur xcode-27, garder une sentinelle compat macos-26 (ou génération précédente) — 27 rouge bloque le merge, 26 rouge alerte seulement. Jour 2 : toutes les destinations de test en UDID dynamique, noms marketing hors YAML. Jour 3 : invalider le préfixe cache, forcer un build froid, noter le wall time comme baseline. Jour 4 : splitter le pool self-hosted : ci-pr et ci-release, aucun nœud Intel collé au label 27.

Astreinte quotidienne : Changelog / runner-images pour une nouvelle image, disque runners, ratio queued/run — le jaune plus long que le vert ? Chiffres qui se dégradent : d’abord couper le parallélisme matrix, ensuite ajouter des machines — plus de machines sans séparer les labels ne fait qu’accélérer les mauvais jobs.

Quand passer au Mac cloud / runner Silicon dédié
Quand le xcode-27 hébergé queue déjà plus longtemps que la compile, ou qu’il faut figer une image GM pour notarisation et upload : louer au jour un Mac cloud Apple Silicon en self-hosted coûte souvent moins cher que de jouer à la loterie en file partagée. Nœuds dédiés pour Release et chaîne de certificats ; le volume PR peut rester sur les images preview hébergées comme première porte.

FAQ

Faut-il migrer tout de suite tous les jobs vers xcode-27 ?

Non. Acceptation lancement et builds store sur 27 ; compat ancien OS et hotfixes peuvent rester un temps sur l’image précédente. L’essentiel : labels et branch protection clairs — pas de « un vert n’importe où = merge ».

Xcode 27 vert en local, CI encore rouge — pourquoi ?

Trois checks d’abord : le runner est-il bien arm64 xcode-27, le nom de simulateur existe-t-il, le cache a-t-il hit un vieux DerivedData ? Runtime complet en local, pas forcément dans l’image hébergée.

Self-hosted et hébergé GitHub dans le même workflow ?

Oui, mais jobs et labels distincts. Pas un même tableau runs-on qui matche hébergé et n’importe quel self-hosted — sinon le scheduling n’est pas reproductible.

Le test appareil Phone 18 peut-il remplacer la CI simulateur ?

Non. Appareil : caméra, cellulaire, ressenti perf ; CI : compile, unit tests, régression à chaque PR. Semaine de lancement : les deux — l’appareil pas comme seul gate de merge.

Fenêtre Phone 18 · Astreinte Xcode 27

Besoin d’un Apple Silicon hors loterie de file partagée ?

Figer Release et notarisation sur un Mac cloud dédié ; les PR restent sur xcode-27 hébergé. Valider image et chaîne de certificats au jour — plus serein que de chasser la concurrence le jour du keynote.

Voir les offres Cloud Mac →

Offre limitée

Besoin d’un Apple Silicon hors file partagée ?

Xcode 27 · iOS 27 · Mac cloud dédié · jour/mois

Accueil
Offre limitée Voir les forfaits