Vai al contenuto

Azioni GitHub

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:

  • Un account Capgo con un abbonamento attivo e una chiave Capgo API
  • La tua app registrata su Capgo (bunx @capgo/cli@latest app add se no)
  • Credenziali di build configurate in locale con bunx @capgo/cli@latest build init — vedi Gestione credenziali per la guida del wizard
  • Una build locale riuscita (bunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — la CI non è il posto giusto per debuggare la tua prima build
  • Il GitHub CLI (gh) 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.

  1. 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:

    Finestra del terminale
    gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"

    Genera la chiave in dashboard di Capgo con upload permessi o superiori.

  2. Esporta le tue credenziali in un .env file

    Avvia il gestore interattivo delle credenziali:

    Finestra del terminale
    bunx @capgo/cli@latest build credentials manage --appId com.example.app

    Nella 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.

  3. 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:

    Finestra del terminale
    gh secret set -f .env.capgo.com.example.app

    Fatto — tutti i segreti necessari al tuo workflow sono ora in GitHub. Verifica con gh secret list.

  4. 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):

PiattaformaSegreti creati
iOSBUILD_CERTIFICATE_BASE64, P12_PASSWORD, CAPGO_IOS_PROVISIONING_MAP_BASE64, APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_KEY_CONTENT, APP_STORE_CONNECT_TEAM_ID
AndroidANDROID_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.

.github/workflows/capgo-build-manual.yml
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.

.github/workflows/capgo-build-release.yml
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 release

La 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.

.github/workflows/capgo-build-main.yml
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-upload

Il 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-release

Passa --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-bump

bun 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') }}
SintomoCausa probabile
CAPGO_TOKEN is not setSegreto non aggiunto o il job non ha accesso (controlla le protezioni di ambiente/branch)
Errori per credenziali iOS / Android mancantigh 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 localeUn 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 ConnectTeam 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 IDLa 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 ancoraNon 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 combinatoLe 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 vuotoLa 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 schemaVersionIl 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.