Les trains de release mobile s’arrêtent quand un seul Mac exécute tous les tests UI en série. Ce guide explique quand le sharding rapporte, compare stratégie mono-nœud et flotte fragmentée dans un tableau, définit labels de runner et budgets d’exécution, et détaille huit étapes concrètes pour répartir le travail XCTest UI sur des Mac mini M4 cloud dédiés avec une file d’attente prévisible.
Si vous standardisez sur des runners GitHub Actions auto-hébergés, le sharding transforme « un Mac rapide » en flotte qui termine la validation des pull requests avant que les relecteurs changent de contexte. Pour plus de parallélisme de build, voyez aussi ferme de nœuds Mac parallèles pour CI/CD.
Pourquoi un Mac très puissant peut encore manquer votre SLA de tests UI
Xcode parallélise agressivement les tests unitaires, mais les tests UI passent du temps à lancer des simulateurs, animer des transitions et attendre SpringBoard—un travail qui ne monte pas linéairement avec le nombre de cœurs sur un même hôte.
- Contention GPU simulateur : Trois suites UI simultanées sur un M4 poussent souvent les frames au-delà du seuil implicite de 33 ms, d’où taps instables et faux échecs.
- Amplification disque : Chaque shard duplique les écritures DerivedData ; sans 500 Go+ de marge SSD, les jobs parallèles s’effondrent quand l’espace libre passe sous environ 15 %.
- File opaque : Sans labels par shard, on ne sait pas si une PR lente attend l’UI ou la compilation—on surprovisionne les runners de build et on rate quand même les délais UI.
Matrice de décision : un Mac unique contre flotte shardée
| Critère | M4 unique « tout-en-un » | Mac UI shardés dédiés |
|---|---|---|
| Temps réel pour suite UI 90 min | Série ≈ 90 min | 3 shards ≈ 35–40 min si équilibrés |
| Sensibilité aux flakiness | Élevée sous charge | Plus faible avec une suite par machine |
| Complexité ops | Faible | Moyenne ; labels + tableaux de bord |
| Meilleure géographie | Partout | Placer les shards HK / JP / KR / SG / US près des devs |
Segmenter les tests avant d’acheter du matériel
Le sharding est un problème d’ordonnancement déguisé en infra. Partitionnez les suites en paquets à variance de durée comparable—visez ±20 % autour de la médiane pour qu’aucun shard ne traîne systématiquement.
- Exporter l’historique de durées depuis Xcode Cloud, journaux XCTest ou base CI ; trier par p95.
- Isoler les parcours lourds en login dans un paquet dédié pour ne pas bloquer checkout ou réglages parallélisables.
- Étiqueter séparément les tests nécessitant des labos matériels—les Mac mini cloud excellent sur simulateur, pas sur fermes USB.
- Plafonner la taille des paquets pour respecter le budget PR ; si un paquet dépasse encore 25 minutes, rescinder par module fonctionnel.
- Versionner la carte des paquets dans Git (
ui-shards.json) pour des relances reproductibles.
Astuce : Gardez compile et UI sur des labels différents. Les mélanger provoque des inversions de file quand un gros xcodebuild test vole une machine avec timeouts simulateur.
Contrat de labels runner pour shards UI
| Jeu de labels | Rôle | Exemple runs-on |
|---|---|---|
| self-hosted, macOS, m4, ios-compile | Build + tests unitaires uniquement | [self-hosted, macOS, m4, ios-compile] |
| self-hosted, macOS, m4, ios-ui, shard-1 | Paquet UI A | [self-hosted, macOS, m4, ios-ui, shard-1] |
| self-hosted, macOS, m4, ios-ui, shard-2 | Paquet UI B | Même schéma pour B/C/D … |
Matrice GitHub Actions sans double planification accidentelle
Les équipes expriment souvent les shards comme dimension de matrice. Le piège : déclarer à la fois shard: [1,2,3] et un runs-on trop large—GitHub peut placer plusieurs shards sur un hôte et annuler votre investissement matériel. Attachez chaque branche de matrice à un label unique ou mappez des variables dépôt 1:1 avec les noms de machine.
matrix:
shard: [1, 2, 3]
include:
- shard: 1
runner_labels: [self-hosted, macOS, m4, ios-ui, shard-1]
- shard: 2
runner_labels: [self-hosted, macOS, m4, ios-ui, shard-2]
- shard: 3
runner_labels: [self-hosted, macOS, m4, ios-ui, shard-3]
jobs:
ui-tests:
runs-on: ${{ matrix.runner_labels }}
timeout-minutes: 40
Ajoutez une règle de dépôt qui rejette les workflows sans label shard-* sur les jobs UI ; une seule politique évite qu’un contributeur bienveillant effondre le parallélisme. Si vous louez des Mac supplémentaires dans une seconde région—Singapour avec relecteurs à Tokyo—dupliquez le schéma de labels par région (shard-1-sg) pour garder la proximité réseau explicite dans le YAML.
Huit étapes pour des shards UI sur Mac mini M4 cloud
Ces étapes supposent un accès SSH aux hôtes Mac mini M4 NodeMac. Les modèles de connexion sont décrits dans notre centre d’aide.
- Provisionner N machines où N = nombre de shards cible plus un spare chaud pour relances flaky.
- Préinstaller des builds Xcode identiques et runtimes simulateur ; la dérive entre shards produit de faux « ça marche sur mon runner ».
- Enregistrer les runners GitHub avec noms uniques et uniquement le label shard attendu.
- Définir
timeout-minutespar workflow—commencez à 40 pour l’UI puis resserrez selon p95. - Passer les identifiants de shard à
xcodebuildvia schémas ou plans de test (listes-only-testingpar paquet). - Désactiver la veille écran et garantir des sessions GUI pour l’utilisateur CI si le harness l’exige ; documentez pour la revue sécurité.
- Centraliser les artefacts (JUnit, captures) avec le nom du shard dans les fichiers pour un triage évident.
- Alerter sur déséquilibre : si un shard dépasse les autres de 1,5× trois runs de suite, rééquilibrez les paquets.
KPI et SLO pour une flotte shardée
Sans métriques, le sharding devient achat matériel à l’aveugle. Fixez un objectif de service pour « PR avec UI verte » (par ex. p95 sous 45 minutes) et mesurez séparément l’attente en file runner, la durée pure des tests et l’upload d’artefacts. Les tableaux par label ios-ui doivent montrer l’utilisation pour savoir si vous manquez de shards ou si vos paquets sont trop lourds.
Un examen hebdomadaire des dix tests les plus lents paie souvent mieux qu’un Mac supplémentaire. Les nœuds NodeMac à Hong Kong, Japon, Corée, Singapour et États-Unis réduisent la latence réseau ; combinez régions runners et calcul de file ci-dessus plutôt que tout empiler dans un fuseau.
Exportez JUnit et les résumés de tests par shard vers le même backend d’artefacts que vos tests unitaires pour voir les tendances sur plusieurs semaines. Si le p95 bondit soudainement, corrélez avec les mises à jour Xcode ou macOS sur les hôtes shard—cause fréquente de régressions silencieuses plutôt que les nouveaux commits applicatifs.
FAQ
Combien de shards de tests UI tiennent sur un seul Mac mini M4 ?
Traitez chaque shard UI gourmand en simulateur comme un job principal par machine sauf si vous avez mesuré de la marge ; deux shards peuvent fonctionner pour des suites légères, mais la contention GPU et stockage annule souvent le gain de temps réel.
Les shards doivent-ils utiliser les mêmes labels de runner que les jobs de compilation ?
Non—utilisez des labels dédiés comme ios-ui-shard pour que les jobs de compilation ne prennent pas des machines configurées avec des simulateurs supplémentaires et des hypothèses de session graphique.
Besoin de machines à quelques minutes de vos équipes à Hong Kong, Tokyo, Séoul, Singapour ou aux États-Unis ? Comparez les offres NodeMac pour aligner le nombre de shards avec la logique de file ci-dessus.
Le Mac mini M4 est une unité de shard pragmatique pour l’UI iOS : Apple Silicon offre d’excellentes perfs single-thread pour XCTest, de la mémoire unifiée pour plusieurs services simulateur, et une conso idle efficace entre rafales de PR. NodeMac loue des Mac mini physiques dédiés avec SSH et VNC à HK, JP, KR, SG et US—chaque shard correspond à du matériel réel débogable à distance. Plutôt qu’un placard de Macs, la location à la demande limite le CapEx pendant que vous validez la carte des shards et rééquilibrez avec de la télémétrie réelle.