Das Einrichten von CI/CD für Capacitor-Apps kann komplex und zeitaufwendig sein. Hier ist das Wichtigste:
Empfohlen für neue Builds: Nutze Capgo Build
Wir empfehlen jetzt Capgo Build mit Capgo CLI für native Capacitor Builds. Dieser Fastlane-Guide ist für Teams gedacht, die bestehende GitHub Actions-Pipelines pflegen. Neue iOS-Builds sollten jedoch Capgo CLI nutzen, damit ihr Fastlane, Xcode-Runner, Zertifikate und Upload-Skripte nicht selbst verwalten müsst.
Capgo Build für CI/CD von Capgo
Spart die Wartung von Fastlane, Xcode-Runnern, Zertifikaten, Provisioning Profiles und Upload-Skripten. Capgo Build führt signierte native iOS-Builds aus eurer bestehenden CI/CD-Pipeline aus:
- Kompatibel mit eurer Pipeline: Löst den Capgo Build via GitHub Actions, GitLab CI, Jenkins oder lokale Skripte nach eurem Web-Build aus und
npx cap sync. - Signing via CI-Secrets: Behaltet App Store Connect Keys, Zertifikate, Provisioning Profiles, Passwörter und Team-IDs sicher in euren eigenen CI-Secrets.
- Kein Wartungsaufwand für Runner: Capgo Build bietet gewartete Apple-Build-Umgebungen, sodass ihr keine macOS-Runner, Xcode-Images oder Fastlane-Lanes verwalten müsst.
- Artefakte und Einreichung: Lade signierte Artefakte für QA herunter oder reiche Release-Builds über Capgo CLI ein.
Preise
- Capgo-Pläne ab 12 $/Monat
- Inklusive OTA-Updates und ca. 15 Native Builds pro Monat
- Zusätzliche Build-Minuten werden minutengenau über Credits abgerechnet
Capgo Build in CI/CD einrichten
Manuelle Setup-Anleitung
Das müssen Sie tun:
Continuous Delivery für iOS mit Fastlane, GitHub Actions und Zertifikaten
Voraussetzungen
Bevor du mit dem Tutorial fortfährst:
- Stelle sicher, dass Fastlane installiert ist installiert ist auf deiner Entwicklungsmaschine.
- Vergewissere dich, dass du Mitglied im iOS Developer Program bist.
Wichtige Informationen zum Preis

https://github.com/features/actions
Der Service ist „kostenlos“ bis zum Limit, je nach gewählter Maschine.
Wir werden eine macOS Maschine nutzen; im Screenshot siehst du den Preis und die Limits (Preise zum Zeitpunkt der Tutorial-Erstellung, Änderungen vorbehalten).
Nachdem wir Anforderungen und Preise geklärt haben, geht es weiter.
Hinweis: Im Beitrag gehe ich davon aus, dass die App in App Store Connect bereits erstellt ist. Die wichtigen Informationen werden von Fastlane übernommen!
Das lernst du in diesem Tutorial
Schritte im Beitrag
- App Store Connect API mit Fastlane nutzen
- Voraussetzungen:
- App Store Connect API Key erstellen
- Einen App Store Connect API Key verwenden
- Voraussetzungen:
- Fastlane-Dateien kopieren
- GitHub Actions konfigurieren
1. App Store Connect API mit Fastlane nutzen
Seit Februar 2021 ist für alle Nutzer eine Zwei-Faktor-Authentifizierung oder eine Zwei-Schritt-Verifizierung erforderlich, um sich bei App Store Connect anzumelden. Diese zusätzliche Sicherheitsebene für Ihre Apple ID hilft sicherzustellen, dass nur Sie auf Ihr Konto zugreifen können.
Von Apple Support
Anforderungen
Damit Fastlane API von App Store Connect nutzen kann, um deine App hochzuladen, musst du Folgendes angeben: drei Dinge:
- Issuer-ID
- Key-ID
- Key-Datei oder Key-Inhalt
So erhältst du einen App Store Connect API Key
Um Keys zu generieren, benötigst du die Admin-Berechtigung in App Store Connect. Falls dir diese fehlt, kannst du die zuständige Person auf diesen Artikel verweisen.
-
Anmelden bei App Store Connect.
-
Wähle Benutzer und Zugriff.

3 — Wähle den Tab Integration.

- Klicke auf Generate API Key oder das Add (+)-Symbol.

- Gib einen Namen für den Key ein. Der Name dient nur deiner Referenz und ist nicht Teil des Keys selbst.

6 — Wähle unter Access die Rolle für den Key. Die verfügbaren Rollen für Keys entsprechen den Rollen deiner Teammitglieder. Siehe Rollenberechtigungen. Wir empfehlen die Auswahl von App Manager.
- Klicke auf Generate.
Der Zugriff eines API Keys kann nicht auf bestimmte Apps beschränkt werden.
Der Name des neuen Keys, die Key-ID, ein Download-Link und weitere Infos werden auf der Seite angezeigt.

Hier findest du alle drei benötigten Informationen.
<1> Issue-ID. (APPLE_ISSUER_ID geheim)
<2> Key ID. (APPLE_KEY_ID geheim)
<3> Klicke auf „Download API Key“, um deinen API Private Key herunterzuladen. Der Download-Link erscheint nur, wenn der Private Key noch nicht heruntergeladen wurde. Apple speichert keine Kopie des Private Keys. Du kannst ihn also nur einmal herunterladen.
🔴 Speichere deinen Private Key an einem sicheren Ort. Du solltest deine Keys niemals teilen, sie nicht in einem code-Repository speichern oder in clientseitigem code einbinden.
Einen App Store Connect API Key verwenden
Die API Key-Datei (die heruntergeladene p8-Datei), die Key ID und die Issuer ID werden benötigt, um den JWT-Token für die Autorisierung zu erstellen. Es gibt verschiedene Wege, diese Informationen an Fastlane zu übergeben. Ich habe mich für die neue Fastlane-Action entschieden: app_store_connect_api_key. Weitere Methoden findest du in der Fastlane-Dokumentation. Ich zeige diese Methode, weil sie meiner Meinung nach am einfachsten mit den meisten CI-Systemen funktioniert, bei denen man Umgebungsvariablen setzen kann.
Bitte konvertiere die heruntergeladene p8-Datei in Base64 und speichere sie als Secret (APPLE_KEY_CONTENT).
base64 -i APPLE_KEY_CONTENT.p8 | pbcopy
Jetzt können wir App Store Connect mit Fastlane und dem API Key verwalten, super!
2. Zertifikate
Öffne Xcode und gehe zu Einstellungen > Konten > Apple ID > Teams und wähle dein Team aus.

Klicken Sie auf Zertifikate verwalten.
Falls du noch kein Zertifikat erstellt hast, kannst du ein neues erstellen.
Klicken Sie auf + und wählen Apple-Distribution

Dann musst du in die Schlüsselbundverwaltung, um das Zertifikat als .p12 Datei.
Dazu musst du in der Schlüsselbundverwaltung zum Schlüsselbund Anmeldung wechseln und dann zum Tab Meine Zertifikate.

Dann kannst du das Zertifikat auswählen, das du herunterladen möchtest. (Achte auf das Datum des Zertifikats)
Klicke dann mit der rechten Maustaste auf den privaten Schlüssel des Zertifikats und wähle Exportieren.
Wähle das Dateiformat Austausch persönlicher Informationen (.p12).
Damit wird das Zertifikat als .p12 Datei.
Öffne die Datei im Terminal und nutze diesen Befehl, um sie in Base64 zu konvertieren:
base64 -i BUILD_CERTIFICATE.p12 | pbcopy
This will become your BUILD_CERTIFICATE_BASE64 Secret. Gib auf Nachfrage bitte das Passwort des Zertifikats an. Dieses Passwort ist dein P12_PASSWORD Secret.
3. Provisioning Profiles
Öffne Apple Developer und wähle das richtige Team aus.
Erstelle dann ein neues Profil, indem du auf +

Und wähle App Store Connect.

Wähle dann die richtige App aus; achte darauf, keine Wildcards zu verwenden, da sonst das Signing fehlschlägt.

Wähle das zuvor erstellte, passende Zertifikat aus (achte auf das Ablaufdatum; es sollte den gleichen Tag und Monat wie heute haben) und klicke auf Weiter.

Gib abschließend den Namen des Profils ein und klicke auf Generieren.
Der Name dient zur Identifizierung des Profils in Fastlane unter dem Wert
APPLE_PROFILE_NAME.

You can download the profile as a .mobileprovision Datei.

Bitte konvertiere das Profil in Base64 und speichere es als Secret (BUILD_PROVISION_PROFILE_BASE64).
base64 -i BUILD_PROVISION_PROFILE.mobileprovision | pbcopy
4. Fastlane-Dateien kopieren
Fastlane ist eine Ruby-Library, mit der sich gängige Aufgaben in der Mobile-Entwicklung automatisieren lassen. Mit Fastlane kannst du eigene „Lanes“ konfigurieren, die eine Reihe von „Actions“ bündeln, um Aufgaben auszuführen, die du normalerweise in Android Studio erledigst. Mit Fastlane lässt sich viel erreichen, aber in diesem Tutorial nutzen wir nur eine Handvoll Core-Actions.
Erstelle den Fastlane-Ordner im Root deines Capacitor/Ionic-Projekts und füge dort die Fastfile hinzu:
- Ordner:
<project-root>/fastlane/ - Datei:
<project-root>/fastlane/Fastfile
Dies liegt auf derselben Ebene wie package.json, capacitor.config.*, und die ios/ Ordner. Erstelle ihn nicht innerhalb von ios/App/.
platform :ios do
desc 'Export ipa and submit to TestFlight'
lane :beta do
keychain_info = { keychain_name: "ios-build-#{Time.now.to_i}.keychain", keychain_password: SecureRandom.uuid }
begin
setup_signing(keychain_info)
bump_build_number
build_app_with_signing(keychain_info)
submit_to_testflight
ensure
cleanup_keychain(keychain_info)
end
end
private_lane :setup_signing do |options|
create_keychain(
name: options[:keychain_name],
password: options[:keychain_password],
unlock: true,
timeout: 0,
lock_when_sleeps: false,
add_to_search_list: true
)
import_cert(options)
install_profile
update_project_settings
end
lane :bump_build_number do
file = File.read('../package.json')
data_hash = JSON.parse(file)
api_key = app_store_connect_api_key(
key_id: ENV['APPLE_KEY_ID'],
issuer_id: ENV['APPLE_ISSUER_ID'],
key_content: ENV['APPLE_KEY_CONTENT'],
is_key_content_base64: true,
duration: 1200,
in_house: false
)
build_num = app_store_build_number(
api_key: api_key,
app_identifier: ENV['BUNDLE_IDENTIFIER'],
live: false
)
build_num = build_num + 1
UI.message("Bumped build number to #{build_num}")
increment_build_number(
build_number: build_num,
xcodeproj: "./ios/App/App.xcodeproj",
skip_info_plist: true
)
end
private_lane :import_cert do |options|
cert_path = "#{Dir.tmpdir}/build_certificate.p12"
File.write(cert_path, Base64.decode64(ENV['BUILD_CERTIFICATE_BASE64']))
import_certificate(
certificate_path: cert_path,
certificate_password: ENV['P12_PASSWORD'] || "",
keychain_name: options[:keychain_name],
keychain_password: options[:keychain_password],
log_output: true
)
File.delete(cert_path)
end
private_lane :cleanup_keychain do |options|
delete_keychain(
name: options[:keychain_name]
)
end
private_lane :install_profile do
profile_path = "#{Dir.tmpdir}/build_pp.mobileprovision"
File.write(profile_path, Base64.decode64(ENV['BUILD_PROVISION_PROFILE_BASE64']))
UI.user_error!("Failed to create provisioning profile at #{profile_path}") unless File.exist?(profile_path)
ENV['PROVISIONING_PROFILE_PATH'] = profile_path
install_provisioning_profile(path: profile_path)
File.delete(profile_path)
end
private_lane :update_project_settings do
update_code_signing_settings(
use_automatic_signing: false,
path: "./ios/App/App.xcodeproj",
code_sign_identity: "iPhone Distribution",
profile_name: ENV['APPLE_PROFILE_NAME'],
bundle_identifier: ENV['BUNDLE_IDENTIFIER'],
team_id: ENV['APP_STORE_CONNECT_TEAM_ID']
)
update_project_team(
path: "./ios/App/App.xcodeproj",
teamid: ENV['APP_STORE_CONNECT_TEAM_ID']
)
end
private_lane :build_app_with_signing do |options|
unlock_keychain(
path: options[:keychain_name],
password: options[:keychain_password],
set_default: false
)
build_app(
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
configuration: "Release",
export_method: "app-store",
output_name: "App.ipa",
export_options: {
provisioningProfiles: {
ENV['BUNDLE_IDENTIFIER'] => ENV['APPLE_PROFILE_NAME']
}
},
xcargs: "-verbose",
buildlog_path: "./build_logs",
export_xcargs: "-allowProvisioningUpdates",
)
end
private_lane :submit_to_testflight do
api_key = app_store_connect_api_key(
key_id: ENV['APPLE_KEY_ID'],
issuer_id: ENV['APPLE_ISSUER_ID'],
key_content: ENV['APPLE_KEY_CONTENT'],
is_key_content_base64: true,
duration: 1200,
in_house: false
)
pilot(
api_key: api_key,
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false,
ipa: "./App.ipa"
)
end
end
5. Secrets einrichten
GitHub Actions nutzt die Repository-Secrets, die du im nächsten Schritt konfigurierst. Du benötigst nur eine lokale .env Datei, wenn du Fastlane von deinem eigenen Rechner aus ausführen oder testen willst.
Erstelle für lokale Tests <project-root>/fastlane/.env direkt neben Fastfile. Committe diese Datei nicht. Füge sie fastlane/.env in deine .gitignore zuerst hinzu (oder prüfe, ob sie bereits ignoriert wird). Hier ist ein Beispiel:
APP_STORE_CONNECT_TEAM_ID=UVTJ336J2D
BUNDLE_IDENTIFIER=ee.forgr.testfastlane
# See previous section for these secrets
BUILD_CERTIFICATE_BASE64=
BUILD_PROVISION_PROFILE_BASE64=
APPLE_KEY_ID=
APPLE_ISSUER_ID=
APPLE_KEY_CONTENT=
P12_PASSWORD=
APPLE_PROFILE_NAME=
Die APP_STORE_CONNECT_TEAM_ID ermitteln
Gehe zu Developer Center und scrolle nach unten zu Membership details Abschnitt.
Den Team ID is the value you need to set in the APP_STORE_CONNECT_TEAM_ID secret.
Den BUNDLE_IDENTIFIER abrufen
- Xcode öffnen
- Doppelklicke auf den
Appim Project Navigator - Klicke dann auf den Tab
Signing and Capabilities - Kopiere den Wert von
Bundle identifier. Dies ist der Wert, den du imBUNDLE_IDENTIFIERsecret.
6. Build-Verarbeitung
In GitHub Actions erfolgt die Abrechnung basierend auf den Minuten, die du für deinen CI/CD-Workflow verbraucht hast. Meiner Erfahrung nach dauert es etwa 10–15 Minuten, bis ein Build in App Store Connect verarbeitet werden kann.
Bei privaten Projekten können die geschätzten Kosten pro Build bis zu $0,08/Min. x 15 Min. = $1,2betragen oder sogar höher ausfallen, je nach Konfiguration und Abhängigkeiten deines Projekts.
Wenn du dir wegen der Kosten für private Projekte Sorgen machst, kannst du skip_waiting_for_build_processing zu true. Das spart Build-Minuten, da man nicht warten muss, bis App Store Connect die Verarbeitung des Builds abgeschlossen hat.
Es gibt jedoch einen Kompromiss: Du musst die Compliance-Informationen deiner App in App Store Connect manuell aktualisieren, bevor du den Build an Nutzer verteilen kannst.
This optimization is mainly useful for private projects where build minutes cost money. For public/free projects, the build minutes are free so there’s no need to enable this setting. See GitHub’s Preisseite für weitere Details.
7. GitHub Actions einrichten
GitHub Secrets konfigurieren
Bitte kopiere die Secrets aus der .env Datei und füge sie in die GitHub Repository-Secrets ein.
Gehe zu Einstellungen > Secrets und Variablen > Aktionen > Neues Repository-Secret
2. BUILD_CERTIFICATE_BASE64 - Base64-kodiertes Zertifikat.
3. BUILD_PROVISION_PROFILE_BASE64 - Base64-kodiertes Provisioning Profile.
4. BUNDLE_IDENTIFIER - dem Bundle Identifier deiner App.
5. APPLE_KEY_ID — App Store Connect API Key 🔺Key ID.
6. APPLE_ISSUER_ID — App Store Connect API Key 🔺Issuer ID.
7. APPLE_KEY_CONTENT — App Store Connect API Key 🔺 Key-Inhalt von .p8, Prüfen
8. GitHub Workflow-Datei konfigurieren
Erstelle ein GitHub Workflow-Verzeichnis.
cd .github/workflows
Im workflow Ordner erstelle eine Datei namens build-upload-ios.ymlund füge Folgendes hinzu.
name: Build source code on ios
on:
push:
tags:
- '*'
jobs:
build_ios:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v6
- name: Set Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Install dependencies
id: install_code
run: npm ci
- name: Build
id: build_code
run: npm run build
- uses: actions/cache@v5
with:
path: ios/App/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Sync
id: sync_code
run: npx cap sync
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- uses: maierj/fastlane-action@v3.1.0
env:
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
BUNDLE_IDENTIFIER: ${{ secrets.BUNDLE_IDENTIFIER }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
APPLE_PROFILE_NAME: ${{ secrets.APPLE_PROFILE_NAME }}
with:
lane: ios beta
- name: Upload release bundle
uses: actions/upload-artifact@v6
with:
name: ios-release
path: ./App.ipa
retention-days: 10
Dieser Workflow sollte nach jedem GitHub ausgelöst werden Tag, falls du das Tagging automatisieren möchtest, schau bitte in Automatischer Build und Release mit GitHub Actions zuerst.
Anschließend lädt dieser Workflow deine NodeJS-Abhängigkeiten herunter, installiert sie und baut deine JavaScript-App.
Jedes Mal, wenn du einen neuen Commit pushst, wird ein Release in TestFlight erstellt.
Deine App muss nicht Ionic nutzen, nur die Capacitor Basis ist Pflicht. Sie kann alte Cordova-Module enthalten, aber Capacitor JS-Plugins sollten bevorzugt werden.
8. Workflow auslösen
Einen Commit erstellen
Erstelle einen Commit, dann solltest du den aktiven Workflow im Repository sehen.
Workflow auslösen
Neue Commits in den Branch pushen main oder development um den Workflow auszulösen.

Nach wenigen Minuten sollte der Build in deinem App Store Connect Dashboard verfügbar sein.

9. Kann ich vom lokalen Rechner aus deployen?
Ja, das geht und ist absolut mühelos.
Du kannst wie gewohnt Xcode zum Builden und Signieren deiner App nutzen.
Ähnliche Artikel
CI/CD Setup-Guides
- Automatischer Capacitor Android Build mit GitHub Actions - Vollständiges Android CI/CD Setup
- Automatischer Build und Release mit GitHub Actions - Komplette CI/CD-Pipeline Anleitung
- Dev- und Prod-Builds verwalten mit GitHub Actions - Environment-Management
- Automatischer Capacitor iOS Build mit Match - Alternative mit Fastlane Match
Alternative CI/CD-Plattformen
- Build mit GitLab CI - GitLab Alternative
- Build mit CodeMagic - CodeMagic Setup-Guide
Live Updates & Deployment
- Capgo Live Updates Dokumentation - OTA-Updates zu deiner App hinzufügen
- CI/CD-Integration mit Capgo - Live-Updates in deine Pipeline integrieren
Danke
Dieser Blogpost basiert auf folgenden Artikeln:
- Continuous Delivery für iOS mit Fastlane und GitHub Actions
- Fastlane-Dokumentation
- Diese GitHub Nachricht von @mrogunlana
- Diese GitHub Dokumentation
Weiter mit automatischem Capacitor iOS Build via GitHub Actions mit Zertifikat
Wenn du es nutzt Automatisierter Capacitor iOS Build mit GitHub Actions inklusive Zertifikat um CI/CD-Automatisierung zu planen, verbinde es mit Capgo CI/CD für den Produkt-Workflow in Capgo CI/CD, Capgo Native Builds optimieren für den Produkt-Workflow in Capgo Native Builds, Capgo Integrationen für den Produkt-Workflow in Capgo Integrations, CI/CD-Integration für die Implementierungsdetails in der CI/CD-Integration und GitHub Actions-Integration für die Implementierungsdetails in der GitHub Actions-Integration.