Salta al contenuto principale

Come firmare e buildare un'app Capacitor nel cloud

Firma e builda la tua app Capacitor nel cloud: crea il keystore Android e il certificato iOS, archivia le credenziali in modo sicuro ed esegui build firmate dalla CI.

Certificati iOS e keystore Android per firmare un'app Capacitor in un build cloud

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 .p8 file 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
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 .env i 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.

Live updates per le app Capacitor

Quando un bug nel web-layer è live, rilascia la fix tramite Capgo invece di aspettare giorni l'approvazione degli store. Gli utenti ricevono l'update in background, mentre le modifiche native restano nel normale processo di review.

Ultimi articoli dal blog

Capgo ti offre gli insight migliori che ti servono per creare un'app mobile davvero professionale.