Aller au contenu principal

Comment bien gérer les mises à jour OTA pour les apps CapacitorJS

Apprenez à effectuer des mises à jour OTA sur vos apps CapacitorJS et Electron avec Capgo, de la configuration à la signature, en passant par les canaux, la CI/CD, les tests et le rollback dans ce guide pratique.

Comment bien gérer les mises à jour OTA pour les apps CapacitorJS

Vous découvrez une régression lors du checkout un vendredi après-midi. Le correctif est déjà présent dans votre couche web Capacitor, mais la période de révision de l'App Store ne se terminera que dans trois jours. Les utilisateurs Android peuvent recevoir un nouveau package plus rapidement, mais forcer chaque client à réinstaller un build natif pour une correction purement JavaScript reste une perte de ressources.

C'est la raison concrète pour laquelle les équipes apprennent à utiliser les mises à jour OTA sur les apps CapacitorJS. Une release over-the-air contrôlée peut envoyer un bundle web signé aux binaires installés éligibles, le télécharger en arrière-plan et l'appliquer au prochain lancement, tandis que les changements natifs suivent le processus classique des stores. La difficulté n'est pas d'envoyer un fichier. C'est de maintenir le ciblage des versions, la signature, le contrôle du déploiement, l'observabilité et la récupération alignés sur l'ensemble de votre parc d'appareils.

Table of Contents

Pourquoi l'OTA compte pour les équipes CapacitorJS

Une application Capacitor contient généralement deux surfaces de release. Le binaire natif embarque le shell de la plateforme, les permissions, les plugins, les icônes, les entitlements et les autres fonctionnalités validées par les stores. La couche web contient le JavaScript, le CSS, l'HTML, le routage, les textes et les assets. Les mises à jour OTA ciblent la seconde surface, ce qui permet à une équipe de corriger un parcours de paiement défectueux sans recompiler le shell natif, à condition que la modification reste dans les limites de la plateforme et des politiques des stores décrites dans le Guide OTA Capgo.

Un diagramme illustrant l'importance des mises à jour OTA en comparant les délais des stores aux correctifs instantanés.

L'avantage opérationnel va au-delà de la vitesse. Les binaires installés n'évoluent pas au même rythme. Certains clients lancent un build natif plus ancien, d'autres utilisent une version récente du store, et chaque binaire peut exposer des API natives différentes au bundle web. Un bundle compilé contre un API natif non pris en charge peut échouer même si le diff JavaScript est valide. L'OTA est donc un système de compatibilité, pas un raccourci pour contourner l'ingénierie de release.

Considérez l'updater comme un pipeline de livraison

Une configuration de production nécessite une séquence claire :

  1. Installer le bridge natif : Ajouter le package de l'updater et synchroniser Capacitor pour qu'iOS et Android en soient informés.
  2. Signer le bundle : Garder les éléments de signature hors du dépôt et intégrer la vérification au chemin client.
  3. Cibler un canal : Routez délibérément vers des cohortes de staging, beta, production ou spécifiques à un client.
  4. Automatisez la livraison : Laissez la CI compiler, signer, envoyer et promouvoir uniquement après la réussite des tests.
  5. Observez l'adoption : Suivez les signaux de téléchargement, d'installation, de boot, de crash et de santé par canal et par binaire.
  6. Effectuez un rollback rapidement : Restaurez un bundle stable côté serveur tout en conservant la protection de récupération côté client.

Capgo est une option pour ce workflow. Son updater Capacitor open source et son service cloud publient des web bundles signés vers des canaux ciblés, les appliquent au prochain lancement et exposent les informations de livraison par version et par appareil. Les équipes évaluant la disponibilité et la résilience des releases peuvent également consulter la disponibilité des apps pour les applications Capacitor.

Règle pratique : Si vous ne pouvez pas identifier quel binaire natif un bundle cible, ne le promevez pas en production.

L'OTA réussit lorsqu'elle réduit les releases inutiles sur les stores sans masquer la frontière entre le code web et le code natif. La question n'est pas de savoir si votre équipe peut pousser un bundle, mais si vous pouvez expliquer qui l'a reçu, pourquoi ils étaient éligibles, ce qui s'est passé après le lancement et comment vous restaurerez le service si le bundle se comporte mal.

Prérequis et installation du Capgo Updater

Avant d'ouvrir un terminal, confirmez que les comptes du projet et de la release sont prêts. Vous aurez besoin d'une application Capacitor 5 ou 6 avec @capacitor/cli initialisé, Node 18 ou plus récent, des comptes Apple Developer et Google Play Console actifs pour les binaires cibles, et un compte cloud Capgo avec un appId et une clé API.

La première installation est volontairement légère :

npm install @capgo/capacitor-updater
npx cap sync
npx @capgo/cli init

npm install ajoute le package JavaScript et la dépendance native. npx cap sync est l'étape que les gens sautent, et cette omission laisse le bridge natif non lié. La couche JavaScript peut compiler alors que le runtime appellera plus tard un bridge absent du binaire installé. Lancez la synchronisation après l'installation et à nouveau lors de tout changement de configuration de plugin natif.

L'initialiseur patche votre capacitor.config.ts avec les paramètres de l'updater, l'endpoint web et le canal par défaut. N'acceptez pas le patch aveuglément. Ouvrez le fichier et vérifiez explicitement l'identité de l'application et le contrat de mise à jour :

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'Example',
  version: '1.0.0',
  autoUpdate: true,
  updateUrl: '',
  capgo: {
    channel: 'staging'
  }
}

La structure exacte générée peut varier selon votre projet et la version de CLI, mais les valeurs importantes restent les mêmes. appId doit correspondre au binaire installé, version doit décrire la relation avec le build natif, autoUpdate doit refléter votre politique de lancement, updateUrl doit pointer vers le service de confiance de votre binaire, et le capgo bloc doit identifier le canal initial.

Vérifier avant de compiler une release

Exécutez la commande de diagnostic avant d'ouvrir Xcode ou Android Studio :

npx @capgo/cli doctor

Un résultat propre doit confirmer que CLI est disponible, que la configuration du projet est lisible, que le package de l'updater est détecté, que les identifiants d'application requis existent et que l'authentification peut atteindre le compte configuré. Il ne doit pas signaler de manque de sync natif, d'absence d'identité d'app ou de configuration d'updater invalide.

Capture d'écran de https://capgo.app/docs/img/cli-doctor.png

Gardez le premier build natif volontairement basique. Installez-le sur un appareil iOS et un appareil Android physiques, lancez-l’avec un accès réseau, fermez-le puis rouvrez-le, et confirmez que l'updater peut vérifier les mises à jour sans affecter le démarrage normal. Le workflow d'installation de l'updater Capacitor est utile lorsque vous devez comparer la configuration du projet avec la configuration attendue du plugin.

Déployer votre premier bundle OTA en toute sécurité

Considérez le premier bundle comme un test de chemin de release, et non comme un lancement de fonctionnalité. Créez ou changez la clé de signature avant de préparer l'artifact :

npx @capgo/cli key create

Placez la clé privée dans un gestionnaire de secrets. Ne la commitez pas, ne la stockez pas dans une archive de projet et ne l'exposez pas dans les logs de la CI. Le chemin de confiance natif nécessite uniquement le matériel de vérification public. Seul le job de signature doit avoir accès à la clé privée.

Modifiez la version côté JavaScript dans package.json ou vos métadonnées de release web. Conservez les champs de version native inchangés pour un correctif web uniquement. Un bundle OTA ne peut pas ajouter de code natif ni modifier les capacités déclarées par le binaire installé ; un changement de version native masquerait la compatibilité au lieu de l'améliorer.

Envoyez l'artefact signé vers le canal cible :

npx @capgo/cli bundle upload --channel production

Un upload réussi confirme seulement que le serveur a accepté la requête. Lisez la sortie de la commande et vérifiez l'identifiant du bundle, la contrainte de version native cible, le checksum signé et l'attribution du canal. Ces champs identifient l'artefact et indiquent si les binaires installés sont éligibles pour le recevoir.

Utilisez le dashboard comme barrière de release

La vue détaillée du bundle doit répondre à quatre questions de release :

  • Version native minimale : Which oldest binary can run this bundle?
  • Version native maximale : Quels binaires plus récents sont intentionnellement exclus ?
  • Canal : Quelle audience peut découvrir l'artefact ?
  • Pourcentage de déploiement : Quelle part de cette audience éligible peut la recevoir ?

Commencer l'exposition en production à 5%, puis définissez les preuves requises pour l'extension. Vérifiez le succès du téléchargement et de l'installation, les démarrages à froid normaux, les sessions sans crash et les erreurs JavaScript dans le flux modifié. Gardez l'identité de l'artefact et les contrôles de livraison visibles ensemble dans le dashboard Capgo.

Capture d'écran de https://capgo.app/docs/img/bundle-detail.png

Utilisez un build de debug pour tester le chemin de l'appareil. getCurrent() signale le bundle actif, et notifyAppReady() confirme que le nouveau bundle est dans un état sain :

import { CapacitorUpdater } from '@capgo/capacitor-updater'

const current = await CapacitorUpdater.getCurrent()
console.log(current)

await CapacitorUpdater.notifyAppReady()

N'appelez la disponibilité qu'une fois que l'application est suffisamment initialisée pour passer vos tests de santé. Si elle ne confirme jamais sa disponibilité, la récupération automatique peut marquer le bundle comme échoué lors du prochain démarrage à froid. Cette sécurité protège les utilisateurs en production, mais elle peut aussi faire passer un test incomplet pour un problème de livraison. Enregistrez le bundle actif et le résultat du démarrage pour chaque appareil de test avant d'étendre l'exposition.

Canaux, déploiements progressifs et automatisation CI/CD

Les canaux sont la couche de routage entre un bundle publié et un appareil installé. Ils servent aussi de barrière de release. Un canal de staging doit pointer vers un binaire natif connu, un canal beta doit servir une cohorte contrôlée, et la production ne doit évoluer qu'après le passage des smoke tests sur le canal précédent.

Créez un chemin de staging avec des noms explicites :

npx @capgo/cli channel create staging
npx @capgo/cli bundle assign <bundle-id> --channel staging

Liez ce canal à la version native utilisée par vos appareils de test. Les testeurs doivent utiliser le même binaire que celui de la production, et non un build de développement local avec des plugins supplémentaires ou une configuration différente. Une fois que la suite de tests smoke est validée, propagez l'artefact testé plutôt que d'envoyer un second bundle légèrement différent.

Votre mapping de canaux doit résider dans capgo.config.json et être revu comme le code de l'application. Gardez des noms de canaux stables, identifiez la plage de compatibilité native prévue, et faites de la promotion en production une action CI explicite. Pour les équipes gérant l'exposition des fonctionnalités en parallèle de la livraison, ces conseils de gouvernance des feature flags offrent un moyen utile de séparer les permissions de déploiement de l'activation côté utilisateur.

Connecter la promotion à la CI

Une conception pratique de GitHub Actions propose deux voies :

  • Pull requests : Compilez la couche web, signez-l’avec un identifiant de preview restreint, et publiez-la sur un canal de preview éphémère. Détruisez ou expirez ce canal lorsque la pull request est fermée.
  • Releases main taguées : Exécutez les tests unitaires, compilez le bundle de production, validez la contrainte de version native, envoyez-l’et déployez-l’uniquement si le job de test se termine avec succès.

Une commande de promotion peut ressembler à ceci :

npx @capgo/cli bundle promote <bundle-id> \
  --to-channel production \
  --percent 5

Augmentez l'exposition par étapes délibérées telles que 25 %, 50 % et 100 %, avec une approbation CI ou un job monitoré entre chaque étape. Les pourcentages et les commandes sont des contrôles, pas des preuves de sécurité. Un build réussi vous indique que le bundle est syntaxiquement valide. Cela ne vous dit pas comment il se comporte sur un binaire natif spécifique, avec un état local persisté, une connexion lente ou un appareil qui reprend une ancienne session.

Limite de la release : Un bundle web appartient à une fenêtre de compatibilité binaire. Un canal ne doit jamais devenir une faille permettant de servir du code qui fait référence à des API natives absentes de l'application installée.

Maintenez la cohérence des builds TestFlight et des tracks internes Android en liant chaque bundle à la version native exacte pour laquelle il a été conçu. Si le build natif change, publiez un nouveau bundle ciblant cette compatibilité ou créez un nouveau mapping de canal. Le guide d'intégration Capgo GitHub Actions peut vous aider à traduire cette politique en étapes de workflow reproductibles.

Un diagramme illustrant les trois étapes des canaux logiciels et de l'automatisation : canal de staging, épinglage du binaire et auto-déploiement CI/CD.

Stratégies de test et rollback automatique

Une release OTA peut passer la CI et échouer malgré tout après activation. L'échec peut dépendre du bundle, du binaire natif, de l'état stocké de l'appareil ou des conditions réseau. Un simulateur peut confirmer qu'un écran s'affiche, mais il ne peut pas couvrir chaque binaire installé ni montrer si un démarrage échoué redémarre proprement.

Utilisez trois niveaux de test :

  1. Tests de bundle en CI : Exécutez les tests unitaires, le typage, le linting et un build web de production. Testez les parcours de checkout, d'authentification, de navigation et de persistance modifiés au lieu de vous arrêter à la compilation.
  2. Canal d'appareils privés : Alimentez un canal privé avec des appareils physiques exécutant l'ancien binaire natif. Couvrez les deux plateformes, les installations propres, les mises à jour et les états de stockage représentatifs.
  3. Canari en production : Commencez par une petite cohorte éligible, avec un reporting de crash connecté et des alertes d'erreurs JavaScript. Traitez les échecs au démarrage comme urgents, car les utilisateurs concernés pourraient ne jamais atteindre le code qui rapporte une erreur in-app.

Le Capacitor Guide de test OTA explique la mécanique de test. La règle opérationnelle est simple : testez chaque mise à jour par rapport au binaire natif qu'elle est censée protéger.

Séparer le contrôle serveur de la récupération client

Server-side rollback stops new downloads:

npx @capgo/cli channel set production --bundle <previous-id>

Cela modifie ce que les appareils éligibles découvriront ensuite. Cela n'efface pas un bundle déjà téléchargé ou actif sur chaque appareil ; le client doit donc disposer de contrôles de récupération. Configurez l'updater pour conserver un fallback stable et revenir en arrière après une condition d'échec au démarrage définie.

Un parcours de récupération fiable inclut :

  • Le suivi des échecs de téléchargement : Distinguer les problèmes de connectivité des artefacts invalides.
  • Le suivi des échecs d'installation : Detect unpacking, verification, and filesystem issues.
  • Le suivi de l'état au démarrage : Confirmer que l'app atteint un état utilisable après l'activation.
  • Le fallback automatique : Restaurer le précédent bundle stable lorsque le démarrage échoue de manière répétée.
  • L'escalade manuelle : Conserver les identifiants de l'appareil et du bundle pour le support et l'ingénierie.

À l'échelle d'une flotte, même un faible taux d'échec génère une charge de support importante. Un taux de réussite de 99,95 % sur les mises à jour OTA implique encore environ 1 000 échecs pour 1 million d'appareils, according to les benchmarks de test OTA pour les flottes IoT. Cette même source décrit des garde-fous : rollback en moins de 30 minutes, taux de crash inférieur à 0,1 % et 98 % d'appareils dans la fenêtre de support. Considérez ces chiffres comme des exemples de référence, pas comme des critères d'acceptation universels. Définissez le budget d'erreur selon le risque de l'app et l'impact utilisateur.

Signature, sécurité et ce que l'OTA ne peut pas changer

Une mise à jour non signée fait du point de terminaison de livraison une partie de votre surface d'attaque de la supply chain. TLS protège la connexion, mais le client doit aussi confirmer que l'artefact téléchargé provient d'un processus de release autorisé et n'a pas été remplacé ou altéré pendant le transit.

Générez une paire de clés Ed25519 avec l'outillage de l'updater. Stockez la clé privée dans un secret CI et intégrez la clé de vérification publique dans le binaire natif lors du build de l'app. Le client doit vérifier chaque bundle avant activation. Limitez les CLI tokens par environnement et par périmètre de permissions, conservez les logs d'upload et de promotion, et exigez une authentification forte pour les actions en production.

Considérez la rotation des clés comme une migration de compatibilité, pas comme un simple changement de configuration. Générez une clé de remplacement, déployez un build natif qui fait confiance à la fois à la clé publique actuelle et à la clé de remplacement, puis signez les releases avec la nouvelle clé privée. Ne supprimez l'ancienne clé qu'une fois que les binaires natifs compatibles ont adopté la nouvelle. Supprimer la confiance trop tôt empêche les anciens binaires d'accepter des mises à jour valides. Laisser indéfiniment une clé compromise dans la liste de confiance annule l'intérêt de la rotation.

Délimitez le périmètre dans le plan de release

L'OTA gère les modifications de la couche web. Une release native est nécessaire lorsqu'une modification dépend de capacités absentes du binaire installé :

Catégorie Déploiement via OTA Nécessite une release native
Comportement de l'application Logique JavaScript, routage, validation et gestion d'état Implémentation de plugins natifs
Présentation CSS, HTML, textes, tokens de thème et assets images compatibles Icône de l'app et ressources splash screen
Accès à la plateforme Appels Capacitor de la couche web vers des capacités déjà présentes dans le binaire Nouvelles permissions, entitlements ou API natives
Configuration Configuration web compatible et règles de contenu distant Info.plist, AndroidManifest.xml, identité de signature
Métadonnées du store Aucune modification du comportement révisé par le store ou des métadonnées de version Métadonnées sensibles aux politiques du store et changements de numéro de version

Le documentation sur la signature Capacitor updater code explique le modèle de vérification. Appliquez-l’opérationnellement avec des logs d'audit infalsifiables, la vérification des certificats, le TLS, des contrôles d'accès stricts et un processus d'enquête en cas d'usurpation de version ou de compromission de clé.

Le ciblage de compatibilité reste crucial car la population d'appareils natifs installés évolue progressivement. Apple a rapporté 66 % de tous les appareils actifs sous iOS 26 et 74 % des appareils sortis ces quatre dernières années sous iOS 26, tandis qu'un autre rapport situe iOS 26 à 79 % de l'ensemble des appareils en fin de cycle, comme le résume La recherche sur la gestion des clés OTA mobile. Ces chiffres couvrent différents points et populations d'appareils. La conclusion pratique est la même : même les plateformes matures ne mettent pas tous les appareils à jour en même temps. Assignez les bundles par version native et capacité, plutôt que de supposer qu'un seul artefact OTA convient à toute votre flotte.

Checklist opérationnelle avant chaque release

Gardez la checklist de release sur une seule page, stockée avec le repository ou le runbook. Mettez-l’à jour après chaque incident. Un contrôl’ajouté après un échec réel permet généralement d'éviter sa récurrence.

Avant l'upload

  • Confirmer la compatibilité : Vérifiez que le bundle cible exactement le binaire natif et n'utilise aucune API de plugin indisponible.
  • Vérifier l'artefact : Compilez depuis un espace de travail propre, inspectez les fichiers générés et confirmez la version web prévue.
  • Protéger la signature : Confirmez que la CI possède le secret et la clé attendus. Vérifiez que les logs ne peuvent pas exposer de données privées.
  • Valider les canaux : Révisez les correspondances staging, beta et production avant d'assigner le bundle.
  • Préserver la récupération : Enregistrez le précédent bundle stable et vérifiez que le chemin de fallback fonctionne toujours.
  • Effectuer des tests de fumée physiques : Testez le démarrage, la connexion, le paiement, la navigation, la persistance et la disponibilité des mises à jour sur des appareils représentatifs.

Pendant la promotion

Déployez d'abord sur une cohorte limitée, puis surveillez les indicateurs liés à l'impact utilisateur :

  • Sessions sans crash : Comparez le résultat avec le bundle précédent et analysez les régressions.
  • Taux d'erreurs JavaScript : Groupez les erreurs par bundle, version native, plateforme et chemin de fonctionnalité.
  • Comportement au démarrage à froid : Vérifiez si l'activation modifie le démarrage ou laisse les utilisateurs sur un écran blanc.
  • Couverture des fonctionnalités : Confirmez que les fonctionnalités activées à distance correspondent au binaire qui les reçoit.
  • Adoption et échecs : Séparez les appareils éligibles n'ayant pas vérifié de mise à jour des appareils ayant vérifié mais échoué.

Maintenez la première fenêtre d'observation post-promotion pendant 30 minutes avant d'élargir l'exposition. Si un chemin critique est interrompu, effectuez un rollback du canal de production vers le bundle précédent, conservez les logs, et décidez si le correctif doit figurer dans un autre bundle OTA ou dans une nouvelle release native.

Discipline le jour du déploiement : Un bundle de secours n'est utile que si l'équipe connaît son identifiant, sa plage de compatibilité et la commande de restauration.

Considérez cette checklist comme un code opérationnel partagé. Capgo peut assurer la livraison de bundles signés, le ciblage de canaux, le contrôle du déploiement progressif, l'historique des mises à jour et l'observabilité au niveau de l'appareil. Votre équipe reste responsable de la politique de compatibilité et de la décision de promotion.


Capgo offre aux équipes CapacitorJS un chemin contrôlé pour les mises à jour signées de JavaScript, CSS, de configuration et d'assets, avec des canaux, un déploiement progressif, une protection contre le rollback et l'observabilité des releases. Intégrez cette checklist au prochain déploiement, testez-la sur un binaire de staging, et évaluez-la Capgo pour votre workflow de production.

Live updates pour les apps Capacitor

Quand un bug de la couche web est en production, déployez le correctif via Capgo au lieu d'attendre des jours l'approbation des stores. Les utilisateurs reçoivent la mise à jour en arrière-plan, tandis que les changements natifs suivent le circuit de validation habituel.

Les derniers articles du blog

Capgo vous apporte les meilleures informations pour créer une application mobile vraiment professionnelle.