SwiftPM 6.4 Build-Artefaktpfad geändert? 2026 Remote-Mac-CI reparieren

Wenn der Build erfolgreich endet, aber der Upload „Datei nicht gefunden“ meldet, sollten Sie den .build-Verzeichnisbaum nicht weiter raten oder fest verdrahten: Ermitteln Sie den tatsächlichen Zielpfad mit swift build --show-bin-path und passen Sie Cache- sowie Artefaktsammlung an dieselben Parameter an. Nur wenn ein reproduzierbarer Unterschied zwischen Swift Build und dem nativen Build-System nachgewiesen ist, sollte native vorübergehend als Diagnosevergleich dienen; vor einer Produktionsumstellung brauchen Sie einen geprüften Parallelbetrieb.

Zuletzt geprüft am 27.08.2026; die Angaben wurden anhand der offiziellen SwiftPM-Dokumentation, des Swift-Build-Repositorys und des Swift-Evolution-Status überprüft.

Diese Anleitung ist für Sie gedacht, wenn Sie Shell-, Makefile-, Fastlane- oder CI-Skripte pflegen und nach dem Upgrade zwar einen erfolgreichen Build sehen, aber keine Binärdatei hochladen können. Sie ist ebenso relevant für Maintainer von Swift Packages, Build-Plugins und Multi-Package-Repositories sowie für DevOps- und Release-Teams, die Remote-Mac-Knoten, Caches und Rückfallstrategien verwalten.

Warum ein erfolgreicher Build trotzdem kein verfügbares Artefakt bedeutet

Bei diesem Fehler müssen Sie drei Zustände auseinanderhalten:

  • Der Compiler oder das Build-System ist fehlgeschlagen.
  • Der Build ist erfolgreich, aber das nachgelagerte Skript sucht am falschen Ort.
  • Der Pfad ist korrekt berechnet, aber Arbeitsverzeichnis, Benutzerkonto oder Knoten unterscheiden sich zwischen den CI-Schritten.
Die entscheidende Beobachtung lautet daher nicht „die Datei fehlt“, sondern: **Welcher Befehl hatte welchen Exit-Status, in welchem Arbeitsverzeichnis, mit welcher Toolchain und welcher tatsächlichen Ausgabe?** Ein erfolgreicher swift build-Prozess beweist lediglich, dass dieser Prozess sein Ziel erreicht hat. Er beweist nicht, dass ein anschließender cp, Archivierungs- oder Upload-Schritt dieselbe Konfiguration verwendet.

Die offiziellen SwiftPM-Unterlagen beschreiben den Wechsel zu Swift Build als Standard und weisen auf veränderte Artefaktpositionen hin. Sie empfehlen, den Binärpfad über eine Abfrage statt über interne .build-Strukturen zu bestimmen. Lesen Sie dazu die offizielle Swift-Build-Migrationsdokumentation.

Welche Hinweise Sie zuerst sichern

Bevor Sie eine Zeile ändern, speichern Sie pro fehlgeschlagenem Lauf:

  1. Den vollständigen Build-Befehl einschließlich --configuration, Architektur- und Destination-Optionen.
  2. Das Arbeitsverzeichnis, etwa über pwd, sowie die Repository-Revision.
  3. Die Ausgabe von swift --version, xcode-select -p und der verwendeten Xcode- oder Swift-Toolchain.
  4. Den vollständigen Pfad, den das Skript erwartet.
  5. Die tatsächliche Ausgabe von swift build --show-bin-path.
  6. Exit-Status und Log des Upload- oder Kopierschritts.
Diese Informationen machen sichtbar, ob ein Pfadfehler erst nach dem Build entsteht oder ob bereits die Erzeugung des gewünschten Targets nicht stattfindet. Das ist besonders wichtig auf einem Remote Mac, wo mehrere Jobs zwar denselben Host, aber unterschiedliche Arbeitsverzeichnisse und Benutzerumgebungen verwenden können.

Erste Schritt: Skriptpfade durch eine identische Pfadabfrage ersetzen

Die häufigste Reparatur betrifft nicht den Compiler, sondern eine alte Annahme wie .build/release/Produktname. Diese Annahme kann in Shell-Skripten, Makefiles, Fastlane-Lanes und eigenen Release-Helfern mehrfach verborgen sein. Suchen Sie nicht nur nach .build, sondern auch nach fest eingetragenen Architektur-, Konfigurations- und Target-Namen.

Ein belastbares Muster sieht so aus:

#!/usr/bin/env bash
set -euo pipefail

REPO_DIR="${REPO_DIR:?REPO_DIR fehlt}"
PRODUCT_NAME="${PRODUCT_NAME:?PRODUCT_NAME fehlt}"
BUILD_CONFIGURATION="${BUILD_CONFIGURATION:-release}"
BUILD_ARCH="${BUILD_ARCH:?BUILD_ARCH fehlt}"
BUILD_DESTINATION="${BUILD_DESTINATION:?BUILD_DESTINATION fehlt}"

cd "$REPO_DIR"

swift build \
  --configuration "$BUILD_CONFIGURATION" \
  --arch "$BUILD_ARCH" \
  --destination "$BUILD_DESTINATION"

BIN_PATH="$(
  swift build \
    --show-bin-path \
    --configuration "$BUILD_CONFIGURATION" \
    --arch "$BUILD_ARCH" \
    --destination "$BUILD_DESTINATION"
)"

ARTIFACT="$BIN_PATH/$PRODUCT_NAME"

test -f "$ARTIFACT"
printf 'Artefakt: %s\n' "$ARTIFACT"

Die beiden Befehle müssen dieselben Werte für Konfiguration, Architektur, Destination und Arbeitsverzeichnis erhalten. Ein häufiger Fehler besteht darin, den Build als release auszuführen, den Pfad aber ohne --configuration abzufragen. Ebenso problematisch ist ein Build für eine Architektur, während die Abfrage den Standard der Maschine verwendet.

Das offizielle SwiftPM-Repository und die dort dokumentierten Befehle sollten gegenüber internen Verzeichnissen Ihre Referenz bleiben. Interne Pfadstrukturen dürfen Sie für Diagnose-Logs ausgeben, aber nicht als dauerhafte CI-Schnittstelle behandeln.

Was sich in Makefile und Fastlane ändern muss

Im Makefile sollte die Pfadermittlung in einer Variable oder Funktion zentralisiert werden:

CONFIGURATION ?= release
ARCH ?= arm64
DESTINATION ?= generic/platform=macOS

bin-path:
	swift build --show-bin-path \
	  --configuration "$(CONFIGURATION)" \
	  --arch "$(ARCH)" \
	  --destination "$(DESTINATION)"

In Fastlane oder einem Ruby-Skript sollten Sie die Ausgabe des Befehls erfassen, trimmen und anschließend mit File.file? prüfen. Vermeiden Sie, .build durch eine neue, ebenfalls geratene Unterstruktur zu ersetzen. Der Fix ist nicht „ein anderer statischer Pfad“, sondern eine reproduzierbare Abfrage des Outputs.

Für ein Swift Build-Szenario müssen Sie zusätzlich dokumentieren, ob der Befehl eine ausführbare Binärdatei, ein Bundle, eine Bibliothek oder ein Archiv liefern soll. --show-bin-path beantwortet die Frage nach dem Binärverzeichnis; es ersetzt nicht automatisch die Suche nach jedem Testbericht, Coverage-File oder signierten Archiv.

Welche Pfade und Artefakte je Verantwortungsbereich geprüft werden

Die Reparatur wird stabiler, wenn jede Rolle nur die Artefakte und Beweise prüft, die sie tatsächlich konsumiert.

<
VerantwortungsbereichErwartetes ErgebnisNachweisTypischer Reparaturschritt
SkriptpflegeBinärdatei oder BundleVollständiger Build- und AbfragebefehlHarte .build-Annahmen entfernen
Package-MaintainerPlugin-, Ressourcen- oder Binary-Target-AusgabePlugin-Input, Output-Deklaration, LogÖffentliche SwiftPM-Schnittstellen verwenden
TestteamTeststatus, Bericht, Coverage und LogsSeparater Test- und BerichtsnachweisNicht nur eine erwartete Datei prüfen
CI-PlattformReproduzierbarer KnotenlaufToolchain-, Cache- und ArbeitsbereichsdatenCache-Identität und Bereinigung korrigieren
Release-TeamSigniertes, validiertes LieferartefaktPrüfsumme, Signatur- und Upload-LogSwift Build und native parallel abnehmen

Für Package-Autoren: Plugins, Ressourcen und Binary Targets

Wenn Ihr Package ein Build-Tool-Plugin, ein Command-Plugin oder einen Script-Plugin verwendet, prüfen Sie zuerst, ob dieser Code selbst einen Pfad zusammensetzt. Das gilt auch für Ressourcenverarbeitung und Binary Targets. Ein Plugin, das Ausgaben aus einem angenommenen .build-Unterordner liest, kann nach einer Build-Systemänderung unabhängig vom eigentlichen Compilerfehler ausfallen.

Trennen Sie dabei öffentliche Schnittstellen von internen Verzeichnissen:

  • Verwenden Sie vom Package Manager bereitgestellte Pfad- und Kontextinformationen, sofern die Plugin-Schnittstelle sie anbietet.
  • Schreiben Sie Input- und Output-Dateien explizit in das Plugin-Log.
  • Prüfen Sie, ob das Plugin nur deklarierte Outputs verändert.
  • Speichern Sie den exakten Fehler einschließlich Toolchain und Zielplattform.
  • Vermeiden Sie Suchläufe über den gesamten Workspace als dauerhafte Lösung.
Der [offizielle Swift-Build-Code](https://github.com/swiftlang/swift-build) ist für das Verständnis der neuen Architektur hilfreich, aber interne Implementierungsdetails sind kein stabiler Vertrag für Ihr Release-Skript. Wenn ein Problem nur in Swift Build auftritt und ein identischer Vergleichslauf mit native funktioniert, legen Sie einen kleinen reproduzierbaren Fall an. Ein entsprechender [offizieller Bericht zur Ausgabeverzeichnis-Differenz](https://github.com/swiftlang/swift-build/issues/1363) zeigt, warum Sie solche Abweichungen getrennt dokumentieren sollten.

**Hinweis aus dem Bereitschaftsbetrieb:** Ein find .build -type f kann bestätigen, dass irgendwo eine Datei erzeugt wurde. Es beantwortet aber nicht, ob Ihr Befehl das richtige Target, die richtige Konfiguration oder die richtige Architektur gebaut hat. Verwenden Sie diese Suche nur zur Diagnose, nicht als Ersatz für die Pfadabfrage.

Für Testingenieure: Testläufe nicht auf einen festen Ordner reduzieren

Testresultate bestehen nicht zwangsläufig aus einer einzigen Datei an einem unveränderlichen Ort. Prüfen Sie mindestens drei Dinge getrennt:

  1. Ob swift test den erwarteten Exit-Status liefert.
  2. Aus welcher Quelle Ihr Testbericht oder Coverage-Bericht stammt.
  3. Ob ein fehlgeschlagener Testfall weiterhin eindeutig lokalisierbar ist.
Wenn Ihr Aggregator einen festen Test-Runner-Ordner erwartet, kann er nach der Umstellung einen erfolgreichen Lauf als fehlerhaft melden. Lassen Sie den Testschritt deshalb seine eigene Ausgabe protokollieren und übertragen Sie nur explizit ermittelte Dateien. Für Coverage und Logs müssen Sie die Erzeugung jeweils mit einem absichtlich fehlschlagenden Test sowie mit einem erfolgreichen Test validieren.

Behalten Sie während der Migration einen nativen Vergleichslauf mit derselben Revision. Das bedeutet nicht, dass native automatisch die bessere Produktionswahl ist. Der Vergleich beantwortet lediglich die Frage, ob die Abweichung durch Swift Build oder durch Ihr Skript verursacht wird. Die offizielle SwiftPM-Migrationsbeschreibung sollte dabei die Grenze zwischen unterstützter Abfrage und interner Annahme vorgeben.

Zweite Tabelle: Swift Build, native und ein statischer Pfad im CI-Vergleich

<
VarianteGeeignet fürRisikoEntscheidung
Statischer .build-PfadKurzfristige lokale DiagnoseBricht bei Struktur- oder ParameteränderungNicht als CI-Schnittstelle verwenden
Swift Build plus --show-bin-pathNeue oder zu migrierende CI-PipelinesZusätzliche Prüfung für Tests, Plugins und Archive nötigBevorzugte Zielrichtung
native als VergleichEingrenzung eines Swift-Build-ProblemsZwei Pfad- und Cache-Verhalten müssen gepflegt werdenZeitlich begrenzter Diagnosepfad
Manuelle DateisucheEinmalige Untersuchung eines unbekannten WorkspacesKann falsches Target oder alte Cache-Datei erwischenNur zur Ursachenanalyse
Die aktuelle Dokumentationslage bestätigt die veränderte Standardrichtung, aber Swift 6.4 ist auf der Swift-Evolution-Seite noch nicht als eigenständige stabile Veröffentlichung markiert. Den [aktuellen Veröffentlichungsstatus von Swift Evolution](https://github.com/swiftlang/swift-evolution) sollten Sie deshalb vor einer verbindlichen Toolchain-Freigabe erneut prüfen. Auch der Status von Xcode 27 muss anhand der zum Prüfdatum gültigen Beta-, RC- oder Release Notes bewertet werden; Medienberichte sind dafür kein Beleg. Ergänzend steht die [Apple-Developer-Übersicht zu Swift 6.4](https://developer.apple.com/wwdc26/guides/swift/) als offizielle Referenz zur Verfügung.

Dritter Schritt: Cache-Identität und Remote-Mac-Umgebung stabilisieren

Ein korrigierter Pfad hilft nicht, wenn Ihr CI einen alten Output-Ordner aus einem inkompatiblen Lauf wiederverwendet. Die Cache-Identität sollte mindestens folgende Merkmale berücksichtigen:

  • Swift- und Xcode-Toolchain-Version,
  • verwendetes Build-System,
  • Architektur,
  • Build-Konfiguration,
  • Destination,
  • Lockfile beziehungsweise aufgelöste Package-Abhängigkeiten,
  • relevante Repository-Revision oder Cache-Generation.
Die Cache-Regel sollte bei einer Änderung dieser Merkmale einen neuen Namespace erzeugen. Löschen Sie nicht blind jeden Cache nach jedem Lauf, denn damit verlieren Sie die Möglichkeit, zwischen einem Pfadproblem und einem Cache-Kollisionsproblem zu unterscheiden. Führen Sie stattdessen einen gezielten Kaltstart sowie einen Wiederholungslauf mit warmem Cache durch.

Auf einem Remote Mac kontrollieren Sie außerdem:

  • Welcher Benutzer den Runner-Prozess startet.
  • Ob HOME, PATH und DEVELOPER_DIR im interaktiven und nicht-interaktiven Lauf identisch sind.
  • Ob xcode-select -p auf die erwartete Toolchain zeigt.
  • Ob Arbeitsverzeichnisse nach einem Job entfernt werden.
  • Ob ein Neustart den Runner automatisch und mit denselben Rechten startet.
  • Ob ein paralleler Job denselben Workspace oder Cache sperrt.
Die [Hilfsimplementierung des offiziellen SourceKit-LSP-Build-Skripts](https://github.com/swiftlang/sourcekit-lsp/blob/main/Utilities/build-script-helper.py) ist ein nützlicher Referenzpunkt dafür, wie Build-Parameter und ermittelte Pfade zusammengeführt werden können. Übernehmen Sie daraus jedoch keine Annahme ungeprüft in Ihre eigene Pipeline.

Wenn Ihre lokale Swift-Build-Ausführung funktioniert, die Übertragung auf dem Remote Mac aber scheitert, vergleichen Sie nicht nur die Swift-Version. Vergleichen Sie Arbeitsverzeichnis, Zielarchitektur, Shell, Berechtigungen, Umgebungsvariablen und Cache-Zustand. Ein lokaler Erfolg widerlegt keinen Fehler in der Remote-Mac-CI.

Vierter Schritt: Mit einer kontrollierten Matrix statt mit einem Einzellauf abnehmen

Für die Produktionsfreigabe brauchen Sie eine kleine, aber aussagekräftige Matrix. Verwenden Sie dieselbe Commit-Revision und dieselben Platzhalterwerte für Repository, Workspace, Konfiguration, Architektur, Destination und Artefaktname.

<
PrüffallSwift BuildNativeErwarteter Nachweis
Kaltstart ohne CacheAusführenVergleichBuild, Pfadabfrage und Kopie
Warmstart mit identischem CacheAusführenVergleichKeine fremde oder alte Binärdatei
Nach Knoten-NeustartAusführenNur falls nötigRunner, Toolchain und Workspace konsistent
Fehlender TestfallAusführenVergleichExit-Status und Bericht zeigen den Fehler
Signierung und UploadAusführenVergleichIdentifizierbares, validiertes Lieferartefakt
Ein einmaliger grüner Build reicht nicht. Besonders die Kombination „Kaltstart, warmer Cache, Neustart“ deckt unterschiedliche Fehlerklassen ab. Prüfen Sie bei jedem Lauf den ermittelten Binärpfad, die Existenz des erwarteten Artefakts, die Dateigröße nur als Diagnosehinweis und die Identität der Datei über eine Prüfsumme. Eine Prüfsumme ist keine Aussage über Inhalt oder Qualität, verhindert aber, dass ein alter Cache-Treffer unbemerkt als aktuelles Ergebnis veröffentlicht wird.

Wann Sie auf native zurückfallen sollten

Ein Rückfall ist vertretbar, wenn drei Bedingungen erfüllt sind: Swift Build und native verwenden dieselbe Revision und dieselben relevanten Parameter, der Fehler lässt sich ausschließlich in Swift Build reproduzieren, und Sie bewahren die vollständigen Logs samt Umgebung auf. Dann kann native vorübergehend als Diagnose- oder Isolationspfad laufen.

Für die Produktionsentscheidung sollten Sie zunächst beide Wege parallel testen. Wenn native erfolgreich ist, Swift Build aber scheitert, behandeln Sie das nicht als Berechtigungsproblem des Remote Mac, solange die Pfade, Benutzerrechte und Eingaben identisch sind. Prüfen Sie bekannte Probleme im offiziellen Swift-Build-Issue-Tracker, erstellen Sie gegebenenfalls einen Minimalfall und verschieben Sie die Umstellung, wenn Signierung, Tests oder Upload nicht reproduzierbar sind.

Legen Sie außerdem ein Rückfallkriterium fest: etwa ein nicht lokalisierbares Artefakt, ein fehlender Testbericht oder ein nach Neustart nicht reproduzierbarer Pfad. Erst wenn die Ursache behoben oder offiziell bewertet ist, sollte Swift Build wieder zum alleinigen Produktionspfad werden.

Abnahme-Checkliste für Ihre Remote-Mac-CI

  • [ ] Der Build-Befehl, die Pfadabfrage und der Kopierschritt verwenden dasselbe Arbeitsverzeichnis.
  • [ ] --configuration, Architektur und Destination sind in Build und --show-bin-path identisch.
  • [ ] Kein Produktionsskript setzt eine interne .build-Unterstruktur als dauerhafte Schnittstelle voraus.
  • [ ] Binärdatei, Testbericht, Coverage und Archiv werden als getrennte Artefakte geprüft.
  • [ ] Plugin-Inputs und -Outputs stehen im Log und sind nicht durch geratenes String-Verketten bestimmt.
  • [ ] Swift-Version, Xcode-Auswahl, Build-System und Lockfile fließen in die Cache-Identität ein.
  • [ ] Ein Lauf ohne Cache und ein Lauf mit warmem Cache liefern erwartbare Pfade.
  • [ ] Nach dem Neustart des Remote Mac startet der Runner mit demselben Benutzer und derselben Toolchain.
  • [ ] Ein nativer Vergleichslauf ist nur als dokumentierter Diagnosepfad eingerichtet.
  • [ ] Vor der Produktionsfreigabe sind Signierung, Upload und Wiederherstellung anhand derselben Commit-Revision geprüft.
  • [ ] Für einen Rückfall sind Auslöser, zuständige Person und erneuter Prüfzeitpunkt festgelegt.
Für isolierte Kaltstart- und Neustarttests ist ein Remote Mac oft geeigneter als ein gemeinsam genutzter Entwicklerrechner: Sie können den Workspace zurücksetzen, die Toolchain kontrollieren und den Runner-Lebenszyklus prüfen, ohne lokale Arbeitsstände zu gefährden. Wenn Sie Ihre Umgebung zunächst reproduzierbar aufbauen möchten, finden Sie auf der [MACGPU-Übersicht für Remote-Mac-Umgebungen](https://macgpu.com/de/index.html) den passenden Einstieg. Für die Auswahl einer konkreten M-Series-Maschine können Sie außerdem die [Informationen zu verfügbaren M4-Konfigurationen](https://macgpu.com/de/m4-bestellen.html) heranziehen; entscheidend für diese Reparatur bleiben jedoch Toolchain- und Cache-Konsistenz, nicht ein pauschal größeres Modell.

Der bisherige Ansatz — .build-Pfade fest einzutragen, lokale Erfolge als Remote-Nachweis zu nehmen und Caches unabhängig von Toolchain und Architektur zu teilen — hat drei reale Nachteile: Er bricht bei Build-Systemänderungen, kann veraltete Artefakte unbemerkt weiterreichen und erschwert die Trennung von Pfad-, Rechte- und Runnerfehlern. Wenn Ihr vorhandener Knoten für diese Tests nicht sauber isolierbar ist, bietet die zeitweise Anmietung eines Remote Mac von MACGPU einen kontrollierbaren Prüfplatz mit vollständiger Systemzugriffsmöglichkeit, bevor Sie die Produktionspipeline umstellen. Für dauerhaft hohe, planbare Last oder Anforderungen an physische Schnittstellen bleibt ein eigener Mac die ehrlichere Wahl; für Migration, Kaltstart, Neustart und doppelte CI-Abnahme ist ein zurücksetzbarer Remote Mac meist der risikoärmere nächste Schritt.