Scegli automaticamente Live Update o Native Build
Copia un prompt di configurazione con i passaggi di installazione e la guida markdown completa per questo plugin.
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.
La decisione
Sezione intitolata “La decisione”Capgo sa già quale percorso è sicuro. Dopo il build web (e prima di fare l'upload o richiedere un Native Build), esegui:
npx @capgo/cli@latest bundle releaseType com.example.app --channel production# → OTA ship with bundle upload# → native ship with Capgo BuildOTA 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.
Prerequisiti
Sezione intitolata “Prerequisiti”- 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
metadatastrategia, così ogni upload può includere--auto-min-update-version(una tantum):
npx @capgo/cli@latest channel set production com.example.app --disable-auto-update metadataCome dovrebbe funzionare la pipeline
Sezione intitolata “Come dovrebbe funzionare la Pipeline”flowchart TD A[Push / merge] --> B[Install + web build] B --> C["bundle releaseType"] C -->|OTA| D["bundle upload"] C -->|native| E["build request iOS + Android"] E --> F[Store / TestFlight / Play]
- Build degli asset web come al solito.
- Se il commit modifica
ios/,android/, ocapacitor.config.*, forza il percorso nativo. - Altrimenti chiedi a Capgo
releaseTypese il commit è sicuro per l'OTA. - Se
OTA, esegui l'upload con--fail-on-incompatiblee--auto-min-update-version. - Se
native, avvia Capgo Build, poi carica il bundle corrispondente con--auto-min-update-versioncosì i metadati nativi del canale avanzano. Fai hai usa--fail-on-incompatibleper quel baseline upload — i nuovi pacchetti native dovrebbero differire. Vedi Workflow Native + OTA Channel per le FAQ a livello di channel.
Azioni GitHub
Sezione intitolata “GitHub Actions”Un workflow che blocca i percorsi native, per poi biforcarsi su releaseType:
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-versionSostituisci com.example.app e configurare i signing secrets come descritto in GitHub Actions per Capgo Build.
GitLab CI
Sezione intitolata “GitLab CI”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):
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: - mainSalva CAPGO_TOKEN e le variabili di firma Capgo Build come variabili CI/CD protette/mascherate.
Altre piattaforme CI
Sezione intitolata “Other CI Platforms”Gli stessi tre passaggi funzionano ovunque:
| Step | Comando |
|---|---|
| Verdetto | npx @capgo/cli@latest bundle releaseType APP_ID --channel production |
| Percorso OTA | npx @capgo/cli@latest bundle upload APP_ID --channel production --fail-on-incompatible --auto-min-update-version |
| Percorso native | npx @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 sottooutput-variables, e dirama i passaggi successivi concondition: state: RELEASE_TYPE == "OTA"(i soli artifact su file non possono guidarecondition) - CircleCI —
whenviene valutato in fase di config-compile, quindi fai il branch con uno shell a runtimeif(o dynamic config / continuation), non un valore del workspace inwhen - 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.
Dopo un esito Native
Sezione intitolata “Dopo un verdetto Native”Quando la CI sceglie native:
- Capgo Build produce binari firmati e può inviarli a TestFlight / Play (vedi configurazione).
- 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à ancoranative. - Una volta che gli utenti installano il nuovo binario, i successivi commit JavaScript-only tornano a
OTAancora.