Le code est déjà modifié par Claude Code, mais le runner généraliste ne peut pas exécuter la chaîne Apple.

La solution la plus rapide consiste à séparer le flux en deux jobs : Claude Code GitHub Actions analyse la demande et propose la modification, puis un Mac distant exécute uniquement la construction et les tests Xcode sous contrôle.

Périmètre de ce guide

Ce guide s’adresse à vous si vous automatisez le traitement d’Issues ou de Pull Requests avec Claude Code et devez valider un projet iOS ou macOS sur un véritable environnement macOS.

Il concerne également les ingénieurs DevOps qui administrent un GitHub self-hosted runner sur Mac, ainsi que les responsables plateforme qui doivent limiter l’accès au code, au réseau, au trousseau et aux certificats de publication.

La distinction centrale est importante : Claude Code Action, Claude Code CLI, GitHub Actions Runner et Xcode ne sont pas le même composant. Le premier orchestre l’intégration avec le dépôt, le second exécute l’agent, le troisième reçoit les tâches et Xcode construit ou teste le projet. Confondre ces rôles produit souvent un pipeline qui paraît « vert » alors que le projet Apple n’a jamais été compilé.

Dernière mise à jour : 7 septembre 2026. Les points relatifs aux permissions, aux runners auto-hébergés, à Xcode et à l’automatisation des tests ont été vérifiés à partir de la documentation officielle de Claude Code Action, des règles de sécurité de Claude Code Action, de la documentation GitHub sur l’usage sécurisé des Actions et des références Apple citées plus bas.

Job d’agent et job Mac

Le premier job reçoit l’événement GitHub, lit le périmètre autorisé, exécute Claude Code et remet une modification examinable. Il peut créer une branche, produire un commit ou proposer une sortie destinée à la revue. Il ne doit pas avoir besoin d’un certificat de signature pour comprendre une Issue, corriger une fonction ou ajuster un test.

Le second job récupère un commit précis et l’exécute sur le Mac distant. Son rôle est limité à la vérification : installation ou résolution des dépendances prévues, construction, tests, collecte des journaux et transmission du résultat. Il ne doit pas laisser l’agent modifier librement la machine parce qu’une commande Xcode échoue.

Pour éviter toute divergence, le premier job doit publier le SHA du commit comme sortie contrôlée. Le job Mac doit ensuite effectuer un checkout de cette valeur, et non de la branche par défaut. Cette règle évite de tester un état différent de celui que Claude Code vient de produire.

Les permissions du flux doivent être explicites. Commencez avec une lecture du contenu et la création d’un résultat limité. N’autorisez l’écriture sur une branche protégée qu’après revue. Les événements venant d’un dépôt externe, les modifications du fichier de workflow et les scripts ajoutés par une contribution doivent être considérés comme des entrées non fiables. La documentation de sécurité de GitHub Actions rappelle notamment que le code exécuté dans un workflow peut tenter de lire des données accessibles au processus.

Avertissement : un runner auto-hébergé n’est pas une simple machine virtuelle jetable. Des fichiers, caches, processus et identifiants peuvent rester après une tâche. Si vous ne pouvez pas démontrer le nettoyage, ne lui confiez pas de secret de production.

Scénario de modification dans une Issue ou une Pull Request

Dans ce scénario, la tâche de Claude Code est de comprendre une demande, d’examiner les fichiers autorisés et de proposer une modification. Le job peut s’exécuter sur un runner généraliste tant qu’il dispose des outils nécessaires et d’un accès réseau réduit.

La sortie attendue doit contenir au minimum :

  • l’identifiant de l’Issue ou de la Pull Request ;
  • le SHA du commit créé ou sélectionné ;
  • la liste des fichiers modifiés ;
  • le résultat des contrôles statiques disponibles ;
  • la décision de déclencher, ou non, la validation sur Mac.

Ne faites pas dépendre chaque analyse de code d’un Mac distant. Une vérification de formatage, une lecture de fichiers ou une analyse d’API n’a pas besoin de la chaîne Apple. En revanche, un projet qui importe UIKit, SwiftUI, des frameworks macOS ou une configuration de projet Xcode doit être envoyé au runner Mac pour la vérification appropriée.

Le routage peut utiliser une étiquette dédiée, par exemple macos-xcode-<niveau>, ou un groupe de runners réservé au dépôt. Les étiquettes et les groupes ne remplacent pas la confiance : ils indiquent où envoyer la tâche, pas si le contenu est autorisé à accéder aux secrets. Consultez les règles officielles d’attribution des étiquettes aux runners auto-hébergés avant de figer votre nomenclature.

Scénario de construction Xcode

Une fois le SHA transmis, le Mac distant doit vérifier l’environnement avant de lancer une construction. Contrôlez la version active de Xcode, les outils en ligne de commande, le chemin du projet ou de l’espace de travail, le schéma et la méthode de résolution des dépendances. Les commandes exactes doivent venir du projet réel ; ne remplacez pas un schéma absent par une valeur générique.

La commande xcodebuild doit être traitée comme une étape observable. Enregistrez son code de retour, ses journaux et, pour les tests, le paquet de résultats produit par Xcode. La référence Apple de la ligne de commande Xcode décrit les outils et options à vérifier dans votre environnement.

Un runner affiché comme « en ligne » prouve seulement qu’il peut recevoir une tâche. Il ne prouve ni que le bon commit a été récupéré, ni que Xcode est sélectionné, ni que la construction a réussi. Votre critère de succès doit donc combiner :

  1. le SHA attendu présent dans le répertoire de travail ;
  2. le projet et le schéma réellement utilisés ;
  3. le code de retour de la commande ;
  4. le résultat de test ou de construction archivé ;
  5. des journaux accessibles depuis le système de revue.

Si la construction échoue, retournez un résumé structuré à la Pull Request : phase concernée, erreur principale, chemin du journal et identifiant de la tâche. N’autorisez pas Claude Code à supprimer systématiquement les caches, à changer la version de Xcode ou à modifier le runner pour faire disparaître l’erreur. Une correction ponctuelle du projet doit rester dans le commit examiné.

Pour une équipe qui ne possède pas encore de nœud Mac isolable, vous pouvez commencer par examiner les options de Mac distant pour construire avec Xcode. La décision doit cependant venir après la définition des permissions et des preuves d’acceptation, pas avant.

Scénario de simulateur et de tests graphiques

Une construction sans interface graphique, un test sur simulateur et un test visuel n’exigent pas le même état de session. La première opération peut parfois fonctionner dans une session non interactive. Le simulateur doit pouvoir être lancé et rester accessible au processus de test. Une validation graphique peut, elle, dépendre d’une session utilisateur, d’une résolution d’écran ou d’un service qui ne se comporte pas comme une commande SSH ordinaire.

Séparez donc les trois niveaux :

  • construction en ligne de commande : vérification du projet et des dépendances ;
  • test sur simulateur : démarrage du périphérique prévu, installation de l’application et exécution des tests ;
  • test graphique : observation d’une session macOS active, capture éventuelle et contrôle des interruptions.

La documentation Apple sur l’automatisation des tests Xcode doit servir de référence pour les commandes et les résultats attendus. Vérifiez aussi que le périphérique de simulation sélectionné est bien celui du projet, au lieu de considérer qu’un simulateur quelconque suffit.

Après une coupure réseau, vous devez savoir si le processus continue, s’arrête ou laisse un résultat incomplet. Un écran de simulateur qui s’ouvre ne prouve pas qu’un test UI est reproductible sans surveillance. De même, le simulateur ne remplace pas une validation sur matériel réel lorsque le comportement dépend de capteurs, de performances physiques, de notifications ou d’accessoires.

Pour les projets audio, vidéo ou de design, ce contrôle est encore plus strict. Une construction réussie peut coexister avec un rendu incorrect, une ressource absente ou un test visuel impossible à interpréter sans session graphique. Ajoutez alors une preuve adaptée : capture, paquet de résultats, fichier exporté ou comparaison approuvée par un humain.

Scénario de signature et de publication

Par défaut, le job de Claude Code doit produire une construction sans signature de distribution ou une validation qui n’utilise aucun secret de publication. Les certificats, profils, clés du trousseau, jetons de publication et identifiants d’équipe doivent rester dans un périmètre distinct.

Un flux d’archivage signé doit réunir plusieurs conditions : branche protégée, runner dédié, environnement soumis à approbation et entrées limitées à la version examinée. Les scripts d’un Pull Request externe ne doivent pas atteindre ce runner. Les fichiers de workflow modifiables par la contribution doivent eux aussi être revus avant d’autoriser une étape privilégiée.

Apple documente la création de code signé pour la distribution dans sa documentation consacrée à la signature et à l’archivage. Cela ne signifie pas que tous les secrets doivent être injectés dans chaque job. Au contraire, le job qui ne signe pas ne doit pas pouvoir les lire.

Les principaux avantages de cette séparation sont clairs :

  • une modification d’agent peut être testée sans exposer la clé de publication ;
  • un échec de construction ne déclenche pas automatiquement une distribution ;
  • la rotation d’un secret ne nécessite pas de reconfigurer tout le pipeline ;
  • l’audit peut relier l’approbation, le SHA et l’archive produite.

Les limites doivent aussi être assumées :

  • le flux comporte davantage d’étapes et de validations ;
  • le diagnostic d’un échec de signature demande un accès contrôlé ;
  • un runner dédié coûte davantage qu’un environnement généraliste ;
  • la reprise automatique d’une publication interrompue est dangereuse.

Scénario de plusieurs dépôts sur un même Mac

Un Mac partagé entre plusieurs dépôts doit être organisé par niveau de confiance, et non seulement par équipe. Utilisez des groupes de runners distincts lorsque les projets n’ont pas les mêmes secrets, les mêmes contraintes de réseau ou le même cycle de publication. Les règles GitHub relatives à l’accès aux groupes de runners sont à intégrer dans cette décision.

Chaque tâche doit laisser une trace : dépôt, SHA, identifiant du workflow, compte utilisé, répertoire de travail et résultat du nettoyage. Supprimez le checkout, les artefacts temporaires et les fichiers générés qui ne sont pas nécessaires à l’audit. Vérifiez également les caches, les processus persistants et les journaux locaux.

Un runner permanent simplifie la disponibilité, mais augmente le risque de résidu. Un runner recréé ou réinitialisé à chaque tâche réduit ce risque, sans offrir pour autant la même isolation qu’un conteneur Linux éphémère. Les outils Apple, le trousseau, les simulateurs et la session graphique ne se transposent pas automatiquement dans un modèle de conteneur.

La documentation GitHub sur les runners auto-hébergés doit être complétée par un runbook local : démarrage du processus, mise à jour, nettoyage, retrait du groupe et procédure d’urgence. Ne considérez pas la présence du runner dans l’interface comme une preuve de bonne santé.

Reprise après redémarrage

Le redémarrage doit être testé comme une interruption normale du service, pas comme une exception théorique. Votre contrôle doit couvrir l’hôte, le processus du runner, son enregistrement, la session macOS, le répertoire de travail et l’état de la tâche.

Une procédure fiable suit cette séquence :

  1. vérifier que l’hôte répond et que le compte de service est disponible ;
  2. confirmer que le processus du runner est actif et reconnu par le groupe attendu ;
  3. contrôler la version et l’état du répertoire de travail ;
  4. supprimer ou isoler les fichiers laissés par la tâche interrompue ;
  5. retrouver le dépôt, le SHA et l’identifiant du workflow ;
  6. relancer uniquement une étape idempotente après validation des journaux.

Le flux ne doit pas reprendre automatiquement une publication signée interrompue. Un résultat partiel peut être ambigu, et une nouvelle tentative peut produire une archive différente. La reprise automatique est plus acceptable pour une construction ou un test dont les entrées sont figées et dont le résultat peut être comparé.

Règle d’exploitation : si vous ne pouvez pas répondre à « quel commit a été exécuté, dans quel répertoire et avec quels secrets ? », la tâche doit être arrêtée, non relancée.

Décision de déploiement par niveau de confiance

Utilisez les conditions suivantes pour choisir votre architecture :

  • Si le job ne fait que lire le code, modifier des fichiers et produire une proposition, utilisez un runner généraliste et gardez le Mac hors de ce chemin.
  • Si le projet exige Xcode, un simulateur ou un outil Apple, envoyez le SHA vers un runner Mac identifié par une étiquette dédiée.
  • Si la demande vient d’un dépôt externe ou modifie le workflow, refusez l’accès aux secrets et au runner de publication ; utilisez seulement un environnement isolé ou demandez une revue.
  • Si l’archive doit être signée, utilisez un runner distinct, une branche protégée et une approbation humaine.
  • Si le Mac héberge plusieurs dépôts, séparez les groupes selon la confiance et imposez un nettoyage vérifiable.
  • Si le redémarrage n’a pas encore été testé, limitez le système à la construction non signée jusqu’à obtention de preuves.
Scénario Job Claude Code Job Mac distant Arrêt obligatoire
Analyse d’Issue Lecture et modification contrôlée Aucun ou construction simple SHA absent ou permission inattendue
Pull Request interne Proposition et commit Construction et tests Xcode Schéma absent, résultat incomplet
Pull Request externe Environnement sans secrets Runner isolé sans signature Script ou workflow non examiné
Archive de publication Aucun accès au trousseau Runner dédié et approuvé Branche ou approbation manquante
Test graphique Description et préparation Session macOS et simulateur Session perdue ou preuve visuelle absente

Comparaison des modèles d’exploitation

Le tableau suivant ne remplace pas un audit. Il sert à choisir le niveau de contrôle avant une mise en service.

Modèle Avantage principal Risque dominant Usage recommandé
Runner Mac partagé Mise en route rapide et mutualisation Résidus entre dépôts, caches et sessions persistantes Essais internes à faible sensibilité
Runner Mac par équipe Meilleure séparation des projets Administration et maintenance supplémentaires Développement et intégration d’équipe
Runner Mac dédié à la publication Contrôle des secrets et approbation claire Coût et procédure plus lourds Archives et distribution protégées
Mac distant loué pour essai Test d’un environnement réel sans achat immédiat Nécessité de vérifier l’isolation et la reprise Validation temporaire d’un pipeline
Mac local permanent Accès direct aux périphériques et réglages Immobilisation du matériel et maintenance locale Besoin durable de matériel physique

Pour un besoin limité à la validation, vous pouvez évaluer un Mac distant pour un runner Xcode isolé. Si votre équipe doit comparer plusieurs implantations ou organiser une reprise après redémarrage, choisissez d’abord un environnement dont vous pouvez administrer le compte, le répertoire de travail et la procédure de récupération.

Contrôle avant mise en production

Avant d’autoriser le flux à toucher une branche protégée, exécutez un essai complet : Issue ou Pull Request de test, modification par Claude Code, publication du SHA, checkout sur le Mac, construction Xcode, test éventuel sur simulateur, retour des journaux, nettoyage, redémarrage du nœud et nouvelle validation.

Classez ensuite le dispositif selon trois niveaux :

  • Prêt pour le développement : construction non signée, secrets absents, logs exploitables et nettoyage vérifié.
  • Limité à l’équipe : groupe de runners séparé, accès maîtrisé, reprise testée et revue des contributions externes.
  • Prêt pour la publication : runner distinct, approbation d’environnement, branche protégée, audit du SHA et procédure d’arrêt documentée.

Si l’un de ces contrôles échoue, revenez au niveau précédent. Ne compensez pas une mauvaise isolation par davantage de permissions.

Conclusion opérationnelle

Le bon déploiement de Claude Code GitHub Actions sur un Mac distant n’est pas une installation unique de runner. C’est une séparation des responsabilités : l’agent modifie et explique, le Mac construit et teste, tandis que la signature reste dans un périmètre approuvé.

Un runner généraliste expose moins de surface Apple, mais ne peut pas valider Xcode. Un Mac partagé accélère les essais, mais conserve davantage de traces entre les tâches. Une machine dédiée à la publication protège mieux les secrets, au prix d’une procédure plus stricte. Dans tous les cas, le SHA, les journaux, le résultat Xcode et l’état du nettoyage doivent être vérifiables.

Si votre solution actuelle repose sur un Mac personnel laissé allumé, elle introduit généralement trois faiblesses : disponibilité incertaine après redémarrage, mélange entre fichiers privés et tâches CI, et absence de séparation nette pour les certificats. Une machine virtuelle ou un serveur Linux évite parfois ces contraintes, mais ne fournit pas nécessairement l’environnement macOS réel requis par Xcode, le simulateur ou certains workflows audio, vidéo et design.

Pour un essai non productif, louer un Mac auprès de MACCOME peut donc être plus cohérent que d’acheter immédiatement du matériel ou de détourner un poste de développement. Commencez par un nœud administrable et isolable, validez le commit réel, la construction, les journaux et la reprise après redémarrage, puis choisissez seulement ensuite la durée de location et l’éventuel nœud séparé réservé à la publication.