Zum Hauptinhalt springen

CI/CD für Cordova-Apps 2026: Eine umfassende Einrichtungsanleitung

2026 für Cordova-Apps einrichten: Signierte Android AAB- und iOS-IPA-Builds, Store-Uploads, live update-Optionen und der Zeitpunkt, an dem man zu Capacitor wechseln sollte.

CI/CD für Cordova-Apps in 2026: Eine umfassende Anleitung

CI/CD for a Cordova app in 2026 means building and signing the Android AAB on a Linux runner, building and signing the iOS IPA on a macOS runner, and uploading both to the stores from the same pipeline. The managed services Cordova teams used for this are gone or closing, so most teams now run the Cordova CLI on a general-purpose CI. This guide gives you a working GitHub Actions setup, the same steps for other CIs, and an honest look at live updates and long-term options.

Was sich für Cordova-Teams geändert hat

Drei Ereignisse haben die Cordova-CI/CD geprägt:

  • PhoneGap Build am 1. Oktober 2020 eingestellt.
  • Microsoft App Center am 31. März 2025 eingestellt. Die Bereitstellung, Verteilung und der gehostete CodePush-Dienst endeten mit ihm.
  • Ionic Appflow hatte im Februar 2025 neue Verkäufe eingestellt. Bestehende Kunden behalten bis zum 31. Dezember 2027 Zugriff.

Cordova selbst funktioniert noch. Das Apache-Projekt liefert cordova-android und cordova-ios Veröffentlichungen, und viele interne und unternehmensweite Apps laufen darauf. Der Riss ist die verwaltete Schicht: Signierungsspeicher, Laden von Dateien und über-ein-Netz-Updates. Sie bauen nun diese aus einem CI-Dienst und einigen Werkzeugen zusammen.

Anatomie eines Cordova-Pipelines

Schritt Android iOS
Runner Linux macOS mit Xcode 26
Restore cordova prepare (Plattformen und Plugins von package.json) gleich
Web-Build Ihr Bundler (Vite, webpack, Angular CLI) in www/ gleich
Native-Build Gradle über cordova build android --release xcodebuild via cordova build ios --release --device
Signierung Hochladen des Keystore (.jks) Verteilungszertifikat (.p12) und Provisionierungsprofil
Artikel .aab für Google Play .ipa für TestFlight und den App Store
Hochladen Google Play-Entwickler API (Dienstkontoinformationen) App Store Connect API-Schlüssel

Zwei Plattformregeln gelten für jede Pipeline:

  • Seit dem 28. April 2026 akzeptiert App Store Connect nur Builds, die mit Xcode 26 und iOS 26 SDK oder später erstellt wurden. Überprüfen Sie, ob Ihre cordova-ios Die Version unterstützt es.
  • Google Play verlangt AAB-Uploads für neue Apps und erhöht sein Mindestziel API jährlich. Halten cordova-android Schritt 1: Machen Sie das Projekt wiederherstellbar targetSdkVersion follows.

Schritt 1: Machen Sie das Projekt wiederherstellbar

CI kann nur das neu aufbauen, was im Repository ist. Bevor Sie einen Workflow schreiben:

  1. Commit package.json Schritt 1: Machen Sie das Projekt wiederherstellbar cordova Teil der package.json, so cordova prepare wiederherstellt sie.
  2. Vermeiden Sie das Commit platforms/ oder plugins/Sie werden generiert.
  3. Installieren Sie Cordova CLI als Entwicklungsabhängigkeit, damit jede Maschine die gleiche Version verwendet:
bun add -d cordova
  1. Verschieben Sie die Signierungsdaten aus config.xml und in eine build.json die Geheimnisse bei der Buildzeit liest (Schritt 2).
  2. Fixieren Sie die Node.js-Version in .nvmrc oder package.json engines.

Schritt 2: Signieren mit build.json

Cordova liest die Signierungsdaten aus einem build.json Datei. Commiten Sie eine build.template.json mit Ersatzzeichen, generieren Sie das echte build.json in CI aus Geheimnissen, und committieren Sie das generierte Datei nie:

{
  "android": {
    "release": {
      "keystore": "release.jks",
      "storePassword": "${KEYSTORE_STORE_PASSWORD}",
      "alias": "upload",
      "password": "${KEYSTORE_KEY_PASSWORD}",
      "packageType": "bundle"
    }
  },
  "ios": {
    "release": {
      "codeSignIdentity": "Apple Distribution",
      "developmentTeam": "ABCDE12345",
      "packageType": "app-store",
      "provisioningProfile": "com.example.app AppStore",
      "automaticProvisioning": false
    }
  }
}

Das ${...} Ersatzzeichen werden nicht durch Cordova erweitert. Der Workflow unten schreibt die echten Werte mit envsubst.

Wenn Sie noch keinen Android-Keystore haben, erstellen Sie einen mit keytool oder der browserbasierten Android-Keystore-Generator. Für iOS erstellt der iOS-Zertifikatsgenerator eine Zertifikatsanforderung und .p12 ohne einen Mac.

Schritt 3: Ein GitHub Actions-Workflow

Dieses Workflow baut beide Plattformen parallel auf einer Versionsnummer auf und lädt sie in die internen Testtracks hoch.

# .github/workflows/cordova-release.yml
name: Cordova release

on:
  push:
    tags: ['v*']

jobs:
  android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: oven-sh/setup-bun@v2
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'
      - run: bun install --frozen-lockfile
      - run: bun run build            # outputs to www/
      - run: bunx cordova prepare android
      - name: Signing files
        env:
          KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
          KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
          KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
        run: |
          echo "$KEYSTORE_BASE64" | base64 --decode > release.jks
          envsubst < build.template.json > build.json
      - run: bunx cordova build android --release --buildConfig=build.json
      - uses: r0adkll/upload-google-play@v1
        with:
          serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
          packageName: com.example.app
          releaseFiles: platforms/android/app/build/outputs/bundle/release/app-release.aab
          track: internal
          status: completed

  ios:
    runs-on: macos-26
    steps:
      - uses: actions/checkout@v6
      - uses: oven-sh/setup-bun@v2
      - run: bun install --frozen-lockfile
      - run: bun run build
      - run: bunx cordova prepare ios
      - name: Install certificate and profile
        env:
          P12_BASE64: ${{ secrets.IOS_P12_BASE64 }}
          P12_PASSWORD: ${{ secrets.IOS_P12_PASSWORD }}
          PROFILE_BASE64: ${{ secrets.IOS_PROFILE_BASE64 }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          echo "$P12_BASE64" | base64 --decode > dist.p12
          security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
          security set-keychain-settings -lut 21600 build.keychain
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
          security import dist.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
          security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
          security list-keychains -d user -s build.keychain login.keychain
          for dir in "$HOME/Library/MobileDevice/Provisioning Profiles" \
                     "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"; do
            mkdir -p "$dir"
            echo "$PROFILE_BASE64" | base64 --decode > "$dir/app.mobileprovision"
          done
          cp build.template.json build.json   # iOS values hold no secrets
      - run: bunx cordova build ios --release --device --buildConfig=build.json
      - name: Upload to TestFlight
        env:
          API_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
          API_ISSUER: ${{ secrets.APPLE_ISSUER_ID }}
          API_KEY_BASE64: ${{ secrets.APPLE_KEY_CONTENT }}
        run: |
          mkdir -p ~/.appstoreconnect/private_keys
          echo "$API_KEY_BASE64" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
          IPA=$(find platforms/ios/build -name '*.ipa' | head -n 1)
          xcrun altool --upload-app -f "$IPA" -t ios --apiKey "$API_KEY_ID" --apiIssuer "$API_ISSUER"
      - name: Clean up keychain
        if: always()
        run: security delete-keychain build.keychain || true

Warum einige Zeilen da sind:

  • Zwei Provisionierungsprofil-Ordner. Xcode 16 und später liest Profile aus ~/Library/Developer/Xcode/UserData/Provisioning ProfilesÄltere Xcode verwendeten ~/Library/MobileDevice/Provisioning ProfilesBeides schreibt, um „Keine Profile für ‘com.example.app’ gefunden“ zu vermeiden.
  • set-key-partition-list Stoppt macOS von der Anforderung von Zugriff auf den Schlüsselkette, was einen CI-Auftrag blockieren würde.
  • JDK-Version. Verwenden Sie die JDK-Version, die in Ihren cordova-android Veröffentlichungsunterlagen angegeben ist. Neuere Versionen bauen mit JDK 17.
  • Build-Zahlen. Erhöhen android-versionCode und ios-CFBundleVersion in config.xml vor der Veröffentlichung, zum Beispiel aus der CI-Auftragsnummer oder wenn die Stores die Uploadung als Duplikat ablehnen.

Sie können die altool Upload für fastlanes upload_to_testflight und die Play-Aktion für fastlanes supply wenn Ihr Team bereits fastlane verwendet.

Schritt 4: Die gleiche Pipeline auf anderen CI-Diensten

Die Befehle ändern sich nicht zwischen CIs. Nur die Runner-Auswahl und die Geheimnis-Syntax.

CI Android-Runner iOS-Runner Hinweise
GitHub Aktionen ubuntu-latest macos-26 / macos-latest macOS-Minuten sind teurer als Linux auf privaten Repositories
GitLab CI jeder Linux-Runner gehostete macOS-Runner (Beta, Premium und Ultimate) oder selbst gehostet Bilder wie macos-26-xcode-26
Bitbucket Pipelines Linux-Docker-Bild nur selbst gehostet auf Mac siehe Bitbucket iOS-Leitfaden
Gitea / Forgejo Linux-Runner eigenes gehostetes Mac in Host-Modus siehe Gitea iOS-Leitfaden
Bitrise Linux-Stacks macOS-Stacks versendet Cordova-Schritte (Vorbereitung, Archivierung)
Codemagic Linux Mac mini-Instanzen Dokumente von Ionic Cordova Builds codemagic.yaml
Azure DevOps ubuntu-latest macOS-latest Aufgaben zum Installieren von Zertifikaten und Profilen

Für eine features-basierte Ansicht lesen Sie Vergleich von CI/CD-Plattformen für Cordova-Anwendungen.

Schritt 5: Live-Updates für Cordova

Live-Updates ermöglichen Ihnen, HTML-, CSS- und JavaScript-Fixes ohne eine App-Store-Überprüfung zu liefern. App Center CodePush endete im März 2025, Appflow Live Updates enden am 31. Dezember 2027 und die alten Community-Hot code-Push-Plugins sind nicht mehr unterstützt. Eine unterstützte Option ist Capgo-Live-Updates mit dem @capgo/cordova-updater Plugin, das denselben Backend, Kanälen und CLI wie der Capacitor-Updater verwendet.

Anforderungen

  • Cordova CLI 12+
  • cordova-android 13+ und/oder cordova-ios 7+ (der Plugin hängt von ihren Standard https://localhost/ und app://localhost/ und
  • Schemata cordova-plugin-ionic-webview mit ihm. Der Ionic WebView umgeht die Scheme-Handler von Cordova, daher würden heruntergeladene Bundles nicht geladen werden.

Installieren Sie das Plugin

Erstellen Sie die App in Capgo auf die gleiche Weise wie für Capacitor, dann installieren Sie das Plugin mit Ihrem Capgo App-Id.

cordova plugin add @capgo/cordova-updater \
  --variable APP_ID=com.example.app \
  --variable DEFAULT_CHANNEL=production
cordova prepare android ios

DEFAULT_CHANNEL, UPDATE_URL, and AUTO_UPDATE sind optional installierbare Variablen. Ausführen cordova prepare sind optional installierbare Variablen. Führen Sie

wiederholt, sobald Sie sie ändern.

After deviceready, das Plugin ist verfügbar als cordova.plugins.Updater. Ruf notifyAppReady() auf jedem Start, oder das Plugin behandelt das neue Bundle als defekt und rollt zurück:

document.addEventListener('deviceready', async () => {
  const { Updater } = cordova.plugins

  await Updater.notifyAppReady()

  const latest = await Updater.getLatest()
  if (latest.url && !latest.error) {
    const bundle = await Updater.download({
      url: latest.url,
      version: latest.version,
      checksum: latest.checksum,
    })
    await Updater.next({ id: bundle.id })
  }
})

Hochladen von Bundles aus CI

Hinzufügen einer Aufgabe, die das Weblayer baut und hochlädt, für Web-only-Änderungen:

  live-update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: oven-sh/setup-bun@v2
      - run: bun install --frozen-lockfile
      - run: bun run build
      - run: bunx @capgo/cli@latest bundle upload --channel=production
        env:
          CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}

Live-Updates ersetzen nur das Web-Bundle. Hinzufügen, Entfernen oder Upgraden eines Cordova-Plugins benötigt immer noch eine neue Store-Build. Capgo vergleicht die native Plugins, die für das Live-Bundle aufgezeichnet wurden, mit Ihrem Projekt und markiert inkompatible Uploads; siehe live update-Kompatibilität. Vollständige Konfiguration ist in den Dokumentationen zum Cordova-Updater.

Auf der Build-Seite ist der Capgo Build Dokumentation deckt nur Capacitor-Projekte ab (sie lädt das native Projekt hoch, das von} cap syncCordova-Binaries bauen weiterhin auf Ihrem CI wie oben gezeigt.

Optional: Migration zu Capacitor später

Sie müssen nicht Cordova verlassen, um eine funktionierende Pipeline und Live-Updates zu erhalten. Die Migration ist eine separate Entscheidung, die sich lohnt, wenn:

  • Sie iOS-Builds ohne die Verwaltung von macOS-Runnern wollen. Capgo Build kompiliert Capacitor-Apps aus einem Linux-CI-Auftrag.
  • Die Plugins, auf die Sie angewiesen sind, erhalten keine Cordova-Updates mehr, aber haben Capacitor-Äquivalente.
  • Sie Swift Package Manager-Unterstützung und aktuelle Android Gradle Plugin-Versionen ohne Plattform-Patching wollen.

Die Migration hält www code. You add Capacitor, move plugins over (most Cordova plugins work as is), and replace a few that have Capacitor-native equivalents. Your Capgo app ID and channels stay the same; only the updater plugin changes from @capgo/cordova-updater to @capgo/capacitor-updaterMigration von Cordova zu __CAPGO_KEEP_0__ Live-Updates von Capacitor zu Capacitor, und das Cordova zu Lösung für Capacitor beschreibt die Unterstützung bei der Migration. Nach der Migration reduziert sich die CI oben auf eine Web-Ausgabe, cap sync, und eine build request Aufruf pro Plattform, wie in Vergleich von CI/CD-Plattformen für Capacitor-Anwendungen.

Troubleshooting von Cordova-Builds in CI

Fehler Ursache und Lösung
Current working directory is not a Cordova-based project config.xml oder www/ fehlen. Führen Sie Ihre Web-Build-Ausführung vor Cordova-Befehlen aus, oder erstellen Sie einen leeren www/.
No platforms added to this project oder (Appflow-Plugins oder) package.json. Ausführen cordova platform add lokal einmal und committieren package.json.
Could not find an installed version of Gradle Neueste cordova-android Verwendet den Gradle Wrapper. Aktualisieren Sie die Plattform anstatt Gradle global zu installieren.
Unsupported class file major version JDK auf dem Runner entspricht nicht dem auf der Seite cordova-android erwartet. Pin es mit setup-java.
No signing certificate "iOS Distribution" found Use Apple Distribution enthält den privaten Schlüssel. .p12 enthält den privaten Schlüssel.
errSecInternalComponent Geschlossener Schlüsselkette oder fehlende Partitionenliste. Die Schlüsselkette-Einstellungen erneut ausführen.
Upload abgelehnt: SDK ist zu alt Runner-Bild verwendet Xcode älter als 26. Wählen Sie macos-26 oder Xcode mit xcode-select.
Play hochladen: Version code has already been used Bump android-versionCode für jeden Upload.

Zusammenfassung

Eine Cordova-Pipeline im Jahr 2026 ist ein CI-Job pro Plattform: ein Linux-Runner für das Android AAB, ein macOS-Runner mit Xcode 26 für das IPA, geheime Codes in eine generierte build.json, und API-Schlüssel für beide Stores. Jeder Mainstream-CI kann ihn ausführen. Fügen Sie @capgo/cordova-updater und einen bundle upload Job für Web-only-Fixes hinzu, und Sie haben die Build-, Store- und Over-the-Air-Punkte, die Appflow und App Center früher bereitgestellt haben. Die Umstellung auf Capacitor bleibt eine Option für später, kein Erfordernis.

Live-Updates für Capacitor-Apps

Wenn ein Web-Schicht-Bug live ist, liefern Sie die Reparatur über Capgo anstatt Tage für die Genehmigung im App-Store abzuwarten. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Prozess bleiben.

Neueste aus unserem Blog

Capgo bietet Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle mobile App zu erstellen.