CI/CD 2026.09.06

Le packaging sur un Mac distant s’arrête-t-il après une coupure SSH ? Solution pour les tâches continues en 2026

Une coupure SSH ne permet pas de conclure qu’un build iOS est arrêté ou terminé. Cet article distingue la connexion, la session Shell, le processus de compilation, la session graphique et le traitement App Store Connect, puis propose une méthode de reprise avec journaux, artefacts et contrôles après redémarrage.

Une tâche de packaging sur Mac distant après coupure SSH ne doit jamais être considérée comme sûre si elle a été lancée directement dans le terminal interactif. Pour un Archive ponctuel, utilisez une session reconnectable et conservez séparément les journaux, le code de sortie et les artefacts ; pour les builds répétés, confiez le travail à un CI Runner ou à une tâche administrée. Les opérations liées au simulateur, au trousseau ou à une autorisation graphique nécessitent en plus une vérification de la session utilisateur.

Cette méthode s’applique aux développeurs Windows ou Linux qui exécutent xcodebuild à distance, aux petites équipes qui veulent programmer des tests nocturnes ou une publication TestFlight, ainsi qu’aux responsables qui ne savent plus si une interruption réseau a arrêté le processus, supprimé les journaux ou laissé un résultat incomplet.

01 Chronologie de contrôle avant toute relance

Imaginez un Archive arrivé à mi-parcours lorsque le réseau local tombe. Après reconnexion, la fenêtre distante ne montre plus la sortie précédente, le processus semble peut-être encore présent et personne ne sait si le binaire peut être envoyé. Dans cette situation, relancer immédiatement toute la chaîne est souvent la décision la plus coûteuse : une première compilation peut encore occuper les ressources, un fichier d’archive peut déjà exister et un upload partiel peut avoir modifié l’état côté App Store Connect.

Nous séparons donc six éléments qui sont fréquemment confondus :

  • la connexion SSH entre votre poste et le Mac ;
  • la session Shell qui a reçu la commande ;
  • le processus xcodebuild ;
  • le fichier journal qui conserve les événements ;
  • la session de connexion de l’utilisateur macOS ;
  • le traitement distant effectué ensuite par App Store Connect.

Ces éléments ne disparaissent pas nécessairement ensemble. Une coupure SSH peut interrompre la commande, laisser le processus actif sans conserver l’affichage, ou laisser un processus vivant alors que la compilation attend une autorisation ou une ressource indisponible. Apple documente la configuration de Remote Login et le format de connexion SSH, mais ne transforme pas une commande interactive en tâche autonome simplement parce qu’elle est exécutée sur un Mac distant dans la documentation Apple sur Remote Login.

Le premier contrôle consiste donc à ne rien supposer à partir de l’écran du terminal. Recherchez le processus autorisé, vérifiez son heure de lancement, examinez le journal et cherchez l’artefact attendu. Si l’un de ces éléments manque, marquez la tentative comme indéterminée au lieu de la déclarer réussie.

02 Choix de méthode selon le scénario

La bonne solution dépend moins de la durée théorique du build que de la manière dont il doit être déclenché et repris. Une compilation manuelle n’a pas les mêmes exigences qu’un service nocturne, et un Archive signé n’a pas les mêmes dépendances qu’un simple build destiné au simulateur.

Scénario Méthode adaptée Preuves à conserver Limite principale
Build ou test lancé ponctuellement Session Shell reconnectable Journal standard, journal d’erreur, code de sortie, xcresult Reprise manuelle après une panne
Archive long avec export Étapes séparées dans une session persistante xcarchive, dossier d’export, journaux par étape Signature et trousseau à contrôler
Commits fréquents ou tests nocturnes CI Runner Identifiant du job, journaux, artefacts, état final Contexte utilisateur à configurer
Service à démarrer après redémarrage Tâche administrée avec launchd ou mécanisme équivalent Journal de démarrage, état du service, résultat du job Ne résout pas automatiquement les autorisations graphiques
Test avec simulateur ou interface graphique Runner associé à une session validée xcresult, état du simulateur, session utilisateur Un processus actif peut rester bloqué

Cette grille ne signifie pas qu’un outil est universellement supérieur. Elle sert à éviter une erreur fréquente : utiliser une session interactive comme infrastructure permanente, puis essayer de déduire la réussite d’un build à partir d’un écran qui n’est plus disponible.

Pour une commande ponctuelle, un terminal reconnectable suffit généralement si les données sont écrites dans des fichiers indépendants. Pour une succession de commits, il faut un déclencheur, un compte d’exécution, une règle de conservation des artefacts et un état consultable sans ouvrir une session SSH manuelle. Pour un redémarrage, le service doit être défini avec un contexte explicite ; la documentation Apple décrit launchd comme le mécanisme de gestion des travaux et de leur contexte de lancement dans la documentation sur les travaux launchd.

03 Préparation d’un build ponctuel avec preuves séparées

Voici une procédure utilisable pour un Build, un Test ou un Archive déclenché manuellement. Les valeurs d’exemple restent volontairement génériques : remplacez chaque élément entre crochets par vos propres données, sans copier un identifiant réel dans un script partagé.

1. Définir un dossier de travail et un dossier de preuves

Avant le lancement, créez un répertoire propre pour le journal et les résultats :

RUN_DIR="$HOME/build-runs/[IDENTIFIANT_JOB]"
mkdir -p "$RUN_DIR/logs" "$RUN_DIR/artifacts"

Le dossier doit contenir le numéro de build, le nom du schéma et une référence de commit, mais jamais une clé privée ou un mot de passe. Cette séparation facilite le diagnostic lorsqu’un ancien xcarchive se trouve encore dans le répertoire du projet.

2. Placer la commande dans une session reconnectable

L’objectif n’est pas de conserver l’image du terminal, mais de maintenir un contexte auquel vous pourrez revenir après une reconnexion. Lancez la session selon l’outil retenu par votre environnement, puis vérifiez que le Shell est bien attaché avant d’exécuter xcodebuild.

Pour un projet Xcode, utilisez les options documentées par Apple et indiquez explicitement le workspace ou le projet, le scheme, la destination et le chemin de sortie. La référence Apple de xcodebuild doit servir de base pour vérifier les options disponibles dans votre version installée.

3. Séparer sortie standard, erreurs et code de sortie

Une redirection unique rend le diagnostic incomplet. Conservez au minimum un fichier pour la sortie standard, un autre pour les erreurs et un fichier final contenant le code de sortie :

LOG_OUT="$RUN_DIR/logs/stdout.log"
LOG_ERR="$RUN_DIR/logs/stderr.log"
STATUS_FILE="$RUN_DIR/logs/exit-status.txt"

xcodebuild \
  -workspace "[NOM_PROJET].xcworkspace" \
  -scheme "[NOM_SCHEME]" \
  -destination 'generic/platform=iOS' \
  archive \
  -archivePath "$RUN_DIR/artifacts/[NOM_APP].xcarchive" \
  >"$LOG_OUT" 2>"$LOG_ERR"

printf '%s\n' "$?" > "$STATUS_FILE"

Le chemin de l’archive doit être distinct du répertoire source. Le code de sortie ne remplace pas l’inspection du résultat, mais il fournit une information vérifiable ; Apple documente les variables et états liés à l’exécution des builds Xcode dans la référence officielle sur l’environnement de compilation.

Si le Shell est interrompu avant l’écriture de exit-status.txt, le résultat doit être déclaré incomplet. Il est dangereux de traiter l’absence de message comme un code zéro.

4. Provoquer une coupure contrôlée

Une fois que le journal indique que la compilation a réellement commencé, déconnectez volontairement SSH. Ne tuez pas le processus et ne supprimez pas le dossier de travail : le but est de tester la dépendance à la connexion, pas de simuler une panne de stockage.

Après la coupure, notez séparément :

  • si le processus est toujours visible ;
  • si la taille du journal évolue ;
  • si le fichier d’archive apparaît ou continue de grossir ;
  • si le Shell peut être rejoint ;
  • si une erreur est écrite après la reconnexion.

L’écran initial ne constitue pas une preuve. Un journal qui cesse de changer peut signaler une fin normale, une attente, une erreur de sortie ou une interruption ; seul le rapprochement avec le code de sortie et l’artefact permet de trancher.

5. Revenir dans la session et vérifier les traces

Reconnectez-vous au Mac, attachez-vous à la session persistante si elle existe, puis lisez les fichiers depuis leur emplacement absolu. Contrôlez le processus sans l’arrêter automatiquement. Toute commande de terminaison doit être précédée d’une vérification de l’identifiant du processus, de son propriétaire et de l’effet possible sur les autres builds.

Pour un Test, recherchez aussi le xcresult. Apple explique comment exécuter les tests et interpréter leurs résultats dans la documentation Xcode consacrée aux tests. Un fichier présent ne suffit pas : vérifiez qu’il correspond à la tentative courante et qu’il n’est pas un reste d’un lancement précédent.

6. Valider l’artefact avant toute nouvelle tentative

Pour un Archive, contrôlez le dossier xcarchive, son horodatage, son contenu et la cohérence avec le numéro de build. Pour un export, conservez un dossier séparé et notez le résultat de l’opération. Apple distingue bien l’Archive, l’export et la distribution dans son parcours de création de code signé et d’export Xcode.

Ne relancez donc pas l’Archive uniquement parce que l’upload n’a pas été confirmé. Une archive valide peut permettre de reprendre à l’étape d’export ou de livraison, alors qu’une commande d’upload interrompue doit être contrôlée avec le numéro de version et le numéro de build avant toute répétition.

04 Séparation des étapes Archive, export et livraison

Une chaîne de publication ne doit pas être considérée comme une seule commande opaque. Nous recommandons de donner à chaque phase son journal et son marqueur de fin :

  1. compilation et création de l’Archive ;
  2. export du paquet distribuable ;
  3. transmission vers App Store Connect ;
  4. traitement et validation côté plateforme.

La fin de la troisième étape ne prouve pas que la quatrième est achevée. Le réseau peut revenir alors que le traitement côté App Store Connect continue, ou un upload peut être accepté avant qu’une erreur de validation ne soit signalée. Le parcours Apple de distribution pour les tests et les releases décrit cette distinction entre préparation, envoi et distribution.

Pour reprendre proprement, utilisez la décision suivante :

  • si l’Archive n’existe pas ou si son journal se termine par une erreur, reprenez la compilation ;
  • si l’Archive est complète mais que l’export manque, reprenez l’export ;
  • si l’export est présent mais que la livraison est incertaine, vérifiez d’abord l’état de la version et du build ;
  • si la livraison est acceptée mais que le traitement reste en attente, ne renvoyez pas le même artefact sans raison documentée.

Cette organisation est particulièrement importante pour un développeur indépendant qui paie du temps de machine à distance : reconstruire tout le projet pour remplacer une étape de livraison incertaine consomme des ressources et augmente le risque de créer plusieurs artefacts portant des numéros difficiles à suivre.

05 Limites du simulateur, du trousseau et de la session graphique

Un processus xcodebuild encore présent ne signifie pas que toutes ses dépendances fonctionnent. Un Build générique peut continuer alors qu’un test avec simulateur attend une session utilisateur. Une signature peut échouer parce que le trousseau n’est pas accessible dans le contexte du compte qui exécute le job. Une autorisation graphique peut être valable dans une session ouverte, mais absente après une déconnexion.

Apple distingue les contextes de processus et les sessions de connexion dans la documentation consacrée aux contextes système. Nous séparons donc les essais :

  • Build sans simulateur ni signature de distribution ;
  • Test sur simulateur ;
  • Archive avec accès au trousseau ;
  • export signé ;
  • tâche lancée après fermeture de session ;
  • tâche relancée après redémarrage.

Ne désactivez pas au hasard les protections du trousseau, ne rendez pas une clé accessible à tous les processus et ne modifiez pas les autorisations de fond sans noter l’impact et le retour arrière. Si une modification est indispensable, limitez-la au compte de service concerné, documentez la permission ajoutée et prévoyez une suppression contrôlée après le test.

Pour des opérations audio, vidéo ou de design qui utilisent des outils graphiques en complément de la chaîne iOS, cette distinction est encore plus importante : un encodage ou un rendu peut rester actif en arrière-plan, tandis qu’une étape nécessitant une interface ou une session utilisateur échoue silencieusement. Il faut alors tester le processus et le contexte graphique séparément.

06 Bascule vers un Runner pour les tâches répétées

Une session reconnectable est un bon filet de sécurité pour un lancement manuel, mais elle devient fragile lorsqu’elle porte chaque nuit les mêmes responsabilités. Les commits fréquents, les tests programmés et les livraisons régulières doivent être confiés à un CI Runner ou à une tâche administrée dont le démarrage ne dépend pas de la fenêtre SSH d’un développeur.

Le Runner doit posséder :

  • un compte d’exécution clairement identifié ;
  • un répertoire de travail nettoyé entre deux jobs ;
  • des journaux horodatés et consultables ;
  • une conservation explicite des artefacts ;
  • un code de sortie exploitable par l’orchestrateur ;
  • une procédure après échec ;
  • un test de redémarrage de la machine.

launchd peut convenir au démarrage et à la supervision d’un travail local, mais son utilisation ne transforme pas automatiquement une commande en pipeline de publication. Il faut encore vérifier les variables d’environnement, les chemins absolus, l’accès au trousseau, la session graphique et le réseau. Lisez également notre guide de choix d’un Mac distant pour le packaging iOS avant de décider si une machine personnelle peut réellement rester disponible pour ces tâches.

Un Mac qui dort, redémarre sans service restauré ou perd son contexte utilisateur ne fournit pas la même continuité qu’un environnement administré. Si le Runner est installé sur une machine que personne ne peut surveiller, prévoyez une alerte sur l’absence de résultat, et non seulement une alerte sur l’arrêt du processus.

07 Checklist d’acceptation avant une publication réelle

Utilisez cette liste sur le Mac qui devra réellement produire les builds. Chaque case doit être validée avec un artefact ou une observation conservée ; une réponse basée uniquement sur l’affichage SSH ne suffit pas.

  • [ ] Le Build, le Test et l’Archive possèdent chacun un répertoire de résultat distinct.
  • [ ] La sortie standard et les erreurs sont écrites dans deux journaux séparés.
  • [ ] Le code de sortie est enregistré même lorsque la commande échoue.
  • [ ] Le chemin du xcresult, du xcarchive ou du dossier exporté est documenté.
  • [ ] Une coupure SSH volontaire a été réalisée pendant un build réel.
  • [ ] La reconnexion permet de retrouver le processus ou son état final sans relancer la chaîne.
  • [ ] Un Archive complet peut être distingué d’un dossier résiduel.
  • [ ] Un export interrompu peut être repris sans recréer inutilement l’Archive.
  • [ ] Le numéro de version et le numéro de build sont vérifiés avant une nouvelle livraison.
  • [ ] Un test avec simulateur a été exécuté dans le contexte utilisateur prévu.
  • [ ] La signature a été vérifiée avec le compte de service réel.
  • [ ] Le comportement après fermeture de session est connu.
  • [ ] Le comportement après redémarrage du Mac est connu.
  • [ ] Le Runner ou la tâche administrée laisse un état consultable après échec.
  • [ ] Une procédure de retour arrière existe pour toute modification de permission ou de trousseau.

Si une seule case critique reste vide, conservez la méthode comme environnement de test et ne la présentez pas comme serveur de packaging fiable. Nous recommandons notamment de considérer comme bloquantes l’absence de journaux complets, l’impossibilité de distinguer une ancienne archive et l’absence de validation après redémarrage.

08 Questions fréquentes sur la reprise des tâches

SSH interrompu et processus xcodebuild

Une commande lancée directement dans le Shell peut dépendre de la session qui l’a créée. Dans d’autres configurations, le processus peut continuer, mais sans sortie visible dans le terminal initial. Il faut donc vérifier le processus, les journaux, le code de sortie et l’artefact, plutôt que d’appliquer une règle universelle à tous les Mac.

Reconnexion à une compilation en cours

Reconnectez-vous, recherchez la session persistante ou le contexte du Runner, puis consultez les journaux depuis leur chemin absolu. N’arrêtez pas immédiatement le processus retrouvé : contrôlez son propriétaire, son heure de lancement et son fichier de sortie. Un résultat déjà terminé doit être validé avant toute nouvelle exécution.

Build nocturne et choix d’architecture

Pour une tâche isolée, la session reconnectable réduit le risque de perdre l’affichage. Pour un build nocturne, un CI Runner fournit une meilleure séparation entre déclenchement, exécution, journaux et artefacts. Une tâche launchd peut compléter cette architecture après redémarrage, mais elle doit être testée avec le compte et les autorisations réellement utilisés.

Reprise après redémarrage

Après un redémarrage, vérifiez d’abord que le service est lancé, que son journal est accessible et que le compte dispose des outils nécessaires. Ensuite seulement, testez un Build sans signature, puis une opération signée et enfin un test avec simulateur. Cette progression permet de distinguer un problème de démarrage d’un problème de trousseau ou de session graphique.

Upload interrompu et risque de doublon

La reprise d’une commande d’envoi ne doit pas être décidée à partir d’un message SSH incomplet. Vérifiez l’état de la version, le numéro de build et l’artefact exporté. Si App Store Connect a déjà accepté le fichier, reconstruire ou renvoyer sans contrôle peut créer une confusion opérationnelle, même si la compilation locale était parfaitement valide.

09 Validation finale et choix du Mac distant

Réalisez trois familles de tests avant de confier une publication à l’environnement : déconnexion SSH pendant la compilation, fermeture ou changement de session utilisateur pendant une opération sensible, puis redémarrage du Mac avec relance du service. Pour chacune, conservez le journal, le code de sortie, le résultat xcresult ou xcarchive, l’état de l’export et la possibilité réelle de poursuivre la livraison.

Si l’environnement actuel dépend d’un ordinateur personnel toujours allumé, il cumule plusieurs faiblesses : disponibilité incertaine, redémarrage non surveillé, espace de stockage partagé et absence de séparation claire entre votre session de travail et le compte de build. Un simple serveur distant non macOS ajoute en outre l’obstacle de Xcode, du simulateur et des outils de signature Apple. Dans ce contexte, continuer à relancer manuellement la même chaîne après chaque coupure coûte souvent plus cher en temps que la location d’un Mac administré.

Après l’acceptation des tests, consultez les solutions de location de Mac distant de JEXCLOUD si vos tâches nécessitent une machine disponible, un accès administrateur et un environnement séparé de votre poste personnel. Cela ne remplace pas la configuration des journaux, du Runner ou du trousseau, mais fournit une base plus cohérente pour un build nocturne ou une publication ponctuelle. Si le besoin porte sur une charge permanente et prévisible, l’achat d’un Mac dédié peut rester plus rationnel ; pour les essais, les sorties irrégulières ou la mise en place progressive d’une chaîne iOS, la location évite en revanche de maintenir un ordinateur personnel allumé en permanence.

JEXCLOUD

Poursuivez vos tâches continues avec un Mac distant JEXCLOUD

Louez un Mac distant JEXCLOUD pour exécuter vos compilations et vos tâches de packaging dans un environnement accessible à distance.

Séparez la connexion SSH du processus de build afin de mieux gérer les coupures et de reprendre vos opérations avec méthode.

Louer maintenant