Aller au contenu

Choisir automatiquement Live Update ou Native Build

Most Capacitor releases are JavaScript-only and should ship as a live update. Some changes touch native code and need a new binary from Build Capgo. Ce guide explique comment configurer GitHub Actions, GitLab CI, ou toute autre plateforme CI/CD pour choisir le bon chemin à chaque push — sans intervention humaine.

Capgo sait déjà quel chemin est sûr. Après votre build web (et avant d'effectuer l'upload ou de demander un Native Build), lancez :

Fenêtre de terminal
npx @capgo/cli@latest bundle releaseType com.example.app --channel production
# → OTA ship with bundle upload
# → native ship with Capgo Build

OTA signifie que les packages natifs correspondent à ce qui est déjà en ligne sur le canal. native signifie qu'un plugin, une version Capacitor, ou une autre dépendance native a changé — un simple bundle via live update ne peut pas mettre à jour ces appareils en toute sécurité.

releaseType compare métadonnées du package natif (plugins et versions Capacitor/Cordova). Cela pas voit chaque modification sous ios/, android/, ou capacitor.config.*. Verrouillez ces chemins dans git d'abord, puis utilisez releaseType pour la compatibilité des dépendances — les exemples ci-dessous font les deux.

Voir Compatibilité native pour l'ensemble des règles et le manuel bundle compatibility tableau.

  • L'application Capgo est enregistrée et un clé Capgo API dans les secrets CI en tant que CAPGO_TOKEN
  • L'upload de Live Updates fonctionne (bundle upload) — voir Intégration CI/CD
  • Identifiants de build Capgo dans la CI si vous prévoyez des jobs natifs — voir Actions GitHub ou Identifiants
  • Un canal existant qui correspond à la production (les exemples utilisent production)
  • Canal sur le metadata stratégie pour que chaque upload puisse transporter --auto-min-update-version (une seule fois) :
Fenêtre de terminal
npx @capgo/cli@latest channel set production com.example.app --disable-auto-update metadata
  1. Compilez les assets web comme d'habitude.
  2. Si le commit modifie ios/, android/, ou capacitor.config.*, forcez le chemin natif.
  3. Sinon, demandez à Capgo releaseType si le commit est compatible OTA.
  4. Si OTA, envoyez avec --fail-on-incompatible et --auto-min-update-version.
  5. Si native, lancez le build Capgo, puis envoyez le bundle correspondant avec --auto-min-update-version ainsi, les métadonnées natives du canal progressent. Do pas utiliser --fail-on-incompatible pour cet upload de base — les nouveaux packages natifs sont censés différer. Voir Workflow des canaux natifs + OTA pour la FAQ au niveau du canal.

Un workflow qui verrouille les chemins natifs, puis bifurque sur 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

Remplacer com.example.app et configurer les secrets de signature comme décrit dans GitHub Actions pour le build Capgo.

GitLab évalue rules lors de la création du pipeline, donc une branche avec un shell if dans un job de déploiement (ou générez un pipeline enfant dynamique si vous avez besoin de jobs de matrice natifs séparés) :

.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

Stockez CAPGO_TOKEN et les variables de signature de Capgo Build en tant que variables CI/CD masquées ou protégées.

Les trois mêmes étapes fonctionnent partout :

ÉtapeCommande
Verdictnpx @capgo/cli@latest bundle releaseType APP_ID --channel production
Chemin OTAnpx @capgo/cli@latest bundle upload APP_ID --channel production --fail-on-incompatible --auto-min-update-version
Chemin natifnpx @capgo/cli@latest build request APP_ID --platform ios (ou android) --build-mode release

Mappez l'exit code / stdout du shell dans les conditions de votre plateforme (ou conservez un job unique avec un shell) if, comme dans GitLab ci-dessus) :

  • Azure Pipelines — définissez une variable de sortie via une étape de script, puis utilisez condition: eq(variables['releaseType'], 'OTA')
  • Bitbucket Pipelines — écrivez RELEASE_TYPE=… à $BITBUCKET_PIPELINES_VARIABLES_PATH, déclarez-la sous output-variables, et les étapes suivantes de la branche avec condition: state: RELEASE_TYPE == "OTA" (file artifacts alone cannot drive condition)
  • CircleCI — when est évalué lors de la compilation de la config, donc branchez avec un shell au runtime if (ou une config dynamique / continuation), pas une valeur de workspace dans when
  • Jenkins — capturez le stdout dans une variable d'env et utilisez when { environment name: 'RELEASE_TYPE', value: 'OTA' }

Les filtres de chemins servent à optimiser les coûts, ils ne remplacent pas la vérification Capgo. Privilégiez l'exclusion des chemins contenant uniquement de la doc plutôt que de maintenir une allowlist fragile — les builds web dépendent souvent aussi de vite.config.*, tsconfig*.json, et des fichiers de config du framework :

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

Si vous utilisez plutôt une liste d'autorisation, incluez toutes les entrées lues par vos builds web et natifs, pas seulement src/ et package.json.

Quand la CI choisit le natif :

  1. Capgo le build produit des binaires signés et peut être soumis à TestFlight / Play (voir configuration).
  2. Envoyez le bundle JS correspondant avec --auto-min-update-version (stratégie de métadonnées) pour que le canal enregistre les nouveaux packages natifs — sinon, le prochain commit JS-only renverra native.
  3. Une fois que les utilisateurs ont installé le nouveau binaire, les commits JavaScript ultérieurs reviendront à OTA à nouveau.