Trigger Native Build via Webhook
Salin prompt setup yang berisi langkah install dan panduan markdown lengkap untuk plugin ini.
Capgo Build biasanya dimulai dari laptop atau job CI. Tim yang melakukan rilis dari dashboard admin, CMS, atau portal internal sering kali menginginkan satu Webhook HTTP: cukup tekan tombol di UI mereka sendiri, dan signed native build akan dimulai. Panduan ini menunjukkan pola standarnya — sebuah panggilan HTTP terautentikasi ke host code Anda, yang menjalankan workflow Capgo Build yang sama dengan yang sudah Anda gunakan.
Arsitektur
Bagian berjudul “Arsitektur”sequenceDiagram participant Admin as Admin dashboard participant Hook as Webhook endpoint participant CI as GitHub / GitLab participant Capgo as Capgo Build Admin->>Hook: POST /native-build (secret) Hook->>CI: repository_dispatch / pipeline trigger CI->>CI: checkout, npm ci, cap sync CI->>Capgo: build request Capgo-->>CI: signed binary / store upload
Anda tidak perlu mengekspos “build webhook” publik di Capgo. CI Anda sudah memiliki signing secrets; tugas webhook hanyalah memulai job CI tersebut dengan aman.
Prerequisites
Bagian berjudul “Prasyarat”- Workflow Capgo Build yang sudah berjalan dari UI CI atau saat push (Aksi GitHub)
- Izin untuk membuat fine-grained GitHub token, GitLab trigger token, atau setara
- Shared secret yang akan dikirim oleh admin dashboard Anda (header atau body)
Opsi A — GitHub repository_dispatch (direkomendasikan)
Bagian berjudul “Opsi A — GitHub repository_dispatch (direkomendasikan)”GitHub menerima panggilan API terautentikasi yang memulai workflow untuk mendengarkan repository_dispatch. Dashboard apa pun yang bisa POST JSON dapat memicunya.
1. Workflow yang mendengarkan webhook
Bagian berjudul “1. Workflow yang mendengarkan webhook”Validasi payload sebelum checkout dan sebelum langkah yang mengandung secret. Teruskan nilai yang diterima melalui job outputs / env vars — jangan pernah melakukan interpolasi client_payload secara langsung ke dalam run: script (panduan script injection).
name: Capgo Build (Webhook)
on: repository_dispatch: types: [capgo-native-build]
jobs: validate: runs-on: ubuntu-latest outputs: platform: ${{ steps.check.outputs.platform }} mode: ${{ steps.check.outputs.mode }} ref: ${{ steps.check.outputs.ref }} platforms_json: ${{ steps.check.outputs.platforms_json }} steps: - id: check env: RAW_PLATFORM: ${{ github.event.client_payload.platform }} RAW_MODE: ${{ github.event.client_payload.mode }} RAW_REF: ${{ github.event.client_payload.ref }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | PLATFORM="${RAW_PLATFORM:-android}" MODE="${RAW_MODE:-release}" REF="${RAW_REF:-$DEFAULT_BRANCH}" case "$PLATFORM" in ios|android|both) ;; *) echo "Invalid platform: $PLATFORM" >&2; exit 1;; esac case "$MODE" in debug|release) ;; *) echo "Invalid mode: $MODE" >&2; exit 1;; esac # Allowlist branches / tags / full SHAs only if [[ ! "$REF" =~ ^(main|master|production|release/[A-Za-z0-9._-]+|[0-9a-f]{40})$ ]]; then echo "Ref not allowlisted: $REF" >&2 exit 1 fi if [ "$PLATFORM" = "both" ]; then PLATFORMS_JSON='["ios","android"]' else PLATFORMS_JSON=$(printf '["%s"]' "$PLATFORM") fi { echo "platform=$PLATFORM" echo "mode=$MODE" echo "ref=$REF" echo "platforms_json=$PLATFORMS_JSON" } >> "$GITHUB_OUTPUT"
build: needs: validate runs-on: ubuntu-latest environment: ${{ needs.validate.outputs.mode == 'release' && 'production' || 'build-debug' }} strategy: fail-fast: false matrix: platform: ${{ fromJSON(needs.validate.outputs.platforms_json) }} steps: - uses: actions/checkout@v4 with: ref: ${{ needs.validate.outputs.ref }}
- uses: actions/setup-node@v6 with: node-version: '24' cache: 'npm'
- run: npm ci - run: npm run build - name: Sync native project env: PLATFORM: ${{ matrix.platform }} run: npx cap sync "$PLATFORM"
- name: Capgo Build 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 }} PLATFORM: ${{ matrix.platform }} MODE: ${{ needs.validate.outputs.mode }} run: | npx @capgo/cli@latest build request com.example.app \ --platform "$PLATFORM" \ --build-mode "$MODE"2. Buat token GitHub
Bagian berjudul “2. Buat token GitHub”Buat personal access token yang spesifik (atau token instalasi GitHub App) dengan Isi: Read and write pada repositori (diperlukan untuk repository_dispatch). Simpan hanya di backend admin Anda — jangan pernah di browser.
3. Panggil webhook dari dashboard admin Anda
Bagian berjudul “3. Panggil webhook dari admin dashboard Anda”Backend Anda (bukan browser end-user) harus mengirim:
curl -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/OWNER/REPO/dispatches \ -d '{ "event_type": "capgo-native-build", "client_payload": { "platform": "both", "mode": "release", "ref": "main", "requested_by": "admin@example.com" } }'| Kolom | Tujuan |
|---|---|
event_type | Harus cocok types di workflow (capgo-native-build) |
client_payload.platform | ios, android, atau both |
client_payload.mode | debug atau release |
client_payload.ref | Branch atau tag untuk build (opsional) |
Hubungkan JSON POST yang sama ke tombol di admin UI Anda (“Build native apps”). Dashboard hanya perlu mengakses URL backend; backend tersebut menyimpan GITHUB_TOKEN.
Opsi B — Tiny proxy webhook (host apa pun)
Bagian berjudul “Opsi B — Tiny proxy webhook (host apa pun)”Jika admin tool hanya bisa melakukan POST ke URL yang Anda kontrol (Zapier, Make, Cloudflare Worker, Express route), pasang proxy singkat di depan GitHub:
// Example Cloudflare Worker / Node handler (sketch)export default { async fetch(request, env) { if (request.method !== 'POST') { return new Response('Method not allowed', { status: 405 }) } if (request.headers.get('x-webhook-secret') !== env.WEBHOOK_SECRET) { return new Response('Unauthorized', { status: 401 }) } const body = await request.json().catch(() => ({})) const platform = body.platform || 'both' const mode = body.mode || 'release' const ref = body.ref || 'main' if (!['ios', 'android', 'both'].includes(platform)) { return new Response('Invalid platform', { status: 400 }) } if (!['debug', 'release'].includes(mode)) { return new Response('Invalid mode', { status: 400 }) } if (!/^(main|master|production|release\/[A-Za-z0-9._-]+|[0-9a-f]{40})$/.test(ref)) { return new Response('Ref not allowlisted', { status: 400 }) } const res = await fetch( `https://api.github.com/repos/${env.GITHUB_OWNER}/${env.GITHUB_REPO}/dispatches`, { method: 'POST', headers: { Accept: 'application/vnd.github+json', Authorization: `Bearer ${env.GITHUB_TOKEN}`, 'X-GitHub-Api-Version': '2022-11-28', }, body: JSON.stringify({ event_type: 'capgo-native-build', client_payload: { platform, mode, ref }, }), }, ) return new Response(res.status === 204 ? 'Build queued' : await res.text(), { status: res.status === 204 ? 200 : res.status, }) },}Kemudian konfigurasi produk admin:
| Pengaturan | Nilai |
|---|---|
| URL | https://your-worker.example.com/native-build |
| Metode | POST |
| Header | x-webhook-secret: <shared secret> |
| Body | { "platform": "both", "mode": "release" } |
Ini adalah format umum untuk menghubungkan webhook ke dashboard admin: dashboard menyimpan satu URL dan satu secret; kredensial Capgo tetap berada di GitHub Actions.
Pemicu GitLab Pipeline
Bagian berjudul “GitLab Pipeline Trigger”GitLab menyediakan token trigger pipeline yang berfungsi sebagai target webhook.
# .gitlab-ci.yml fragmentcapgo_native_webhook: stage: build script: - npm ci && npm run build - npx cap sync "${PLATFORM:-android}" - npx @capgo/cli@latest build request com.example.app --platform "${PLATFORM:-android}" --build-mode "${BUILD_MODE:-release}" rules: - if: '$CI_PIPELINE_SOURCE == "trigger"'Buat trigger token di Pengaturan → CI/CD → Token pemicu Pipeline, lalu dari admin backend:
curl -X POST \ -F token=$GITLAB_TRIGGER_TOKEN \ -F ref=main \ -F "variables[PLATFORM]=android" \ -F "variables[BUILD_MODE]=release" \ https://gitlab.com/api/v4/projects/PROJECT_ID/trigger/pipelineUntuk kedua platform, gunakan dua trigger atau perluas job menjadi parallel matrix seperti contoh GitHub.
Bitbucket dan Azure
Bagian berjudul “Bitbucket dan Azure”| Platform | Mekanisme Webhook |
|---|---|
| Bitbucket | URL trigger pipeline atau custom pipeline + app password POST |
| Azure DevOps | REST API run pipeline dengan PAT; gunakan manual pipeline dari Trigger dari UI CI |
Polanya sama: admin → secret check Anda → host API → Capgo Build job.
Checklist payload untuk admin tools
Bagian berjudul “Checklist Payload untuk Admin Tools”Saat membuat form dashboard, kumpulkan minimal:
- Platform — ios / android / keduanya
- Mode — debug (QA) atau release (store)
- Ref Git — branch atau tag yang akan di-build
- Actor — email atau user id untuk audit log (teruskan
client_payload)
Opsional: setelah run selesai, minta CI mengirim balik ke admin API dengan URL download dari --output-record / build last-output.
Keamanan
Bagian berjudul “Security”- Autentikasi setiap webhook (
x-webhook-secret, tanda tangan HMAC, atau mTLS). - Allowlist
platform,mode, danrefbaik di proxy maupun di workflowvalidatejob — perlakukanclient_payloadsebagai input yang tidak terpercaya. - Teruskan nilai yang diterima melalui env vars / job outputs; jangan interpolasi field payload ke dalam
run:scripts. - Simpan token GitHub/GitLab hanya di sisi server.
- Utamakan token yang cakupannya hanya satu repositori.
- Beri rate limit pada proxy; native build memakan build minutes.
- Untuk rilis yang di-submit ke store, petakan
releaseke Environment GitHub yang terlindungi (seperti pada contoh) atau wajibkan flag konfirmasi tambahan yang dicentang divalidate.