← Zurück zum Tagebuch

Fastlane Dual-Cloud-Mac: Die 3 häufigsten Fehler nach Build/Upload-Split

Runbook · 2026.06.04 · ~8 Min. · für den Bereitschafts-Runbook

Zwei Cloud-Macs: Hongkong archive, Kanada Fastlane-Upload

Sie sind im Dienst und nutzen mindestens zwei gemietete Cloud-Macs mit Fastlane für iOS-Releases — und sehen grüne Build-Logs, aber keinen neuen TestFlight-Build (oder das falsche Paket). Noch unentschieden wegen Cloud oder zweitem Mac? Zuerst TestFlight-Dedicated-Runner oder Xcode-Builds in die Cloud — hier gilt: ein Mac baut, einer lädt hoch.

Nach dem Lesen sollten Sie zwei Dinge können: ① aus Logs erkennen, ob Zertifikat, Artefakt oder Netzwerk das Problem ist; ② prüfen, ob die Rollen der beiden Macs stimmen und ob mehr Hardware wirklich hilft.

Begriffe (werden unten wiederholt)
  • Build-Maschine: kompiliert in Xcode und exportiert nur das Installationspaket (.ipa)
  • Upload-Maschine: signiert mit dem Release-Zertifikat und lädt die .ipa zu TestFlight hoch; die in App Store Connect eingetragene Ausgangs-IP gilt nur für diesen Host
  • Archive / Build: Xcode-Ausgabe für Distribution; zwischen Rechenzentren nur fertige .ipa, kein Projekt-Cache-Ordner
  • match: Fastlane-Tool für Release-Zertifikate — nur auf einem Host

Überspringen, wenn: Sie nur einen Mac haben oder TestFlight stabil läuft und Sie noch nicht in „Build + Upload“ getrennt haben. Bei mehreren Cloud-Macs und Pipeline-Problemen: weiterlesen.

TL;DR (30 Sekunden)
Nach dem Dual-Cloud-Mac-Split liegt der Engpass selten bei der CPU, sondern bei drei Fastlane-Grenzfehlern:
  1. Zertifikatsgrenze — Release-Zertifikat wurde auf die Build-Maschine synchronisiert, Upload-Maschine kann nicht signieren (kritisch)
  2. Artefaktgrenze — .xcarchive wird zwischen Rechenzentren verschoben statt einer prüfbaren .ipa (am leichtesten zu übersehen)
  3. Netzwerk-Identitätsdrift — ASC-Whitelist zeigt noch die alte IPv4 des Upload-Hosts (am mühsamsten zu debuggen)
Unten: ein 30-Sekunden-Diagnosebaum, dann die drei Fehlermuster im Detail; am Ende Abnahmetabelle, vier CI-Stufen und ein „Endurteil“-Block, mit dem ihr auch ohne Volltext entscheiden könnt. Tabellen und Code-Blöcke dienen der Referenz — die Entscheidungslogik steht in den Fließtext-Absätzen.

Kontext (1 Minute): Nach dem Zweit-Mac knallt meist die Grenze, nicht die Leistung

Viele Teams mieten zwei Cloud-Macs: einer nahe Asien kompiliert tagsüber, einer in Kanada liefert an Apple (TestFlight / App Store). Der zweite Mac soll Zeit sparen — aber im Dienst kosten beide Maschinen, die Zertifikate und Dateien anfassen, am meisten Zeit: Build grün, TestFlight ohne neue Version.

Zuerst die typische Fehlaufteilung (Modell B), dann unser Schnitt (Modell A) und die Verifikation.

Empfohlen: Modell A (Build nur Paket, Upload nur Veröffentlichung)

Kurz: Die Build-Maschine liefert nur .ipa; die Upload-Maschine besitzt Zertifikate und TestFlight. match nicht auf beiden — der Private Key landet auf dem falschen Host.

Dual cloud Mac roles (Model A)
Rolle Build-Maschine (Hongkong) Example: APAC daytime builds Upload-Maschine (Kanada) Fixed IP for Apple
AufgabeCode ziehen → Xcode-Build → .ipa exportieren.ipa empfangen → Release-Signatur → TestFlight
NichtKein match, kein TestFlight-UploadKein vollständiger Projekt-Build
ÜbergabeInstallationspaket + RUN_IDKeine (Ziel: App Store Connect)

Beide Runner laufen auf dedizierten Hashvps-Mac-minis — primär wegen fester IP + Rollenisolation (Upload-IP in ASC, Build-IP nicht). Hongkong-Spezifikationen: Mac-mini-Miete Hongkong. Vor dem horizontalen Skalieren von Build-Runnern zuerst die Upload-Identität in ASC absichern.

Build · kein match Upload · alleinige Signatur build → export .ipa no certs · no upload includes build ID certs + TestFlight upload fixed public IP registered in ASC .ipa → Minimale Einheit zwischen Rechenzentren: signaturprüfbare IPA, kein xcarchive
Modell A: Signatur und match nur auf dem Upload-Runner; Build liefert IPA

Beide Runner laufen auf dedizierten Hashvps-Mac-minis — primär wegen fester IP + Rollenisolation (Upload-IP in ASC, Build-IP nicht). Hongkong-Spezifikationen: Mac-mini-Miete Hongkong. Vor dem horizontalen Skalieren von Build-Runnern zuerst die Upload-Identität in ASC absichern.

Häufiger Fehler: Modell B (beide „helfen mit“)

Modell B heißt: Rollen nie getrennt — so lief es bei uns in Woche eins. Es sieht nach Aufteilung aus, ist aber:

  • Beide führen match aus → Release-Private-Key bleibt auf der Build-Maschine → Upload kann nicht signieren → TestFlight scheitert dauernd
  • Build rsynct .xcarchive direkt → Upload exportiert erneut, anderer SHA als auf dem Build-Host → falsches Artefakt, Invalid Binary
  • Beide Hosts export_ipa → zwei driftende ExportOptions.plistUpload OK, Build nicht promotable

Trifft eine Zeile auf euren Workflow zu, hilft kein dritter Mac — ihr braucht den Build-/Upload-Role-Split (Modell A), nicht mehr Runner-Kapazität.

Observability: gleicher Build auf Build- und Upload-Seite nachweisen

Der häufigste Vorfall: „IPA von gestern hochgeladen“. Dieselben Felder in Build- und Upload-Logs:

  • RUN_ID (Pipeline-Lauf, z. B. hk-build-88421)
  • GIT_SHA (kurzer Commit-Hash)
  • Artefaktpfad + SHA256 (in build/manifest.json)
Build erfolgreich · Upload erfolgreich (gleiche RUN_ID)
# Hongkong · build · build
[15:11:42]: Successfully exported: ./build/MyApp-20260604-1502.ipa
[15:11:42]: RUN_ID=hk-build-88421  GIT_SHA=a3f91c2  SHA256=9f2a…

# Kanada · upload · upload
[02:22:01]: RUN_ID=hk-build-88421  GIT_SHA=a3f91c2  ipa_sha256=9f2a…
[02:24:18]: Successfully uploaded package to App Store Connect

Dienstregel: Fehlt im Upload-Log dieselbe RUN_ID, zuerst Artefaktfehler behandeln — nicht ASC oder Apple-Statusseiten.

30-Sekunden-Triage: kein neuer TestFlight-Build?

Nicht sofort das vollständige Log durchscrollen. Eine Ebene im Baum reicht, um das Kapitel zu finden (für Runbooks bookmarken):

Dienst-Triage-Baum (ins Runbook kopieren)
Kein neuer TestFlight-Build?
 ├─ Upload RUN_ID ≠ Build RUN_ID (oder manifest fehlt)
 │     → Fallstrick 2 · Artefaktgrenze
 ├─ Logs: match / AppStoreDistribution / code signing identity
 │     → Fallstrick 1 · Zertifikatsgrenze
 └─ Upload „erfolgreich“, ASC leer / 403 / Invalid Binary (Build alles grün)
       → Fallstrick 3 · Netzwerk-Identitätsdrift
Drei Fehlermuster · Kurzreferenz (Dienst)
Muster Log-Schlüsselwörter (grep) Release-Auswirkung
Fall 1 Zertifikat AppStoreDistribution, No matching provisioning, match failed Blocker: TestFlight / Store-Upload gestoppt
Fall 2 Artefakt RUN_ID mismatch, Invalid Binary, export_method-Konflikt Hoch: falscher Build oder kein Promote
Fall 3 Identität 403, Upload OK ohne processing, ASC-Netzwerklimits Intermittierend: wirkt wie „Zufall“

Drei Fehlermuster (ausführlich)

Fall 1: Zertifikatsgrenze falsch

30 Sekunden: Build-Archive grün; Upload rot, Fehler bei match / Signing.

Log: AppStoreDistribution, Could not find a matching code signing identity, No matching provisioning profiles.

Release: Blocker — TestFlight und App Store bis der Privatkey wieder nur auf dem Upload-Host liegt.

Symptom: Archiv auf dem Build-Runner erfolgreich, Upload-Lane scheitert; TestFlight ohne neuen Build.

Typisches Log
Could not find a matching code signing identity for type 'AppStoreDistribution'
❌  Lane upload failed

Ursache: Modell B — Build-Runner führt noch match(appstore) aus, Distribution-Key nicht auf Upload.

Fix: Alle match-Aufrufe vom Build-Runner entfernen; Upload exklusiv (Rotate nur dort, eigenes Wartungsfenster). Siehe match readonly.

Fall 2: Artefaktgrenze falsch

30 Sekunden: RUN_ID und ipa_sha256 in Build- vs. Upload-Log vergleichen; oder ASC meldet Invalid Binary ohne Signing-Fehler auf dem Build-Host.

Log: RUN_ID ungleich, Invalid Binary, doppeltes export_ipa / ExportOptions auf zwei Hosts.

Release: hoch — alter Commit, falscher Build oder hängendes Processing; Pipeline kann noch grün wirken.

Ursache: .xcarchive zwischen RZ verschoben oder doppelt exportiert. Minimale Einheit zwischen RZ: IPA mit SHA, kein Archivordner.

Fix: Einmal export_ipa + manifest.json auf dem Build-Host; Upload nur noch upload_to_testflight, kein zweites Export.

Fall 3: Netzwerk-Identitätsdrift

30 Sekunden: Fastlane meldet Upload-Erfolg; Signing auf beiden Hosts grün; TestFlight leer oder ASC 403.

Log: 403, Successfully uploaded ohne neuen Build, ASC-Netzwerkablehnung trotz grüner Build-Logs.

Release: intermittierend — mal geht’s, mal nicht; frisst Dienstzeit.

Ursache: Upload-IPv4 ≠ Eintrag in der ASC-Whitelist (dritte, leise Fehlerklasse).

Fix: Täglich auf dem Upload-Host curl -4 ifconfig.me gegen ASC abgleichen; bei Drift Whitelist + Alert. Build-IPv4 gehört nicht in die ASC-Liste — sonst maskiert ein falscher Eintrag echte Upload-Drift.

So erkennt ihr, dass der Split wirklich sitzt

Checkliste statt verstreuter FAQ — eine Woche nach dem Rollout sollte jede Zeile ohne Diskussion „ja“ sein:

Abnahme Dual-Mac (Modell A)
Prüfpunkt Erwartung
RUN_ID ausgerichtetIn Build-Export- und Upload-Logs identisch: RUN_ID, GIT_SHA, ipa_sha256
Build ohne DistributionAuf dem Build-Host in Keychain/Logs nie AppStoreDistribution oder match-Step
Upload nur DistributionUpload-Lane: nur match (oder resign) + upload_to_testflight, kein ARCHIVE SUCCEEDED
ArtefaktformZwischen RZ nur .ipa + manifest (< 200 MB); kein .xcarchive-rsync
ASC-IdentitätAktuelle Upload-IPv4 = ASC-Whitelist; Build-IP nicht in ASC
Runner-IsolationLabels role=ios-build-hk und role=ios-upload-ca, Workflow-needs-Kette

Upgrade-Einordnung: in welcher Stufe seid ihr?

Incident-Fix beantwortet „heute Nacht“; die Stufe beantwortet „nächste Woche Architektur ändern?“. Vier Stufen — halten, korrigieren oder Role-Split erzwingen. Viele Teams springen von Stufe 1 direkt zu zwei Macs ohne Labels und landen in Stufe 2; dieser Text ist die Brücke zu Stufe 3 mit messbarer Abnahme statt Bauchgefühl.

Stufe 1: Ein Mac, eine Fastlane

Merkmal: ein Runner; match, build, upload in einem Fastfile und einer Keychain. Zuerst Disk, Derived Data und GitHub-Actions-Abrechnung optimieren, dann erst einen zweiten Build-Knoten erwägen.

Fazit: kein Dual-Mac nötig. Nur APAC-Build langsam → Build-Knoten hinzufügen, Upload nicht vorziehen splitten.

Stufe 2: Zwei Macs, kein Role-Split (Modell B)

Merkmal: zwei oder mehr Runner; mehrere führen match / export / upload aus; Logs zeigen die drei Grenzfehler dieses Artikels. Oft entsteht das aus dem Wunsch, „jeder Mac soll etwas können“ — genau das erzeugt Zertifikats- und Artefakt-Drift, die in Stufe 3 mit klaren Labels und needs-Ketten verschwindet.

Fazit:Ein dritter Mac löst nichts, erhöht nur Zertifikats- und Artefakt-Drift. Nächster Schritt: Modell A, nicht mehr Runner.

Stufe 3: Role-Split (Modell A · Ziel dieses Textes)

Merkmal: Build/Upload getrennt; zwischen RZ nur IPA mit RUN_ID; match nur auf Upload; feste Upload-IP. In dieser Stufe lohnt Monitoring auf Drift der Upload-IPv4 und wöchentliche Stichproben der Abnahmetabelle — nicht nur Reaktion bei rotem TestFlight.

Fazit: ✔ Abnahmetabelle stabil grün → horizontal Build-Runner skalieren oder Upload-Host härten. Feste IPs und Knoten: Hashvps-Angebote (zuerst ASC-IP für Upload, dann Build erweitern).

Stufe 4: Mehrere Upload-Regionen (fortgeschritten)

Merkmal: Upload in US/EU/APAC; ASC-Keys und IP-Policy pro Region; Promotion und Compliance als eigene Linie.

Fazit: Distributionsplattform, nicht „noch ein CI-Mac“ — Artefaktregistry, Policy, Audit; außerhalb dieses Runbooks.

Stufe → Aktion (Entscheidung)
Stufe Jetzt sinnvoll
Stage 1Einzel-Mac halten; Build-/Upload-Fenster tunen
Stage 2Keine weiteren Macs; Modell A + Abnahmetabelle
Stage 3Build horizontal; Upload-Monitoring festziehen
Stage 4Eigenes Projekt: Multi-Region, nicht Fastlane-Patch
Upgrade-Trigger (Problem bereits da)
Wenn eure CI schon „TestFlight sporadisch leer + mehrere Mac-Runner + match auf mehreren Knoten“ zeigt, seid ihr in der Role-Split-Pflicht, nicht in der „noch einen Runner kaufen“-Phase. Wer bei Stufe 2 hängen bleibt: Diagnosebaum und Modell-B-Lanes anpassen — keinen dritten Mac vor dem Split. Dokumentiert die Abnahmetabelle im Ticket; erst wenn alle sechs Zeilen grün sind, lohnt sich ein zusätzlicher Build-Runner in Hongkong.

Endurteil (nur dieser Block reicht zum Handeln)

Wenn alle drei Punkte zutreffen, entscheidet hier — ohne den Rest noch einmal zu lesen:

  • Mindestens 2 Mac-Runner (oder äquivalente Multi-Node-CI)
  • Fastlane-Kette mit instabilem TestFlight (match failed, Processing hängt, sporadisch kein Build)
  • match lief bereits auf mehr als einem Host

👉 Keine weiteren Maschinen kaufen.

👉 Drei Schritte (heute startbar):

  1. Stoppen: match / sync_code_signing auf allen Nicht-Upload-Knoten (Signatur nur Upload)
  2. Erzwingen: zwischen RZ nur .ipa + manifest.json (kein .xcarchive-rsync)
  3. Vereinheitlichen: RUN_ID + GIT_SHA + ipa_sha256 vor Upload prüfen

Wenn das nicht geht: ihr seid in Stufe 2 (Modell B). Mehr Hardware vergrößert den Ausfall, behebt ihn nicht. Fastfile und Workflow-Labels zuerst, Abnahmetabelle grün, dann Build-Kapazität. Plant ein Wartungsfenster nur für den Upload-Host, wenn match rotiert werden muss — nie parallel auf dem Build-Runner.

Upload-Fastfile (Modell A · Auszug)
lane :upload_only do |options|
  verify_run_id!(options) # manifest.json
  match(type: "appstore", readonly: true)
  upload_to_testflight(ipa: options[:ipa_path], api_key_path: "asc_api_key.json")
end
Änderungsdisziplin
In der Split-Woche kein match-Rotate. Zertifikatswechsel = separates Ereignis: beide Lanes stoppen, Rotate nur auf dem Upload-Host.

Kurz gefragt, kurz beantwortet

Kann der Build-Runner ohne Distribution archivieren? Projektabhängig; wir exportieren auf dem Build-Host eine IPA für die finale App-Store-Signatur auf dem Upload-Host (oder Build nur Compile-Check, Upload resign). Entscheidend: match nur auf einem Host. Verteilt signing auf zwei Keychains ohne klare Rolle — das ist Modell B in Verkleidung.

match läuft bald ab? Rotate nur auf dem Upload-Host im Nicht-readonly-Fenster; Build-Runner bis Profile stabil pausieren.

Unterschied zum Reise-Runbook? Reise-Text = WLAN vor Ort; dieser Text = Rechenzentrum-Rollen und Fastlane-Grenzen — Abnahmetabelle 1:1 übernehmbar.

Serie: ① Runbook: Dual-Cloud-Mac + Fastlane (TestFlight leer / match failed / Multi-Mac-iOS-CI). Folge: ② Build·Sign·Distribute, ③ Modell-B-Anti-Muster; Einstieg TestFlight-Setup. Bookmarkt den 30-Sekunden-Baum für die nächste Nachtschicht.

Weiterlesen

Rollen und Knoten: Hongkong und Preise. Upload-Mac-Bedarf: TestFlight-Artikel.

Hashvps

Stufe 2? Erst Role-Split, dann mehr Macs

Feste Upload-IPv4 für ASC; Build-Runner in APAC skalieren.

Pläne ansehen
Sonderangebot