Trovi una regressione in checkout il venerdì pomeriggio. La fix è già nel tuo web layer Capacitor, ma i tempi di revisione dell'App Store non si chiuderanno prima di tre giorni. Gli utenti Android possono ricevere un nuovo pacchetto più velocemente, ma costringere ogni cliente a reinstallare un Native Build per una correzione solo JavaScript è uno spreco.
Questo è il motivo pratico per cui i team imparano a fare l'OTA update delle app CapacitorJS. Un rilascio over-the-air controllato può inviare un web bundle firmato ai binari installati idonei, scaricarlo in background e applicarlo al prossimo avvio, mentre le modifiche native seguono ancora il processo degli store. La parte difficile non è fare l'upload di un file. È mantenere allineati version targeting, signing, controllo del rollout, osservabilità e recovery su un'intera flotta live.
Indice dei contenuti
- Perché l'OTA è fondamentale per i team CapacitorJS
- Prerequisiti e installazione dell'updater Capgo
- Pubblicare il primo bundle OTA in sicurezza
- Channel, Rollout e automazione CI/CD
- Strategie di test e rollback automatico
- Firma, sicurezza e limiti degli OTA
- Checklist operativa prima di ogni release
Perché l'OTA è fondamentale per i team CapacitorJS
Un'app Capacitor contiene solitamente due superfici di rilascio. Il binario nativo include lo shell della piattaforma, permessi, plugin, icone, entitlements e altre funzionalità soggette a revisione negli store. Il layer web contiene JavaScript, CSS, HTML, routing, testi e asset. Gli aggiornamenti OTA agiscono sulla seconda superficie, permettendo al team di correggere un flusso di checkout rotto senza dover ricostruire lo shell nativo, purché la modifica rimanga entro i limiti della piattaforma e delle policy degli store descritte nella guida OTA di Capgo.

Il vantaggio operativo va oltre la velocità. I binari installati non sono tutti sincronizzati. Alcuni utenti usano una versione nativa datata, altri l'ultima versione dello store, e ogni binario può avere diverse API native disponibili per il bundle web. Un bundle compilato per un API nativo non supportato può fallire anche se il diff JavaScript è valido. Questo rende l'OTA un sistema di compatibilità, non una scorciatoia per evitare il release engineering.
Considera l'updater come una delivery pipeline
Un setup in produzione richiede una sequenza chiara:
- Installa il bridge nativo: Aggiungi il pacchetto updater e sincronizza Capacitor affinché iOS e Android lo riconoscano.
- Firma il bundle: Mantieni i materiali di firma fuori dal repository e rendi la verifica parte del client path.
- Punta a un canale: Definisci percorsi per staging, beta, produzione o cohort specifiche per cliente.
- Automatizza il rilascio: Usa la CI per build, firma, upload e promozione solo dopo il superamento dei test.
- Monitora l'adozione: Traccia download, installazione, boot, crash e segnali di health per canale e binario.
- Rollback rapido: Ripristina un bundle stabile lato server mantenendo la protezione di recovery lato client.
Capgo è un'opzione per questo workflow. Il suo updater open-source Capacitor e il servizio cloud pubblicano web bundle firmati su canali mirati, li applicano al prossimo avvio e mostrano dati su versioni e dispositivi. app availability per applicazioni Capacitor.
Regola pratica: Se non riesci a identificare a quale binario nativo punta un bundle, non promuoverlo in produzione.
L'OTA ha successo quando riduce i rilasci inutili sugli store senza nascondere il confine tra web code e nativo code. La domanda non è se il team può pushare un bundle, ma se sai spiegare chi lo ha ricevuto, perché era idoneo, cosa è successo dopo il lancio e come ripristinerai il servizio in caso di errori.
Prerequisiti e installazione dell'updater Capgo
Prima di aprire il terminale, verifica che il progetto e gli account di rilascio siano pronti. Avrai bisogno di un'app Capacitor 5 o 6 con @capacitor/cli inizializzato, Node 18 o superiore, account Apple Developer e Google Play Console attivi per i binari target, e un account cloud Capgo con appId e una chiave API.
La prima installazione è volutamente ridotta:
npm install @capgo/capacitor-updater
npx cap sync
npx @capgo/cli init
npm install aggiunge il pacchetto JavaScript e la dipendenza nativa. npx cap sync è il passaggio che molti saltano, ma questa omissione lascia il bridge nativo non collegato. Il layer JavaScript potrebbe compilare, ma il runtime chiamerà un bridge assente nel binario installato. Esegui la sincronizzazione dopo l'installazione e di nuovo quando cambia la configurazione dei plugin nativi.
L'initializer patcha il tuo capacitor.config.ts con le impostazioni dell'updater, l'endpoint web e il canale predefinito. Non accettare la patch alla cieca. Apri il file e verifica esplicitamente l'identità dell'app e il contratto di aggiornamento:
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
version: '1.0.0',
autoUpdate: true,
updateUrl: '',
capgo: {
channel: 'staging'
}
}
La struttura esatta generata può variare in base al progetto e alla versione di CLI, ma i valori importanti sono gli stessi. appId deve corrispondere al binario installato, version deve descrivere la relazione con il Native Build, autoUpdate deve riflettere la tua policy di rilascio, updateUrl deve puntare al servizio di cui si fida il tuo binario, e il capgo blocco deve identificare il canale iniziale.
Verifica prima di buildare una release
Esegui il comando diagnostico prima di aprire Xcode o Android Studio:
npx @capgo/cli doctor
Un risultato pulito deve confermare che CLI sia disponibile, che la configurazione del progetto sia leggibile, che il pacchetto updater sia rilevato, che gli identificatori applicativi richiesti esistano e che l'autenticazione riesca a raggiungere l'account configurato. Non deve segnalare sync nativa mancante, app identity assente o configurazione updater non valida.

Mantieni la prima build nativa volutamente semplice. Installala su un dispositivo iOS e uno Android fisici, avviala con accesso alla rete, chiudila e riaprila, e conferma che l'updater riesca a eseguire il check senza impattare il normale avvio. Il workflow di installazione dell'updater Capacitor è utile quando devi confrontare la configurazione del progetto con il setup dei plugin previsto.
Pubblicare il primo bundle OTA in sicurezza
Tratta il primo bundle come un test del percorso di rilascio, non come il lancio di una feature. Crea o ruota la chiave di firma prima di preparare l'artifact:
npx @capgo/cli key create
Inserisci la chiave privata in un secrets manager. Non fare il commit, non salvarla in un archivio di progetto e non esporla nei log della CI. Il percorso di trust nativo richiede solo il materiale di verifica pubblico. Solo il job di signing deve avere accesso alla chiave privata.
Cambia la versione lato JavaScript in package.json o nei metadati del tuo web release. Mantieni invariati i campi della versione nativa per un fix solo web. Un bundle OTA non può aggiungere code nativi o alterare le capacità dichiarate dal binario installato; un cambio di versione nativa creerebbe problemi di compatibilità invece di risolverli.
Carica l'artifact firmato sul canale desiderato:
npx @capgo/cli bundle upload --channel production
Un upload riuscito conferma solo che il server ha accettato la richiesta. Leggi l'output del comando e verifica il bundle identifier, il vincolo della native-version target, il checksum firmato e l'assegnazione del canale. Questi campi identificano l'artifact e mostrano se i binari installati sono idonei a riceverlo.
Usa la dashboard come release gate
La vista dettagli del bundle dovrebbe rispondere a quattro domande sulla release:
- Versione nativa minima: Which oldest binary can run this bundle?
- Versione nativa massima: Quali binari più recenti sono stati intenzionalmente esclusi?
- Canale: Quale pubblico può scoprire l'artifact?
- Percentuale di rollout: Quale parte del pubblico idoneo può riceverlo?
Inizia l'esposizione in produzione a 5%, quindi definisci le metriche necessarie per l'espansione. Controlla il successo di download e installazione, i cold start normali, le sessioni senza crash e gli errori JavaScript nel nuovo flusso. Mantieni l'identità dell'artifact e i controlli di delivery visibili insieme nella dashboard di Capgo.

Usa una debug build per testare il percorso del dispositivo. getCurrent() riporta il bundle attivo, e notifyAppReady() conferma che il nuovo bundle sia in uno stato stabile:
import { CapacitorUpdater } from '@capgo/capacitor-updater'
const current = await CapacitorUpdater.getCurrent()
console.log(current)
await CapacitorUpdater.notifyAppReady()
Chiama la readiness solo dopo che l'app si è inizializzata a sufficienza per superare i tuoi health check. Se non conferma mai la readiness, il recovery automatico potrebbe segnare il bundle come fallito al prossimo cold start. Questa protezione tutela gli utenti in produzione, ma può far sembrare un test incompleto un problema di delivery. Registra il bundle attivo e il risultato dell'avvio per ogni dispositivo di test prima di espandere l'esposizione.
Channel, Rollout e automazione CI/CD
I Channel sono lo strato di routing tra un bundle pubblicato e un dispositivo installato. Sono anche il tuo gate di rilascio. Un channel di staging dovrebbe puntare a un binario nativo noto, un channel beta dovrebbe servire una coorte controllata, e la produzione dovrebbe partire solo dopo che il channel precedente ha superato i smoke test.
Crea un percorso di staging con nomi espliciti:
npx @capgo/cli channel create staging
npx @capgo/cli bundle assign <bundle-id> --channel staging
Collega quel canale alla versione native utilizzata dai tuoi dispositivi di test. I tester dovrebbero eseguire lo stesso binario supportato dalla produzione, non una build di sviluppo locale con plugin extra o configurazioni diverse. Una volta superata la smoke suite, promuovi l'artifact testato invece di fare l'upload di un secondo bundle leggermente diverso.
La tua mappa dei canali dovrebbe risiedere in capgo.config.json e essere revisionata come l'code dell'applicazione. Mantieni stabili i nomi dei canali, identifica il range di compatibilità native previsto e rendi la promozione in produzione un'azione CI esplicita. Per i team che gestiscono il rilascio delle feature insieme alla distribuzione, questi consigli sulla governance dei feature flag offrono un modo utile per separare i permessi di deployment dall'attivazione lato utente.
Collega la promozione alla CI
Un design pratico per GitHub Actions prevede due percorsi:
- Pull request: Builda il layer web, firmalo con una credential di preview limitata e pubblicalo su un canale di preview effimero. Distruggi o fai scadere quel canale quando la pull request viene chiusa.
- Release taggate su main: Esegui i unit test, builda il bundle di produzione, valida il vincolo della versione native, fai l'upload e promuovi solo se il job di test termina con successo.
Un comando di promozione può essere così:
npx @capgo/cli bundle promote <bundle-id> \
--to-channel production \
--percent 5
Aumenta l'esposizione in step controllati come 25%, 50% e 100%, con un'approvazione CI o un job monitorato tra ogni step. Le percentuali e i comandi sono controlli, non prove di sicurezza. Una build che passa ti dice che il bundle è sintatticamente valido. Non ti dice come si comporterà su un determinato binario nativo, con stato locale persistente, una connessione lenta o un dispositivo che riprende da una vecchia sessione.
Limite della release: Un web bundle appartiene a una finestra di compatibilità binaria. Un canale non deve mai diventare una scappatoia per servire code che fa riferimento a API native non presenti nell'app installata.
Mantieni coerenti le build di TestFlight e Android internal-track legando ogni bundle all'esatta versione nativa per cui è stato creato. Se la build nativa cambia, pubblica un nuovo bundle mirato alla compatibilità o crea un nuovo mapping del canale. La guida all'integrazione di Capgo GitHub Actions può aiutarti a trasformare questa policy in step di workflow ripetibili.

Strategie di testing e rollback automatico
Un rilascio OTA può superare la CI e fallire comunque dopo l'attivazione. Il fallimento può dipendere dal bundle, dal binario nativo, dallo stato salvato del dispositivo o dalle condizioni di rete. Un simulatore può confermare il rendering di una schermata, ma non può coprire ogni binario installato o mostrare se un avvio fallito si riprende correttamente.
Usa tre livelli di test:
- Test del bundle in CI: Esegui unit test, type check, linting e la build web di produzione. Verifica i percorsi di checkout, autenticazione, navigazione e persistenza modificati, invece di fermarti alla compilazione.
- Canale device privato: Popola un canale privato con device fisici che eseguono l'ultima Native Build. Copri entrambe le piattaforme, installazioni pulite, aggiornamenti e diversi stati di persistenza.
- Canary in produzione: Inizia con un piccolo gruppo di utenti, crash reporting attivo e alert per errori JavaScript. Gestisci i fallimenti all'avvio come critici, poiché gli utenti colpiti potrebbero non raggiungere mai il code necessario per riportare l'errore.
L'oggetto Guida ai test OTA con Capacitor spiega la meccanica dei test. La regola operativa è semplice: testa ogni aggiornamento rispetto alla Native Build che deve proteggere.
Separa il controllo del server dal recovery del client
Il rollback lato server blocca i nuovi download:
npx @capgo/cli channel set production --bundle <previous-id>
Questo modifica ciò che i dispositivi idonei scopriranno successivamente. Non cancella un bundle già scaricato o attivo su ogni dispositivo, quindi il client necessita di controlli di recovery. Configura l'updater per mantenere un fallback funzionante e ripristinarlo dopo una condizione di errore all'avvio.
Un percorso di recovery affidabile include:
- Monitoraggio fallimenti download: Distinguere tra problemi di connettività e artefatti non validi.
- Monitoraggio fallimenti installazione: Rilevare problemi di unpacking, verifica e filesystem.
- Monitoraggio stato boot: Confermare che l'app raggiunga uno stato utilizzabile dopo l'attivazione.
- Fallback automatico: Ripristinare il precedente bundle funzionante quando l'avvio fallisce ripetutamente.
- Escalation manuale: Preservare gli identificativi di dispositivo e bundle per il supporto e l'engineering.
Su larga scala, anche un basso tasso di errore genera un carico di supporto significativo. Un tasso di successo OTA del 99,95% implica comunque circa 1.000 fallimenti ogni milione di dispositivi, according to i benchmark di test OTA per flotte IoT. La stessa fonte descrive guardrail tra cui rollback entro 30 minuti, crash rate sotto lo 0,1% e il 98% dei dispositivi dentro la finestra di supporto. Considerali esempi di benchmark, non criteri di accettazione universali. Definisci l'error budget in base al rischio dell'app e all'impatto sugli utenti.
Firma, Sicurezza e i Limiti degli OTA
Un aggiornamento non firmato rende l'endpoint di distribuzione parte della superficie d'attacco della tua supply chain. TLS protegge la connessione, ma il client deve anche verificare che l'artefatto scaricato provenga da un processo di release autorizzato e non sia stato sostituito o alterato in transito.
Genera una coppia di chiavi Ed25519 con gli strumenti di aggiornamento. Salva la chiave privata in un secret della CI e incorpora la chiave pubblica di verifica nel binario nativo durante la build dell'app. Il client deve verificare ogni bundle prima dell'attivazione. Limita i token CLI per ambiente e scope dei permessi, conserva i log di upload e promozione e richiedi un'autenticazione forte per le azioni in produzione.
Considera la rotazione delle chiavi come una migrazione di compatibilità, non come una semplice modifica di configurazione. Genera una nuova chiave, rilascia una build nativa che si fida sia della chiave pubblica attuale che di quella nuova, poi firma le release con la nuova chiave privata. Rimuovi la vecchia chiave solo dopo che i binari nativi compatibili avranno adottato la nuova. Rimuovere la fiducia troppo presto impedisce ai binari più vecchi di accettare aggiornamenti validi. Lasciare per sempre una chiave compromessa considerata attendibile rende inutile la rotazione.
Definisci il confine nel piano di release
L'OTA gestisce le modifiche al layer web. Le release native sono necessarie quando una modifica dipende da funzionalità assenti dal binario installato:
| Categoria | Rilascia via OTA | Richiede release nativa |
|---|---|---|
| Comportamento dell'app | Logica JavaScript, routing, validazione e gestione dello stato | Implementazione di plugin nativi |
| Presentazione | CSS, HTML, testi, token del tema e asset immagine compatibili | Icona dell'app e risorse splash |
| Accesso alla piattaforma | Chiamate Capacitor web-layer esistenti verso capacità già presenti nel binario | Nuovi permessi, entitlements o API native |
| Configurazione | Configurazione web e regole sui contenuti remoti compatibili | Info.plist, AndroidManifest.xml, identità di firma |
| Metadati dello Store | Nessuno che modifichi il comportamento approvato dallo Store o i metadati della versione | Metadati sensibili alle policy dello Store e modifiche al numero di versione |
L'oggetto Documentazione sul signing dell'updater Capacitor code spiega il modello di verifica. Applicalo operativamente con audit log tamper-evident, verifica dei certificati, TLS, controlli di accesso rigorosi e un processo di investigazione per version spoofing o compromissione delle chiavi.
Il targeting della compatibilità conta ancora perché la popolazione nativa installata cambia gradualmente. Apple ha riportato il 66% di tutti i dispositivi attivi su iOS 26 e il 74% dei dispositivi usciti negli ultimi quattro anni su iOS 26, mentre un altro report ha indicato iOS 26 al 79% of all devices later in the cycle, come riassunto in ricerca sulla gestione delle chiavi OTA per mobile. Questi dati si riferiscono a momenti e popolazioni di dispositivi differenti. La conclusione pratica è la stessa: anche le piattaforme mature non aggiornano tutti i dispositivi contemporaneamente. Assegna i bundle in base alla versione nativa e alle capacità, invece di assumere che un singolo artefatto OTA sia adatto a tutta la flotta.
Checklist operativa prima di ogni release
Mantieni la checklist di release su una sola pagina, salvata nel repository o nel runbook. Aggiornala dopo ogni incidente. Un controllo aggiunto dopo un errore reale di solito previene la ricorrenza.
Prima dell'upload
- Conferma la compatibilità: Verifica che il bundle punti al binario nativo corretto e non utilizzi API di plugin non disponibili.
- Controlla l'artefatto: Esegui il build da un workspace pulito, ispeziona i file generati e conferma la versione web desiderata.
- Proteggi la firma: Assicurati che la CI abbia il secret e la chiave corretti. Verifica che i log non espongano dati privati.
- Valida i canali: Controlla i mapping di staging, beta e production prima di assegnare il bundle.
- Mantieni il recovery: Registra il precedente bundle funzionante e verifica che il fallback funzioni ancora.
- Esegui smoke test fisici: Testa avvio, login, checkout, navigazione, persistenza e prontezza degli update su dispositivi rappresentativi.
Durante la promozione
Rilascia prima a un gruppo limitato, poi monitora i segnali relativi all'impatto sugli utenti:
- Sessioni senza crash: Confronta il risultato con il bundle precedente e investiga eventuali regressioni.
- Tasso di errori JavaScript: Raggruppa gli errori per bundle, versione native, piattaforma e feature path.
- Comportamento al cold-start: Verifica se l'attivazione influisce sull'avvio o se lascia gli utenti su una schermata bianca.
- Copertura delle feature: Conferma che la funzionalità abilitata da remoto corrisponda al binario che la riceve.
- Adozione e fallimenti: Separa i dispositivi idonei che non hanno cercato aggiornamenti da quelli che hanno cercato e hanno fallito.
Mantieni la prima finestra di osservazione post-promotion per 30 minuti prima di aumentare l'esposizione. Se un percorso critico si interrompe, fai il rollback del canale di produzione al bundle precedente, conserva i log e decidi se la fix debba andare in un altro bundle OTA o in una nuova Native Build.
Disciplina del giorno del rilascio: Un bundle di fallback è utile solo se il team ne conosce l'identifier, l'intervallo di compatibilità e il comando di ripristino.
Considera questa checklist come code operativo condiviso. Capgo può fornire la consegna di bundle firmati, il targeting dei canali, il controllo del rollout, la cronologia degli update e l'osservabilità a livello di device. Il tuo team rimane responsabile della policy di compatibilità e della decisione di promozione.
Capgo offre ai team CapacitorJS un percorso controllato per gli update firmati di JavaScript, CSS, configurazione e asset, con canali, rilascio graduale, protezione dai rollback e osservabilità del rilascio. Applica la checklist al prossimo deployment, testala su un binario di staging e valuta Capgo il workflow di produzione.