Zum Inhalt springen

Trigger Native Builds über Webhook

Capgo Der Build wird normalerweise von einem Laptop oder CI-Job aus gestartet. Teams, die von einem Verwaltungsoberfläche, CMS oder internen Portal aus liefern, möchten oft einen einzelnen HTTP-Webhook: Drücken Sie einen Button in Ihrer eigenen Oberfläche, und ein signierter nativer Build wird gestartet. Diese Anleitung zeigt das Standardmuster — einen dünnen authentifizierten HTTP-Aufruf in Ihren code Host, der den gleichen Capgo Build-Werkfluss ausführt, den Sie bereits verwenden.

Sie müssen nicht __CAPGO_KEEP_0__ haben, um eine öffentliche "Build-Webhook" auszuführen. Ihre CI hat bereits die Signiergeheimnisse; die Webhook-Aufgabe besteht nur darin, das CI-Job sicher zu starten. Voraussetzungen need Capgo to expose a public “build webhook.” Your CI already has the signing secrets; the webhook’s only job is to start that CI job safely.

Ein __CAPGO_KEEP_0__ Build-Workflow, der bereits aus der CI-Oberfläche oder bei einem Push funktioniert (

CI-Oberfläche
  • A Capgo Build workflow that already works from the __CAPGO_KEEP_0__ Aktionen Zugriff auf eine fein abgestufte __CAPGO_KEEP_0__-Token, GitLab-Trigger-Token oder ÄquivalentGitHub Actions)
  • Option A — GitHub
  • Option B — __CAPGO_KEEP_0__
GitHub akzeptiert einen authentifizierten __CAPGO_KEEP_1__-Aufruf, der einen Workflow startet, der auf einen Webhook lauscht

GitHub accepts an authenticated API call that starts a workflow listening for repository_dispatchJSON kann es auslösen. POST 1. Workflow, der auf den Webhook lauscht

Die Payload überprüfen

vor

dem Checkout und vor jedem Schritt, der geheime Daten enthält. Akzeptierte Werte übergeben Sie über Job-Ausgaben / Umgebungsvariablen – nie direkt in Skripte einsetzen ( 1. Workflow, der auf den Webhook lauscht client_payload Die Payload überprüfen run: vor dem Checkout und vor jedem Schritt, der geheime Daten enthält. Akzeptierte Werte übergeben Sie über Job-Ausgaben / Umgebungsvariablen – nie direkt in Skripte einsetzen.Skriptinjektionsleitfaden).

github/workflows/capgo-build-webhook.yml
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"

Erstelle einen fein aufgeschichteten persönlichen Zugriffstoken (oder GitHub-App-Installationstoken) mit Inhalte: Lesen und Schreiben auf dem Repository (erforderlich für repository_dispatch). Speichere es nur in deinem Admin-Hintergrund — nie im Browser.

Dein Backend (nicht der Endbenutzer-Browser) sollte senden:

Terminalfenster
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"
}
}'
FeldZweck
event_typeMuss übereinstimmen types im Workflow (capgo-native-build)
client_payload.platformios, android, oder both
client_payload.modedebug oder release
client_payload.refZweig oder Versionsnummer zum Bauen (optional)

Die gleiche JSON-POST an einen Button in Ihrer Admin-Oberfläche (“NATIVE-Apps bauen”) anbinden. Die Dashboard-Übermittlung muss nur Ihr Backend erreichen; das Backend hält GITHUB_TOKEN.

Wenn die Admin-Tool nur POST an eine URL senden kann, die Sie kontrollieren (Zapier, Make, Cloudflare-Arbeiter, Express-Route), legen Sie einen kurzen Proxy vor 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,
})
},
}

Dann konfigurieren Sie das Admin-Produkt:

EinstellungWert
URLhttps://your-worker.example.com/native-build
MethodenPOST
Headerx-webhook-secret: <shared secret>
Body{ "platform": "both", "mode": "release" }

Diese ist die übliche Form, um eine Webhook-Verbindung zu einem Admin-Dashboard anzuschließen: Das Dashboard speichert eine URL und einen geheimen Schlüssel; Capgo-Anmeldeinformationen bleiben in GitHub Aktionen.

GitLab legt Pipeline-Auslösetoken für Webhooks frei, die natürliche Ziele sind.

# .gitlab-ci.yml fragment
capgo_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"'

Erstelle ein Auslösetoken unter Einstellungen → CI/CD → Pipeline-Auslösetoken, dann vom Admin-Backend:

Terminalfenster
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/pipeline

Für beide Plattformen kann man entweder zwei Trigger auslösen oder das Job in ein paralleles Matrix wie im Beispiel GitHub erweitern.

PlattformWebhook-Mechanismus
BitbucketPipeline-Auslöser-URL oder benutzerdefinierte Pipeline + App-Passwort POST
Azure DevOpsPipeline-Ausführung-REST API mit einem PAT; verwenden Sie die manuelle Pipeline von Trigger aus CI-Benutzeroberfläche

Muster ist identisch: admin → Ihr geheimes Prüfen → Host API → Capgo Build-Auftrag

Wenn das Dashboard-Formular erstellt wird, sammeln Sie mindestens:

  • Plattform — ios / android / beide
  • Modus — Debug (QA) oder Release (Laden)
  • Git-Referenz — Zweig oder Etikett zum Bauen
  • Akteur — E-Mail-Adresse oder Benutzer-ID für Audit-Protokolle (durchlassen client_payload)

Optional: Nach dem Lauf soll die CI zurück an den Admin API mit der Download-URL von --output-record / build last-output.

  • Authentifizieren Sie jeden Webhook (x-webhook-secret, HMAC-Signatur oder mTLS).
  • Zulassungsliste platform, mode, und ref in beiden Proxy und Workflow validate Job — als unvertrauenswürdige Eingabe behandeln. client_payload Security
  • Übertragen Sie akzeptierte Werte über Umgebungsvariablen / Jobausgaben; interagieren Sie nicht mit Payload-Feldern. run: Skripte.
  • Halten Sie GitHub/GitLab-Tokens serverseitig nur auf.
  • Präferieren Sie Tokens, die auf ein einzelnes Repository beschränkt sind.
  • Beschränken Sie den Proxy; native Builds kosten Build-Minuten.
  • Für store-submitting Releases, mappen Sie release zu einem geschützten GitHub Umgebungsvariablen (wie im Beispiel) oder fordern Sie ein zusätzliches Bestätigungsflag an, das in validate.