DevOps / CI·CD 25 avril 2026

2026-04-25 xcodebuild test couverture, xcresult vers JUnit et garde-fous PR sur Mac cloud loué (HK / JP / KR / SG / US)

Équipe technique MacXCode 25 avril 2026 ~18 min de lecture

Les équipes iOS et macOS qui planifient déjà un headless xcodebuild test sur un Mac mini M4 Apple Silicon loué fusionnent souvent les PR sur un seul code de sortie et une case rouge/verte du fournisseur CI. Ce guide 2026-04-25 comble l’écart entre « tests OK » et « on peut expliquer la qualité cette semaine » : -resultBundlePath vers un répertoire par job sous votre racine de build isolée, -enableCodeCoverage YES pour LLVM profdata, export JUnit (xcresulttool ou wrapper de confiance), politique de taux de lignes avec xccov. Complète plans de test + xcresult parallèle. Porte compilateur : Swift 6 concurrence stricte. OpenClaw le même jour : OpenClaw doctor et liste blanche.

Ce qu’un gate PR doit voir en plus du code 0

Trois paquets : (1) junit/xunit annotable ; (2) .xcresult fusionné ou unique pour tri Xcode, même rétention que vos tickets xcresult ; (3) couverture diffable contre la base. Multi-SSH HK/JP/KR/SG/US : définissez le gate sur des métriques agrégées après shard par destination. Associez latences au label pool imprimé dans les métadonnées.

Flags : bundle de résultats, couverture, destinations

Fixez DEVELOPER_DIR=/Applications/Xcode.app et une destination simulateur nommée.

DEVELOPER_DIR=/Applications/Xcode.app xcodebuild test -workspace App.xcworkspace -scheme App -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.2' -enableCodeCoverage YES -resultBundlePath "$CI_ROOT/Test-$(date +%s).xcresult" -derivedDataPath "$CI_DERIVED/job-$CI_JOB_ID" -parallel-testing-enabled YES CODE_SIGNING_ALLOWED=YES

Ajustez -only-testing / -skip-testing par shard ; coordinateur pour fusionner. -retry-tests-on-failure seulement avec budget flaky écrit—sinon vous masquez un keychain / signing cassé. Lane Swift 6 strict séparée : ne comptez pas deux fois les mêmes tests unitaires sans vrai split de scheme.

De .xcresult à JUnit

Sur hôtes macOS CI, xcresulttool exporte tests/diagnostics. Chemin -resultBundlePath unique par run, pas de symlink vers NFS partagé. Fusionnez avec ordre documenté ; rejetez les testStatus contradictoires. Archivez le brut comme pour simulateur.

profdata, xccov, seuils défendables

xcrun llvm-profdata merge puis xcrun xccov. Plancher sur modules app et framework cœur ; exclusions check-in pour code généré et tiers. Après déplacement runner self-hosted, même SHA git doit aligner les hachages sources ; l’incrémental peut diverger. Si vous changez couverture la même nuit que dSYM, vérifiez dSYM vs produits LLVM livrés.

Garde-fou CI : échouez si xccov ne peut pas ouvrir le profdata—ne passez pas silencieusement à 0 %.

Shards : fusionner avant le gate

Chaque shard a son profdata et xcresult. Le coordinateur : fin de tous les shards + artefacts ; fusion profdata ; JUnit agrégé avec skipped explicites ; shard perdu = échec sauf règle écrite rare. Voir fan-out M4.

Symptôme / couche / correctif

Symptôme Couche Correctif
Couverture 0 % mais tests passent Réglages build / appartenance cible Code Coverage dans le scheme, flags couverture
JUnit vide, UI verte Export outil Valider xcresulttool sur la version Xcode hôte
Écart énorme entre deux hôtes Branche / incrémental / shard Désactiver incrémental pour le gate, fusionner profdata, fixer destinations

Avec gateway OpenClaw, ne partagez pas un seul /tmpTMPDIR par job. Livraison : archive distante, IPA via API App Store Connect.

FAQ

Question Réponse
Bloquer sur couverture de branches ? Si le mix langage le permet ; lignes souvent plus simples pour les PM.
Rétention zip xcresult ? Alignée SLA incidents—souvent 14+ jours ; leases 1–2 To permettent plus.
US-Est ou Asie d’abord ? Région proche des committers pour repro interactive ; matrice complète en release.

Mac mini M4 pour cette charge

Simulateur et couverture : CPU+NVMe+inodes avant GPU. Bare-metal M4 MacXCode, I/O prévisible, RAM pour plusieurs racines CoreSimulator chaudes sans voisin bruyant avec OpenClaw. Scalez via tarifs. GUI occasionnelle : VNC break-glass.

CI tests iOS reproductibles in-région

M4 · SSH par défaut · options 1–2 To