Trovi una regressione al checkout venerdì pomeriggio. La correzione è già nel tuo layer web Capacitor, ma la finestra di revisione dell'App Store non si chiuderà per tre giorni. Gli utenti Android possono ricevere un nuovo pacchetto prima, ma costringere ogni cliente a reinstallare un build nativo per una correzione solo JavaScript è comunque uno spreco.
Questa è la ragione pratica per cui i team imparano come fare OTA update delle app CapacitorJS. Un rilascio over-the-air controllato può consegnare un bundle web firmato ai binari installati idonei, scaricarlo in background e applicarlo al prossimo avvio, mentre le modifiche native seguono ancora il processo dello store. La parte difficile non è caricare un file. È mantenere allineati targeting delle versioni, firma, controllo del rollout, osservabilità e recovery su una 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 cosa l'OTA non può cambiare
- Checklist operativa prima di ogni release
Perché l'OTA è fondamentale per i team CapacitorJS
Un'app Capacitor contiene in genere due superfici di rilascio. Il binario nativo gestisce la shell della piattaforma, i permessi, i plugin, le icone, gli entitlement e altre funzionalità soggette a revisione dello store. Lo strato web gestisce JavaScript, CSS, HTML, routing, testi e asset. Gli aggiornamenti OTA interessano la seconda superficie, permettendo al team di correggere un flusso di checkout rotto senza ricompilare la shell nativa, a patto che la modifica resti entro i limiti di piattaforma e policy dello store descritti nel guida OTA di Capgo.

Il vantaggio operativo va oltre la velocità. I binari installati non si muovono in sincronia. Alcuni clienti avviano un build nativo più vecchio, altri usano una versione recente dello store, e ogni binario può avere API native diverse disponibili per il web bundle. Un bundle compilato contro un API nativo non supportato può fallire anche se la diff JavaScript è valida. Questo rende l'OTA un sistema di compatibilità, non una scorciatoia per l'ingegneria delle release.
Considera l'updater come una pipeline di delivery
Una configurazione di produzione richiede una sequenza chiara:
- Installa il bridge nativo: Aggiungi il pacchetto updater e sincronizza Capacitor in modo che iOS e Android ne siano a conoscenza.
- Firma il bundle: Tieni il materiale di firma fuori dal repository e rendi la verifica parte del percorso lato client.
- Punta a un canale: Instrada in modo mirato staging, beta, produzione o gruppi specifici per cliente.
- Automatizza la distribuzione: Lascia che la CI compili, firmi, carichi e promuova solo dopo il superamento dei test.
- Monitora l'adozione: Traccia download, installazione, avvio, crash e segnali di stato per canale e binario.
- Esegui il rollback rapidamente: Ripristina un bundle noto e funzionante lato server e mantieni la protezione di recupero lato client.
Capgo è un'opzione per questo workflow. Il suo updater open-source Capacitor e il servizio cloud pubblicano bundle web firmati su canali mirati, li applicano al successivo avvio ed espongono informazioni sulla distribuzione a livello di versione e dispositivo. I team che valutano disponibilità e resilienza dei rilasci possono anche consultare la disponibilità dell'app per le applicazioni Capacitor.
Regola pratica: Se non riesci a capire a quale binario nativo è destinato un bundle, non promuoverlo in produzione.
L'OTA funziona quando riduce i rilasci inutili sullo store senza nascondere il confine tra web code e nativo code. La domanda non è se il tuo team può pubblicare un bundle. È se sai spiegare chi lo ha ricevuto, perché era idoneo, cosa è successo dopo il lancio e come ripristinerai il servizio se il bundle si comporta male.
Prerequisiti e installazione dell'updater Capgo
Prima di aprire il terminale, verifica che il progetto e gli account di rilascio siano pronti. Ti serve 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 di destinazione e un account cloud Capgo con una appId e una chiave API.
La prima installazione è volutamente minima:
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 passo che spesso viene saltato, e questa omissione lascia il bridge nativo non collegato. Lo strato JavaScript potrebbe compilare, ma a runtime viene chiamato un bridge assente nel binario installato. Esegui la sincronizzazione dopo l'installazione e di nuovo quando cambia la configurazione dei plugin nativi.
L'inizializzatore applica una patch al tuo capacitor.config.ts con le impostazioni dell'updater, l'endpoint web e il canale predefinito. Non accettare la patch acriticamente. Apri il file e verifica esplicitamente l'identità dell'applicazione 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 restano gli stessi. appId deve corrispondere al binario installato, version deve descrivere la relazione con la build nativa, 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 creare 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, la configurazione del progetto sia leggibile, il pacchetto updater sia rilevato, gli identificativi applicativi richiesti esistano e l'autenticazione raggiunga l'account configurato. Non deve segnalare mancanza di sync nativo, assenza di app identity o configurazione updater non valida.

Mantieni il primo native build volutamente noioso. Installalo su un dispositivo iOS fisico e su un dispositivo Android fisico, avvialo con accesso alla rete, chiudilo e riaprilo, e conferma che l'updater riesca a eseguire il check senza interferire con 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
Metti la chiave privata in un secrets manager. Non committarla, non salvarla in un archivio di progetto e non esporla nell'output della CI. Il percorso di trust nativo richiede il materiale di verifica pubblico. Solo il job di signing deve poter accedere alla chiave privata.
Cambia la versione lato JavaScript in package.json o nei metadati della tua release web. 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 nasconderebbe la compatibilità invece di migliorarla.
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 sulla versione nativa 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 deve rispondere a quattro domande sulla release:
- Versione nativa minima: Quale binario più vecchio può eseguire questo bundle?
- Versione nativa massima: Quali binari più recenti sono stati intenzionalmente esclusi?
- Canale: Quale pubblico può scoprire l'artefatto?
- Percentuale di rollout: Quanta parte di quel pubblico idoneo può riceverlo?
Inizia l'esposizione in produzione al 5%, poi definisci le evidenze richieste per l'espansione. Verifica il successo di download e installazione, gli avviamenti a freddo normali, le sessioni senza crash e gli errori JavaScript nel flusso modificato. Mantieni visibili insieme l'identità dell'artefatto e i controlli di consegna nel dashboard Capgo.

Usa una build di debug per testare il percorso sul dispositivo. getCurrent() riporta il bundle attivo, e notifyAppReady() conferma che il nuovo bundle ha raggiunto uno stato sano:
import { CapacitorUpdater } from '@capgo/capacitor-updater'
const current = await CapacitorUpdater.getCurrent()
console.log(current)
await CapacitorUpdater.notifyAppReady()
Chiama readiness solo dopo che l'app si è inizializzata abbastanza da superare i tuoi health check. Se non conferma mai la readiness, il recupero automatico potrebbe segnare il bundle come fallito durante il successivo avvio a freddo. Questa salvaguardia protegge gli utenti in produzione, ma può anche far sembrare un test incompleto un problema di consegna. 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 canali sono il layer di routing tra un bundle pubblicato e un dispositivo installato. Sono anche il tuo gate di rilascio. Un canale di staging dovrebbe puntare a un binario nativo noto, un canale beta dovrebbe servire una coorte controllata, e la produzione dovrebbe procedere solo dopo che il canale 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 nativa usata dai tuoi dispositivi di test. I tester dovrebbero eseguire lo stesso binario che supporterà la produzione, non una build di sviluppo locale con plugin extra o una configurazione diversa. Una volta superata la smoke suite, promuovi l'artefatto testato invece di fare l'upload di un secondo bundle leggermente diverso.
La tua mappa dei canali dovrebbe stare in capgo.config.json e sottoposta a review come code dell'applicazione. Mantieni stabili i nomi dei canali, identifica il range di compatibilità nativa previsto e rendi la promozione in produzione un'azione CI esplicita. Per i team che gestiscono l'esposizione delle feature insieme a quella del delivery, questi consigli sulla governance dei feature flag offrono un modo utile per separare il permesso di deployment dall'attivazione per l'utente.
Collega la promozione alla CI
Un design pratico per GitHub Actions prevede due percorsi:
- Pull request: Builda il layer web, firmalo con una credenziale 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 gli unit test, builda il bundle di produzione, valida il vincolo sulla versione nativa, fai l'upload e promuovi solo se il job di test termina con successo.
Un comando di promozione può apparire così:
npx @capgo/cli bundle promote <bundle-id> \
--to-channel production \
--percent 5
Aumenta l'esposizione in step graduali come 25%, 50% e 100%, con un'approvazione CI o un job monitorato tra uno step e l'altro. Le percentuali e i comandi sono controlli, non prove di sicurezza. Una build andata a buon fine ti dice che il bundle è sintatticamente valido. Non ti dice come si comporterà su un determinato binario nativo, con uno stato locale persistente, una connessione lenta o un dispositivo che riprende da una vecchia sessione.
Limite del rilascio: Un web bundle appartiene a una finestra di compatibilità del binario. Un channel 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 degli internal track Android collegando 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 channel. Lo strumento guida all'integrazione Capgo GitHub Actions può aiutare a trasformare questa policy in step di workflow ripetibili.

Strategie di test 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 sul dispositivo o dalle condizioni di rete. Un simulatore può confermare il rendering di una schermata, ma non può coprire ogni binario installato né 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 una build web di produzione. Testa i percorsi modificati di checkout, autenticazione, navigazione e persistenza, invece di fermarti alla compilazione.
- Canale privato per dispositivi: Popola un canale privato con dispositivi fisici che eseguono il binario nativo precedente. Copri entrambe le piattaforme, installazioni pulite, aggiornamenti e stati salvati rappresentativi.
- Canary in produzione: Inizia con un piccolo gruppo di dispositivi idonei, crash reporting collegato e alert per errori JavaScript. Tratta i fallimenti all'avvio come urgenti, perché gli utenti interessati potrebbero non arrivare mai al code che segnala un errore in-app.
Il Guida ai test OTA di Capacitor spiega il funzionamento dei test. La regola operativa è semplice: testa ogni update sul binario nativo che deve proteggere.
Separa il controllo del server dal recupero del client
Il rollback lato server blocca i nuovi download:
npx @capgo/cli channel set production --bundle <previous-id>
Questo cambia ciò che i dispositivi idonei troveranno dopo. Non elimina un bundle già scaricato o attivo su ogni dispositivo, quindi il client ha bisogno anche di controlli di recupero. Configura l'updater per mantenere un fallback noto e funzionante e per tornare indietro dopo una condizione di errore all'avvio definita.
Un percorso di recupero affidabile include:
- Tracciamento dei fallimenti di download: Distingui i problemi di connettività dagli artefatti non validi.
- Tracciamento dei fallimenti di installazione: Rileva problemi di estrazione, verifica e filesystem.
- Monitoraggio dello stato di avvio: Verifica che l'app raggiunga uno stato utilizzabile dopo l'attivazione.
- Fallback automatico: Ripristina il bundle precedente noto come funzionante quando l'avvio fallisce ripetutamente.
- Escalation manuale: Conserva gli identificativi del dispositivo e del bundle per supporto e ingegneria.
Su scala di flotta, anche un piccolo tasso di fallimento genera un carico di supporto significativo. Un Un tasso di successo degli OTA update del 99,95% implica comunque circa 1.000 fallimenti per 1 milione di dispositivi, secondo i dati di Benchmark di test OTA per flotte IoT. La stessa fonte descrive guardrail come il rollback entro 30 minuti, un crash rate inferiore allo 0,1% e il 98% dei dispositivi all'interno della finestra supportata. Considerali come esempi di benchmark, non come criteri di accettazione universali. Imposta l'error budget in base al rischio dell'app e all'impatto sugli utenti.
Firma, sicurezza e cosa l'OTA non può cambiare
Un update non firmato rende l'endpoint di delivery parte della superficie di attacco della tua supply chain. TLS protegge la connessione, ma il client deve anche confermare che l'artifact scaricato provenga da un processo di rilascio autorizzato e non sia stato sostituito o alterato durante il trasferimento.
Genera una keypair Ed25519 con lo tooling dell'updater. Archivia la chiave privata in un segreto 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 di permessi, conserva i log di upload e promozione e richiede un'autenticazione forte per le azioni di produzione.
Considera la rotazione delle chiavi come una migrazione di compatibilità, non come una singola modifica di configurazione. Genera una chiave sostitutiva, rilascia una build nativa che si fidi sia della chiave pubblica attuale sia di quella sostitutiva, poi firma le release con la nuova chiave privata. Rimuovi la vecchia chiave solo dopo che i binari nativi compatibili hanno adottato quella sostitutiva. Revocare la fiducia troppo presto impedisce ai binari più vecchi di accettare aggiornamenti validi. Lasciare indefinitamente attendibile una chiave compromessa vanifica la rotazione.
Definisci il perimetro nel piano di rilascio
L'OTA gestisce le modifiche al layer web. I rilasci nativi sono necessari quando una modifica dipende da funzionalità assenti nel binario installato:
| Categoria | Rilascia via OTA | Richiede rilascio nativo |
|---|---|---|
| Comportamento dell'app | Logica JavaScript, routing, validazione e gestione dello stato | Implementazione di plugin nativi |
| Presentazione | CSS, HTML, testi, theme tokens e asset immagine compatibili | Icona dell'app e risorse splash |
| Accesso alla piattaforma | Chiamate web-layer esistenti di Capacitor verso capacità già presenti nel binario | Nuovi permessi, entitlement o API native |
| Configurazione | Configurazione web compatibile e regole sui contenuti remoti | Info.plist, AndroidManifest.xml, identità di firma |
| Metadati dello store | Nessuna che cambi comportamento revisionato dallo store o metadati di versione | Metadati sensibili alle policy store e modifiche di versione |
Il documentazione sulla firma di Capacitor updater code spiega il modello di verifica. Applicalo operativamente con log di audit anti-manomissione, verifica dei certificati, TLS, controlli di accesso rigorosi e un processo di indagine per lo spoofing delle versioni o la compromissione delle chiavi.
La compatibilità di destinazione conta ancora, perché la popolazione nativa installata cambia gradualmente. Apple ha riportato 66% di tutti i dispositivi attivi su iOS 26 e 74% dei dispositivi introdotti negli ultimi quattro anni su iOS 26, mentre un altro rapporto ha collocato iOS 26 al 79% di tutti i dispositivi più avanti nel ciclo, come sintetizzato in ricerca sulla gestione delle chiavi OTA mobile. Queste cifre coprono punti e popolazioni di dispositivi diversi. La conclusione pratica è coerente: anche le piattaforme mature non aggiornano tutti i dispositivi contemporaneamente. Assegna i bundle per versione nativa e capacità, invece di assumere che un singolo artefatto OTA si adatti a tutta la flotta.
Checklist operativa prima di ogni release
Mantieni la checklist di release su una pagina, archiviata con il repository o il runbook. Aggiornala dopo ogni incidente. Un controllo aggiunto dopo un fallimento reale di solito previene la prossima ricorrenza.
Prima dell'upload
- Conferma la compatibilità: Verifica che il bundle punti al binario nativo corretto e non utilizzi API dei 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 l'ultimo bundle funzionante e verifica che il percorso di fallback sia operativo.
- Esegui smoke test fisici: Testa avvio, login, checkout, navigazione, persistenza e prontezza agli 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 nativa, piattaforma e percorso della feature.
- 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 ancora cercato un aggiornamento da quelli che hanno effettuato il controllo senza successo.
Mantieni la prima finestra di osservazione post-promozione per 30 minuti prima di aumentare l'esposizione. Se un percorso critico si interrompe, fai rollback del canale di produzione al bundle precedente, conserva i log e decidi se la correzione debba far parte di un altro bundle OTA o di una nuova release nativa.
Disciplina del giorno di 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, controlli di rollout, la cronologia degli update e l'osservabilità a livello di device. Il tuo team resta 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 dal rollback e osservabilità del rilascio. Applica la checklist al prossimo deployment, testala su un binario di staging e valuta Capgo per il workflow di produzione.