L'automatisation transforme les builds Expo et les mises à jour over-the-air (OTA) en un flux prévisible et à faible friction qui s'exécute à chaque commit. Ce guide vous accompagne dans la mise en place d'un parcours CI/CD sûr et progressif pour les projets Expo, en utilisant des canaux basés sur les branches, des portes de validation et des procédures de rollback pratiques. Vous apprendrez à connecter GitHub Actions ou GitLab CI à EAS Build et EAS Update, à vérifier ce qui a été déployé et à récupérer rapidement en cas de problème.
La façon la plus rapide de réussir est de commencer petit. Lancez un pipeline de prévisualisation Android unique, facile à inspecter, puis étendez-le à la production et à iOS une fois qu'il s'avère stable.
Inventaire des versions et de l'environnement
Avant de câbler un pipeline, verrouillez les versions, la topologie, les identifiants et les rôles.
Outils pris en charge
- Node.js : LTS (par exemple 18.x ou 20.x)
- Gestionnaire de paquets : npm ou yarn
- Expo SDK : aligné avec votre application (par exemple SDK 50 ou 51)
- EAS CLI : dernière version (installation via npm)
- Fournisseur Git : n'importe lequel (les exemples utilisent GitHub Actions et GitLab CI)
Prérequis
- Compte Expo et jeton d'accès personnel (EXPO_TOKEN)
- Keystore Android et signature iOS configurés dans EAS (vous pouvez les stocker et les gérer dans EAS)
- Projet utilisant Expo Updates (managed ou bare), avec une stratégie runtimeVersion définie
- Branches protégées définies dans votre dépôt (par exemple main pour la production, develop pour la prévisualisation)
Topologie de dépôt exemple (cas simple)
- Dépôt d'application unique
- Branches :
- main : production
- develop : prévisualisation
Secrets et variables
Stockez les secrets dans votre système CI. Ne les commitez pas dans le dépôt.
| Nom | Exemple de valeur | Objectif |
|---|---|---|
| EXPO_TOKEN | expo1...redacted | Authentification non interactive pour EAS CLI |
| NODE_VERSION | 20 | Fixer la version Node pour des builds cohérents |
Profils eas.json minimaux
Placez ce fichier à la racine du projet pour décrire les profils de build et de soumission. Adaptez-le à votre application et votre SDK.
{
"cli": {
"version": ">= 3.16.0"
},
"build": {
"preview": {
"channel": "preview",
"android": {
"gradleCommand": ":app:bundleRelease"
},
"ios": {
"image": "latest"
}
},
"production": {
"channel": "production",
"android": {
"gradleCommand": ":app:bundleRelease"
},
"ios": {
"image": "latest"
}
}
},
"submit": {
"production": {
"android": {
"track": "internal"
},
"ios": {
"ascAppId": "VOTRE_ASC_APP_ID"
}
}
}
}
Notes :
- Le champ
channeldéfinit le canal Expo Updates par défaut pour le binaire produit par ce profil. - Pour un premier pilote, ciblez les builds Android de prévisualisation et les mises à jour OTA uniquement.
Parcours de configuration sécurisé
Ce parcours met en œuvre un pilote étroit et mesurable que vous pourrez étendre plus tard.
1) Authentifier et initialiser
Exécutez ces commandes localement une fois pour vous assurer qu'EAS connaît votre projet.
npm i -g eas-cli
expo login # ou : eas login
# Initialiser le projet EAS s'il n'est pas encore lié
cd votre-app
EAS_NO_VCS=1 eas init --id VOTRE_PROJECT_ID
Résultat attendu : EAS CLI confirme le projet lié et peut lire eas.json.
2) Créer les canaux et confirmer le mappage
Créez des canaux qui correspondent à votre stratégie de branches.
eas channel:create preview --non-interactive
eas channel:create production --non-interactive
# Inspecter les canaux
eas channel:list
Résultat attendu : les canaux preview et production existent et apparaissent dans la liste.
3) Ajouter des portes de validation
Placez les builds et les mises à jour derrière des vérifications rapides :
expo doctorouexpo-doctorpour détecter les mauvaises configurations.- Tests unitaires et vérifications de types le cas échéant.
# Exemple de vérifications locales
npx expo-doctor
npm test --silent || yarn test --ci
Résultat attendu : aucune erreur dans la sortie expo-doctor. Les tests passent.
4) Exemple CI : GitHub Actions (Android Preview + Production)
Ce workflow :
- S'exécute sur les pushes vers main et develop.
- Installe Node et les dépendances.
- Valide avec expo-doctor et les tests.
- Sur develop : envoie une mise à jour OTA vers le canal preview.
- Sur main : lance un build cloud avec le profil production.
name: expo-ci
on:
push:
branches: [main, develop]
jobs:
expo:
runs-on: ubuntu-latest
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
NODE_VERSION: '20'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Install dependencies
run: |
yarn install --frozen-lockfile || npm ci
- name: Install EAS CLI
run: npm i -g eas-cli
- name: Validate with expo-doctor
run: npx expo-doctor
- name: Run tests
run: |
if [ -f package.json ]; then
(yarn test --ci || npm test) || exit 1
fi
- name: Authenticate to EAS
run: |
eas whoami || eas account:login --token "$EXPO_TOKEN"
- name: OTA update to preview on develop
if: github.ref == 'refs/heads/develop'
run: |
eas update \
--branch preview \
--message "CI: ${GITHUB_SHA}"
- name: Build production binary on main
if: github.ref == 'refs/heads/main'
run: |
eas build \
--platform android \
--profile production \
--non-interactive
Résultat attendu :
- develop : une mise à jour OTA apparaît sur le canal preview.
- main : un nouveau build Android production démarre sur EAS Build.
Notes :
- EAS Build s'exécute dans le cloud ; votre workflow n'a pas besoin d'Android SDK ou Xcode localement.
- Ajoutez un second job ou étendez l'étape de build pour inclure iOS une fois le pilote stable.
5) Exemple CI : GitLab CI (minimal)
Ce pipeline minimal utilise les mêmes étapes pour une mise à jour OTA de prévisualisation.
stages:
- validate
- update
variables:
NODE_VERSION: '20'
validate:
image: node:20
stage: validate
script:
- yarn install --frozen-lockfile || npm ci
- npx expo-doctor
- yarn test --ci || npm test
preview_update:
image: node:20
stage: update
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
script:
- npm i -g eas-cli
- eas account:login --token "$EXPO_TOKEN"
- eas update --branch preview --message "CI: $CI_COMMIT_SHORT_SHA"
Résultat attendu : sur les commits de la branche develop, une mise à jour OTA preview est publiée.
6) Soumission aux stores (après le build)
Lorsque les builds de production sont stables, ajoutez une étape de soumission. Vous pouvez déclencher la soumission en utilisant le dernier build terminé.
# Android (exemple : piste interne)
eas submit -p android --latest --profile production --non-interactive
# iOS (une fois configuré)
eas submit -p ios --latest --profile production --non-interactive
Résultat attendu : les soumissions démarrent dans leurs stores respectifs en utilisant les derniers artefacts de build EAS.
Vérification et diagnostics
Concentrez-vous sur les signaux observables pour savoir exactement ce qui a été expédié et où.
Vérifier une mise à jour OTA
Lister les mises à jour sur la branche cible :
eas update:list --branch preview
Résultat attendu : le dernier groupe de mises à jour affiche votre message de commit et la version d'exécution.
Confirmer que le canal pointe vers le bon groupe de mises à jour :
eas channel:list
Résultat attendu : les canaux preview et production existent et pointent vers les groupes de mises à jour attendus.
Journalisation optionnelle dans l'application (exemple construit) :
// App.tsx (exemple construit uniquement)
import * as Updates from 'expo-updates';
console.log('Canal Expo:', (Updates as any).channel || 'inconnu');
console.log('ID mise à jour:', (Updates as any).updateId || 'inconnu');
Résultat attendu : l'application journalise le canal et l'ID de mise à jour correspondant à votre déploiement au lancement.
Vérifier un build
Depuis les logs CI, capturez l'URL EAS Build affichée par la CLI, ou listez les builds :
eas build:list --limit 5
Résultat attendu : l'entrée la plus récente correspond à votre branche et votre profil (par exemple production, android).
Diagnostics d'environnement
Lorsque les builds se comportent de manière incohérente, capturez les versions des outils en CI et localement :
eas --version
node --version
yarn --version || npm --version
npx expo-doctor
Résultat attendu : les versions sont fixées et cohérentes avec votre inventaire documenté ; expo-doctor ne signale aucune erreur.
Modes de défaillance et récupération
Même avec des garde-fous, des problèmes surviennent. Préparez les étapes de récupération à l'avance.
Défaillances courantes du pipeline et correctifs rapides
| Défaillance | Symptôme | Correctif rapide |
|---|---|---|
| EXPO_TOKEN manquant | EAS CLI demande une connexion ou quitte | Ajouter le secret EXPO_TOKEN et se connecter avec --token |
| expo-doctor cassé | Étape de validation échoue | Corriger les dépendances peer, versions SDK, problèmes app.json/app.config |
| Build Android échoue à Gradle | Erreur de build dans les logs EAS cloud | Vérifier gradleCommand, mémoire dans les logs EAS, compatibilité modules natifs |
| Problèmes de signature iOS | EAS Build échoue avec erreurs de signature | Re-provisionner les identifiants dans EAS, vérifier bundle ID et ASC app id |
| Mise à jour non visible | L'appareil ne récupère pas la nouvelle OTA | Confirmer le mappage de canal, compatibilité runtimeVersion, réinstallation de l'app avec le bon canal |
| Échec de soumission | Le store rejette l'artefact | Vérifier package name/bundle id, incrémentation versionCode/buildNumber, permissions de piste |
Rollback OTA
Si une OTA preview ou production cause des problèmes :
- Identifiez le dernier groupe de mises à jour connu comme bon :
eas update:list --branch production
- Remettez le canal sur ce groupe en déplaçant le canal vers la branche contenant la mise à jour connue comme bonne (exemple construit utilisant une branche nommée prod-stable) :
eas channel:edit production --branch prod-stable
- Demandez aux utilisateurs affectés de relancer l'application, ou attendez l'intervalle de récupération au premier plan suivant.
Résultat attendu : les appareils sur le canal production reçoivent la mise à jour précédente.
Notes :
- Le rollback OTA ne fonctionne que lorsque la runtimeVersion correspond entre le binaire et la mise à jour. Si vous avez changé la runtimeVersion, vous avez besoin d'un nouveau binaire.
Rollback binaire
Si la modification défectueuse se trouve dans le code natif ou que la runtimeVersion a changé :
- Revenir sur le(s) commit(s) fautif(s) et incrémenter versionCode/buildNumber comme requis par les stores.
- Déclencher un nouveau build production avec le profil production :
eas build --platform android --profile production --non-interactive
# et/ou iOS
- Soumettre le nouveau build sur la même piste utilisée précédemment.
Résultat attendu : les stores reçoivent un binaire revenu en arrière. Les utilisateurs mettent à jour via le store.
Récupération après identifiants cassés
- Pour Android : ne faites pivoter le keystore qu'en dernier recours. Préférez ré-uploader le bon keystore vers EAS s'il a été égaré localement.
- Pour iOS : régénérez les profils de provisionnement et réauthentifiez-vous avec le bon compte Apple. Confirmez que l'identifiant de bundle correspond à celui des certificats.
Liste de contrôle opérationnelle
Utilisez ceci comme un runbook rapide pour les opérations quotidiennes.
Quotidien
- Vérifier que les derniers runs sur develop et main se sont terminés avec succès.
- Confirmer que le canal preview affiche le groupe de mises à jour le plus récent.
- Parcourir les résultats expo-doctor et tests pour détecter les régressions.
Avant de fusionner vers main
- S'assurer que l'application compile et s'exécute localement sur au moins un appareil ou émulateur.
- Vérifier que la runtimeVersion n'a pas changé de manière inattendue.
- Confirmer que les modifications de modules natifs sont reflétées dans les profils de build.
Après le build de production
- Vérifier que le statut EAS Build est terminé et que les artefacts existent.
- Soumettre sur la piste prévue avec les derniers artefacts.
- Surveiller la télémétrie de crash et d'erreur pendant les premières heures après le déploiement (par exemple, surveiller les logs d'erreur ou les rapports in-app).
En cas de problème
- Pour OTA : rediriger le canal vers la dernière mise à jour connue comme bonne.
- Pour binaire : revenir en arrière et reconstruire ; resoumettre avec versioning incrémenté.
- Documenter la défaillance et le correctif pour que le prochain incident soit plus rapide.
Conclusion
Vous disposez désormais d'un parcours sûr et observable pour automatiser les builds et les mises à jour Expo. Le pipeline commence par un pilote étroit qui protège les changements grâce à expo-doctor et aux tests, puis utilise des canaux basés sur les branches pour la prévisualisation et la production. Des étapes de vérification claires confirment exactement ce qui a été expédié et où, tandis que les procédures de rollback OTA et binaire permettent de récupérer rapidement en cas de problème. Une liste de contrôle pratique couvre les opérations quotidiennes, la validation pré-fusion, la surveillance post-déploiement et la réponse aux incidents. Étendez cette fondation progressivement : ajoutez iOS, élargissez la couverture de tests, introduisez la configuration spécifique à l'environnement et renforcez la gestion des identifiants. En faisant évoluer le pipeline par petites étapes mesurables, vous conservez la vitesse tout en réduisant le risque.