Zum Inhalt springen

GitHub Aktionen

Automatisiere deine iOS- und Android-Builds direkt aus deinem GitHub Repository. Mit nur einer Workflow-Datei und ein paar Repository-Secrets kann jeder Push, Tag oder manuelle Trigger signierte, Store-ready Apps erstellen – ohne dass jemand im Team einen Mac, Xcode oder Android Studio installiert haben muss.

Kurz gesagt: für Capacitor CI/CD auf GitHub Actions füge einen Workflow hinzu, der den Capgo CLI ausführt: Der Capgo Builder erstellt die signierten iOS- und Android-Builds und kann sie in die Stores hochladen. Mit einem zusätzlichen bundle upload Job (siehe Auto OTA oder Native), kann derselbe Workflow Web-only-Änderungen als Capgo Live Updates ausliefern.

Automatisierte Releases

Tagge ein Release in Git, und deine signierten iOS- und Android-Binaries werden automatisch an TestFlight und den Play Store übergeben.

Kein lokales Setup

Contributor auf Windows oder Linux können iOS-Builds triggern. Kein Xcode, kein Stress mit Provisioning oder geteilten Signing-Zertifikaten auf verschiedenen Laptops.

Scoped Secrets

Credentials liegen in den GitHub Repository-Secrets, sind auf dein Repo beschränkt und nur für den Workflow-Runner sichtbar. Einfach zu rotieren und zu auditieren.

Parallele Builds

Baue iOS und Android gleichzeitig mit einem Matrix-Job. Ein typisches Release ist in unter 10 Minuten fertig.

Bevor du den Workflow einrichtest, stelle sicher, dass du Folgendes hast:

  • Ein Capgo Account mit aktivem Abo und ein Capgo API Key ein
  • Deine in Capgo registrierte App (bunx @capgo/cli@latest app add aus)
  • Lokal konfigurierte Build-Credentials mit bunx @capgo/cli@latest build init — siehe Credentials verwalten für den Wizard-Durchlauf
  • Ein erfolgreicher lokaler Build (bunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — CI ist nicht der richtige Ort, um den ersten Build zu debuggen
  • Der GitHub CLI ("gh) installiert und authentifiziert (gh auth login)

Der Capgo CLI kann deine lokalen Credentials als fertige .env Datei exportieren. In Kombination mit gh secret set -f, so wird dein gesamtes CI/CD-Setup zu drei Befehlen – kein manuelles Base64-Encoding, kein JSON-Gefummel, kein Kopieren einzelner Secrets.

  1. Füge deinen Capgo API Key als Repository-Secret hinzu

    Der API Key gehört nicht zum Credential-Store der einzelnen Apps, füge ihn daher einmalig manuell hinzu:

    Terminalfenster
    gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"

    Generiere den Key im Capgo Dashboard mit Upload Berechtigungen oder höher.

  2. Exportiere deine Credentials in eine .env Datei

    Starte den interaktiven Credentials Manager:

    Terminalfenster
    bunx @capgo/cli@latest build credentials manage --appId com.example.app

    Wähle in der TUI Nach .env exportieren. Die CLI schreibt .env.capgo.<appId> in dein aktuelles Verzeichnis mit Modus 0600 (nur für Owner lesbar) — zum Beispiel, .env.capgo.com.example.app. Wenn sowohl iOS als auch Android konfiguriert sind, landen die Secrets beider Plattformen in derselben Datei unter # === IOS === und # === ANDROID === Abschnittsüberschriften. Da sich die iOS- und Android-Umgebungsvariablen-Namen nicht überschneiden, ist das Zusammenführen konfliktfrei.

  3. Push die .env Datei zu den GitHub Actions-Secrets.

    Der gh secret set -f Der Befehl liest eine .env-Datei und erstellt pro KEY=value line:

    Terminalfenster
    gh secret set -f .env.capgo.com.example.app

    Das war’s – alle Secrets, die dein Workflow braucht, sind jetzt in GitHub. Prüfe mit gh secret list.

  4. Workflow-Datei erstellen

    Füge .github/workflows/capgo-build.yml in dein Repository. Wähle eines der drei Trigger-Muster unten, je nachdem, wie du Builds auslösen möchtest.

Als Referenz: gh secret set -f erstellt diese Repository-Secrets (deine Workflow-YAML referenziert sie unter genau diesen Namen):

PlattformErstellte Secrets
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
(manuell hinzugefügt)CAPGO_TOKEN

Du musst dir diese nicht merken – die folgenden Workflow-Beispiele enthalten bereits alle Referenzen.

Die drei folgenden Beispiele decken die gängigsten Patterns ab. Sie folgen alle demselben Schema: Repo auschecken, Dependencies installieren, Web-Assets builden, mit Native synchronisieren und dann Capgo Build mit als Umgebungsvariablen übergebenen Credentials aufrufen.

Ermöglicht jedem mit Schreibrechten, einen Build aus der Aktionen Tab in GitHub mit einem Plattform-Dropdown. Ideal für Ad-hoc-Testbuilds oder um Releases nach Bedarf zu starten.

.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 }}

Ersetze com.example.app mit deiner App-ID. Nach dem Commit gehe zu Actions → Capgo Build (Manuell) → Workflow ausführen um den Workflow zu starten.

Baut und veröffentlicht beide Plattformen parallel, sobald du einen Version-Tag pushst, wie zum Beispiel v1.4.0. Dies ist das gängigste Production-Setup — git tag v1.4.0 && git push --tags wird zu deinem Release-Befehl.

.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

Die Matrix führt iOS und Android parallel auf separaten Runnern aus. Das Setzen von fail-fast: false bedeutet, dass ein fehlgeschlagener iOS-Build den laufenden Android-Build nicht abbricht (und umgekehrt) — hilfreich, wenn eine Plattform temporäre Probleme beim Signing hat.

Erkennt Native-Build-Regressionen frühzeitig, indem bei jedem Push auf den Branch ein Android-Debug-Build erstellt wird main. Günstig im Betrieb, schnelles Feedback, und du kannst den Play-Store-Upload überspringen, um es als reinen Smoke-Test zu nutzen.

.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

Der paths Der Filter stellt sicher, dass der Workflow bei reinen Doc-Änderungen nicht läuft. --no-playstore-upload überspringt die Play Store Einreichung (nicht PLAY_CONFIG_JSON erforderlich) und --output-upload erstellt eine Download-URL für die resultierende APK, damit du sie auf einem Testgerät installieren kannst.

Play Store / TestFlight Upload überspringen

Abschnitt: „Play Store / TestFlight Upload überspringen“

Für Test-Builds die Store-Einreichung überspringen: Android nutzt --no-playstore-upload; für iOS im ad-hoc Modus bauen mit --ios-distribution ad_hoc (was niemals an den App Store sendet). Kombiniere dies mit --output-upload um eine zeitlich begrenzte Download-URL für die Binärdatei zu erhalten.

Standardmäßig laden Release-Builds das signierte Artefakt hoch und überlassen die finale Store-Aktion Ihrer Kontrolle. Für CI-Releases, die direkt in den Store-Review-Prozess gehen sollen, fügen Sie hinzu: --submit-to-store-review.

Android verwendet Ihren PLAY_CONFIG_JSON Service-Account. Ohne expliziten Track --submit-to-store-review wird standardmäßig der Production-Track mit release_status: completed. Geben Sie den Track besser am Aufrufpunkt mit --android-track (oder PLAY_STORE_TRACK), und überschreiben Sie den Status mit --android-release-status / PLAY_STORE_RELEASE_STATUS bei Bedarf:

- 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}"

Für ein internes, abgeschlossenes Release statt der Produktion:

- 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 nutzt den App Store Connect API Key-Pfad und reicht den verarbeiteten TestFlight-Build zur App Store Prüfung ein. Dies erfordert app_store Distribution; --ios-testflight-groups ist optional für die externe Beta-Distribution und nicht erforderlich für die App Store Prüfung:

- 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

Übergeben --output-record <path> um die Build-Artifact-URL und den QR-Code code bei erfolgreichem Build auf der Festplatte zu speichern und in späteren Schritten mit ... wieder auszulesen build last-output. Kein Log-Scraping, kein 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 schreibt einen JSON-Eintrag (mit jobId, status, outputUrl, qrCodeAscii, qrCodePngPath, finishedAt) und daneben einen PNG-QR code unter /tmp/build.json.qr.png. build last-output liest ihn wieder aus:

  • --field outputUrl gibt nur die Download-URL aus (mit Zeilenumbruch; sicher für URL=$(...)).
  • --field qrCodePngPath gibt den PNG-Pfad aus, damit du ihn als PR-Attachment hochladen kannst.
  • --qr gibt den gerenderten ASCII-QR aus — pack ihn in einen Markdown code-Codeblock im PR-Kommentar, damit er direkt scanbar ist.

Standardmäßig erhöht jeder Release-Build die Build-Nummer. Um sie auf einen von dir kontrollierten Wert festzulegen (z. B. das Git-Tag), übergib --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

bun install ist bereits so schnell, dass sich ein JS-deps-Cache selten lohnt, aber die nativen Abhängigkeiten von Capacitor (CocoaPods, Gradle) lohnen sich bei größeren Projekten:

- uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
ios/App/Pods
android/.gradle
key: ${{ runner.os }}-capgo-${{ hashFiles('**/bun.lock', '**/Podfile.lock') }}
SymptomWahrscheinliche Ursache
CAPGO_TOKEN is not setSecret nicht hinzugefügt oder Job hat keinen Zugriff (Environment-/Branch-Protections prüfen)
Fehlende iOS / Android Credential Errorsgh secret set -f wurde nicht ausgeführt oder gegen ein anderes Repo ausgeführt. Prüfen mit gh secret list
cap sync Schlägt in der CI fehl, funktioniert aber lokalEin Native Plugin fehlt package.json, oder du hast vergessen bun install bevor cap sync
Build erfolgreich, aber keine App in App Store Connect sichtbarFalsche Team-ID oder der App-Eintrag existiert noch nicht in App Store Connect. Lokal prüfen mit bunx @capgo/cli@latest build credentials manage
Build hängt nach „Uploading project“Projekt-Archiv ist ungewöhnlich groß — prüfe, ob node_modules hochgeladen wird (sollte standardmäßig nicht der Fall sein)
Provisioning profile doesn't match bundle IDDie Provisioning Map verweist auf eine andere Bundle ID als die, die Xcode signiert. Erneut ausführen mit build init um das Profil zu aktualisieren, dann erneut exportieren mit build credentials manage
Credentials lokal geändert, aber CI schlägt weiterhin fehlNicht vergessen, erneut zu exportieren und zu pushen: bunx @capgo/cli@latest build credentials manage → gh secret set -f .env.capgo.<appId>
Manager weigert sich, die kombinierte Datei zu schreibenShared Config Keys unterscheiden sich zwischen den Plattformen — der Manager warnt und bittet um Bestätigung. Entweder bestätigen (Overwrite-one-wins) oder pro Plattform erneut exportieren mit --platform ios / --platform android
build last-output gibt eine leere URL ausDer Build ist fehlgeschlagen --output-upload, oder es ist fehlgeschlagen, bevor ein Artefakt erzeugt wurde. outputUrl wird sein null im Datensatz. Verzweige nach [ -n "$URL" ] bevor du es nutzt
build last-output Fehler mit Unsupported record schemaVersionDer Runner läuft mit einer älteren CLI als die, die den Datensatz geschrieben hat. Pinne sowohl Producer als auch Reader auf dieselbe explizite Version (z. B. bunx @capgo/cli@7.104.0 … auf beiden Seiten) anstatt @latest, die floatet und zwischen Jobs driften kann

Für plattformspezifische Build-Fehler siehe den Troubleshooting-Guide.