Skip to content

Pipeline iOS (CI CD)

Alexandre Grisey edited this page Sep 25, 2025 · 5 revisions

Ce document décrit le fonctionnement du workflow GitHub Actions ios-action.yml, la liste complète des secrets à provisionner et les actions à mener lors d’un renouvellement de certificats ou de profils de signature.

Vue d’ensemble

Le pipeline se déclenche lorsqu’un tag deploy/ios/* est poussé. Les commandes npm run deploy:* créent ces tags automatiquement. Le workflow prépare les assets web (Vite + Capacitor), applique la configuration associée à l’application sélectionnée (scripts/.selected-app), construit l’archive Xcode en mode production, exporte un .ipa et le publie vers TestFlight via l’API App Store Connect.

Le workflow suppose que tous les secrets détaillés ci-dessous sont présents dans le dépôt GitHub (onglet Settings → Secrets and variables → Actions).

Secrets requis

Secret Application Usage Comment l’obtenir
DISTRIBUTION_CERTIFICATE_P12 Commun Certificat de distribution Apple (fichier .p12 encodé en base64). Exporter le certificat depuis Keychain Access (Fichier → Exporter des éléments…) avec l’identité "Apple Distribution". Puis base64 -i certificat.p12 | pbcopy pour copier la valeur.
P12_PASSWORD_DISTR Commun Mot de passe défini lors de l’export .p12. Choisi librement lors de l’export du certificat; le noter et le enregistrer dans le secret.
KEYCHAIN_PASSWORD Commun Mot de passe temporaire pour le trousseau créé pendant l’action. Générer une chaîne de caractères aléatoire.
DEPLOY_PROVISION_PROFILE_BASE64_ESPACECO EspaceCo Profil de provisioning (distribution) encodé en base64. Créer ou télécharger le profil sur https://developer.apple.com/account/resources/profiles/list (sélectionner le bundle ID d’EspaceCo). Puis base64 -i EspaceCo.mobileprovision | pbcopy. En cas de création de nouveau profile, choisir 'Distribution' et 'App Store Connect' dans les options.
IOS_EXPORT_PRODUCTION_ESPACECO EspaceCo Fichier ExportOptions.plist utilisé pour l’export .ipa (base64). Après une archive manuelle dans Xcode (Product → Archive → Distribute App → Distribute → Export… ou Window → Organizer → Distribute App → Distribute → Export…), récupérer le ExportOptions.plist généré (dans le dossier exporté) et exécuter base64 -i ExportOptions.plist | pbcopy. Attention, le fichier ExportOptions.plist doit être modifié (voir section Renouvellement des certificats/profils plus bas dans cette page)
DEPLOY_PROVISION_PROFILE_BASE64_NAVIFOREST NaviForest Profil de provisioning spécifique à NaviForest (base64). Même procédure que pour EspaceCo mais sélectionner le provisioning profile de NaviForest.
IOS_EXPORT_PRODUCTION_NAVIFOREST NaviForest ExportOptions.plist pour NaviForest (base64). Même procédure que ci-dessus mais sur l’archive NaviForest.
APPSTORE_API_PRIVATE_KEY Commun Clé privée .p8 App Store Connect (base64). Créer une clé API (Admin ou Account Holder) dans https://appstoreconnect.apple.com/access/integrations/api, télécharger le fichier AuthKey_XXX.p8, puis base64 -i AuthKey_XXX.p8 | pbcopy.
APPSTORE_API_KEY_ID Commun Identifiant de la clé API (ex : ABC123DEF). Visible sur la page App Store Connect lors de la création de la clé API.
APPSTORE_ISSUER_ID Commun Identifiant issuer (UUID) de l’organisation App Store Connect. Affiché sur la même page que la clé API.

Remarque : Les valeurs de l'application EspaceCo sont utilisées par défaut si aucune app n'est définie dans le fichier .selected-app.

Déroulé du workflow

  1. Checkout (actions/checkout@v4) : récupération du dépôt pour la branche en cours.
  2. Installation Node.js : installe Node 20 avec cache npm partagé entre runs.
  3. Initialisation .env : crée un fichier .env vierge puis y injecte les secrets applicatifs (API) si présents. Les valeurs manquantes sont simplement ignorées.
  4. npm ci : installe les dépendances avec un lockfile reproductible.
  5. npm run build : prépare l’application web (Vite) et exécute scripts/prepare-app.js pour appliquer la configuration de l’app courante.
  6. npx @capacitor/assets generate --ios : régénère les icônes et splash iOS à partir du contenu resources/.
  7. npx cap sync ios : synchronise le projet Capacitor avec la version web produite.
  8. Détection de l’application (Detect selected app…) :
    • Lit scripts/.selected-app (défaut : EspaceCo).
    • Charge les secrets NaviForest si disponibles, sinon conserve EspaceCo.
    • Valide que les secrets indispensables (profil + export plist) sont fournis, puis exporte leurs valeurs dans GITHUB_ENV.
  9. Installation du certificat et du profil :
    • Décode le certificat .p12 dans le RUNNER_TEMP.
    • Crée un trousseau temporaire, l’ouvre avec KEYCHAIN_PASSWORD, importe le certificat et ajoute le profil de provisioning (issu de la variable précédente).
  10. Affichage des paramètres Xcode : xcodebuild -showBuildSettings pour exposer les réglages de signature dans les logs (utile au diagnostic).
  11. security find-identity (optionnel) : vérifie que les identités de signature sont bien disponibles.
  12. Compilation archive (xcodebuild archive) : génère App.xcarchive en configuration « Release Production » (signature désactivée car gérée à l’export).
  13. Export .ipa (xcodebuild -exportArchive) : transforme l’archive en .ipa à l’aide du ExportOptions.plist correspondant.
  14. Sauvegarde de la clé API App Store : place la clé AuthKey_<ID>.p8 dans ~/private_keys et ~/.appstoreconnect/private_keys/, emplacement attendu par altool.
  15. Upload TestFlight (xcrun altool --upload-app) : téléverse l’IPA vers le compte App Store Connect en utilisant l’API Key / Issuer ID.

Renouvellement des certificats/profils

Lorsque le certificat ou le profil de provisioning expire :

  1. Certificat de distribution

    • Connectez-vous sur https://developer.apple.com/account/resources/certificates/list.
    • Révoquez l’ancien certificat si nécessaire et générez un nouveau certificat Apple Distribution (via un CSR). Téléchargez le .cer.
    • Importez le certificat dans Keychain Access (trousseau login) et rattachez la clé privée.
    • Exportez l’identité en .p12 (clic droit → Exporter) avec un nouveau mot de passe → mettre à jour les secrets DISTRIBUTION_CERTIFICATE_P12 (base64, avec la commande base64 -i certificat.p12 | pbcopy) et P12_PASSWORD_DISTR dans les settings GitHub.
  2. Provisioning profiles

    • Sur https://developer.apple.com/account/resources/profiles/list, ouvrez chaque profil (EspaceCo → EspaceCo_provProf, NaviForest → NaviForest_provProf) et cliquez sur Edit → Generate pour les régénérer en liant le nouveau certificat.
    • Téléchargez chaque profil .mobileprovision puis mettez à jour les secrets DEPLOY_PROVISION_PROFILE_BASE64_<APP> avec base64 -i fichier.mobileprovision | pbcopy.
    • En cas de création de nouveau profile, choisir 'Distribution' et 'App Store Connect' dans les options.
  3. ExportOptions.plist

    • Dans Xcode, créez une archive (Product → Archive) pour chaque app, ou ouvrez l'organizer (Window → Organizer).
    • Utilisez Distribute App pour générer un nouvel ExportOptions.plist (Distribute → Export… dans la fenêtre Xcode, une fois l'.ipa processé).
    • Modifier le contenu du ExportOptions.plist: la valeur de destination doit être export ; la valeur de signingStyle doit être manual ; une clé provisioningProfiles doit être ajoutée et contenir un code similaire à :
<key>provisioningProfiles</key>
  <dict>
    <key>fr.ign.collaboratif</key> <!-- ou fr.ign.navi-forest -->
    <string>EspaceCo_provProf</string> <!-- ou NaviForest_provProf -->
  </dict>
  • Encodez-le en base64 (base64 -i ExportOptions.plist \| pbcopy) et mettez à jour IOS_EXPORT_PRODUCTION_<APP>.
  1. Clé API App Store (si expirée ou révoquée)

  2. Validation

    • Lancer le workflow iOS CI/CD via l’onglet Actions.
    • Vérifier la génération de l’IPA, l’installation du profil et l’upload TestFlight.

Astuces & dépannage

  • Fichier .selected-app absent : la CI construit par défaut EspaceCo. Utilisez npm run selectapp:naviforest pour basculer puis commitez le fichier.
  • Erreur Missing … secret : assurez-vous que tous les secrets requis pour l’app sélectionnée sont présents et valides (copiés sans retour à la ligne supplémentaire).
  • Erreur App Store Connect (altool) : vérifier que le fichier .p8 est toujours valide et que l’utilisateur dispose des droits nécessaires. Renouveler l’API key si besoin.

En cas de doute, réexécuter localement les commandes Xcode (xcodebuild archive/export) sur un Mac de développement pour reproduire les problèmes de signature.

Déploiement depuis la ligne de commande

Trois scripts npm permettent de déclencher directement les pipelines CI/CD tout en incrémentant uniquement les numéros de build :

  • npm run deploy:ios : incrémente CURRENT_PROJECT_VERSION, crée un commit, génère un tag deploy/ios/<timestamp> et pousse l’ensemble (le tag déclenche le workflow iOS).
  • npm run deploy:android : incrémente versionCode, crée un commit, génère un tag deploy/android/<timestamp> et le pousse (déclenche le workflow Android).
  • npm run deploy : applique les deux opérations et pousse les tags deploy/ios/<timestamp> et deploy/android/<timestamp>.

Avant d’exécuter ces commandes :

  1. Vérifiez que le dépôt est propre (git status vide).
  2. Sélectionnez l’application cible via npm run selectapp:espaceco ou npm run selectapp:naviforest.
  3. Assurez-vous d’avoir les droits push sur le dépôt.

Chaque script ajoute un commit chore: bump ... build number, puis pousse ce commit et les tags générés. Les workflows GitHub sont configurés pour démarrer automatiquement dès qu’un tag deploy/ios/* ou deploy/android/* est publié.

Les tags utilisent l’UTC (format YYYYMMDD-HHMMSS). Ils servent d’historique de déploiement; ne les supprimez pas sans raison.

Clone this wiki locally