Déclencher des builds natives via webhook
Copiez une commande de configuration avec les étapes d'installation et le guide markdown complet pour ce plugin.
Capgo 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 sont tableau de bord administratifou CMS, ou portail interne souhaitent souvent un seul webhook HTTP: appuyez sur un bouton dans leur propre interface, 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à.
Architecture
Section intitulée « Architecture »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
Vous devez ne pas exposer un Capgo webhook de build public. Votre CI dispose déjà des secrets de signature ; le seul rôle du webhook est de démarrer ce job CI de manière sécurisée.
Prérequis
Section intitulée « Prérequis »- Un Capgo workflow de build qui fonctionne déjà depuis la interface utilisateur de la 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)
Option A — GitHub repository_dispatch (recommandé)
Section intitulée « Option A — GitHub repository_dispatch (recommandé) »GitHub accepte un appel API authentifié qui démarre un flux d'écoute des repository_dispatch. N'importe quel tableau de bord qui peut POST JSON peut le déclencher.
1. Flux d'écoute du webhook
Section intitulée « 1. Flux d'écoute du webhook »Valider le payload avant (contexte : avant de travailler sur un nouveau projet, il est recommandé de créer un problème et de 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 — n'interprétez jamais client_payload directement dans run: scripts (guidance sur l'injection de script).
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. Créez un jeton GitHub
Titre de la section « 2. Créez un jeton GitHub »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_dispatchStockez-l’uniquement dans votre back-office — n'enregistrez jamais dans le navigateur.
3. Appeler la mise à jour webhook depuis votre tableau de bord administratif
Section intitulée « 3. Appeler la mise à jour webhook depuis votre tableau de bord administratif »Votre serveur backend (pas le navigateur de l'utilisateur final) doit envoyer :
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" } }'| Champ | Objectif |
|---|---|
event_type | context : Page/zone : Site web de marketing Capgo. Rôle : Étiquette de navigation ou élément UI court. Clé de message `subprocessors_table_purpose` (Objectif de la table des sous-processus). types Doit correspondrecapgo-native-build) |
client_payload.platform | ios, androidou both |
client_payload.mode | debug ou release |
client_payload.ref | context : Fragment de texte HTML provenant d'une chaîne de dialogue Capgo plus longue (clé de message parente `alternatives_cta_questions`). Page/zone : Page de comparaison des alternatives de mise à jour en direct de Capacitor. Rôle : Paragraphe de marketing ou juridique long. Voir : page alternatives.astro. Conservez les termes de produit et de marque Capgo ainsi que les termes de développeur exactement. Clé de message `alternatives_cta_questions` (Questions de l'appel à l'action des alternatives). | Fragment de texte HTML provenant d'une chaîne de dialogue Capgo plus longue (clé de message parente `appflow_cta_questions`). Page/zone : Copie de marketing de comparaison/migration d'Appflow. Rôle : Paragraphe de marketing ou juridique long. Voir : page ionic-appflow.astro. Conservez les termes de produit et de marque Capgo ainsi que les termes de développeur exactement. Clé de message `appflow_cta_questions` (Questions de l'appel à l'action d'Appflow). | Fragment de texte HTML provenant d'une chaîne de dialogue Capgo plus longue (clé de message parente `capwesome_cta_questions`). Page/zone : Page de comparaison de Capawesome. Rôle : Paragraphe de marketing ou juridique long. Voir : page capwesome.astro. Conservez les termes de produit et de marque Capgo ainsi que les termes de développeur exactement. Clé de message `capwesome_cta_questions` (Questions de l'appel à l'action de Capawesome). | Page/zone : Page de services de conseil. Rôle : Sous-titre ou slogan de section. Voir : page consulting.astro. Conservez les termes de produit et de marque Capgo ainsi que les termes de développeur exactement. Clé de message `consulting_faq_subtitle` (Sous-titre des questions fréquentes de conseil). | Page/zone : Copie de marketing de comparaison/migration d'Appflow. Rôle : Étiquette de navigation ou élément UI court. Voir : page ionic-appflow.astro, page ionic-enterprise-plugins.astro, page solutions/ionic-enterprise-plugins.astro. Clé de message `appflow_plugins_or` (Appflow Plugins ou). |
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 (hôte quelconque)
Sous-titre « Option B — Petit proxy webhook (hôte quelconque) »Si l'outil d'administration ne peut que poster 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ètre | Valeur |
|---|---|
| URL | https://your-worker.example.com/native-build |
| Méthode | POST |
| En-tête | x-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.
Déclencheur de pipeline GitLab
Section intitulée « Déclencheur de pipeline GitLab »GitLab expose des jetons de déclencheur de pipeline qui sont des cibles webhooks naturelles.
# .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"'Créer un jeton de déclencheur sous Paramètres → CI/CD → Jetons de déclencheur de pipeline, puis à partir du backend administrateur :
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/pipelinePour les deux plateformes, soit déclencher deux déclencheurs ou étendre l'opération en une matrice parallèle de la même manière que l'exemple GitHub.
Bitbucket et Azure
Section intitulée “Bitbucket et Azure”| Plateforme | Mécanisme de déclencheur Webhook |
|---|---|
| Bitbucket | URL de déclencheur de pipeline ou mot de passe de pipeline personnalisé + POST |
| Azure DevOps | Pipeline 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 : administrateur → votre secret vérification → hôte API → Capgo Job de construction.
Vérification du payload pour les outils administrateurs
Section intitulée “Vérification du payload pour les outils administrateurs”Lorsque le formulaire de tableau de bord est construit, 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 identifiant utilisateur pour les journaux d'audit (transmettre)
client_payload)
Facultatif : après l'exécution, avoir CI renvoyer à l'administrateur API avec l'URL de téléchargement depuis --output-record / build last-output.
Sécurité
Section intitulée « Sécurité »- Authentifier chaque webhook (
x-webhook-secretListe blanche - , et
platform,modeSecurityrefsur les deux proxy et les workflowsvalidatetraiter — commeclient_payloadune 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 de la charge utile dans
run:scripts. - Conserver les GitHub/GitLab tokens côté serveur uniquement.
- Préférez les jetons scoping à un seul référentiel.
- Limitez le taux de requêtes du proxy ; les builds natifs coûtent des minutes de build.
- context : Page/zone : Capgo Builder / page de produit de build cloud natif. 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 natif).
releaseto a protected GitHub Environment (as in the sample) or require an extra confirmation flag checked invalidate.