Startseite / Blog / GitLab CI iOS-Build: Remote-Mac-Anleitung 2026
ENGINEERING_BLOG · 2026.08.31

GitLab CI iOS-Build: Remote-Mac-Anleitung 2026

Linux Runner: Der Build läuft durch, aber der iOS-Job findet kein Xcode.
Schnellste Lösung: Verwenden Sie einen dedizierten macOS-Runner mit Benutzer-Sitzung und Shell Executor, fixieren Sie die Xcode-Toolchain, trennen Sie Signaturgeheimnisse und akzeptieren Sie einen produktiven iOS-Build erst nach echtem Archive-, TestFlight- und Neustarttest.

Diese Anleitung ist für Sie gedacht, wenn Ihr GitLab Runner bisher Android- oder Backend-Aufgaben übernimmt und iOS-Builds daran scheitern. Sie richtet sich außerdem an unabhängige Entwickler, die manuelle Xcode-Archive automatisieren möchten, sowie an kleine Teams, die einen dauerhaft verfügbaren Remote Mac als Veröffentlichungsumgebung prüfen.

SECTION 01Die sechs Bedingungen für einen produktionsfähigen GitLab-CI-iOS-Build

Ein erfolgreicher Pipeline-Lauf ist noch kein Beweis für eine belastbare Veröffentlichungsumgebung. Bei GitLab CI iOS-Builds müssen Sie mindestens sechs voneinander getrennte Bedingungen abnehmen:

  1. Der richtige macOS-Benutzer ist angemeldet und der Runner nimmt Jobs an.
  2. Xcode, SDK, Abhängigkeiten und Shell-Umgebung zeigen auf eine definierte Toolchain.
  3. Tags und geschützte Branches verhindern, dass ein falscher Job auf dem Veröffentlichungsrechner landet.
  4. Zertifikate, private Schlüssel, Provisioning Profile und API-Schlüssel besitzen nur die erforderlichen Rechte.
  5. Cache, Artifacts, Archive und Testergebnisse werden nach ihrem Zweck getrennt behandelt.
  6. Ein echtes Archive, der Upload zu App Store Connect und ein Neustarttest funktionieren gemeinsam.

Diese Reihenfolge ist keine Installationsanleitung. Sie ist eine Abnahmelogik: Wenn Bedingung eins nicht erfüllt ist, lohnt die Fehlersuche an Signatur oder Export noch nicht. Wenn Bedingung sechs fehlt, ist die Pipeline für einen Release-Prozess nicht freigegeben.

Ein macOS-Runner ist erforderlich, weil die iOS-Buildkette auf Xcode und Apple SDKs basiert. Ein Linux Runner kann Quellcode analysieren, Backend-Komponenten bauen oder Android-Aufgaben übernehmen, aber kein echtes Xcode-Archive erzeugen. GitLab dokumentiert für macOS den Betrieb als Benutzerprozess über einen LaunchAgent; der empfohlene Shell Executor führt die Befehle direkt auf dem Host aus. Das ermöglicht den Zugriff auf die Benutzer-Keychain, bedeutet aber auch eine begrenzte Isolation. GitLabs Dokumentation zum macOS Runner und zum Shell Executor beschreiben diese Grenzen.

Fallbeispiel: Der grüne Android-Job führt in die falsche Richtung

Sie sehen in GitLab einen erfolgreichen Pipeline-Lauf. Der Android-Job kompiliert, die Tests laufen, und nur der iOS-Job endet mit einer Meldung wie „Xcode not found“. Das ist kein fehlender YAML-Schalter im bestehenden Linux Runner. Der Job wurde auf eine Plattform geroutet, auf der die benötigte Toolchain nicht vorhanden sein kann.

Die korrekte Reaktion ist ein eigener macOS-Runner, nicht die Freigabe eines beliebigen Shell-Runners für alle Projekte. Ein separater Benutzer, ein eigener Arbeitsbereich und kontrollierte Tags bilden die technische Grenze zwischen gewöhnlichen Buildaufgaben und dem Veröffentlichungsweg.

Achtung: Eine automatische Anmeldung kann den Neustart eines Rechners vereinfachen, ist aber keine vollständige Sicherheitsarchitektur. Prüfen Sie zusätzlich, welche Dienste starten, welche Benutzerrechte bestehen und ob der Host ausschließlich für vertrauenswürdige Veröffentlichungsjobs eingesetzt wird.

SECTION 02Erste Prüfung: Benutzer-Sitzung und Runner-Verfügbarkeit

Der Runner-Service und die grafische Benutzer-Sitzung sind zwei unterschiedliche Dinge. Der Service kann registriert sein, während der vorgesehene Benutzer nicht angemeldet ist oder der LaunchAgent nicht geladen wurde. Umgekehrt kann eine Sitzung aktiv sein, während der Runner im GitLab-Projekt offline erscheint.

Prüfen Sie diese Beziehung in einer festen Reihenfolge:

  1. Melden Sie sich mit dem dedizierten CI-Benutzer am Remote Mac an.
  2. Prüfen Sie, ob der macOS-Runner als Benutzerprozess beziehungsweise LaunchAgent gestartet wurde.
  3. Kontrollieren Sie im GitLab-Projekt, ob der Runner online ist und Jobs annimmt.
  4. Starten Sie einen ungefährlichen Diagnosejob mit dem vorgesehenen Tag.
  5. Lassen Sie diesen Job den effektiven Benutzer, das Arbeitsverzeichnis und die Xcode-Auswahl ausgeben.
  6. Beenden Sie die Sitzung kontrolliert und prüfen Sie, ob das Verhalten Ihren Sicherheitsvorgaben entspricht.

Der Diagnosejob darf keine geheimen Variablen, Schlüsselbunddaten oder vollständigen Umgebungswerte ausgeben. Besonders bei Shell Executor müssen Sie davon ausgehen, dass ein Job auf dem Host mit den Rechten des Runner-Benutzers läuft. GitLab beschreibt die eingeschränkte Isolation des Shell Executors; behandeln Sie den Veröffentlichungsrechner deshalb nicht wie einen beliebigen gemeinsam genutzten Buildserver.

Prüfpunkte Bestanden Nicht bestanden: Rückfall
Benutzer-Sitzung aktiv Runner startet im vorgesehenen Kontext Sitzung und LaunchAgent prüfen
Runner online und mit Tag verfügbar Diagnosejob wird angenommen Registrierung, Tag und Projektzuordnung prüfen
Keychain im Benutzerkontext erreichbar Signaturtest kann beginnen Konto, Sitzung und Keychain-Sperre prüfen
Host nur für vertrauenswürdige Jobs Veröffentlichung darf weitergehen Runner aus ungeschützten Jobs entfernen

Zweite Prüfung: Xcode und Abhängigkeiten reproduzierbar halten

Installierte Xcode-Apps allein beweisen nicht, welches Entwicklerverzeichnis ein Job verwendet. Sie müssen den tatsächlich aufgerufenen Pfad, die SDK-Auswahl und die Kommandozeilenkomponenten aus dem CI-Kontext prüfen. Verwenden Sie dafür in einem isolierten Testprojekt ausschließlich bereinigte Ausgaben, etwa den Pfad des aktiven Entwicklerverzeichnisses und die Toolchain-Version, ohne vollständige Umgebungsvariablen zu protokollieren.

Die Baseline sollte gemeinsam festlegen:

  • aktives Xcode-Entwicklerverzeichnis;
  • verwendetes iOS SDK;
  • installierte Kommandozeilenkomponenten;
  • Abhängigkeitsmanager und Lockfile;
  • Shell-Pfad und relevante Buildvariablen;
  • Workspace, Scheme und Konfiguration für den Release-Build.

Entscheidend ist nicht die Aussage „Xcode ist installiert“, sondern die Beweiskette für denselben Commit. Lassen Sie denselben unveränderten Commit nacheinander Abhängigkeiten auflösen, kompilieren, testen und archivieren. Dokumentieren Sie die Ergebnisse getrennt:

  • Eine erfolgreiche Abhängigkeitsauflösung sagt nur, dass Quellen und Lockfile zusammenpassen.
  • Ein erfolgreicher Compile sagt, dass der Code für die gewählte Konfiguration gebaut wurde.
  • Ein erfolgreiches Archive sagt, dass die Release-Struktur für Export und Signierung erzeugt werden konnte.

Apple beschreibt den Xcode-Ablauf für Archive und Distribution. Die Dokumentation ersetzt jedoch nicht Ihre konkrete Baseline. Wenn mehrere Xcode-Versionen auf dem Host liegen, muss die Pipeline explizit das gewünschte Entwicklerverzeichnis setzen und anschließend kontrollieren, dass genau dieses Verzeichnis verwendet wird.

Erfahrung aus der Fehlersuche: Ein Build, der nach einer manuellen Sitzung funktioniert, kann in CI trotzdem scheitern, wenn PATH, Keychain-Zustand oder das aktive Entwicklerverzeichnis nur in der interaktiven Shell gesetzt wurden. Die Pipeline muss ihre benötigte Umgebung selbst reproduzierbar herstellen.

SECTION 03Dritte Prüfung: Routing und Isolation des Veröffentlichungsjobs

Der iOS-Build sollte nicht einfach „irgendeinen verfügbaren Runner“ anfordern. Vergeben Sie einen eindeutigen Tag für den vorgesehenen macOS-Runner und verwenden Sie diesen Tag nur bei Jobs, die tatsächlich auf macOS ausgeführt werden müssen. GitLab beschreibt Tags und geschützte Runner als Mechanismen, mit denen Sie Jobs gezielt zuordnen und Veröffentlichungsaufgaben auf geschützte Branches begrenzen können. Die GitLab-Richtlinien für Tags und geschützte Runner sind dafür die maßgebliche Referenz.

Ein mögliches Routingmodell sieht so aus:

Jobtyp Geeigneter Runner Branch- oder Berechtigungsregel Arbeitsbereich
Linting und Quellcodeprüfung Linux oder allgemeiner Runner normale Branches möglich temporär
iOS-Kompilierung dedizierter macOS-Runner vertrauenswürdige Pipeline getrennt vom Release
UI- und Gerätetests macOS mit benötigten Ressourcen nach Projektregel eigener Testbereich
Archive und Upload geschützter macOS-Runner nur geschützter Release-Pfad getrennt und kontrolliert

Ob Build, Test und Release denselben Benutzer verwenden dürfen, hängt vom Risiko ab. Für ein kleines, vollständig kontrolliertes Projekt kann ein gemeinsamer CI-Benutzer vertretbar sein, wenn Arbeitsverzeichnisse, Variablen und Branch-Schutz sauber getrennt sind. Sobald externe Beiträge, beliebige Merge Requests oder unzuverlässige Skripte beteiligt sind, sollte der Veröffentlichungsrunner diese Jobs nicht annehmen.

Die entscheidende Grenze lautet: Ein Job aus einem nicht vertrauenswürdigen Quellstand darf nicht gleichzeitig Zugriff auf private Schlüssel und auf den Veröffentlichungsweg erhalten. Das gilt auch dann, wenn der Job technisch erfolgreich bauen könnte.

SECTION 04Vierte Prüfung: Signaturmaterial und zweistufige Berechtigungen

Bei der iOS-Signierung werden häufig mehrere Dinge vermischt. Für die Abnahme müssen Sie sie einzeln benennen:

  • GitLab-CI/CD-Variablen speichern Werte oder verweisen auf Dateien.
  • Ein App-Store-Connect-API-Key autorisiert bestimmte API-Aktionen.
  • Ein Zertifikat identifiziert die Signaturart.
  • Der private Schlüssel ermöglicht die kryptografische Signatur.
  • Die Keychain verwaltet Zertifikat und privaten Schlüssel im macOS-Benutzerkontext.
  • Das Provisioning Profile verbindet App-ID, Berechtigungen und Signaturvoraussetzungen.

Ein Upload-Schlüssel ist daher nicht automatisch vollständiges Signaturmaterial. Apple beschreibt die Erstellung von App-Store-Connect-API-Keys; prüfen Sie für jeden Schlüssel die geringstmögliche Rolle. Der eigentliche Archive- und Exportvorgang benötigt zusätzlich eine passende Projektkonfiguration und die auf dem Mac verfügbare Signaturkette.

Für GitLab sollten geschützte Variablen nur in geschützten Pipelines verfügbar sein. Datei-Variablen eignen sich für temporär abgelegte Profile oder Zertifikatsdateien, müssen aber nach dem Job entfernt werden. GitLab erklärt Schutz, Maskierung und Datei-Variablen in der CI/CD-Variablendokumentation. Maskierung verhindert nicht jede Form der Datenpreisgabe: Ein Skript kann Geheimnisse indirekt ausgeben oder in Artefakte schreiben.

Verwenden Sie in Dokumentation und Beispielskripten ausschließlich Platzhalter:

<REPOSITORY_URL>
<PROJECT_RUNNER_TAG>
<APP_BUNDLE_IDENTIFIER>
<APPLE_TEAM_IDENTIFIER>
<APP_STORE_CONNECT_KEY_IDENTIFIER>
<PATH_TO_CERTIFICATE>
<KEYCHAIN_PASSWORD>

Geben Sie niemals ein echtes Passwort, Token, Team Identifier, Key Identifier, Zertifikatsnamen oder Bundle Identifier in einem Blogbeispiel aus. In der Pipeline sollten Sie außerdem prüfen, ob temporäre Dateien, xcresult-Bundles, Shell-History oder Fehlerprotokolle Signaturdaten enthalten.

SECTION 05Fünfte Prüfung: Cache, Artifacts und Release-Dateien auseinanderhalten

Cache und Artifacts lösen verschiedene Probleme. Ein Cache beschleunigt wiederkehrende Abhängigkeiten und darf verworfen oder neu aufgebaut werden. Artifacts übertragen definierte Dateien zwischen Jobs oder machen sie für eine begrenzte Projektaufbewahrung verfügbar. GitLab grenzt diese Funktionen in der Dokumentation zu Cache und Artifacts ausdrücklich voneinander ab.

Leiten Sie den Cache-Schlüssel aus dem relevanten Lockfile und der Plattform ab. Ändert sich das Lockfile, muss der Schlüssel wechseln, damit alte Abhängigkeiten nicht stillschweigend in den Build gelangen. Signaturmaterial gehört weder in einen gewöhnlichen Cache noch in ein unkontrolliertes Artifact. Ein einzelnes Release-Archive sollte außerdem nicht die einzige Kopie der später nachvollziehbaren Veröffentlichung sein.

Ordnen Sie die Dateien nach Zweck:

  • Abhängigkeitsdaten: Cache mit nachvollziehbarem Lockfile-Schlüssel.
  • Testergebnisse: xcresult als Artifact für Diagnose und Nachweis.
  • xcarchive: eigenes Release-Artifact mit Commit- und Buildbezug.
  • Exportiertes Paket: getrenntes Artifact für den Upload- oder Freigabejob.
  • Protokolle: bereinigt von Variablen, privaten Pfaden und Geheimnissen.

Aufbewahrungsdauer und Speichergröße dürfen Sie nicht als universelle Werte behandeln. Prüfen Sie die aktuellen Einstellungen Ihres GitLab-Projekts und markieren Sie eigene Werte ausdrücklich als Projektentscheidung. Der wichtige Nachweis ist die Beziehung zwischen Commit, xcarchive, exportiertem Paket und Uploadjob, nicht eine möglichst lange Aufbewahrung jeder temporären Datei.

SECTION 06Sechste Prüfung: Archive, TestFlight und Neustart als gemeinsame Abnahme

Ein gewöhnlicher Debug Build ist kein Ersatz für eine Veröffentlichung. Für die finale Abnahme benötigen Sie einen geschützten Branch oder einen gleichwertig kontrollierten Release-Pfad und einen Ablauf, der die folgenden Zustände sichtbar macht:

  1. Der Runner nimmt den geschützten Job mit dem vorgesehenen macOS-Tag an.
  2. Das Projekt löst seine Abhängigkeiten aus und verwendet den geprüften Commit.
  3. Xcode erstellt ein Release-Archive mit dem vorgesehenen Scheme.
  4. Das Archive wird mit dem erwarteten Exportverfahren signiert.
  5. Das exportierte Paket wird an App Store Connect übergeben.
  6. Der Build erscheint dort anschließend im erwarteten Verarbeitungsstatus.
  7. Nach einem Neustart wird derselbe Ablauf mit einem neuen Testlauf wiederholt.

Apple dokumentiert das Hochladen von Builds zu App Store Connect. Der Upload-Erfolg allein beweist noch nicht, dass die Verarbeitung abgeschlossen oder der Build für TestFlight verfügbar ist. Deshalb muss Ihre Abnahme den Status nach dem Upload als eigenen Prüfschritt behandeln.

Nach dem Neustart prüfen Sie nicht nur das Online-Symbol in GitLab. Kontrollieren Sie Benutzer-Sitzung, LaunchAgent, Runner-Status, aktives Xcode-Entwicklerverzeichnis, Keychain-Zugriff und die Annahme des nächsten Jobs. Wenn der erste Lauf nach einem Neustart nur durch manuelles Öffnen von Xcode oder Entsperren der Keychain funktioniert, ist die Wiederherstellung nicht abgeschlossen.

Entscheidungsbedingungen für die nächste Betriebsform

  • Wenn Sitzung, Toolchain, Routing, Geheimnisse, Artefakte und Neustarttest bestanden sind, wählen Sie den dedizierten Remote Mac als produktiven GitLab-CI-Runner.
  • Wenn der Build funktioniert, aber Signierung oder App-Store-Connect-Upload nicht reproduzierbar sind, wählen Sie zunächst einen isolierten Testbetrieb ohne automatische Veröffentlichung.
  • Wenn der Runner nach Neustarts offline bleibt, wählen Sie keine dauerhafte Veröffentlichung, sondern beheben Sie Sitzungs- und LaunchAgent-Probleme.
  • Wenn ungeschützte Merge Requests denselben Host erreichen können wie der Releasejob, wählen Sie eine Trennung der Runner oder lehnen Sie die gemeinsame Nutzung ab.
  • Wenn Sie physischen Gerätezugriff, lokale USB-Hardware oder dauerhaft hohe Rechenlast benötigen, prüfen Sie einen eigenen Mac statt einer zeitweisen Remote-Umgebung.
  • Wenn nur gelegentliche Archive, TestFlight-Uploads oder reproduzierbare Releaseprüfungen anfallen und kein geeigneter Mac dauerhaft online ist, wählen Sie einen gemieteten Remote Mac und testen Sie zuerst den vollständigen Pipelineweg.

SECTION 07FAQ: Fehlerbilder aus dem täglichen Betrieb

Die folgenden Antworten ergänzen die Abnahme. Sie behandeln nicht die Registrierung als Selbstzweck, sondern die Bedingungen, unter denen ein GitLab CI iOS-Build tatsächlich verlässlich wird.

Warum reicht ein Linux Runner für iOS nicht aus?

Ein Linux Runner kann den Quellcode prüfen und andere Plattformen bedienen, aber nicht die macOS-spezifische Xcode- und Signaturkette ersetzen. Sobald Ihr Job ein echtes Archive, Apple SDKs, Codesignatur oder den vorgesehenen Upload benötigt, muss er auf einem macOS-Runner landen. Der Plattformwechsel ist daher eine Routingentscheidung, kein nachträglicher Installationsschritt im Linux-System.

Was unterscheidet die Runner-Verbindung von der grafischen Sitzung?

Die Runner-Verbindung entscheidet, ob GitLab einen Job zustellt. Die Benutzer-Sitzung bestimmt, unter welchem macOS-Kontext dieser Shell-Job läuft und ob die benötigte Keychain beziehungsweise grafische Umgebung verfügbar ist. Ein online angezeigter Runner ist deshalb noch kein Beweis für einen funktionierenden Signaturjob. Testen Sie beide Zustände getrennt und anschließend gemeinsam.

Warum sollte der Veröffentlichungsrunner keine beliebigen Merge Requests ausführen?

Der Shell Executor arbeitet direkt auf dem Host und bietet keine vollständige Isolation gegenüber dem Betriebssystem. Ein fremdes oder manipuliertes Skript könnte deshalb auf Dateien, Prozesse oder zugängliche Geheimnisse des Runner-Benutzers einwirken. Beschränken Sie den Veröffentlichungsrunner auf vertrauenswürdige Projekte und geschützte Pfade; bauen Sie untrusted Beiträge auf getrennten Runnern ohne Signaturmaterial.

Welche Dateien sollten nach dem Upload erhalten bleiben?

Bewahren Sie mindestens die nachvollziehbar zugeordneten Buildinformationen auf, die Sie für Diagnose und Freigabeprüfung benötigen: Testergebnis, Archive-Bezug, exportiertes Paket und relevante, bereinigte Protokolle. Temporäre Zertifikate, private Schlüssel und API-Geheimnisse gehören nicht in diese Sammlung. Die konkrete Aufbewahrung ist eine Projektentscheidung und muss zu Datenschutz-, Speicher- und Nachweisanforderungen passen.

Wann ist ein Remote Mac für GitLab CI nicht die richtige Wahl?

Ein Remote Mac ist ungeeignet, wenn Sie zwingend auf lokale Hardware, USB-Geräte oder eine nicht teilbare Spezialumgebung zugreifen müssen. Auch dauerhaft hohe Last kann einen eigenen Rechner wirtschaftlicher machen. Für unregelmäßige Releases ist der Kauf eines ständig bereitstehenden Macs dagegen oft schwer zu rechtfertigen. Entscheiden Sie anhand der sechs Abnahmekriterien und der tatsächlichen Betriebsanforderung, nicht anhand eines erfolgreichen Einzelbuilds.

SECTION 08Von der vorhandenen Umgebung zum passenden Mac-Betriebsmodell

Wenn Ihre aktuelle Lösung aus einem Linux Runner, einem persönlichen Mac und manuell verwalteten Signaturdateien besteht, liegen die Schwachstellen meist in drei Bereichen: Der Job landet auf der falschen Plattform, die interaktive Entwicklerumgebung ist nicht reproduzierbar, und ein persönliches Benutzerkonto wird gleichzeitig für Entwicklung und Veröffentlichung verwendet. Diese Kombination erschwert Audits, Neustarts und die Fehlersuche bei einem fehlgeschlagenen Upload.

Prüfen Sie zuerst, ob Ihr vorhandener Mac einen getrennten CI-Benutzer, eine belastbare Benutzer-Sitzung, eine kontrollierte Keychain und die benötigte Xcode-Toolchain bereitstellt. Fehlt ein dauerhaft erreichbarer Host, können Sie über die MACNOX-Übersicht für Remote-Mac-Zugänge prüfen, ob eine gemietete Umgebung zu Ihrem Test- und Release-Rhythmus passt. Für die Auswahl des Zeitraums und der verfügbaren Optionen finden Sie die aktuellen Angaben auf der MACNOX-Preisseite.

Die Entscheidung ist dabei nicht pauschal „Cloud statt eigener Hardware“. Ein eigener Mac bietet Ihnen die direkteste Kontrolle über lokale Geräte, dauerhafte Daten und spezielle Peripherie, verursacht aber Anschaffung, Wartung, Updates und eine dauerhaft gebundene Ressource. Ein gewöhnlicher gemeinsam genutzter Host ist günstiger zu starten, erhöht jedoch das Risiko durch konkurrierende Jobs, unklare Berechtigungen und schwer nachvollziehbare Toolchain-Änderungen. Ein Remote Mac von MACNOX ist vor allem dann sinnvoll, wenn Sie für einen begrenzten Zeitraum eine dedizierte macOS-Umgebung benötigen, ohne sofort einen eigenen Rechner als permanente Buildmaschine zu betreiben.

Nach einem bestandenen Neustarttest können Sie Ihre Wahl belastbar treffen: kurzfristig mieten, wenn Sie zunächst die Pipeline und die Releasekette validieren; länger mieten, wenn regelmäßige Builds ohne eigene Hardware anfallen; selbst anschaffen, wenn die Umgebung dauerhaft hohe Last oder physische Schnittstellen tragen muss. So wird aus einem „Runner ist online“-Status eine überprüfbare Entscheidung für Ihren iOS-Veröffentlichungsbetrieb.

SECTION 09FAQ

Warum braucht ein iOS-Build in GitLab CI einen Mac Runner?

Der entscheidende Grund ist nicht GitLab selbst, sondern die Apple-Buildkette: Xcode, die Apple SDKs, Codesignatur und die vorgesehenen Distributionswerkzeuge laufen in einer macOS-Umgebung. Ein Linux Runner kann Quellcode prüfen oder Android-Aufgaben ausführen, ersetzt aber keine macOS-Instanz für Archive, Signierung und den anschließenden Upload.

Was ist zu tun, wenn der GitLab Runner nach einem Neustart offline bleibt?

Prüfen Sie zuerst, ob der vorgesehene macOS-Benutzer angemeldet ist und die Benutzer-Sitzung läuft. Kontrollieren Sie danach den LaunchAgent, den Runner-Dienst, seine Tags und den Status im GitLab-Projekt. Erst wenn der Runner wieder Jobs annimmt, testen Sie Xcode-Auswahl, Keychain-Zugriff und einen vollständigen Build. Automatische Anmeldung darf dabei nicht die einzige Schutzmaßnahme sein.

Wie kommen Zertifikat und Provisioning Profile sicher in die CI-Umgebung?

Legen Sie sensible Werte als geschützte GitLab-CI/CD-Variablen ab und verwenden Sie Datei-Variablen für temporär benötigte Zertifikats- oder Profil-Dateien. Der Import erfolgt nur in eine kontrollierte Keychain mit Platzhaltern für Passwort und Dateipfade. App Store Connect API Keys dienen dem Upload, ersetzen aber nicht automatisch Zertifikat, privaten Schlüssel und passendes Provisioning Profile.

Wie erstellt GitLab Runner automatisch ein Archive und lädt es zu TestFlight hoch?

Der Pipeline-Ablauf muss getrennte Zustände erkennen: Abhängigkeiten auflösen, kompilieren, testen, archivieren, exportieren und hochladen. Der geschützte Veröffentlichungsjob ruft Xcode mit einer definierten Workspace- oder Projektdatei sowie einem Export-Plan auf. Danach übergibt ein dafür berechtigtes Upload-Werkzeug den Build an App Store Connect. Der erfolgreiche Upload beendet die Prüfung nicht; der Verarbeitungsstatus muss zusätzlich kontrolliert werden.

Muss auf dem Remote Mac eine grafische Benutzeroberfläche geöffnet bleiben?

Für den macOS-Runner im Benutzerkontext ist eine aktive Benutzer-Sitzung relevant, weil der Shell Executor Befehle direkt unter diesem Benutzer ausführt und auf dessen Keychain sowie gegebenenfalls grafische Sitzung zugreifen kann. Sie müssen jedoch nicht jede Pipeline manuell per Fernzugriff bedienen. Entscheidend ist eine sauber gestartete Sitzung mit getrenntem CI-Konto und kontrollierten Zugriffsrechten.