Per firmare e buildare un'app Capacitor nel cloud, crei una volta sola i tuoi materiali di firma (un keystore Android, un certificato di distribuzione iOS e un provisioning profile), li fornisci a un servizio di build cloud e poi avvii le build dal terminale o dalla CI. Il servizio compila il progetto nativo, lo firma e può caricarlo direttamente su TestFlight o Google Play. Questa guida copre ogni file di firma, come crearlo senza un Mac, come configurarlo con Capgo Build e come automatizzare le build firmate in modo sicuro.
Cosa significa “firmare nel cloud”
Entrambi gli store accettano solo binari firmati. La firma dimostra che la build proviene da te e che nessuno l'ha modificata successivamente. In locale, Xcode e Android Studio nascondono la maggior parte di questi dettagli. Nel cloud, nulla è implicito, quindi devi sapere esattamente quali file sono coinvolti:
| Piattaforma | File | Cos'è | Utilizzato per |
|---|---|---|---|
| Android | .jks / .keystore |
Keystore contenente la chiave di upload | Firma dell'AAB o APK |
| Android | Account di servizio .json |
Credenziali Google Cloud | Upload su Google Play |
| iOS | .p12 |
Certificato Apple Distribution e chiave privata | Firma dell'IPA |
| iOS | .mobileprovision |
Provisioning profile che collega bundle ID, certificato e capacità | Consente all'app di essere eseguita e distribuita |
| iOS | .p8 + ID chiave + ID emittente |
Chiave API di App Store Connect | Upload su TestFlight, lettura dei numeri di build |
Tienili fuori da Git. Tutto ciò che segue li salva nel file di credenziali locale o nel secret store della tua CI.
Firma Android
Crea il keystore di upload
Se l'app è già su Google Play, riutilizza il keystore esistente. La firma di un aggiornamento con una chiave diversa viene rifiutata a meno che non si proceda con il reset della chiave di upload tramite Play Console.
Per una nuova app:
keytool -genkeypair -v \
-storetype PKCS12 \
-keystore release.jks \
-alias upload \
-keyalg RSA -keysize 2048 \
-validity 10000
Note:
- Google Play richiede che la chiave sia valida almeno fino al 22 ottobre 2033.
-validity 10000(circa 27 anni) copre questo requisito. - Con il tipo di store PKCS12, la password della chiave è la stessa della password dello store.
- Nessun JDK a portata di mano? Il Generatore di keystore per Android genera lo stesso file nel browser.
Play App Signing e la chiave di upload
Le nuove app su Google Play usano Play App Signing. Google detiene la chiave di firma dell'app e firma ciò che gli utenti scaricano. Il tuo keystore è carica chiave. Se la perdi, il supporto di Play Console può registrare una nuova chiave di upload, motivo per cui perderla è un ritardo, non un disastro. In ogni caso, fai un backup.
Account di servizio per gli upload
Per caricare dalla cloud, crea un account di servizio in Google Cloud, abilita l'API di Google Play Android Developer, scarica la sua chiave JSON e invita l'account di servizio in Play Console sotto Utenti e permessi con permessi di release per la tua app. L'onboarding di Capgo può farlo tramite Google sign-in, come mostrato di seguito.
Firma iOS
I tre elementi Apple
- Certificato Apple Distribution. Uno per team è sufficiente, valido per un anno. Apple limita il numero che puoi avere, quindi non crearne uno per ogni sviluppatore.
- Profilo di provisioning. Collega il bundle ID, il certificato e le capability come le notifiche push. Usa un App Store Connect profile per TestFlight e l'App Store, e un Ad Hoc profile per l'installazione su dispositivi registrati. Ogni app extension (widget, share extension, notification service) richiede il proprio profile.
- Chiave API di App Store Connect. Creato sotto Utenti e Accesso > Integrazioni con accesso App Manager. Il
.p8file viene scaricato una sola volta.
Per crearli servono permessi di admin o account holder nel team Apple Developer.
Creare un certificato senza Mac
Il flusso Keychain Access richiede macOS, ma OpenSSL funziona ovunque:
# 1. Private key and certificate signing request
openssl req -new -newkey rsa:2048 -nodes \
-keyout dist.key -out dist.csr \
-subj "/emailAddress=dev@example.com/CN=Example Inc/C=US"
# 2. Upload dist.csr at developer.apple.com > Certificates > + > Apple Distribution
# and download distribution.cer
# 3. Convert and bundle into a .p12
openssl x509 -inform DER -in distribution.cer -out distribution.pem
openssl pkcs12 -export -legacy \
-inkey dist.key -in distribution.pem \
-out distribution.p12 -passout pass:choose-a-password
Il -legacy flag matters with OpenSSL 3: senza di essa, le macchine di build macOS potrebbero non riuscire a importare il .p12 con “MAC verification failed”. Il browser-based Generatore di certificati iOS effettua gli stessi passaggi se preferisci non usare un terminale.
Poi crea il provisioning profile nel developer portal (Profili > + > App Store Connect), seleziona il tuo app ID e il nuovo certificato, e scaricalo.
Configura la firma con Capgo Build
Build Capgo compila e firma le app Capacitor su macchine gestite da Capgo, così puoi buildare iOS da Windows o Linux. Inizia effettuando il login e registrando l'app:
bunx @capgo/cli@latest login
bunx @capgo/cli@latest app add
Opzione A: onboarding guidato (consigliato)
bunx @capgo/cli@latest build init --platform ios
bunx @capgo/cli@latest build init --platform android
Su iOS, l'onboarding crea o riutilizza il certificato di distribuzione e il provisioning profile App Store con la tua chiave API di App Store Connect. Su macOS può anche guidarti nella creazione di quella chiave API. Su Android crea o importa il keystore e può configurare il service account Google Cloud e l'invito alla Play Console tramite Google sign-in. Al termine propone di avviare la prima build.
Opzione B: salva i file esistenti
Se hai già i file delle sezioni precedenti:
# iOS
bunx @capgo/cli@latest build credentials save \
--platform ios \
--certificate ./distribution.p12 \
--p12-password "choose-a-password" \
--ios-provisioning-profile ./AppStore.mobileprovision \
--apple-key ./AuthKey_ABC1234567.p8 \
--apple-key-id ABC1234567 \
--apple-issuer-id 00000000-0000-0000-0000-000000000000 \
--apple-team-id TEAM123456
# Android
bunx @capgo/cli@latest build credentials save \
--platform android \
--keystore ./release.jks \
--keystore-alias upload \
--keystore-key-password "store-password" \
--keystore-store-password "store-password" \
--play-config ./play-service-account.json
Per le app con estensioni, ripeti --ios-provisioning-profile con un bundleId=path mapping per ogni target:
--ios-provisioning-profile com.example.app=./App.mobileprovision \
--ios-provisioning-profile com.example.app.widget=./Widget.mobileprovision
Le credenziali sono salvate in ~/.capgo-credentials/credentials.json, con chiave app ID e piattaforma. Aggiungi --local per salvarle in .capgo-credentials.json nel progetto, e aggiungi quel file a .gitignore. Verifica cosa viene salvato con bunx @capgo/cli@latest build credentials list.
Avvia una build firmata
Prepara il progetto nativo, poi richiedi la build:
bun run build
bunx cap sync
# iOS: sign with the App Store profile and upload to TestFlight
bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release
# Android: sign the AAB and upload to the internal track
bunx @capgo/cli@latest build request com.example.app --platform android --build-mode release --android-track internal
I log vengono trasmessi in streaming nel terminale. Una scansione pre-build verifica la scadenza dei certificati, le password e l'abbinamento dei profili prima di qualsiasi upload, in modo che la maggior parte degli errori di firma fallisca in pochi secondi anziché in minuti. Esegui da solo con bunx @capgo/cli@latest build prescan --platform ios.
Varianti utili:
| Obiettivo | Flag |
|---|---|
| Build di test su iPhone registrati | --ios-distribution ad_hoc --ios-provisioning-profile ./adhoc.mobileprovision --output-upload |
| APK per dispositivi MDM o kiosk | --platform android --no-playstore-upload --output-upload |
| Invia direttamente a App Review | --submit-to-store-review --store-release-name 2.4.0 |
| Mantieni il tuo numero di build | --skip-build-number-bump |
| Build pulita senza cache | --no-cache |
Per le build ad hoc, raccogli prima gli UDID dei dispositivi con Trova UDID iOS e aggiungili al profilo.
Automatizza i build firmati in CI
In CI, passa le credenziali come variabili d'ambiente invece di un file di credenziali. CLI esporta esattamente ciò di cui hai bisogno:
bunx @capgo/cli@latest build credentials manage --appId com.example.app
# choose "Export to .env"
Su GitHub, spingi ogni riga nei segreti del repository con un solo comando, poi elimina il file:
gh secret set -f .env.capgo.com.example.app
gh secret set CAPGO_TOKEN --body "your-capgo-api-key"
rm .env.capgo.com.example.app
Un workflow di release che firma e pubblica su entrambe le piattaforme tramite tag:
name: Signed release
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync ${{ matrix.platform }}
- run: bunx @capgo/cli@latest build request com.example.app --platform ${{ matrix.platform }} --build-mode release
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
Il job gira su Linux. Niente runner macOS, niente comandi keychain o fastlane. Le stesse variabili d'ambiente funzionano in qualsiasi CI: variabili GitLab CI/CD, variabili protette Bitbucket, secret di Gitea o variable groups di Azure DevOps. Guide specifiche per piattaforma: Bitbucket Pipelines, Gitea Actions, e il Documentazione GitHub Actions.
Come vengono gestite le tue chiavi
Una domanda legittima prima di affidare le chiavi di firma a un servizio cloud. Con Capgo Build:
- Le credenziali restano sulla tua macchina (
~/.capgo-credentials/) o nel secret store della tua CI. Capgo non conserva un vault delle tue chiavi. - Per ogni build, CLI le invia via HTTPS. Vengono usate solo durante quella build e cancellate al termine.
- Viene caricato solo il progetto nativo preparato. Il tuo codice sorgente web,
.git, e.envi file non vengono caricati. - Le app buildate vanno direttamente su App Store Connect o Google Play, oppure su un link di download temporaneo se lo richiedi.
Il compromesso: ruotare una credenziale significa aggiornare da soli i segreti della tua CI. Riesporta con build credentials manage e pusha di nuovo il file.
Scadenza e rotazione
| Elemento | A vita | Cosa fare |
|---|---|---|
| Certificato di distribuzione Apple | 1 anno | Creane uno nuovo, rigenera i profili, salva di nuovo, aggiorna la CI |
| Profilo di provisioning | 1 anno, o fino alla revoca del certificato | Rigenera e salva di nuovo |
| Chiave API di App Store Connect | Fino alla revoca | Revoca quando qualcuno con accesso se ne va |
| Keystore di upload Android | Per tutta la sua validità (impostala su decenni) | Fanne un backup; se perso, reimpostalo da Play Console |
| Chiave del service account di Play | Fino a cancellazione | Ruotala annualmente o quando cambiano gli accessi |
Metti le date Apple in un calendario condiviso. Un certificato scaduto non influisce sulle app già sui dispositivi degli utenti, ma blocca ogni nuovo build.
Risoluzione problemi
| Errore | Causa e soluzione |
|---|---|
Provisioning profile doesn't include signing certificate |
Il profilo è stato generato per un certificato diverso. Rigeneralo con quello attuale. |
Provisioning profile doesn't match bundle ID |
Profilo creato per un altro app ID o mancante di un target di estensione. Aggiungi un bundleId=path mapping per ogni target. |
MAC verification failed |
Errato .p12 password, o export OpenSSL 3 senza -legacy. |
Keystore was tampered with, or password was incorrect |
Password dello store errata, oppure il file è stato corrotto da a capo base64. |
Key alias not found |
L'alias differisce da quello nel keystore. Elencalo con keytool -list -keystore release.jks. |
| Autenticazione App Store Connect non riuscita | Key ID o issuer ID errati, key revocata, oppure orologio di sistema non sincronizzato sulla macchina che firma il token. |
| Upload su Play: il chiamante non ha i permessi | Account di servizio non invitato in Play Console, oppure il API per sviluppatori Android non è abilitato. |
Altre correzioni sono nella Capgo Build troubleshooting guide e CI/CD per Capacitor: errori comuni.
Dopo la prima build firmata
Le build native firmate servono solo quando cambiano i code nativi. Per modifiche a JavaScript, CSS e HTML, invia un live update alle app installate invece, e tieni le build degli store per le release che toccano plugin o configurazione nativa. Se arrivi da un setup basato su Mac, Build di un'app iOS da Windows con Capgo Build mostra l'intero workflow senza macOS.