Saltar al contenido

Elige automáticamente Live Update o Native Build

La mayoría de las releases de Capacitor son solo JavaScript y deberían enviarse como una live update. Algunos cambios afectan al code nativo y requieren un nuevo binario de Build de Capgo. Esta guía explica cómo lograr que GitHub Actions, GitLab CI o cualquier otra plataforma de CI/CD elija la ruta correcta en cada push, sin intervención humana.

Capgo ya sabe qué ruta es segura. Tras tu build web (y antes de subir o solicitar un Native Build), ejecuta:

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

OTA significa que los paquetes nativos coinciden con lo que ya está live en el channel. native significa que un plugin, la versión de Capacitor u otra dependencia nativa ha cambiado; un bundle over-the-air no puede actualizar esos dispositivos de forma segura.

releaseType compara metadatos del paquete nativo (Capacitor/plugins y versiones de Cordova). Lo hace necesitas consulta cada edición en ios/, android/, o capacitor.config.*. Primero restringe esas rutas en git y luego usa releaseType para la compatibilidad de dependencias; los siguientes ejemplos muestran ambos métodos.

Ver Compatibilidad nativa para ver todas las reglas y la tabla del bundle compatibility manual.

  • App de Capgo registrada y un clave API de Capgo en los secrets de CI como CAPGO_TOKEN
  • Subida de Live Updates funcionando (bundle upload) — consulta Integración CI/CD
  • Credenciales de Capgo Build en CI si esperas jobs nativos — consulta Acciones de GitHub o Credenciales
  • Un canal que ya existe y coincide con producción (los ejemplos usan production)
  • Canal en el metadata estrategia para que cada upload pueda incluir --auto-min-update-version (una sola vez):
Ventana de terminal
npx @capgo/cli@latest channel set production com.example.app --disable-auto-update metadata
  1. Build de los assets web de forma habitual.
  2. Si el commit toca ios/, android/, o capacitor.config.*, fuerza la ruta nativa.
  3. De lo contrario, pregunta a Capgo releaseType si el commit es seguro para OTA.
  4. Si OTA, sube con --fail-on-incompatible y --auto-min-update-version.
  5. Si native, ejecuta Capgo Build y luego sube el bundle correspondiente con --auto-min-update-version para que los metadatos nativos del canal se actualicen. Haz necesitas usar --fail-on-incompatible para ese upload de baseline — se supone que los nuevos paquetes nativos deberían ser distintos. Consulta Workflow de canales Native + OTA para las FAQ a nivel de channel.

Un workflow que condiciona las rutas nativas y luego bifurca según 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

Reemplazar com.example.app y configura los secrets de firma como se describe en GitHub Actions para Capgo Build.

GitLab evalúa rules cuando se crea el pipeline, así que haz branch con un shell if dentro de un job de deploy (o genera un pipeline hijo dinámico si necesitas jobs de matriz nativos separados):

.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

Tienda CAPGO_TOKEN y las variables de firma de Capgo Build como variables de CI/CD enmascaradas/protegidas.

Los mismos tres pasos funcionan en cualquier lugar:

PasoComando
Veredictonpx @capgo/cli@latest bundle releaseType APP_ID --channel production
Ruta OTAnpx @capgo/cli@latest bundle upload APP_ID --channel production --fail-on-incompatible --auto-min-update-version
Ruta nativanpx @capgo/cli@latest build request APP_ID --platform ios (o android) --build-mode release

Mapea el exit / stdout del shell a los condicionales de tu plataforma (o mantén un solo job con un shell if, como en GitLab arriba):

  • Azure Pipelines — define una variable de salida desde un paso de script y luego úsala condition: eq(variables['releaseType'], 'OTA')
  • Bitbucket Pipelines — escribe RELEASE_TYPE=… a $BITBUCKET_PIPELINES_VARIABLES_PATH, declárala bajo output-variables, y los pasos siguientes de la rama con condition: state: RELEASE_TYPE == "OTA" (file artifacts alone cannot drive condition)
  • CircleCI — when se evalúa en el tiempo de compilación de la config, así que usa una shell en runtime para la rama if (o config dinámica / continuación), no un valor de workspace en when
  • Jenkins — captura el stdout en una env var y usa when { environment name: 'RELEASE_TYPE', value: 'OTA' }

Filtros de rutas (aceleración opcional)

Sección titulada “Path Filters (Optional Speedup)”

Los path filters son una optimización de costes, no un sustituto del check de Capgo. Es mejor excluir rutas de solo docs que mantener una allowlist frágil; los web builds suelen depender también de vite.config.*, tsconfig*.json, y archivos de config del framework:

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

Si usas una lista de permitidos, incluye todos los inputs que lean tus builds web y nativos, no solo src/ y package.json.

Cuando el CI elige nativo:

  1. Capgo Build genera binarios firmados y puede enviarse a TestFlight / Play (ver configuración).
  2. Sube el bundle JS correspondiente con --auto-min-update-version (estrategia de metadatos) para que el channel registre los nuevos paquetes nativos; de lo contrario, el siguiente commit de solo JS devolverá native.
  3. Una vez que los usuarios instalen el nuevo binario, los siguientes commits de solo JavaScript volverán a OTA de nuevo.