Passer à la navigation principale

Déclencher des builds natives via webhook

Capgo Build is normally started from a laptop or CI job. Teams that ship from an __CAPGO_KEEP_0__ La construction est normalement lancée à partir d'un ordinateur portable ou d'un job CI. Les équipes qui expédient depuis un tableau de bord administratif sontou CMS, ou portail interne souhaitent souvent un seul webhook HTTP: appuyez sur un bouton dans leur propre interface utilisateur, et un build natif signé démarre. Cette guide présente le modèle standard — une appelle HTTP authentifiée fine dans votre hôte code, qui exécute le même flux de travail Build Capgo que vous utilisez déjà.

Vous devez ne pas 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.

  • Un flux de travail Capgo Build qui fonctionne déjà depuis l' interface utilisateur CI ou à l'envoi (GitHub Actions)
  • La permission de créer un jeton GitHub détaillé, un jeton de déclencheur GitLab ou équivalent
  • Un secret partagé que votre tableau de bord administrateur enverra (en-tête ou corps)
Section intitulée « Option A — GitHub repository_dispatch (recommandé) »

GitHub accepte un appel API authentifié qui démarre un flux d'écoute des webhooks repository_dispatch. N'importe quel tableau de bord qui peut POST JSON peut le déclencher.

Valider le payload avant (contexte : avant de travailler sur un nouveau projet, il est recommandé de créer un problème et d'en discuter avant de commencer à travailler sur un nouveau projet.) Vérifiez et avant toute étape comportant un secret. Transmettez les valeurs acceptées à travers les sorties de tâche / variables d'environnement — jamais interprétez client_payload directement dans run: scripts (guidance sur l'injection de script).

github/travaux/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"

Créez un jeton d'accès personnel détaillé (ou un jeton d'installation d'application GitHub) avec Contenu : Lecture et écriture sur le dépôt (obligatoire pour repository_dispatch). Stockez-l’uniquement dans votre back-office administratif — jamais dans le navigateur.

3. Appeler la webhook depuis votre tableau de bord administratif

Section intitulée « 3. Appeler la webhook depuis votre tableau de bord administratif »

Votre backend (pas le navigateur de l'utilisateur final) doit envoyer :

Fenêtre de terminal
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"
}
}'
ChampObjectif
event_typeMust match types oucapgo-native-build)
client_payload.platformios, androidou both
client_payload.modedebug ou release
client_payload.refou

Connectez le même JSON POST à un bouton dans votre interface utilisateur d'administration (« Créez des applications natives »). La table de bord n'a besoin que de rejoindre votre backend ; le backend détient GITHUB_TOKEN.

Option B — Petit proxy webhook (n'importe quel hôte)

Sous-titre : Option B — Petit proxy webhook (n'importe quel hôte)

Si l'outil d'administration ne peut que POST vers une URL que vous contrôlez (Zapier, Make, Cloudflare Worker, route Express), placez un court proxy devant 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,
})
},
}

Ensuite, configurez le produit d'administration :

ParamètreValeur
URLhttps://your-worker.example.com/native-build
MéthodePOST
En-têtex-webhook-secret: <shared secret>
Corps{ "platform": "both", "mode": "release" }

Voici la forme habituelle pour se connecter à un webhook à un tableau de bord administrateur : le tableau de bord stocke une URL et un secret ; les Capgo informations restent dans les GitHub actions.

GitLab expose des jetons de déclencheur de pipeline qui sont des cibles webhooks naturelles.

# .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"'

Créez un jeton d'activation sous Paramètres → CI/CD → Jetons d'activation de pipelinepuis, à partir de l'interface de gestion back-end :

Fenêtre de terminal
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

Pour les deux plateformes, soit déclenchez deux triggers ou étendez l'opération en une matrice parallèle de même manière que l'exemple GitHub.

PlateformeMécanisme de rappel Webhook
BitbucketURL de déclencheur de pipeline ou mot de passe de pipeline personnalisé + POST
Azure DevOpsPipeline de démarrage REST API avec un PAT; utilisez la pipeline manuelle depuis Déclencheur depuis l'interface de l'UI CI

Le modèl’est identique : admin → votre secret vérification → hôte API → Capgo Job de construction.

Vérification de la charge utile pour les outils d'administration

Section intitulée « Vérification de la charge utile pour les outils d'administration »

Lorsque la forme du tableau de bord est construite, collectez au moins :

  • Plateforme — ios / android / les deux
  • Mode — débogage (QA) ou version de production (magasin)
  • Référence Git — brancher ou étiquette pour construire
  • Acteur — adresse e-mail ou ID utilisateur pour les journaux d'audit (transmettre) client_payload)

Facultatif : après l'exécution, faire que le CI postule vers l'administrateur API avec l'URL de téléchargement depuis --output-record / build last-output.

  • Authentifier chaque webhook (x-webhook-secretListe autorisée
  • ), et platform, modeSecurity ref en les deux proxy et workflow validate traiter le job — comme client_payload une entrée non fiable.
  • Passer les valeurs acceptées à travers les variables d'environnement / les sorties du job ; ne pas interpréter les champs de la charge utile dans les run: scripts.
  • Conserver les GitHub/tokens GitLab côté serveur uniquement.
  • Préférez les tokens scoping à un seul dépôt.
  • Limitez le taux de requêtes du proxy ; les builds natives coûtent des minutes de build.
  • context : Page/zone : Capgo Builder / page de produit de build cloud native. Rôle : Copie du site. Vu dans : page native-build.astro. Message clé `native_build_builder_build_minutes` (Minutes de build du constructeur de build native). release to a protected GitHub Environment (as in the sample) or require an extra confirmation flag checked in validate.
Guides connexes : Section intitulée « Guides connexes »