Vai al contenuto

Scegli automaticamente Live Update o Native Build

La maggior parte delle release Capacitor è solo JavaScript e va distribuita come un live update. Alcune modifiche toccano il code nativo e richiedono un nuovo binario da Build Capgo. Questa guida spiega come fare in modo che GitHub Actions, GitLab CI o qualsiasi altra piattaforma CI/CD scelga il percorso corretto a ogni push, senza intervento umano.

Capgo sa già quale percorso è sicuro. Dopo il build web (e prima di fare l'upload o richiedere un Native Build), esegui:

Finestra del terminale
npx @capgo/cli@latest bundle releaseType com.example.app --channel production
# → OTA ship with bundle upload
# → native ship with Capgo Build

OTA significa che i pacchetti nativi corrispondono a quelli già live sul canale. native significa che un plugin, la versione di Capacitor o un'altra dipendenza nativa è cambiata: un semplice bundle over-the-air non può aggiornare questi dispositivi in sicurezza.

releaseType confronta metadati del pacchetto nativo (plugin e versioni Capacitor/Cordova). Questo hai vede ogni modifica sotto ios/, android/, o capacitor.config.*. Proteggi prima quei percorsi in git, poi usa releaseType per la compatibilità delle dipendenze — gli esempi qui sotto fanno entrambi.

Vedi Compatibilità nativa per le regole complete e la tabella bundle compatibility manuale.

  • App Capgo registrata e chiave Capgo API nei segreti della CI come CAPGO_TOKEN
  • Live Updates upload funzionante (bundle upload) — vedi Integrazione CI/CD
  • credenziali Capgo Build nella CI se prevedi job nativi — vedi Azioni GitHub o Credenziali
  • Un canale già esistente che corrisponde alla produzione (gli esempi usano production)
  • Channel on the metadata strategia, così ogni upload può includere --auto-min-update-version (una tantum):
Finestra del terminale
npx @capgo/cli@latest channel set production com.example.app --disable-auto-update metadata
  1. Build degli asset web come al solito.
  2. Se il commit modifica ios/, android/, o capacitor.config.*, forza il percorso nativo.
  3. Altrimenti chiedi a Capgo releaseType se il commit è sicuro per l'OTA.
  4. Se OTA, esegui l'upload con --fail-on-incompatible e --auto-min-update-version.
  5. Se native, avvia Capgo Build, poi carica il bundle corrispondente con --auto-min-update-version così i metadati nativi del canale avanzano. Fai hai usa --fail-on-incompatible per quel baseline upload — i nuovi pacchetti native dovrebbero differire. Vedi Workflow Native + OTA Channel per le FAQ a livello di channel.

Un workflow che blocca i percorsi native, per poi biforcarsi su releaseType:

.github/workflows/capgo-release.yml
name: Capgo Release
on:
push:
branches: [main]
jobs:
decide:
runs-on: ubuntu-latest
outputs:
release_type: ${{ steps.verdict.outputs.type }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Decide OTA vs native
id: verdict
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
run: |
BEFORE="${{ github.event.before }}"
if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then
BEFORE="$(git rev-parse HEAD~1 2>/dev/null || echo '')"
fi
if [ -z "$BEFORE" ] || git diff --name-only "$BEFORE" "${{ github.sha }}" \
| grep -qE '^(ios/|android/|capacitor\.config\.)'; then
TYPE=native
echo "Native path/config changed (or no prior commit) — forcing native"
else
TYPE=$(npx @capgo/cli@latest bundle releaseType com.example.app --channel production | tr -d '[:space:]')
fi
echo "type=$TYPE" >> "$GITHUB_OUTPUT"
echo "Capgo release type: $TYPE"
live_update:
needs: decide
if: needs.decide.outputs.release_type == 'OTA'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Upload live update
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
run: |
npx @capgo/cli@latest bundle upload com.example.app \
--channel production \
--fail-on-incompatible \
--auto-min-update-version
native_build:
needs: decide
if: needs.decide.outputs.release_type == 'native'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- run: npm ci
- run: npm run build
- run: npx cap sync ${{ matrix.platform }}
- name: Capgo Build ${{ matrix.platform }}
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 }}
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 ${{ matrix.platform }} \
--build-mode release
native_bundle:
needs: [decide, native_build]
if: needs.decide.outputs.release_type == 'native'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Upload bundle for new native baseline
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
run: |
# Channel must already be on metadata (see Prerequisites above)
npx @capgo/cli@latest bundle upload com.example.app \
--channel production \
--auto-min-update-version

Sostituisci com.example.app e configurare i signing secrets come descritto in GitHub Actions per Capgo Build.

GitLab valuta rules quando viene creata la pipeline, quindi il branch con una shell if all'interno di un job di deploy (o genera una pipeline child dinamica se ti servono job nativi in una matrice separata):

.gitlab-ci.yml
image: node:24
stages:
- build
- deploy
variables:
APP_ID: com.example.app
CHANNEL: production
build_web:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
- node_modules/
expire_in: 1 hour
only:
- main
deploy:
stage: deploy
needs: [build_web]
script:
- |
BEFORE="${CI_COMMIT_BEFORE_SHA:-}"
if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then
BEFORE="$(git rev-parse HEAD~1 2>/dev/null || echo '')"
fi
if [ -z "$BEFORE" ] || git diff --name-only "$BEFORE" "$CI_COMMIT_SHA" \
| grep -qE '^(ios/|android/|capacitor\.config\.)'; then
TYPE=native
else
TYPE=$(npx @capgo/cli@latest bundle releaseType "$APP_ID" --channel "$CHANNEL" | tr -d '[:space:]')
fi
echo "Capgo release type: $TYPE"
if [ "$TYPE" = "OTA" ]; then
npx @capgo/cli@latest bundle upload "$APP_ID" \
--channel "$CHANNEL" \
--fail-on-incompatible \
--auto-min-update-version
elif [ "$TYPE" = "native" ]; then
npx cap sync
npx @capgo/cli@latest build request "$APP_ID" --platform ios --build-mode release
npx @capgo/cli@latest build request "$APP_ID" --platform android --build-mode release
npx @capgo/cli@latest bundle upload "$APP_ID" \
--channel "$CHANNEL" \
--auto-min-update-version
else
echo "Unexpected release type: $TYPE" >&2
exit 1
fi
only:
- main

Salva CAPGO_TOKEN e le variabili di firma Capgo Build come variabili CI/CD protette/mascherate.

Gli stessi tre passaggi funzionano ovunque:

StepComando
Verdettonpx @capgo/cli@latest bundle releaseType APP_ID --channel production
Percorso OTAnpx @capgo/cli@latest bundle upload APP_ID --channel production --fail-on-incompatible --auto-min-update-version
Percorso nativenpx @capgo/cli@latest build request APP_ID --platform ios (o android) --build-mode release

Mappa l'exit / lo stdout della shell nelle condizionali della tua piattaforma (o mantieni un singolo job con una shell if, come in GitLab sopra):

  • Azure Pipelines — imposta una variabile di output da uno step di script, poi usa condition: eq(variables['releaseType'], 'OTA')
  • Bitbucket Pipelines — scrivi RELEASE_TYPE=… a $BITBUCKET_PIPELINES_VARIABLES_PATH, dichiarala sotto output-variables, e dirama i passaggi successivi con condition: state: RELEASE_TYPE == "OTA" (i soli artifact su file non possono guidare condition)
  • CircleCI — when viene valutato in fase di config-compile, quindi fai il branch con uno shell a runtime if (o dynamic config / continuation), non un valore del workspace in when
  • Jenkins — cattura lo stdout in una env var e usa when { environment name: 'RELEASE_TYPE', value: 'OTA' }

Filtri sui percorsi (accelerazione opzionale)

Sezione intitolata “Path Filters (velocizzazione opzionale)”

I path filter servono per ottimizzare i costi, non sostituiscono il controllo Capgo. Meglio escludere i path delle sole docs invece di mantenere una allowlist fragile — le build web spesso dipendono anche da vite.config.*, tsconfig*.json, e dai file di config del framework:

on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'

Se invece usi una allowlist, includi tutti gli input che le tue build web e native leggono, non solo src/ e package.json.

Quando la CI sceglie native:

  1. Capgo Build produce binari firmati e può inviarli a TestFlight / Play (vedi configurazione).
  2. Carica il bundle JS corrispondente con --auto-min-update-version (strategia metadata) in modo che il channel registri i nuovi pacchetti native — altrimenti il prossimo commit JS-only restituirà ancora native.
  3. Una volta che gli utenti installano il nuovo binario, i successivi commit JavaScript-only tornano a OTA ancora.