Symptôme — votre pipeline attend un environnement macOS stable, mais aucun Mac n’est disponible en permanence ou les tâches sont envoyées au mauvais nœud.
Solution la plus rapide — utilisez un Mac distant Apple Silicon qui reste allumé, dispose de droits administrateur et peut joindre les dépendances du flux, puis enregistrez le runner au niveau du dépôt privé ou de l’organisation avant de l’installer comme service macOS.
Cet article s’adresse à vous si vous développez des applications iOS ou macOS, si vous administrez des ressources CI/CD pour plusieurs dépôts, ou si vos workflows ont besoin d’un trousseau de signature, d’un réseau interne ou d’un cache persistant.
Le Mac distant est-il réellement admissible comme nœud de construction ?
Un Mac distant peut héberger un runner auto-hébergé GitHub Actions si vous contrôlez la machine, pouvez y installer l’application du runner et disposez d’une connectivité sortante suffisante vers GitHub Actions. La documentation officielle indique que macOS 11 ou version ultérieure est pris en charge ; elle précise également que l’hôte doit pouvoir communiquer avec GitHub Actions et disposer de ressources adaptées aux workflows exécutés. (documentation GitHub sur les runners auto-hébergés)
Ne commencez pas par télécharger un paquet trouvé dans un ancien tutoriel. Ouvrez d’abord l’écran GitHub correspondant au dépôt ou à l’organisation, sélectionnez macOS et l’architecture affichée par votre hôte, puis copiez les commandes générées. Le jeton d’enregistrement est temporaire et ne doit ni être archivé dans le dépôt ni être réutilisé comme un secret permanent. (procédure officielle d’ajout d’un runner)
Avant toute installation, cochez les conditions suivantes :
- [ ] Le Mac reste accessible pendant les fenêtres de construction prévues.
- [ ] Vous disposez d’un compte administrateur distinct du compte de développement quotidien.
- [ ] Le système peut effectuer des connexions HTTPS sortantes sur le port 443.
- [ ] Le disque dispose d’une marge suffisante pour les dépôts, les caches, les simulateurs et les artefacts.
- [ ] L’architecture est vérifiée avec
uname -m, et non déduite du nom commercial du Mac. - [ ] Les outils requis par le projet sont compatibles avec la version de macOS retenue.
- [ ] Le réseau autorise les registres de paquets, les services de signature, les dépôts privés et les API nécessaires.
Un Mac Apple Silicon est particulièrement pertinent lorsque vous devez tester une chaîne arm64, compiler pour visionOS ou éviter de masquer des différences d’architecture derrière une traduction. Apple précise que le développement pour visionOS nécessite un Mac Apple Silicon, tandis que la construction d’un binaire universel est possible sur Apple Silicon ou Intel, avec des limites de débogage de la tranche arm64 sur Intel. (exigences système officielles d’Xcode)
Le choix du niveau d’enregistrement dépend ensuite de votre organisation :
| Option d’enregistrement | Cas adapté | Contrôle à prévoir | Limite principale |
|---|---|---|---|
| Dépôt privé | Un projet ou une équipe qui démarre | Accès limité à un seul dépôt | Peu pratique pour plusieurs produits |
| Organisation | Plusieurs dépôts partageant un outil commun | Groupe de runners et liste des dépôts autorisés | Demande une gouvernance plus stricte |
| Entreprise | Plusieurs organisations avec politique centralisée | Règles d’accès et groupes séparés | Administration plus lourde |
Pour un essai limité à un projet, commencez au niveau du dépôt privé. Pour une équipe qui partage un même environnement Xcode, des caches ou des scripts de publication, préférez un runner d’organisation avec un groupe explicitement limité aux dépôts autorisés. GitHub distingue les runners dédiés à un dépôt des runners d’organisation pouvant traiter des tâches provenant de plusieurs dépôts. (documentation GitHub sur les niveaux de gestion)
Préparez l’identité système avant l’inscription
L’erreur la plus coûteuse consiste à installer le runner dans le compte personnel d’un développeur, avec sa session Apple, ses clés SSH, ses fichiers de configuration et son trousseau de signature. Le pipeline fonctionne rapidement, mais le nœud devient difficile à auditer et dangereux à partager.
Créez un compte système dédié à la CI, sans l’utiliser pour naviguer, consulter la messagerie ou conserver des documents personnels. Le compte doit posséder uniquement les autorisations nécessaires à l’installation des outils, à l’accès au répertoire de travail et à l’exécution des commandes de construction.
Séparez au minimum les zones suivantes :
- le répertoire de l’application du runner ;
- le répertoire de travail des dépôts ;
- les caches de dépendances ;
- les fichiers de signature temporaires ;
- les journaux de service ;
- les artefacts destinés à être téléchargés.
Ajoutez également un groupe de runners cohérent avec les droits métier. Un runner qui peut publier une application ne devrait pas être sélectionné par défaut pour les tests de branches expérimentales. Dans le fichier de workflow, utilisez des labels lisibles, par exemple :
jobs:
build:
runs-on: [self-hosted, macOS, apple-silicon, ios-build]
Les labels sont cumulatifs : le job doit trouver un runner qui correspond à l’ensemble des labels demandés. Vous pouvez créer des labels personnalisés lors de la configuration initiale ou les gérer ensuite depuis les paramètres GitHub. Toutefois, GitHub ne vérifie pas qu’un label manuel décrit réellement le système ou l’architecture de l’hôte. (règles officielles relatives aux labels)
Vérifiez donc les propriétés réellement observées par le système :
uname -m
sw_vers
xcode-select -p
xcodebuild -version
git --version
Sur un Mac Apple Silicon, uname -m doit confirmer l’architecture attendue pour votre chaîne. Si vous utilisez Xcode, ne validez pas uniquement la présence de l’application : contrôlez aussi la version active, le chemin sélectionné par xcode-select et l’accès effectif au simulateur ou aux outils de signature.
Inscrivez le runner sans figer des commandes périmées
Depuis GitHub, ouvrez les paramètres du dépôt ou de l’organisation, accédez à Actions, puis à la section des runners et choisissez d’ajouter un runner. Sélectionnez macOS ainsi que l’architecture proposée pour votre Mac. Copiez ensuite les commandes affichées dans une session SSH ouverte avec le compte CI.
La séquence générale est la suivante :
- Créez un répertoire réservé au runner.
- Téléchargez l’archive indiquée par l’interface GitHub.
- Vérifiez l’archive avec la somme de contrôle publiée lorsque cette information est fournie.
- Décompressez le paquet dans le répertoire dédié.
- Lancez le script de configuration avec l’URL du dépôt ou de l’organisation et le jeton temporaire.
- Donnez un nom unique au runner.
- Ajoutez les labels nécessaires au routage.
- Démarrez l’application en mode interactif pour vérifier la connexion.
Exemple de structure, sans imposer de version de paquet :
mkdir -p ~/actions-runner
cd ~/actions-runner
# Copiez ici les commandes de téléchargement et d’extraction
# générées par l’interface GitHub pour votre architecture.
./config.sh \
--url https://github.com/ORGANISATION/DEPOT \
--token JETON_GENERE_PAR_GITHUB \
--name mac-ci-01 \
--labels macOS,apple-silicon,ios-build
Ne remplacez pas le jeton par une valeur conservée dans un fichier .env, un gestionnaire de mots de passe partagé ou un script versionné. Le but du jeton est d’autoriser l’enregistrement ; il ne constitue pas une identité durable du runner.
Évitez également de copier un numéro de version depuis un ancien article. GitHub publie régulièrement de nouvelles versions du runner et l’interface d’administration fournit les commandes adaptées au contexte sélectionné. La commande générée par votre propre dépôt ou organisation doit donc rester la référence opérationnelle.
Faites du démarrage automatique une condition de mise en production
Un runner qui fonctionne uniquement tant que votre session SSH reste ouverte n’est pas un nœud CI opérationnel. Après l’enregistrement, installez le service macOS avec le script fourni dans le répertoire du runner, puis démarrez-le selon les instructions générées par GitHub.
La logique à appliquer est simple :
cd ~/actions-runner
# Les commandes exactes sont celles fournies par le script du runner.
./svc.sh install
./svc.sh start
./svc.sh status
Sur macOS, GitHub recommande l’utilisation de launchctl pour surveiller l’activité d’un runner configuré comme service. Le nom du service dépend de l’installation ; ne supposez donc pas qu’un identifiant trouvé dans un autre système sera identique sur votre hôte. (configuration officielle de l’application du runner)
Validez le service dans cet ordre :
- [ ] Le statut du service indique qu’il est chargé et actif.
- [ ] Le runner apparaît « en ligne » dans les paramètres GitHub.
- [ ] La fermeture de la session SSH ne le déconnecte pas.
- [ ] Un redémarrage du Mac relance automatiquement le service.
- [ ] Le runner accepte un job après le redémarrage.
- [ ] Les journaux indiquent une connexion normale, sans boucle d’échec.
Un état « en ligne » n’est qu’un signal de connectivité. Il ne prouve ni que le job atteint le bon Mac, ni que Xcode utilise la bonne installation, ni que la signature est fonctionnelle.
Validez séparément le routage, l’outil et le produit final
Commencez par un workflow minimal qui ne compile rien de sensible. Il doit imprimer l’architecture, la version macOS, l’outil de développement actif et l’espace disque :
name: Vérification du runner macOS
on:
workflow_dispatch:
jobs:
diagnostic:
runs-on: [self-hosted, macOS, apple-silicon, ios-build]
steps:
- name: Inspecter l’hôte
run: |
uname -m
sw_vers
xcode-select -p
xcodebuild -version
df -h /
Cette étape répond à une question précise : le job a-t-il réellement été exécuté sur le Mac distant attendu ? Conservez le journal comme preuve d’acceptation, surtout si plusieurs runners possèdent des labels proches.
Ajoutez ensuite le dépôt et les dépendances du projet. Séparez les erreurs en deux catégories :
- échec de routage : le job reste en attente, sélectionne un autre runner ou ne correspond pas aux labels ;
- échec de construction : le runner est correct, mais une dépendance, une configuration Xcode, un certificat ou une commande du projet échoue.
Pour les projets iOS et macOS, vérifiez la version Xcode exigée par la cible de publication. Les matrices Apple évoluent ; la page officielle des exigences Xcode doit rester votre référence pour la compatibilité entre Xcode, macOS et les SDK. Apple indique notamment les versions minimales de macOS associées aux versions d’Xcode, ainsi que les exigences propres aux plateformes prises en charge. (exigences système officielles d’Xcode)
Dans un projet audio, vidéo ou design, ajoutez au test les opérations qui révèlent les limites réelles de l’environnement : export d’une séquence Final Cut Pro, génération d’aperçus, rendu d’un projet Motion, traitement de fichiers audio ou compilation d’un module utilisant Metal. Un simple echo confirme le routage, mais pas l’accès aux codecs, aux volumes, aux profils de signature ou aux outils graphiques dont votre production dépend.
Renforcez les secrets, les caches et les répertoires persistants
Un runner persistant ne revient pas automatiquement à un état vierge après chaque tâche. Les fichiers créés par un job peuvent rester sur le disque ; les caches peuvent contenir des dépendances anciennes ; les journaux peuvent révéler des chemins ou des variables ; un processus abandonné peut continuer à écouter sur un port local.
Définissez une politique de nettoyage avant l’arrivée des premiers secrets :
rm -rf "$RUNNER_TEMP"/*
rm -rf "$HOME/Library/Developer/Xcode/DerivedData"/*
Adaptez ces commandes à votre stratégie de cache : supprimer absolument tout accélère l’assainissement, mais peut annuler l’intérêt d’un cache persistant. Conservez uniquement ce qui est reconstruit à partir de sources vérifiables et excluez les certificats, profils, jetons et fichiers de configuration privés.
Pour la signature, injectez les éléments sensibles pendant le job, avec une durée de vie limitée, puis supprimez-les explicitement. Évitez de placer un certificat ou un profil directement dans le dépôt, dans le dossier personnel du compte CI ou dans une archive d’artefacts non chiffrée.
Attention : un runner persistant ne doit pas recevoir directement du code non fiable provenant de demandes de fusion publiques. Un tel code pourrait tenter de lire les fichiers locaux, les identifiants, le jeton
GITHUB_TOKENou les secrets accessibles au workflow. Réservez ce Mac aux dépôts privés de confiance, ou séparez les validations publiques dans une infrastructure éphémère et isolée.
Pour un dépôt public, n’envoyez pas directement les demandes de fusion non contrôlées vers ce Mac. Utilisez plutôt un runner éphémère et isolé, ou séparez strictement les workflows de validation non fiables des étapes de signature et de publication. La documentation GitHub décrit les runners éphémères comme une approche adaptée aux environnements où il faut limiter la persistance des fichiers et des modifications entre deux jobs. (référence GitHub sur les runners auto-hébergés)
Organisez l’exploitation quotidienne du nœud
Après le premier succès, documentez les opérations qui permettront à une autre personne de diagnostiquer le Mac sans improviser. Une maintenance fiable doit couvrir le service, le réseau, le stockage, les outils et la révocation.
| Contrôle | Vérification | Preuve attendue | Action si échec |
|---|---|---|---|
| Disponibilité | Statut GitHub et service macOS | Runner en ligne et service actif | Relancer le service, puis examiner les journaux |
| Routage | Labels et groupe | Job exécuté sur le Mac prévu | Corriger runs-on ou les groupes |
| Outils | xcodebuild, SDK, dépendances |
Versions enregistrées dans le journal | Bloquer la publication et ouvrir une maintenance |
| Stockage | df -h, caches, artefacts |
Marge suffisante avant construction | Nettoyer ou agrandir le volume |
| Sécurité | Secrets temporaires et répertoires nettoyés | Absence de fichiers sensibles résiduels | Révoquer les secrets et isoler le runner |
| Reprise | Redémarrage complet | Job de diagnostic réussi après boot | Corriger le service ou le compte CI |
Planifiez aussi la mise à jour du runner. L’application peut recevoir des mises à jour automatiques lorsqu’un job est affecté ou dans la semaine suivant la publication si aucun job ne l’utilise ; cette mécanique ne remplace pas une validation de vos workflows.
Pour macOS et Xcode, utilisez une fenêtre de maintenance séparée. Un changement système peut modifier les autorisations, les simulateurs, les certificats ou les scripts de build. Conservez un état documenté avant mise à jour, puis exécutez un workflow de diagnostic et un build représentatif avant de rendre le runner à nouveau disponible.
Un Mac distant peut être préférable à un Mac local si vous avez besoin d’une machine accessible à toute l’équipe, d’un nœud toujours allumé ou d’un environnement distinct du poste de conception. En revanche, si vous exécutez en permanence des charges très lourdes, avez besoin de périphériques physiques connectés ou devez contrôler vous-même chaque composant matériel, l’achat et l’hébergement direct peuvent rester plus cohérents.
| Solution | Coûts et contraintes réels | Choix raisonnable si… |
|---|---|---|
| Mac local partagé | Immobilisation du matériel, disponibilité liée aux horaires et au réseau du bureau | Une seule équipe travaille sur place |
| Mac mini auto-administré | Achat, alimentation, supervision, remplacement et accès distant à organiser | Vous acceptez la gestion matérielle sur la durée |
| Mac distant loué | Paiement récurrent, dépendance au fournisseur et validation des accès réseau | Vous voulez démarrer rapidement sans acheter ni héberger |
| Runner hébergé temporaire | Environnement moins personnalisable et caches souvent limités | Vous privilégiez la simplicité pour des jobs standards |
Si vous ne voulez pas acheter puis maintenir un Mac mini, consultez les formules de Mac distant de KVMFLUX et comparez-les à vos besoins de disponibilité, de durée et d’accès administrateur. Pour relier ce runner à un poste Windows ou Linux, la configuration d’un environnement de développement Mac distant permet également de distinguer l’accès interactif par SSH ou VNC de l’exécution automatisée par GitHub Actions.
Validez la mise en production par quatre scénarios
Ne déclarez pas le runner prêt après un seul build vert. Exécutez quatre scénarios contrôlés :
- Redémarrage : redémarrez le Mac, attendez le retour du service, puis lancez le diagnostic.
- Échec maîtrisé : provoquez une étape en erreur et vérifiez que les journaux ne contiennent pas de secret.
- Reprise de tâche : relancez un build interrompu et confirmez que le répertoire de travail ne contient pas de fichiers dangereux.
- Mise hors service : désactivez le runner dans GitHub, retirez ses labels, supprimez l’enregistrement et révoquez les identifiants associés.
Surveillez aussi les tâches en attente. GitHub recherche un runner en ligne et inactif qui correspond aux labels et aux groupes ; si aucun n’est disponible, le job reste dans la file jusqu’au retour d’un runner compatible. La supervision de la file est donc aussi importante que le voyant « en ligne ».
Questions fréquentes
Ces réponses couvrent les décisions qui provoquent le plus souvent une mauvaise installation : le niveau d’enregistrement, le démarrage automatique, l’architecture Apple Silicon, le diagnostic hors ligne et l’exposition des dépôts publics.
Conclusion : choisissez l’hôte avant de choisir la commande
Votre décision ne devrait pas être « quelle commande copier ? », mais « quel Mac pouvez-vous maintenir, isoler et récupérer après un incident ? ». Un runner auto-hébergé GitHub Actions devient un véritable nœud de construction seulement lorsque le routage, les outils, les secrets, le service de démarrage et la reprise ont tous été vérifiés avec des preuves.
Un poste local peut être indisponible, partagé ou saturé ; un Mac mini acheté exige un investissement matériel, une supervision réseau et une responsabilité de remplacement ; un environnement Linux ne remplace pas les outils macOS nécessaires à Xcode, à la signature ou à certains flux audio, vidéo et design. Si vous devez disposer rapidement d’un Mac Apple Silicon distant sans acheter ni administrer le matériel, KVMFLUX vous permet d’examiner une solution de Mac distant à louer, puis d’appliquer exactement cette procédure d’enregistrement, de sécurisation et d’acceptation du runner.
Déployez votre runner auto-hébergé sur un Mac distant KVMFLUX
Louez un Mac mini M4 physique et dédié, prêt à accueillir vos builds, tests et tâches CI macOS. Connectez-vous en SSH ou en VNC avec les droits administrateur pour installer vos outils, dépendances et certificats de signature. Conservez un environnement stable avec vos versions de Xcode, vos caches de compilation et vos réglages entre les exécutions. Choisissez une région et une durée de location adaptées à votre charge, d’une journée de validation à un nœud de build permanent.