Échec d’export IPA avec xcodebuild : comment le corriger sur un Mac distant en 2026 ?
📋 Table des matières
Archive réussi, dossier d’export vide : vous avez probablement confondu la création de l’archive avec la génération de l’IPA.
La correction la plus rapide consiste à conserver le même fichier xcarchive, puis à comparer un export graphique avec xcodebuild -exportArchive avant de modifier le code. Contrôlez ensuite, dans cet ordre, ExportOptions.plist, les certificats, la clé privée, le Provisioning Profile, les entitlements et les droits de la session distante. Ne relancez pas une compilation complète tant que l’erreur d’export n’est pas isolée.
Cet article s’adresse à vous si vous exécutez xcodebuild par SSH ou dans un script d’intégration continue, si l’archive se termine correctement mais qu’aucun IPA n’est créé, ou si l’export fonctionne sur votre Mac local et échoue sur votre machine distante. Il convient aussi aux petites équipes qui doivent distinguer rapidement Build, Archive, Export et Upload.
Archive, export et dépôt : quatre résultats différents à ne pas mélanger
Le premier contrôle consiste à nommer précisément l’étape qui échoue. Apple distingue la distribution d’une application, la préparation de l’archive et les opérations liées à l’envoi. La documentation Apple sur la distribution avec Xcode décrit ce passage entre archive, export et distribution ; elle ne permet pas de conclure qu’une archive réussie donnera automatiquement un IPA.
Dans votre journal, séparez donc les résultats suivants :
- Build : le projet et ses dépendances sont compilés pour une destination donnée.
- Archive : Xcode produit un paquet
xcarchiveexploitable dans Organizer. - Export : le contenu de l’archive est préparé selon une méthode de distribution et signé pour cette destination.
- Upload : le fichier exporté est transmis à App Store Connect ou à un autre service accepté.
Un message comme « Archive succeeded » ne valide que la deuxième étape. Si le script échoue ensuite pendant exportArchive, supprimer l’archive et reconstruire le projet ne traite pas nécessairement le problème. Vous risquez au contraire de changer simultanément le code, les dépendances, l’état du trousseau et les fichiers temporaires, ce qui rend la comparaison impossible.
Commencez par créer un dossier de preuve distinct. Copiez-y la commande exacte, la sortie complète du terminal, le journal de distribution, le chemin de l’archive et le contenu non sensible du fichier d’options. Remplacez les noms du projet, le Bundle ID, le Team ID, le nom du certificat, l’identifiant du profil, le nom d’utilisateur et les chemins personnels par des valeurs neutres avant tout partage.
Même archive, deux chemins d’export : le test qui réduit le périmètre
Votre objectif n’est pas encore de réparer la chaîne complète. Il est de savoir si l’archive est saine ou si le problème apparaît uniquement lorsque xcodebuild interprète les options et la session distante.
| Indicateur contrôlé | Export graphique depuis Organizer | Export avec xcodebuild |
Décision |
|---|---|---|---|
Même xcarchive |
Oui | Oui | Toute différence vient de l’export ou de l’environnement |
| Même destination de distribution | Vérifiée dans l’interface | Déclarée dans ExportOptions.plist |
Corriger la méthode avant de toucher aux profils |
| Même compte macOS | Session graphique | Session SSH ou tâche CI | Comparer trousseau, répertoire et droits |
| Même identité de signature | Visible dans le flux de distribution | Résolue par la machine | Vérifier certificat et clé privée |
| Même emplacement de sortie | Dossier accessible | Chemin créé par le script | Tester l’écriture et la conservation des logs |
| Même résultat attendu | IPA lisible et identifiable | IPA créé au même endroit | Valider le fichier avant l’upload |
Si Organizer exporte cette archive et que la commande échoue, le projet n’est pas votre première hypothèse. Comparez d’abord la configuration et la session. À l’inverse, si Organizer échoue également avec la même archive, inspectez le contenu du paquet et les ressources de signature avant de modifier le script.
Pour exécuter cette comparaison, utilisez une archive conservée après un build Release destiné à un appareil générique. Relancez uniquement l’export avec les mêmes paramètres. La commande doit référencer explicitement archivePath, exportOptionsPlist et exportPath, conformément aux possibilités exposées par le xcodebuild -help de la machine cible. Les noms de clés et les valeurs acceptées doivent être vérifiés dans cet environnement, pas copiés d’un ancien modèle trouvé dans un dépôt.
Attention : ne supprimez pas immédiatement un profil, ne révoquez pas un certificat et ne réinitialisez pas le trousseau. Exportez d’abord les journaux, sauvegardez les fichiers nécessaires et notez la possibilité de retour arrière. Ces opérations peuvent interrompre d’autres applications ou pipelines qui utilisent la même identité.
Un xcarchive complet face à une archive seulement compilée
Un fichier xcarchive peut exister tout en étant impropre à la distribution attendue. Examinez son contenu sans exposer les données d’équipe. Vous devez retrouver l’application principale, les extensions éventuelles, les frameworks intégrés, les informations d’identification de l’archive et les données de signature nécessaires à l’étape suivante.
Vérifiez en particulier les éléments suivants :
- le Scheme utilisé correspond bien à la cible de publication ;
- la Configuration est celle prévue pour la distribution ;
- la destination ne produit pas une archive de simulateur à la place d’un paquet destiné à un appareil ;
- l’application principale et chaque extension possèdent le Bundle ID attendu ;
- les frameworks imbriqués ne portent pas une signature incompatible ;
- les entitlements enregistrés dans l’archive correspondent aux capacités réellement utilisées.
Les projets qui contiennent une extension, un App Clip ou une cible secondaire demandent une lecture par cible. Une application peut sembler correctement archivée alors qu’une extension réclame un profil différent, une capacité absente ou une identité qui n’est pas disponible sur le compte de la session distante.
L’outil graphique permet de lancer une validation ou une distribution à partir de la même archive. Utilisez ce résultat comme point de comparaison, pas comme preuve absolue que la commande distante est saine. Si la validation graphique signale déjà un problème dans l’archive, corrigez le Scheme, les cibles ou les ressources avant de revenir au script.
ExportOptions.plist : comparer la destination avant les signatures
Le fichier ExportOptions.plist ne décrit pas une préférence générale pour tous les projets. Il traduit un objectif de distribution précis. Un export destiné à des appareils enregistrés ne se vérifie pas comme un export destiné à App Store Connect. Réutiliser le même fichier sans confirmer cette destination crée une erreur difficile à lire, surtout lorsque le profil et la méthode de signature ont été changés entre-temps.
Procédez avec une configuration de référence obtenue après une exportation graphique réussie. Comparez ensuite :
- la méthode de distribution sélectionnée ;
- l’équipe associée au projet ;
- le mode de gestion de la signature ;
- la correspondance entre chaque Bundle ID et son profil ;
- le chemin d’export ;
- les options réellement affichées par
xcodebuild -help.
Ne concluez pas qu’une clé est universelle parce qu’elle apparaît dans un exemple ancien. Les options disponibles et leur interprétation dépendent de la version de Xcode installée. La commande locale est donc une source opérationnelle plus fiable qu’un modèle non daté, tandis que la documentation Apple sur les certificats et la page consacrée aux profils de provisioning servent à vérifier le rôle des actifs.
Si vous modifiez le fichier, changez un seul groupe de paramètres à la fois. Gardez la copie précédente, notez l’effet observé et rejouez l’export sur la même archive. Une telle discipline permet de distinguer une destination mal déclarée d’un défaut de signature.
Signature, profil et entitlements : trois contrôles, pas un seul
L’export doit réunir une identité de signature utilisable, une clé privée accessible, un Provisioning Profile adapté et des entitlements cohérents. Importer uniquement un certificat ne suffit pas : sans la clé privée correspondante, la session ne peut pas signer le produit final.
La vue d’ensemble officielle des certificats Apple vous aide à distinguer les usages des certificats. Dans votre environnement, vérifiez séparément :
- la présence du certificat attendu dans le trousseau ;
- la présence de sa clé privée associée ;
- l’accès de l’utilisateur distant à cette clé ;
- la validité et la destination du profil ;
- les capacités autorisées par le profil ;
- les entitlements présents dans l’application archivée ;
- la cohérence de ces éléments pour les extensions et frameworks imbriqués.
En gestion automatique, confirmez que le compte et l’autorisation nécessaires sont disponibles dans la session qui exécute la tâche. En gestion manuelle, contrôlez la correspondance explicite entre les identifiants de cible et les profils. Les rôles du compte peuvent aussi limiter certaines actions : consultez la matrice officielle des autorisations App Store Connect au lieu de supposer qu’un compte capable de consulter un projet peut gérer tous ses actifs.
Ne révoquez pas les certificats comme première réaction. Une révocation peut casser un autre pipeline, un poste local ou une version déjà préparée. Exportez d’abord les éléments de diagnostic, identifiez la cible concernée, puis remplacez l’actif uniquement si la preuve montre qu’il est absent, expiré ou incompatible.
Session graphique contre SSH : l’environnement est une partie du build
Un export local réussi prouve seulement que la combinaison « compte macOS, trousseau, répertoire de développement, variables et chemins » fonctionne dans cette session. Une tâche SSH peut démarrer avec le même nom d’utilisateur tout en possédant un contexte différent.
Comparez une exécution interactive et une exécution automatisée sous le même compte. Contrôlez notamment :
- le chemin courant et les droits du dossier de sortie ;
- le répertoire développeur actif ;
- les variables qui modifient les chemins de travail ;
- l’accès au trousseau et à la clé privée ;
- les autorisations accordées à l’outil de signature ;
- l’existence des dossiers temporaires ;
- la conservation des journaux après l’échec ;
- la présence du même fichier
xcarchive.
Une erreur de chemin peut donner l’impression que l’IPA n’a pas été créé alors qu’il a été écrit ailleurs. Un nettoyage automatique peut aussi supprimer l’archive ou le journal avant votre inspection. Désactivez temporairement cette suppression dans un espace de test, puis rétablissez-la après validation.
Si l’accès à la clé privée réclame une intervention graphique, la tâche n’est pas prête pour un fonctionnement sans surveillance. Il faut alors corriger les autorisations selon votre politique de sécurité, sans enregistrer de secret dans le script. Documentez l’utilisateur concerné, l’origine de la session et le dossier de travail afin de pouvoir reproduire le test après une reconnexion.
Pour un besoin régulier, comparez cette procédure avec un environnement Mac distant pour les charges de développement. Le critère n’est pas seulement l’accès à macOS : il faut pouvoir répéter un export depuis la même archive, récupérer les journaux et redémarrer la tâche sans perdre les preuves.
Si vous devez évaluer le coût d’une machine dédiée avant de déplacer votre pipeline, consultez aussi le guide des tarifs d’un Mac mini M4. Cette comparaison doit intégrer la maintenance, la disponibilité du poste, la conservation des actifs de signature et le temps consacré au dépannage, pas uniquement le prix du matériel.
FAQ de diagnostic pour un export distant sans surveillance
Pourquoi l’archive est-elle réussie alors que le dossier IPA reste vide ?
Parce que la création de l’archive et son export ne valident pas exactement les mêmes éléments. L’archive peut contenir une application compilée, tandis que l’export doit encore appliquer la destination, la signature, le profil et les entitlements. Le premier contrôle consiste donc à rejouer l’export avec la même archive et à lire la première erreur utile, plutôt que le dernier code de sortie.
Que faire lorsqu’exportArchive renvoie l’exit code 70 ?
Traitez ce code comme le symptôme d’un échec à qualifier, non comme une cause unique. Conservez la sortie complète et le journal de distribution, puis comparez l’export graphique et la commande distante. Vérifiez ensuite ExportOptions.plist, le Bundle ID, le profil, la clé privée et le chemin de sortie. Les cas rapportés dans les forums Apple sont des pistes individuelles, pas une règle générale.
Comment valider les options de distribution ?
Identifiez d’abord le canal visé, puis comparez le fichier avec une exportation graphique réussie. Vérifiez la méthode, l’équipe, la gestion de signature et les profils des cibles. Exécutez également xcodebuild -help sur le Mac qui effectuera réellement la tâche. Si une clé ou une valeur n’est pas proposée par cette version, ne la conservez pas par simple habitude.
Pourquoi SSH échoue-t-il alors que l’export graphique fonctionne ?
Les deux sessions peuvent différer par le trousseau, le répertoire actif, les variables, le chemin de sortie et les droits accordés à la clé privée. Un test graphique ne valide donc pas automatiquement un lancement SSH. Comparez les contextes sous le même utilisateur, conservez les fichiers temporaires et vérifiez où le script écrit réellement l’IPA avant de modifier la signature.
Comment savoir si le Mac distant peut devenir un serveur de publication ?
Il doit réussir un export à partir d’une archive conservée, retrouver le même résultat après une reconnexion et préserver ses journaux après un redémarrage contrôlé. L’IPA doit être présent au chemin attendu et les actifs de signature doivent être accessibles sans clic manuel. Si la réussite dépend d’Organizer ou d’une session ouverte, corrigez l’environnement avant d’y confier une publication récurrente.
La matrice d’acceptation avant de modifier votre infrastructure
Après chaque correction, ne validez pas seulement la présence d’un message « succeeded ». Inscrivez, pour la même archive, la méthode choisie, le profil utilisé, l’identité de signature, le chemin de sortie, la présence de l’IPA, la conservation du journal et le résultat après reconnexion.
Une ligne « échec » doit préciser l’indicateur qui a échoué et l’action suivante. Par exemple, une archive lisible mais exportable uniquement depuis Organizer pointe vers la configuration ou la session ; une archive refusée dans les deux contextes pointe plutôt vers son contenu, les capacités ou les actifs de signature. Cette matrice évite de relancer une compilation qui ne change aucun des paramètres contrôlés.
Vous pouvez ensuite automatiser une validation légère : vérifier que l’archive attendue existe, que l’export retourne un résultat exploitable, que le fichier IPA est présent au chemin prévu et que le journal est conservé. L’envoi vers App Store Connect reste une étape distincte. Les statuts officiels des téléversements de builds Apple sont donc à consulter seulement après l’obtention d’un paquet exporté.
Quand remplacer le Mac actuel par un Mac distant dédié
Si le projet s’archive et s’exporte correctement dans une session graphique, mais que l’accès SSH reste instable, le défaut se trouve probablement dans l’environnement d’exécution plutôt que dans le code. Une machine dédiée permet de séparer le poste de travail, les profils de signature, les fichiers temporaires et le rôle de serveur de publication. Elle ne dispense toutefois pas de valider les droits du trousseau et la conservation des journaux.
La location d’un Mac distant devient pertinente pour un besoin temporaire, une migration, une phase de test ou une petite équipe qui ne souhaite pas acheter une machine uniquement pour l’export. Elle est moins adaptée si vous avez besoin d’un poste physique permanent, de périphériques locaux spécifiques ou d’une charge lourde et stable sur une longue période. Dans ce dernier cas, comparez aussi le coût total d’un achat, de la maintenance et de la sécurisation des actifs.
Si votre machine actuelle mélange session graphique, scripts SSH, nettoyages agressifs et profils partagés, ses défauts sont concrets : diagnostic difficile, dépendance à un utilisateur précis, perte des journaux après échec et récupération manuelle de la clé privée. Tester une machine MacDate avec la même archive permet de comparer ces points sans réécrire le projet. Commencez par l’export reproductible, poursuivez avec la reconnexion et le redémarrage, puis décidez seulement après si elle doit devenir votre serveur de compilation permanent.
Ne considérez donc pas l’IPA comme la conséquence automatique d’une archive réussie. La bonne décision consiste à figer l’archive, mesurer chaque indicateur et corriger le premier écart démontré ; si l’écart vient du poste distant, déplacez l’export vers une machine MacDate après une validation complète, plutôt que de reconstruire indéfiniment le même projet.