Passer à la navigation

Déclencher des builds natives via Webhook

L'Capgo__ est généralement lancé à partir d'un ordinateur portable ou d'un job CI. Les équipes qui délivrent depuis un __CAPGO_KEEP_0__ webhook HTTP, CMS ou portail interne souhaitent souvent un seul Webhook HTTP: press a button in their own UI, and a signed native build starts. This guide shows the standard pattern — a thin authenticated HTTP call into your code host, which runs the same Capgo Build workflow you already use.

Vous faites Prérequis 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 de Build Capgo qui fonctionne déjà depuis le CI UI ou lors d'un push (Actions de GitHub)
  • Autorisation de création d'un jeton finement détaillé GitHub, 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 authentifié API qui démarre un flux d'écoute des notifications repository_dispatchTout tableau de bord qui peut POST peut lancer cela.

Valider le payload avant avant de travailler sur une nouvelle fonctionnalité, discutez-en et créez un problème client_payload directement dans run: scripts (guidance sur l'injection de script).

/github/flux de travail/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"

GitHub/travaux/__CAPGO_KEEP_1__-build-webhook.yml

Titre de la section “2. Créez un jeton GitHub”

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

3. Appeler le webhook depuis votre tableau de bord administratif

Sous-titre « 3. Appeler le webhook depuis votre tableau de bord administratif »

Votre back-office (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_typeDoit correspondre types dans le flux de travail (capgo-native-build)
client_payload.platformios, androidou both
client_payload.modedebug ou release
client_payload.refBranche ou tag à construire (facultatif)

Connectez le même JSON POST à un bouton dans votre interface d'administration (“Créez des applications natives”). Le tableau de bord n'a besoin que de s'atteindre. ou backend; le backend détient GITHUB_TOKEN.

Option B — Webhook proxy miniature (toute l'hôte)

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

If the admin tool can only POST to a URL you control (Zapier, Make, Cloudflare Worker, Express route), put a short proxy in front of 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,
})
},
}

Configurez ensuite le produit administrateur :

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 GitHub Actions.

GitLab expose jetons de déclenchement 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éer un jeton de déclenchement sous Paramètres → CI/CD → Jetons de déclenchement de pipeline, puis à partir de l'interface administrative :

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éclencher deux triggers ou étendre l'opération en une matrice parallèle de la même manière que l'exemple GitHub.

PlateformeMécanisme de rappel Web
BitbucketURL de déclencheur de pipeline ou mot de passe de pipeline personnalisé + POST
Azure DevOpsExécution de pipeline REST API avec un jeton PAT; utilisez la pipeline manuelle depuis Déclencheur depuis l'interface de CI

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

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

  • Plateforme ios / android / les deux
  • Mode — débogage (QA) ou mise en production (magasin)
  • Référence Git — branche ou tag à construire
  • Acteur — email or user id for audit logs (pass through client_payload)

Après l'exécution, le CI peut envoyer un message au administrateur API avec l'URL de téléchargement depuis --output-record / build last-output.

  • Authentifier chaque webhook (x-webhook-secret, signature HMAC ou mTLS).
  • Liste autorisée platform, mode, et ref dans les deux le proxy et le workflow validate tâche — traitez client_payload comme une entrée non fiable.
  • Passer les valeurs acceptées à travers les variables d'environnement / les sorties de tâche ; ne pas interpréter les champs du payload. run: scripts.
  • Conservez les GitHub/jetons GitLab côté serveur uniquement.
  • Préférez les jetons scoping à un seul référentiel.
  • Rate-limit the proxy; native builds cost build minutes.
  • Pour les publications de magasin, configurez release à un environnement protégé GitHub (comme dans l'exemple) ou nécessite une confirmation supplémentaire avec un drapeau vérifié validate.