Aller au contenu

GitHub Actions GitHub

Automatisez vos builds iOS et Android directement depuis votre dépôt GitHub. Avec un seul fichier de workflow et quelques secrets de dépôt, chaque push, tag ou déclenchement manuel peut produire des apps signées et prêtes pour les stores — sans que personne dans l’équipe n’ait besoin d’un Mac, de Xcode ou d’Android Studio installé.

Réponse courte : pour le CI/CD Capacitor sur GitHub Actions, ajoutez un workflow qui exécute le Capgo CLI : le Capgo Builder produit les builds iOS et Android signés et peut les envoyer aux stores, et, avec un job supplémentaire bundle upload (voir Auto OTA ou natif), le même workflow peut livrer des changements web-only sous forme de live updates Capgo.

Releases sans intervention

Posez un tag de release dans Git et vos binaires iOS et Android signés sont soumis automatiquement à TestFlight et au Play Store.

Aucune configuration locale

Les contributeurs sous Windows ou Linux peuvent déclencher des builds iOS. Pas de Xcode, pas de tracas de provisionnement, pas de certificats de signature partagés qui traînent sur les portables.

Secrets à portée limitée

Les identifiants sont stockés dans les secrets du dépôt GitHub, limités à votre dépôt et visibles uniquement par le runner du workflow. Faciles à révoquer, faciles à auditer.

Builds parallèles

Compilez iOS et Android en même temps avec une matrice de jobs. Une release typique se termine en moins de 10 minutes.

Avant de configurer le workflow, assurez-vous d’avoir :

  • Un compte Capgo avec un abonnement actif et un clé Capgo API
  • Votre application enregistrée dans Capgo (bunx @capgo/cli@latest app add sinon)
  • Identifiants de build configurés localement avec bunx @capgo/cli@latest build init — voir Gestion des identifiants pour le tutoriel du wizard
  • Un build local réussi (bunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — la CI n'est pas le bon endroit pour déboguer votre premier build
  • Le GitHub CLI (gh) installé et authentifié (gh auth login)

Le Capgo CLI peut exporter vos identifiants locaux sous forme de .env fichier prêt à l’emploi. Combiné à gh secret set -f, ce qui transforme toute votre configuration CI/CD en trois commandes — sans encodage base64 manuel, sans manipulation de JSON, ni copier-coller de secrets un par un.

  1. Ajoutez votre clé Capgo API comme secret de dépôt

    La clé API n'est pas dans le store d'identifiants par application, il faut donc l'ajouter une fois manuellement :

    Fenêtre de terminal
    gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"

    Générez la clé dans les dashboard Capgo par upload permissions ou supérieures.

  2. Exportez vos identifiants vers un .env fichier

    Lancez le gestionnaire d'identifiants interactif :

    Fenêtre de terminal
    bunx @capgo/cli@latest build credentials manage --appId com.example.app

    Dans l'interface TUI, sélectionnez Exporter vers .env. CLI écrit le fichier .env.capgo.<appId> dans votre répertoire actuel avec le mode 0600 (owner-readable only) — for example, .env.capgo.com.example.app. Une fois iOS et Android configurés, les secrets des deux plateformes sont regroupés dans le même fichier sous # === IOS === et # === ANDROID === en-têtes de section. Les noms de variables d'env iOS et Android sont distincts, leur combinaison ne crée donc aucun conflit.

  3. Envoyez le .env fichier vers les secrets GitHub Actions

    Le gh secret set -f la commande lit un fichier .env et crée un secret de dépôt par KEY=value ligne :

    Fenêtre de terminal
    gh secret set -f .env.capgo.com.example.app

    C'est tout — chaque secret nécessaire à votre workflow est désormais dans GitHub. Vérifiez avec gh secret list.

  4. Créer le fichier de workflow

    Ajoutez .github/workflows/capgo-build.yml dans votre dépôt. Choisissez l’un des trois modèles de déclenchement ci-dessous selon la manière dont vous souhaitez lancer les builds.

À titre de référence, gh secret set -f créera ces secrets de dépôt (votre workflow YAML y fait référence avec exactement ces noms) :

PlateformeSecrets créés
iOSBUILD_CERTIFICATE_BASE64, P12_PASSWORD, CAPGO_IOS_PROVISIONING_MAP_BASE64, APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_KEY_CONTENT, APP_STORE_CONNECT_TEAM_ID
AndroidANDROID_KEYSTORE_FILE, KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORD, KEYSTORE_STORE_PASSWORD, PLAY_CONFIG_JSON
(ajoutés manuellement)CAPGO_TOKEN

Pas besoin de les mémoriser — les exemples de workflow ci-dessous les référencent déjà tous.

Les trois exemples ci-dessous couvrent les schémas les plus courants. Ils suivent tous la même structure : vérifier le dépôt, installer les dépendances, compiler les assets web, synchroniser avec le natif, puis appeler Capgo Build en passant les identifiants via des variables d’environnement.

Permet à quiconque ayant un accès en écriture de déclencher un build depuis Actions onglet dans GitHub avec un menu déroulant de plateforme. Pratique pour des builds de test ponctuels ou pour lancer une release à la demande.

.github/workflows/capgo-build-manual.yml
name: Capgo Build (Manual)
on:
workflow_dispatch:
inputs:
platform:
description: 'Platform to build'
required: true
default: 'android'
type: choice
options: [ios, android, both]
mode:
description: 'Build mode'
required: true
default: 'debug'
type: choice
options: [debug, release]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync
- name: Trigger Capgo Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
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 }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ inputs.platform }} \
--build-mode ${{ inputs.mode }}

Remplacer com.example.app avec votre ID d’application. Une fois commit, rendez-vous Actions → Capgo Build (Manual) → Exécuter le workflow pour le déclencher.

Compile et déploie les deux plateformes en parallèle dès que vous poussez un tag de version comme v1.4.0. C’est la configuration de production la plus courante — git tag v1.4.0 && git push --tags devient votre commande de release.

.github/workflows/capgo-build-release.yml
name: Capgo Build (Release)
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync ${{ matrix.platform }}
- name: Build ${{ matrix.platform }}
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# iOS
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
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
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 }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ matrix.platform }} \
--build-mode release

La matrice exécute iOS et Android en parallèle sur des runners distincts. Définir fail-fast: false signifie qu’un échec du build iOS n’annulera pas le build Android en cours (et inversement) — pratique lorsqu’une plateforme rencontre un problème de signature transitoire.

Détecte les régressions du build natif en générant un build Android de debug à chaque push sur main. Coût faible, retour rapide, et vous pouvez ignorer l’upload sur le Play Store pour en faire un simple test de fumée.

.github/workflows/capgo-build-main.yml
name: Capgo Build (Main)
on:
push:
branches: [main]
paths:
- 'src/**'
- 'android/**'
- 'ios/**'
- 'package.json'
- 'capacitor.config.*'
jobs:
smoke-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync android
- name: Smoke build (Android debug)
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode debug \
--no-playstore-upload \
--output-upload

Le paths le filtre garantit que le workflow ne s'exécute pas sur des changements de doc uniquement. --no-playstore-upload ignore la publication sur le Play Store (pas de PLAY_CONFIG_JSON nécessaire), et --output-upload génère une URL de téléchargement pour l'APK obtenu, afin de pouvoir l'installer sur un appareil de test.

For test builds, skip store submission: Android uses --no-playstore-upload; pour iOS, compilez en mode ad-hoc avec --ios-distribution ad_hoc (ce qui ne publie jamais sur l'App Store). Combinez l'un ou l'autre avec --output-upload pour obtenir une URL de téléchargement à durée limitée pour le binaire.

Par défaut, les builds de release envoient l'artefact signé et vous laissent le contrôle de l'action finale sur le store. Pour les releases CI qui doivent passer directement dans le flux de validation du store, ajoutez --submit-to-store-review.

Android utilise votre PLAY_CONFIG_JSON compte de service. Sans canal explicite, --submit-to-store-review utilise par défaut le canal de production avec release_status: completed. Préférez indiquer le canal lors de l'appel avec --android-track (ou PLAY_STORE_TRACK), et remplacez le statut avec --android-release-status / PLAY_STORE_RELEASE_STATUS si nécessaire :

- name: Submit Android release for review
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode release \
--submit-to-store-review \
--android-track production \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}"

Pour une release interne terminée plutôt que de production :

- name: Submit Android internal release
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
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 }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode release \
--submit-to-store-review \
--android-track internal \
--store-release-name "${GITHUB_REF_NAME}"

iOS utilise le chemin de clé API d’App Store Connect et soumet le build TestFlight traité à la revue App Store. Il nécessite app_store la distribution ; --ios-testflight-groups est facultatif pour la distribution bêta externe et n’est pas requis pour la revue App Store :

- name: Submit iOS build to App Store review
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 }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform ios \
--build-mode release \
--ios-distribution app_store \
--submit-to-store-review \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}" \
--no-ios-automatic-release

Passer --output-record <path> pour persister l’URL de l’artefact de build et le QR code sur le disque lorsque le build réussit, puis les relire dans les étapes suivantes avec build last-output. Pas de scraping des logs, pas de regex.

- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android --build-mode debug \
--output-upload --output-retention 1d \
--output-record /tmp/build.json
- name: Comment on PR with build URL
env:
GH_TOKEN: ${{ github.token }}
run: |
URL=$(bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl)
if [ -n "$URL" ]; then
gh pr comment ${{ github.event.pull_request.number }} \
--body "Debug build ready: $URL"
fi

--output-record /tmp/build.json écrit un enregistrement JSON (avec jobId, status, outputUrl, qrCodeAscii, qrCodePngPath, finishedAt) et un QR code PNG à côté, dans /tmp/build.json.qr.png. build last-output le relit :

  • --field outputUrl affiche uniquement l’URL de téléchargement (terminée par un saut de ligne ; sûr pour URL=$(...)).
  • --field qrCodePngPath affiche le chemin du PNG pour que vous puissiez l’uploader en pièce jointe de la PR.
  • --qr affiche le QR code ASCII rendu — placez-le dans une balise code Markdown du commentaire de PR pour un scan en ligne.

Ignorer l'incrémentation du numéro de build

Section titled “Skip build number bumping”

Par défaut, chaque build de release incrémente le numéro de build. Pour le fixer à une valeur que vous contrôlez (par exemple, le tag Git), passez --skip-build-number-bump:

- name: Set version from tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
# Update package.json or your version source here
bun pm version "$VERSION" --no-git-tag-version
- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ios --build-mode release \
--skip-build-number-bump

Mettre les dépendances en cache

Section intitulée « Cache des dépendances »

bun install est déjà assez rapide pour qu'un cache de dépendances JS soit rarement rentable, mais les dépendances natives de Capacitor (CocoaPods, Gradle) méritent d'être mises en cache pour les projets plus volumineux :

- uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
ios/App/Pods
android/.gradle
key: ${{ runner.os }}-capgo-${{ hashFiles('**/bun.lock', '**/Podfile.lock') }}
SymptômeCause probable
CAPGO_TOKEN is not setSecret non ajouté, ou le job n'y a pas accès (vérifiez les protections d'environnement/branche)
Erreurs d'identifiants iOS / Android manquantsgh secret set -f n'a pas été exécuté, ou l'a été sur un autre repo. Vérifiez avec gh secret list
cap sync échoue en CI mais fonctionne en localUn plugin natif n'est pas dans package.json, ou vous avez oublié bun install avant cap sync
Le build réussit mais aucune app n'apparaît dans App Store ConnectTeam ID incorrect, ou l’enregistrement de l’app n’existe pas encore dans App Store Connect. Vérifiez localement avec bunx @capgo/cli@latest build credentials manage
Le build reste bloqué après « Uploading project »L’archive du projet est anormalement volumineuse — vérifiez que node_modules n’est pas envoyé (ce n’est pas le comportement par défaut)
Provisioning profile doesn't match bundle IDLe mapping de provisionnement pointe vers un bundle ID différent de celui que Xcode signe. Relancez build init pour actualiser le profil, puis réexportez avec build credentials manage
Identifiants modifiés localement mais échec persistant en CIN'oubliez pas de réexporter et de push à nouveau : bunx @capgo/cli@latest build credentials manage → gh secret set -f .env.capgo.<appId>
Le manager refuse d'écrire le fichier combinéLes clés de config partagées diffèrent selon les plateformes — le manager vous avertit et demande une confirmation. Confirmez pour appliquer la règle du « overwrite-one-wins », ou réexportez par plateforme avec --platform ios / --platform android
build last-output affiche une URL videLe build a échoué --output-upload, ou il a échoué avant de produire un artefact. outputUrl sera null dans l'enregistrement. Branchez sur [ -n "$URL" ] avant de l'utiliser
build last-output erreurs avec Unsupported record schemaVersionLe runner utilise une version de CLI plus ancienne que celle qui a écrit l'enregistrement. Fixez le producteur et le lecteur sur la même version explicite (ex : bunx @capgo/cli@7.104.0 … des deux côtés) plutôt que @latest, qui est flottante et peut varier entre les jobs

Pour les échecs de build spécifiques à une plateforme, consultez le Guide de dépannage.