Langsung ke konten

Aksi GitHub

Otomatiskan build iOS dan Android Anda langsung dari repositori GitHub. Dengan satu file workflow dan beberapa repository secrets, setiap push, tag, atau trigger manual dapat menghasilkan aplikasi yang ditandatangani dan siap diunggah ke store — tanpa perlu ada anggota tim yang menginstal Mac, Xcode, atau Android Studio.

Jawaban singkat: untuk Capacitor CI/CD di GitHub Actions, tambahkan satu workflow yang menjalankan Capgo CLI: Capgo Builder menghasilkan build iOS dan Android yang ditandatangani dan dapat mengunggahnya ke store, dan, dengan tambahan bundle upload job (lihat Auto OTA atau Native), workflow yang sama dapat mengirim perubahan web-only sebagai Capgo live updates.

Rilis Tanpa Intervensi

Tag sebuah release di Git dan binary iOS serta Android yang sudah ditandatangani akan dikirim ke TestFlight dan Play Store secara otomatis.

Tanpa Setup Lokal

Kontributor di Windows atau Linux bisa memicu build iOS. Tanpa Xcode, tanpa ribet provisioning, dan tanpa sertifikat signing yang berpindah-pindah antar laptop.

Secrets Terbatas Cakupan

Kredensial tersimpan di repository secrets GitHub, dibatasi ke repo Anda dan hanya terlihat oleh workflow runner. Mudah dirotasi, mudah diaudit.

Build Paralel

Build iOS dan Android secara bersamaan dengan matrix job. Proses rilis biasanya selesai dalam waktu kurang dari 10 menit.

Sebelum menyiapkan workflow, pastikan Anda sudah punya:

  • Akun Capgo dengan langganan aktif dan kunci Capgo API
  • Aplikasi Anda yang terdaftar di Capgo (bunx @capgo/cli@latest app add jika belum)
  • Kredensial build yang dikonfigurasi secara lokal dengan bunx @capgo/cli@latest build init — lihat Kelola Kredensial untuk panduan wizard
  • Build lokal yang berhasil (bunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — CI bukan tempat untuk debug build pertama Anda
  • Panduan GitHub CLI (gh) terpasang dan terautentikasi (gh auth login)

Capgo CLI dapat mengekspor kredensial lokal Anda sebagai .env file siap pakai. Digabungkan dengan gh secret set -f, ini mengubah seluruh setup CI/CD menjadi tiga perintah — tanpa encoding base64 manual, tanpa ribet urusan JSON, tanpa perlu copy-paste secret satu per satu.

  1. Tambahkan key Capgo API Anda sebagai repository secret

    Key API bukan bagian dari credential store per-app, jadi tambahkan sekali secara manual:

    Jendela terminal
    gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"

    Generate the key in the Dashboard Capgo dengan upload permissions atau lebih tinggi.

  2. Ekspor kredensial Anda ke .env file

    Jalankan manajer kredensial interaktif:

    Jendela terminal
    bunx @capgo/cli@latest build credentials manage --appId com.example.app

    Di TUI, pilih Ekspor ke .env. CLI akan menulis .env.capgo.<appId> ke direktori saat ini dengan mode 0600 (hanya dapat dibaca owner) — contohnya, .env.capgo.com.example.app. Setelah iOS dan Android dikonfigurasi, secret kedua platform akan masuk ke file yang sama di bawah # === IOS === dan # === ANDROID === header bagian. Nama env-var iOS dan Android tidak tumpang tindih, jadi menggabungkannya bebas konflik.

  3. Push file .env ke secrets GitHub Actions

    Panduan gh secret set -f perintah membaca file dotenv dan membuat satu secret repository per KEY=value baris:

    Jendela terminal
    gh secret set -f .env.capgo.com.example.app

    Selesai — semua secret yang dibutuhkan workflow Anda sekarang ada di GitHub. Verifikasi dengan gh secret list.

  4. Buat file workflow

    Tambah .github/workflows/capgo-build.yml ke repository Anda. Pilih salah satu dari tiga pola trigger di bawah ini, tergantung bagaimana Anda ingin memicu build.

Apa saja yang masuk ke secrets Anda

Bagian berjudul “Apa yang masuk ke secrets Anda”

Sebagai referensi, gh secret set -f akan membuat secrets repository ini (workflow YAML Anda merujuknya dengan nama-nama persis ini):

PlatformSecrets yang dibuat
iOSBUILD_CERTIFICATE_BASE64, P12_PASSWORD, CAPGO_IOS_PROVISIONING_MAP_BASE64, APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_KEY_CONTENT, APP_STORE_CONNECT_TEAM_ID
AndroidANDROID_KEYSTORE_FILE, KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORD, KEYSTORE_STORE_PASSWORD, PLAY_CONFIG_JSON
(ditambahkan secara manual)CAPGO_TOKEN

Anda tidak perlu menghafalnya — contoh workflow di bawah sudah merujuk ke semuanya.

Tiga contoh di bawah mencakup pola yang paling umum. Semuanya memakai struktur yang sama: checkout repo, install dependencies, build web assets, sync ke native, lalu panggil Capgo Build dengan kredensial yang diteruskan sebagai environment variables.

Memungkinkan siapa pun yang punya akses write memicu build dari Aksi tab di GitHub dengan dropdown platform. Berguna untuk test build ad-hoc atau memicu rilis sesuai kebutuhan.

.github/workflows/capgo-build-manual.yml
name: Capgo Build (Manual)
on:
workflow_dispatch:
inputs:
platform:
description: 'Platform to build'
required: true
default: 'android'
type: choice
options: [ios, android, both]
mode:
description: 'Build mode'
required: true
default: 'debug'
type: choice
options: [debug, release]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync
- name: Trigger Capgo Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
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: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ inputs.platform }} \
--build-mode ${{ inputs.mode }}

Ganti com.example.app dengan app ID Anda. Setelah di-commit, buka Actions → Capgo Build (Manual) → Jalankan workflow untuk menjalankannya.

Build dan ship kedua platform secara paralel setiap kali Anda push version tag seperti v1.4.0. Ini adalah setup produksi yang paling umum — git tag v1.4.0 && git push --tags menjadi perintah release Anda.

.github/workflows/capgo-build-release.yml
name: Capgo Build (Release)
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync ${{ matrix.platform }}
- name: Build ${{ matrix.platform }}
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# iOS
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
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
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: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ matrix.platform }} \
--build-mode release

Matrix menjalankan iOS dan Android secara paralel di runner terpisah. Mengatur fail-fast: false berarti build iOS yang gagal tidak akan membatalkan build Android yang sedang berjalan (dan sebaliknya) — berguna jika satu platform mengalami masalah signing sementara.

Mendeteksi regresi native build lebih awal dengan menghasilkan build Android debug pada setiap push ke main. Biaya eksekusi rendah, umpan balik cepat, dan Anda dapat melewati upload ke Play Store agar tetap murni sebagai smoke test.

.github/workflows/capgo-build-main.yml
name: Capgo Build (Main)
on:
push:
branches: [main]
paths:
- 'src/**'
- 'android/**'
- 'ios/**'
- 'package.json'
- 'capacitor.config.*'
jobs:
smoke-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync android
- name: Smoke build (Android debug)
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode debug \
--no-playstore-upload \
--output-upload

Panduan paths filter memastikan workflow tidak berjalan pada perubahan dokumen saja. --no-playstore-upload melewati pengiriman ke Play Store (tidak ada PLAY_CONFIG_JSON diperlukan), dan --output-upload menghasilkan URL unduhan untuk APK yang dihasilkan sehingga Anda dapat menginstalnya di perangkat uji.

Untuk build pengujian, lewati pengiriman ke store: Android menggunakan --no-playstore-upload; untuk iOS, build dalam mode ad-hoc dengan --ios-distribution ad_hoc (yang tidak pernah dikirim ke App Store). Gabungkan salah satunya dengan --output-upload untuk mendapatkan URL download biner yang terbatas waktu.

Secara default, build rilis meng-upload artefak yang ditandatangani dan membiarkan tindakan store akhir di bawah kendali Anda. Untuk rilis CI yang harus langsung masuk ke alur peninjauan store, tambahkan --submit-to-store-review.

Android menggunakan PLAY_CONFIG_JSON service account. Tanpa track eksplisit, --submit-to-store-review default ke track production dengan release_status: completed. Sebaiknya nyatakan track di call site dengan --android-track (atau PLAY_STORE_TRACK), dan override status dengan --android-release-status / PLAY_STORE_RELEASE_STATUS jika diperlukan:

- name: Submit Android release for review
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 android \
--build-mode release \
--submit-to-store-review \
--android-track production \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}"

Untuk internal completed release alih-alih production:

- name: Submit Android internal release
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 android \
--build-mode release \
--submit-to-store-review \
--android-track internal \
--store-release-name "${GITHUB_REF_NAME}"

iOS menggunakan path kunci App Store Connect API dan mengirim build TestFlight yang diproses ke review App Store. Ini membutuhkan app_store distribusi; --ios-testflight-groups opsional untuk distribusi beta eksternal dan tidak diperlukan untuk review App Store:

- name: Submit iOS build to App Store review
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 }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform ios \
--build-mode release \
--ios-distribution app_store \
--submit-to-store-review \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}" \
--no-ios-automatic-release

Gunakan --output-record <path> untuk menyimpan URL build artifact dan QR code ke disk saat build berhasil, lalu membacanya kembali di langkah berikutnya dengan build last-output. Tanpa log scraping, tanpa regex.

- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android --build-mode debug \
--output-upload --output-retention 1d \
--output-record /tmp/build.json
- name: Comment on PR with build URL
env:
GH_TOKEN: ${{ github.token }}
run: |
URL=$(bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl)
if [ -n "$URL" ]; then
gh pr comment ${{ github.event.pull_request.number }} \
--body "Debug build ready: $URL"
fi

--output-record /tmp/build.json menulis record JSON (dengan jobId, status, outputUrl, qrCodeAscii, qrCodePngPath, finishedAt) dan QR code PNG berdampingan di /tmp/build.json.qr.png. build last-output membacanya kembali:

  • --field outputUrl hanya mencetak download URL (diakhiri newline; aman untuk URL=$(...)).
  • --field qrCodePngPath mencetak path PNG agar bisa Anda upload sebagai lampiran PR.
  • --qr mencetak ASCII QR yang sudah di-render — masukkan ke dalam Markdown code fence pada komentar PR agar bisa langsung di-scan.

Secara default, setiap release build akan meningkatkan build number. Untuk menguncinya ke nilai yang Anda kontrol (misalnya, Git tag), pass --skip-build-number-bump:

- name: Set version from tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
# Update package.json or your version source here
bun pm version "$VERSION" --no-git-tag-version
- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ios --build-mode release \
--skip-build-number-bump

bun install sudah cukup cepat sehingga cache JS-deps jarang memberikan manfaat, tetapi dependensi native Capacitor (CocoaPods, Gradle) layak di-cache untuk proyek yang lebih besar:

- uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
ios/App/Pods
android/.gradle
key: ${{ runner.os }}-capgo-${{ hashFiles('**/bun.lock', '**/Podfile.lock') }}
GejalaKemungkinan penyebab
CAPGO_TOKEN is not setSecret tidak ditambahkan, atau job tidak memiliki akses ke secret tersebut (periksa proteksi environment/branch)
Error kredensial iOS / Android tidak ditemukangh secret set -f tidak dijalankan, atau dijalankan pada repo yang berbeda. Verifikasi dengan gh secret list
cap sync gagal di CI tapi berhasil secara lokalPlugin native tidak ada di package.json, atau Anda lupa bun install sebelum cap sync
Build berhasil tapi aplikasi tidak muncul di App Store ConnectTeam ID salah, atau record aplikasi belum ada di App Store Connect. Verifikasi secara lokal dengan bunx @capgo/cli@latest build credentials manage
Build macet setelah “Uploading project”Arsip proyek terlalu besar — periksa apakah node_modules tidak ikut di-upload (defaultnya memang tidak)
Provisioning profile doesn't match bundle IDProvisioning map menunjuk ke bundle ID yang berbeda dari yang di-sign Xcode. Jalankan ulang build init untuk memperbarui profil, lalu ekspor ulang dengan build credentials manage
Kredensial berubah secara lokal tetapi CI masih gagalJangan lupa untuk ekspor ulang dan push ulang: bunx @capgo/cli@latest build credentials manage → gh secret set -f .env.capgo.<appId>
Manager menolak menulis file gabunganKunci konfigurasi bersama berbeda antar platform — manager akan memperingatkan dan meminta konfirmasi. Konfirmasi untuk menimpa (satu menang), atau ekspor ulang per platform dengan --platform ios / --platform android
build last-output menampilkan URL kosongBuild tidak berhasil --output-upload, atau gagal sebelum menghasilkan artifact. outputUrl akan menjadi null dalam record. Branch berdasarkan [ -n "$URL" ] sebelum menggunakannya
build last-output error dengan Unsupported record schemaVersionRunner menggunakan versi CLI yang lebih lama daripada yang menulis record. Kunci (pin) versi eksplisit yang sama untuk producer dan reader (mis. bunx @capgo/cli@7.104.0 … di kedua sisi) alih-alih @latest, yang bisa berubah dan tidak konsisten antar job

Untuk kegagalan build spesifik platform, lihat panduan troubleshooting.