Release automatizzate
Tagga una release su Git e i tuoi binari firmati per iOS e Android verranno inviati automaticamente a TestFlight e Play Store.
Copia un prompt di configurazione con i passaggi di installazione e la guida markdown completa per questo plugin.
Automatizza le build iOS e Android direttamente dal tuo repository GitHub. Con un solo file di workflow e pochi repository secrets, ogni push, tag o trigger manuale può generare app firmate e pronte per gli store — senza che nessuno nel team debba avere un Mac, Xcode o Android Studio installato.
Risposta breve: per la CI/CD di Capacitor su GitHub Actions, aggiungi un workflow che esegue Capgo CLI: Capgo Builder produce i build firmati per iOS e Android e può caricarli sugli store, e, con un job aggiuntivo bundle upload (vedi Auto OTA o Native), lo stesso workflow può distribuire modifiche solo web come Capgo live updates.
Release automatizzate
Tagga una release su Git e i tuoi binari firmati per iOS e Android verranno inviati automaticamente a TestFlight e Play Store.
Nessuna configurazione locale
I contributori su Windows o Linux possono avviare i build iOS. Niente Xcode, niente problemi di provisioning o certificati di firma condivisi tra i vari laptop.
Secret con scope limitato
Le credenziali risiedono nei repository secrets di GitHub, limitati al tuo repo e visibili solo al workflow runner. Facili da ruotare e da auditare.
Build in parallelo
Esegui le build di iOS e Android contemporaneamente con un matrix job. Una release tipica si completa in meno di 10 minuti.
Prima di configurare il workflow, assicurati di avere:
bunx @capgo/cli@latest app add se no)bunx @capgo/cli@latest build init — vedi Gestione credenziali per la guida del wizardbunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — la CI non è il posto giusto per debuggare la tua prima buildgh) installato e autenticato (gh auth login)Il Capgo CLI può esportare le tue credenziali locali come un .env file pronto all'uso. In combinazione con gh secret set -f, trasforma l'intero setup CI/CD in tre comandi: niente codifica base64 manuale, niente gestione JSON, niente copia-incolla segreto per segreto.
Aggiungi la chiave Capgo API come segreto del repository
La chiave API non fa parte dello store di credenziali per app, quindi aggiungila una volta manualmente:
gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"Genera la chiave in dashboard di Capgo con upload permessi o superiori.
Esporta le tue credenziali in un .env file
Avvia il gestore interattivo delle credenziali:
bunx @capgo/cli@latest build credentials manage --appId com.example.appNella TUI, seleziona Esporta in .env. Il comando CLI scrive .env.capgo.<appId> nella directory corrente con modalità 0600 (leggibile solo dal proprietario) — ad esempio, .env.capgo.com.example.app. Quando iOS e Android sono configurati, i secret di entrambe le piattaforme finiscono nello stesso file sotto # === IOS === e # === ANDROID === le intestazioni di sezione. I nomi delle env-var di iOS e Android sono distinti, quindi combinarli non crea conflitti.
Carica il .env file nei secret di GitHub Actions
Il gh secret set -f il comando legge un file dotenv e crea un segreto del repository per ogni KEY=value riga:
gh secret set -f .env.capgo.com.example.appFatto — tutti i segreti necessari al tuo workflow sono ora in GitHub. Verifica con gh secret list.
Crea il file del workflow
Aggiungi .github/workflows/capgo-build.yml nel tuo repository. Scegli uno dei tre pattern di trigger qui sotto in base a come vuoi avviare i build.
Per riferimento, gh secret set -f creerà questi segreti del repository (il tuo workflow YAML li riferisce con questi nomi esatti):
| Piattaforma | Segreti creati |
|---|---|
| iOS | BUILD_CERTIFICATE_BASE64, P12_PASSWORD, CAPGO_IOS_PROVISIONING_MAP_BASE64, APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_KEY_CONTENT, APP_STORE_CONNECT_TEAM_ID |
| Android | ANDROID_KEYSTORE_FILE, KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORD, KEYSTORE_STORE_PASSWORD, PLAY_CONFIG_JSON |
| (aggiunti manualmente) | CAPGO_TOKEN |
Non devi memorizzarli: gli esempi di workflow qui sotto li riferiscono già tutti.
I tre esempi qui sotto coprono i pattern più comuni. Usano tutti la stessa struttura: check out del repository, installazione delle dipendenze, build degli asset web, sync con il nativo, quindi chiamata a Capgo Build con le credenziali passate come variabili d'ambiente.
Permette a chiunque con accesso in scrittura di avviare una build da Azioni tab in GitHub con un menu a tendina per la piattaforma. Utile per build di test ad hoc o per avviare un rilascio su richiesta.
name: Capgo Build (Manual)
on: workflow_dispatch: inputs: platform: description: 'Platform to build' required: true default: 'android' type: choice options: [ios, android, both] mode: description: 'Build mode' required: true default: 'debug' type: choice options: [debug, release]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 with: bun-version: latest
- run: bun install --frozen-lockfile - run: bun run build - run: bunx cap sync
- name: Trigger Capgo Build 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 }} run: | bunx @capgo/cli@latest build request com.example.app \ --platform ${{ inputs.platform }} \ --build-mode ${{ inputs.mode }}Sostituisci com.example.app con il tuo app ID. Una volta commitato, vai su Actions → Capgo Build (Manuale) → Esegui workflow per avviarlo.
Compila e pubblica entrambe le piattaforme in parallelo ogni volta che pushi un tag di versione come v1.4.0. Questa è la configurazione di produzione più comune — git tag v1.4.0 && git push --tags diventa il tuo comando di release.
name: Capgo Build (Release)
on: push: tags: - 'v*'
jobs: build: runs-on: ubuntu-latest strategy: fail-fast: false matrix: platform: [ios, android] steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 with: bun-version: latest
- run: bun install --frozen-lockfile - run: bun run build - run: bunx cap sync ${{ matrix.platform }}
- name: Build ${{ matrix.platform }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} # iOS 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 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 }} run: | bunx @capgo/cli@latest build request com.example.app \ --platform ${{ matrix.platform }} \ --build-mode releaseLa matrix esegue iOS e Android in parallelo su runner separati. Impostare fail-fast: false significa che una build iOS fallita non annullerà la build Android in corso (e viceversa) — utile quando una piattaforma ha un problema di firma transitorio.
Rileva precocemente i regressioni di Native Build generando una build Android di debug a ogni push su main. Costo di esecuzione basso, feedback rapido e puoi saltare l'upload su Play Store per mantenerlo un semplice smoke test.
name: Capgo Build (Main)
on: push: branches: [main] paths: - 'src/**' - 'android/**' - 'ios/**' - 'package.json' - 'capacitor.config.*'
jobs: smoke-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 with: bun-version: latest
- run: bun install --frozen-lockfile - run: bun run build - run: bunx cap sync android
- name: Smoke build (Android debug) env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} 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 }} run: | bunx @capgo/cli@latest build request com.example.app \ --platform android \ --build-mode debug \ --no-playstore-upload \ --output-uploadIl paths il filtro evita che il workflow parta per modifiche alla sola documentazione. --no-playstore-upload salta l'invio al Play Store (non PLAY_CONFIG_JSON necessario) e --output-upload genera un URL di download per l'APK risultante, così puoi installarlo su un dispositivo di test.
Per le build di test, salta l'invio agli store: Android usa --no-playstore-upload; per iOS, esegui la build in modalità ad-hoc con --ios-distribution ad_hoc (che non invia mai all'App Store). Combina una delle due con --output-upload per ottenere un URL di download temporaneo per il binario.
Di default, le release build caricano l'artefatto firmato e lasciano l'azione finale dello store sotto il tuo controllo. Per le release CI che devono passare direttamente al flusso di revisione dello store, aggiungi --submit-to-store-review.
Android utilizza il tuo PLAY_CONFIG_JSON account di servizio. Senza una track esplicita, --submit-to-store-review il default è la track di produzione con release_status: completed. è preferibile specificare la track nel punto di chiamata con --android-track (o PLAY_STORE_TRACK), e sovrascrivere lo status con --android-release-status / PLAY_STORE_RELEASE_STATUS quando necessario:
- name: Submit Android release for review env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} 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 }} run: | npx @capgo/cli@latest build request com.example.app \ --platform android \ --build-mode release \ --submit-to-store-review \ --android-track production \ --store-release-name "${GITHUB_REF_NAME}" \ --store-release-notes "Release ${GITHUB_REF_NAME}" \ --store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}"Per un rilascio interno completato invece di quello di produzione:
- name: Submit Android internal release env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} 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 }} run: | npx @capgo/cli@latest build request com.example.app \ --platform android \ --build-mode release \ --submit-to-store-review \ --android-track internal \ --store-release-name "${GITHUB_REF_NAME}"iOS usa il percorso della chiave API di App Store Connect e invia la build TestFlight processata alla revisione dell'App Store. Richiede app_store la distribuzione; --ios-testflight-groups è opzionale per la distribuzione beta esterna e non serve per la revisione dell'App Store:
- name: Submit iOS build to App Store review env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} P12_PASSWORD: ${{ secrets.P12_PASSWORD }} CAPGO_IOS_PROVISIONING_MAP: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP }} 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 }} run: | npx @capgo/cli@latest build request com.example.app \ --platform ios \ --build-mode release \ --ios-distribution app_store \ --submit-to-store-review \ --store-release-name "${GITHUB_REF_NAME}" \ --store-release-notes "Release ${GITHUB_REF_NAME}" \ --store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}" \ --no-ios-automatic-releasePassa --output-record <path> per salvare su disco l'URL dell'artefatto di build e il QR code quando la build va a buon fine, poi rileggerlo negli step successivi con build last-output. Nessuna estrazione dai log, nessuna regex.
- name: Build env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} # ...credentials... run: | bunx @capgo/cli@latest build request com.example.app \ --platform android --build-mode debug \ --output-upload --output-retention 1d \ --output-record /tmp/build.json
- name: Comment on PR with build URL env: GH_TOKEN: ${{ github.token }} run: | URL=$(bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl) if [ -n "$URL" ]; then gh pr comment ${{ github.event.pull_request.number }} \ --body "Debug build ready: $URL" fi--output-record /tmp/build.json scrive un record JSON (con jobId, status, outputUrl, qrCodeAscii, qrCodePngPath, finishedAt) e un QR code PNG code accanto /tmp/build.json.qr.png. build last-output lo rilegge:
--field outputUrl stampa solo l'URL di download (terminato da newline; sicuro per URL=$(...)).--field qrCodePngPath stampa il percorso del PNG in modo da poterlo caricare come allegato alla PR.--qr stampa il QR code ASCII renderizzato — inseriscilo dentro una fence Markdown code nel commento della PR per la scansione inline.Di default, ogni release build incrementa il numero di build. Per fissarlo a un valore sotto il tuo controllo (ad esempio, il tag Git), passa --skip-build-number-bump:
- name: Set version from tag run: | VERSION="${GITHUB_REF#refs/tags/v}" # Update package.json or your version source here bun pm version "$VERSION" --no-git-tag-version
- name: Build env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} # ...credentials... run: | bunx @capgo/cli@latest build request com.example.app \ --platform ios --build-mode release \ --skip-build-number-bumpbun install è già abbastanza veloce che una cache delle JS-deps raramente conviene, ma per progetti più grandi vale la pena mettere in cache le dipendenze native di Capacitor (CocoaPods, Gradle):
- uses: actions/cache@v4 with: path: | ~/.bun/install/cache ios/App/Pods android/.gradle key: ${{ runner.os }}-capgo-${{ hashFiles('**/bun.lock', '**/Podfile.lock') }}| Sintomo | Causa probabile |
|---|---|
CAPGO_TOKEN is not set | Segreto non aggiunto o il job non ha accesso (controlla le protezioni di ambiente/branch) |
| Errori per credenziali iOS / Android mancanti | gh secret set -f non è stato eseguito, o è stato eseguito su un repository diverso. Verifica con gh secret list |
cap sync fallisce in CI ma funziona in locale | Un plugin nativo non è in package.json, o hai dimenticato bun install prima cap sync |
| La build ha successo ma nessuna app appare in App Store Connect | Team ID errato, oppure il record dell'app non esiste ancora in App Store Connect. Verifica in locale con bunx @capgo/cli@latest build credentials manage |
| La build si blocca dopo "Uploading project" | L'archivio del progetto è insolitamente grande — controlla che node_modules non venga caricato (di default non dovrebbe) |
Provisioning profile doesn't match bundle ID | La provisioning map punta a un bundle ID diverso da quello con cui Xcode firma. Riesegui build init per aggiornare il profilo, poi riesporta con build credentials manage |
| Credenziali cambiate in locale ma la CI fallisce ancora | Non dimenticare di fare il re-export e il re-push: bunx @capgo/cli@latest build credentials manage → gh secret set -f .env.capgo.<appId> |
| Il Manager si rifiuta di scrivere il file combinato | Le chiavi di config condivise differiscono tra le piattaforme — il manager avvisa e chiede conferma. Conferma per sovrascrivere (overwrite-one-wins) oppure riesporta per piattaforma con --platform ios / --platform android |
build last-output stampa un URL vuoto | La build non è passata --output-upload, oppure è fallito prima di produrre un artifact. outputUrl sarà null nel record. Fai branch su [ -n "$URL" ] prima di usarlo |
build last-output errori con Unsupported record schemaVersion | Il runner usa una versione di CLI più vecchia di quella che ha scritto il record. Fissa sia il producer che il reader sulla stessa versione esplicita (es. bunx @capgo/cli@7.104.0 … su entrambi i lati) invece di @latest, che fluttua e può variare tra i job |
Per errori di build specifici della piattaforma, consulta la Guida al troubleshooting.