Langsung ke konten

Pilih Otomatis Live Update atau Native Build

Sebagian besar rilis Capacitor hanya berupa JavaScript dan harus dikirim sebagai live update. Beberapa perubahan menyentuh native code dan butuh binary baru dari Build Capgo. Panduan ini menunjukkan cara agar GitHub Actions, GitLab CI, atau platform CI/CD lainnya memilih jalur yang benar di setiap push — tanpa intervensi manual.

Capgo sudah tahu jalur mana yang aman. Setelah web build Anda (dan sebelum Anda upload atau request Native Build), jalankan:

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

OTA berarti paket native sudah sesuai dengan yang sedang live di channel. native berarti ada plugin, versi Capacitor, atau dependensi native lainnya yang berubah — over-the-air bundle saja tidak bisa mengupdate perangkat tersebut dengan aman.

releaseType membandingkan metadata paket native (plugin dan versi Capacitor/Cordova). Ini tidak melihat setiap perubahan di bawah ios/, android/, atau capacitor.config.*. Batasi path tersebut di git terlebih dahulu, lalu gunakan releaseType untuk kompatibilitas dependensi — contoh di bawah mencakup keduanya.

Lihat Kompatibilitas Native untuk aturan lengkap dan panduan bundle compatibility tabel.

  • Aplikasi Capgo sudah terdaftar dan kunci Capgo API di CI secrets sebagai CAPGO_TOKEN
  • Upload Live Updates berfungsi (bundle upload) — lihat Integrasi CI/CD
  • Kredensial Capgo Build di CI jika Anda memerlukan native job — lihat Aksi GitHub atau Kredensial
  • Channel yang sudah ada dan sesuai dengan production (contoh menggunakan production)
  • Channel pada metadata strategi agar setiap upload dapat membawa --auto-min-update-version (sekali saja):
Jendela terminal
npx @capgo/cli@latest channel set production com.example.app --disable-auto-update metadata

Cara Kerja Pipeline yang Seharusnya

Bagian berjudul “Cara Kerja Pipeline”
  1. Build aset web seperti biasa.
  2. Jika commit mengubah ios/, android/, atau capacitor.config.*, paksa jalur native.
  3. Jika tidak, tanyakan ke Capgo releaseType apakah commit tersebut aman untuk OTA.
  4. Jika OTA, upload dengan --fail-on-incompatible dan --auto-min-update-version.
  5. Jika native, jalankan Capgo Build, lalu upload bundle yang sesuai dengan --auto-min-update-version agar metadata native channel tersebut diperbarui. Lakukan tidak gunakan --fail-on-incompatible untuk baseline upload tersebut — paket native baru seharusnya berbeda. Lihat Workflow Channel Native + OTA untuk FAQ tingkat channel.

Satu workflow yang membatasi jalur native, lalu bercabang pada 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

Ganti com.example.app dan hubungkan signing secrets seperti yang dijelaskan di GitHub Actions untuk Capgo Build.

GitLab mengevaluasi rules saat pipeline dibuat, jadi branch dengan shell if di dalam satu job deploy (atau buat) pipeline anak dinamis jika butuh job native matrix terpisah):

.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

Simpan CAPGO_TOKEN dan variabel signing Capgo Build sebagai variabel CI/CD yang di-mask/protect.

Tiga langkah yang sama berlaku di mana saja:

LangkahPerintah
Kesimpulannpx @capgo/cli@latest bundle releaseType APP_ID --channel production
Jalur OTAnpx @capgo/cli@latest bundle upload APP_ID --channel production --fail-on-incompatible --auto-min-update-version
Jalur Nativenpx @capgo/cli@latest build request APP_ID --platform ios (atau android) --build-mode release

Petakan shell exit / stdout ke dalam kondisional platform Anda (atau gunakan satu job dengan shell if, seperti GitLab di atas):

  • Azure Pipelines — atur output variable dari script step, lalu gunakan condition: eq(variables['releaseType'], 'OTA')
  • Bitbucket Pipelines — tulis RELEASE_TYPE=… ke $BITBUCKET_PIPELINES_VARIABLES_PATH, deklarasikan di bawah output-variables, dan langkah branch selanjutnya dengan condition: state: RELEASE_TYPE == "OTA" (file artifact saja tidak bisa menjalankan condition)
  • CircleCI — when dievaluasi saat config-compile, jadi gunakan branch dengan runtime shell if (atau dynamic config / continuation), bukan nilai workspace di when
  • Jenkins — tangkap stdout ke env var dan gunakan when { environment name: 'RELEASE_TYPE', value: 'OTA' }

Path filter adalah optimasi biaya, bukan pengganti pengecekan Capgo. Lebih baik mengecualikan path khusus docs daripada mengelola allowlist yang rentan — build web sering kali juga bergantung pada vite.config.*, tsconfig*.json, dan file konfigurasi framework:

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

Jika Anda menggunakan allowlist, sertakan semua input yang dibaca oleh web dan Native Build Anda, bukan hanya src/ dan package.json.

Saat CI memilih native:

  1. Capgo Build menghasilkan binary yang sudah ditandatangani dan dapat dikirim ke TestFlight / Play (lihat konfigurasi).
  2. Upload JS bundle yang sesuai dengan --auto-min-update-version (strategi metadata) agar channel mencatat paket native baru — jika tidak, commit JS-only berikutnya tetap akan mengembalikan native.
  3. Setelah pengguna menginstal binary baru, commit JavaScript-only berikutnya akan kembali ke OTA lagi.