Une file d’attente qui s’allonge à chaque période de commits : ne comptez pas les développeurs, mesurez les jobs qui arrivent, leur durée et la capacité réellement disponible.

La solution la plus rapide consiste à séparer les charges PR, tests UI et publication, puis à dimensionner les Mac Runner GitHub Actions sur la fenêtre de pointe, le délai d’attente visé et une réserve de secours. Une machine supplémentaire n’apporte rien si les anciens jobs annulables, les contrôles redondants ou les étapes qui n’ont pas besoin de macOS occupent déjà les nœuds.

Cette méthode s’adresse à :

  • vous qui administrez des Runners macOS auto-hébergés et ne savez pas quand augmenter la capacité ;
  • vous qui planifiez plusieurs projets iOS, des campagnes de tests et des fenêtres de publication ;
  • vous qui envisagez de louer un Mac distant et souhaitez valider le nombre de nœuds avant de choisir la durée.
01

Le bon périmètre de mesure

Un Mac Runner GitHub Actions n’est pas une unité abstraite de puissance. Dans le routage standard, un Runner auto-hébergé prend en charge un job à la fois ; plusieurs jobs simultanés nécessitent donc plusieurs Runners disponibles, sauf si votre outil répartit lui-même le travail à l’intérieur d’un job. Vérifiez ce comportement dans la documentation GitHub sur les Runners auto-hébergés, plutôt que de déduire la capacité du nombre de cœurs annoncé.

Votre première collecte doit associer chaque exécution à quatre valeurs :

  • heure d’arrivée du job ;
  • début réel d’exécution ;
  • durée jusqu’au succès ou à l’échec ;
  • nombre et durée des relances.

Les indicateurs GitHub Actions permettent de suivre les temps d’attente et les durées des jobs. Utilisez la documentation officielle sur les métriques des Runners auto-hébergés pour vérifier les champs disponibles dans votre environnement.

Ne mélangez pas les workflows. Un build PR, une suite de tests UI et une archive de publication n’ont ni la même priorité, ni la même durée, ni le même coût d’échec. Une moyenne globale peut sembler acceptable alors qu’une release reste bloquée au moment où tous les développeurs poussent leurs derniers changements.

Modèle de capacité

Pour chaque famille de tâches, estimez la charge offerte avec une formule simple :

charge offerte = fréquence d’arrivée des jobs × durée d’occupation d’un Runner

Cette valeur sert de point de départ, pas de formule officielle GitHub. Elle doit être confrontée à une fenêtre de pointe vérifiable. Relevez, par exemple, les périodes où les commits sont regroupés, les heures de régression et les créneaux précédant une publication. Analysez aussi un percentile élevé de l’attente et de la durée, car la moyenne masque précisément les exécutions qui dégradent l’expérience.

Le nombre de Runners en ligne ne représente pas toujours la capacité utilisable. Un nœud peut être occupé, hors ligne, en redémarrage, bloqué par une session graphique ou incapable d’accepter le label demandé. La syntaxe des workflows GitHub Actions aide à vérifier les dépendances, les matrices, les conditions et les règles d’annulation qui modifient le nombre réel de jobs.

02

Le socle des builds PR

Les contrôles de code, les tests unitaires et les compilations incrémentales arrivent généralement au fil de la journée. Leur enjeu principal n’est pas le débit maximal d’une nuit de régression, mais le délai de retour perçu par l’équipe. Dimensionnez donc le socle pour absorber la charge habituelle sans laisser une série de commits récents former une file persistante.

Avant d’ajouter un nœud, cherchez les occupations qui ne produisent pas de valeur immédiate :

  • annuler les anciens jobs PR lorsqu’un commit plus récent les rend inutiles ;
  • regrouper les contrôles qui peuvent partager une même compilation ;
  • déplacer vers un environnement non macOS les analyses qui ne dépendent ni de Xcode ni d’un outil Apple ;
  • éviter de reconstruire intégralement lorsque le workflow peut exploiter une stratégie incrémentale ;
  • séparer les tâches obligatoires du contrôle obligatoire des tâches informatives.

Les règles de concurrence de GitHub Actions peuvent contribuer à annuler ou à remplacer certaines exécutions obsolètes. Consultez la documentation GitHub sur la concurrence des workflows avant de modifier vos groupes de concurrence : une règle trop large peut annuler une release légitime, tandis qu’une règle absente laisse les anciens commits monopoliser les Runners.

Mesure spécifique à Xcode CI

Pour une compilation, notez séparément le temps passé dans la file et le temps réellement consommé par Xcode. Apple documente l’utilisation du résumé de temps de compilation et les moyens d’identifier les cibles lentes dans son guide sur l’amélioration de la vitesse des builds incrémentaux.

Cette distinction permet de répondre à une question souvent mal posée : faut-il un Mac Runner supplémentaire, ou faut-il réduire la durée de chaque job ? Si le temps de compilation augmente alors que la file reste faible, ajouter un nœud ne corrigera pas la cause. Si la durée reste stable mais que l’attente augmente pendant les commits groupés, la capacité de la ferme devient le facteur limitant.

03

Les tests UI et les simulateurs

Les tests UI iOS doivent être calculés comme une charge distincte. Un workflow peut lancer plusieurs destinations, plusieurs simulateurs ou plusieurs Workers de test. Cela crée une concurrence interne à la machine, qui n’équivaut pas à plusieurs Mac Runner indépendants.

Apple documente les mécanismes de tests parallèles dans les informations de version de Xcode, notamment les options liées à l’exécution parallèle des tests dans les notes officielles de Xcode. Vérifiez les options utilisées par votre version et par votre projet au lieu de supposer qu’un nombre supérieur de Workers accélérera linéairement la suite.

Mesurez quatre signaux pendant l’essai :

  • durée effective de la suite, hors attente GitHub ;
  • consommation du processeur et de la mémoire ;
  • erreurs de simulateur, timeouts et tests flakys ;
  • temps nécessaire pour nettoyer ou redémarrer l’environnement.

Une machine peut accepter plusieurs processus tout en produisant moins de résultats valides par unité de temps. Les simulateurs se disputent les ressources avec la compilation, l’indexation, les journaux et les services auxiliaires. Si l’augmentation du parallélisme interne allonge la suite ou augmente les échecs, limitez le nombre de Workers par Mac et ajoutez plutôt un Runner de test séparé.

Scénario de partage

Le partage entre compilation PR et test UI est acceptable lorsque les deux charges n’arrivent presque jamais ensemble et que le nettoyage est fiable. Il devient défavorable lorsque les tests ont une priorité de livraison, lorsque les simulateurs restent dans un état incohérent ou lorsque les builds PR remplissent la file avant une campagne de validation.

Utilisez des labels distincts, puis des groupes de Runners lorsque la séparation doit être administrée au niveau du dépôt ou de l’organisation. Les mécanismes de routage par labels et groupes sont décrits dans le guide GitHub consacré aux labels et aux groupes de Runners et dans la documentation des Runner Groups.

Famille de charge Occupation dominante Décision initiale Signal justifiant une séparation
Builds PR Arrivées continues, retour rapide Socle de Runners partagés entre projets compatibles Attente récurrente pendant les heures de travail
Tests UI Simulateurs, mémoire, nettoyage Nœuds dédiés ou parallélisme interne limité Durée ou stabilité se dégrade avec davantage de Workers
Publication Signature, archive, secrets, priorité Capacité réservée et routage contrôlé Une tâche PR bloque une livraison
Régression différable Charge concentrée, faible urgence immédiate Fenêtre planifiée ou capacité temporaire La campagne dépasse sa fenêtre cible
04

La publication et la signature

Une archive de publication ne doit pas être traitée comme un simple build PR. Elle utilise une chaîne de signature, un trousseau, des certificats et un espace de travail qui peuvent être sensibles à l’état laissé par une exécution précédente. Une machine partagée peut fonctionner techniquement et rester inacceptable opérationnellement si le nettoyage est incomplet ou si la récupération après échec prend trop de temps.

Réservez une capacité de publication lorsque l’échec a un impact direct sur la livraison. Le nombre de tâches quotidiennes ne suffit pas pour décider : une seule archive bloquée au mauvais moment peut être plus critique que de nombreux builds de validation.

Appliquez cette séquence :

  1. Créez un label réservé aux nœuds de publication.
  2. Placez ces Runners dans un groupe administré séparément.
  3. Vérifiez que le workflow de release demande bien ce label.
  4. Lancez une archive complète, avec signature et export, dans les conditions habituelles.
  5. Mesurez l’attente, la durée, le nettoyage et la récupération après interruption.
  6. Testez ensuite qu’un job PR ne peut pas prendre ce nœud par défaut.

Le choix entre partage et isolement dépend donc de la priorité, du niveau de confiance accordé au nettoyage et du temps de rétablissement. Une capacité réservée n’est pas forcément un Runner utilisé en permanence : elle peut être maintenue disponible uniquement pendant la fenêtre de publication.

Attention : ne comptez pas deux fois le même parallélisme. Trois jobs GitHub simultanés réclament trois unités de Runner disponibles, mais trois Workers lancés dans un seul job consomment les ressources d’une seule machine. Le gain réel doit être mesuré sur la durée et la stabilité de la suite.

05

Les pics nocturnes et les fenêtres de release

Les régressions nocturnes, les campagnes avant publication et les builds de plusieurs branches créent souvent une pointe courte. La traiter en dimensionnant toute la capacité permanente sur le maximum observé immobilise des nœuds pendant les périodes calmes.

Classez les tâches selon leur échéance :

  • les builds PR doivent préserver un retour rapide ;
  • les tests de non-régression peuvent entrer dans une fenêtre planifiée si leur résultat n’est pas attendu immédiatement ;
  • les publications ont une échéance et une priorité propres ;
  • les tâches d’analyse ou de génération de rapports peuvent être décalées si elles ne bloquent pas une décision.

Pour une charge différable, commencez par l’ordonnancement, la limitation du parallélisme et la suppression des exécutions obsolètes. Pour un pic prévisible mais court, ajoutez temporairement des Mac distants pendant la période mesurée. Pour une file qui revient chaque jour et dégrade les PR, une capacité permanente devient plus cohérente.

La location d’un Mac distant est particulièrement intéressante pour tester cette hypothèse sans acheter immédiatement du matériel. Vous pouvez comparer une extension courte à une réservation plus longue dans l’offre KVMNODE pour les Mac distants, puis conserver uniquement la capacité démontrée par les journaux de votre projet.

Option Quand la choisir Avantage Limite à contrôler
Nœud permanent supplémentaire File présente sur plusieurs fenêtres de travail Capacité prévisible Occupation faible hors période active
Réorganisation des workflows Jobs annulables, contrôles redondants ou étapes mal classées Aucun nœud nouveau requis Risque de retarder un contrôle important
Extension courte Pic lié à une release ou une campagne planifiée Test limité dans le temps Il faut prévoir le routage et le nettoyage
Réserve de secours Impact élevé d’une panne ou d’un redémarrage Continuité des jobs prioritaires Capacité inactive à justifier par le risque
06

Protocole d’essai et capacité de secours

Ne choisissez pas le nombre final à partir d’un seul jour. Construisez une base par type de tâche, puis augmentez progressivement la concurrence pendant une période représentative. L’objectif n’est pas de produire le plus grand nombre de jobs simultanés, mais de trouver le point où l’attente, la durée et les échecs restent acceptables.

Procédez ainsi :

  1. Exportez l’historique des workflows et classez les exécutions en PR, tests UI, publication et tâches différables.
  2. Relevez pour chaque groupe l’arrivée des jobs, l’attente, la durée, les relances et le résultat final.
  3. Éliminez les jobs obsolètes et les étapes qui ne nécessitent pas macOS.
  4. Testez le socle avec le parallélisme interne habituel, sans augmenter simultanément le nombre de Workers et le nombre de Runners.
  5. Ajoutez une unité de capacité, puis observez l’évolution de l’attente et du temps de réalisation.
  6. Répétez l’essai sur une fenêtre de pointe, une campagne UI et une archive complète.
  7. Vérifiez le comportement après redémarrage, perte temporaire d’un nœud et échec de nettoyage.
  8. Formalisez quatre conclusions : socle de compilation, nœuds de test, capacité réservée à la publication et secours.

Pour savoir quelles fonctions peuvent partager un Mac, examinez la simultanéité réelle, les secrets utilisés et l’état laissé sur le disque. Deux projets de compilation peuvent parfois partager un pool. Une publication ne devrait y entrer que si son isolement, son routage et sa récupération ont été validés.

Décision conditionnelle

  • Si la file PR augmente mais que les jobs comportent des contrôles annulables, choisissez d’abord l’optimisation du workflow ; sinon, passez à l’essai d’un nœud additionnel.
  • Si les tests UI ralentissent ou deviennent instables lorsque vous augmentez les Workers, limitez le parallélisme par machine et ajoutez un nœud indépendant ; sinon, conservez le niveau validé.
  • Si une publication attend derrière des builds ordinaires, choisissez un label et un groupe réservés ; sinon, un pool commun peut rester acceptable sous surveillance.
  • Si le pic est concentré sur une campagne identifiable, préférez une extension courte de Mac distants ; sinon, envisagez une capacité permanente.
  • Si la perte d’un Runner bloque une échéance importante, réservez une capacité de secours ; sinon, documentez le temps de remplacement acceptable avant de payer une réserve.
07

Réponses aux décisions fréquentes

Combien de tâches par Runner ?

Dans GitHub Actions, raisonnez d’abord sur le job attribué au Runner, puis sur les processus que ce job lance localement. Le nombre de Workers de test ne transforme pas une machine en plusieurs Runners. Cette séparation évite de promettre une capacité qui disparaît dès que la mémoire, les simulateurs ou le disque deviennent saturés.

Le délai Xcode CI est-il suffisant pour augmenter la ferme ?

Non, pas isolément. Une attente ponctuelle peut provenir d’un pic normal, d’un Runner indisponible ou d’un label mal routé. Comparez l’attente avec la durée d’exécution, la fréquence des occurrences et l’objectif de retour PR. Une attente récurrente, confirmée après optimisation des workflows, constitue un meilleur signal d’extension.

Tests UI et compilation sur le même nœud ?

Le partage convient à une charge légère et bien nettoyée. Dès que les simulateurs consomment une part importante des ressources ou que la release doit passer devant les PR, séparez les pools. Le critère n’est pas la préférence d’architecture, mais la durée effective, la stabilité et la capacité à récupérer rapidement après un échec.

Calcul selon la durée des jobs ?

Utilisez la fréquence d’arrivée multipliée par la durée d’occupation pour obtenir une première charge. Complétez-la avec la fenêtre de pointe, le percentile élevé, les relances et la capacité réservée. Une estimation basée uniquement sur la durée moyenne sous-évalue les archives lentes et les campagnes UI.

Location durable ou extension de pointe ?

Une location durable convient à une file quotidienne et prévisible. Une extension courte convient à une release, une migration ou une campagne ponctuelle. Dans les deux cas, mesurez d’abord la charge et le délai obtenu. Le coût ne doit pas être la seule variable : la perte d’une fenêtre de publication et la maintenance d’un nœud inutilisé ont aussi un impact.

08

Le choix entre votre dispositif actuel et des Mac distants

Si vous conservez un seul Mac partagé, vous subissez souvent trois limites : les builds PR concurrencent les tests UI, une publication peut attendre derrière une tâche non prioritaire, et une panne ou un redémarrage supprime toute marge de manœuvre. L’achat de plusieurs machines corrige la capacité, mais ajoute immobilisation matérielle, maintenance, remplacement et gestion des environnements.

Pour un besoin temporaire ou une montée en charge à valider, louer des Mac distants auprès de KVMNODE permet de tester un pool supplémentaire sans transformer immédiatement un pic en investissement permanent. Vous pouvez commencer par une fenêtre de mesure, vérifier le routage des labels, puis décider si le nœud doit rester dédié aux builds, aux tests ou aux releases. Pour comparer avec une approche matérielle, examinez aussi la fiche Mac mini dédié à la construction CI, en gardant vos mesures de file comme critère principal.

Avant toute commande, consignez une période complète de PR, une campagne de tests UI et une publication. Si la pointe dépasse la capacité validée, choisissez une extension courte de Mac distants correspondant à cette fenêtre. Si la file reste élevée après optimisation et revient chaque jour, conservez plutôt un socle permanent avec une réserve explicitement justifiée. Consultez les solutions de Mac distants de KVMNODE lorsque vous avez défini les labels, les durées et les règles d’isolement à tester.