Der schnellste Weg, den Apple-Silicon-CI-Durchsatz zu sabotieren, ist Caches nach Git-Branches zu benennen. Branch-Keys wiederverwenden Graphen über Commits hinweg, die Package.resolved, Podfile.lock oder Gemfile.lock still ändern—„zufällige“ Rote und schlimmer: Phantom-Grün. Behandeln Sie 2026 Abhängigkeits-Caches wie inhaltsadressierten Speicher: Lockfiles hashen, Toolchain-Build-Nummer pinnen und die Policy veröffentlichen, damit jeder versteht: ein Cache-Miss ist gesund.
Betriebskontext: Disk- und Artefakt-Retention, Worktrees vs. saubere Klone und Runner-Affinität. Für stärker isolierte Mac-mini-M4-Hosts in Hongkong, Japan, Korea, Singapur oder den USA Preise vergleichen und Hilfe für SSH/VNC-Zugangsmuster nutzen.
Warum Lockfile-Hashes Branch-Labels schlagen
Branch-Labels implizieren „alles auf dieser Entwicklungslinie teilt Zustand“. Abhängigkeitsgraphen folgen keinen Linien—sie folgen exakten Auflösungsergebnissen. Ein Merge kann eine transitive Version ohne App-Quelländerung anheben, Binaries invalidieren und den Branch-Namen unverändert lassen. Lockfiles zu hashen macht Cache-Hits zu einer Nachweispflicht: Bei Hash-Gleichheit haben Sie Evidenz, dass die Resolver-Ausgabe modulo Toolchain identisch ist.
- Reproduzierbarkeit: Prüfer korrelieren grüne Builds mit einem bestimmten Lockfile-Digest.
- Parallele PRs: zwei Pull Requests auf demselben Branchnamen (Fork-Workflows) kollidieren nicht mehr still.
- Disk-Ökonomie: LRU über Hashes begrenzt Wachstum besser als „ganzen Branch-Ordner löschen“.
Matrix A: Keying-Rezept pro Ökosystem
| Ökosystem | Lock-Eingaben | Vorgeschlagener Pfad-Suffix |
|---|---|---|
| SwiftPM + Xcode | Package.resolved + Xcode-Build |
spm/<sha256(resolved)>/xc<build> |
| CocoaPods | Podfile.lock + Ruby-Versionsdatei |
pods/<sha256(lock)>/ruby<ver> |
| Bundler | Gemfile.lock |
bundle/<sha256(lock)> |
| npm / pnpm | package-lock.json oder pnpm-lock.yaml |
js/<sha256(lock)>/node<major> |
Matrix B: Wann geteilte Caches weiter unsicher sind
Selbst perfektes Lockfile-Hashing rettet nicht, wenn Post-Install-Skripte während der Wiederherstellung laufen. Behandeln Sie solche Jobs als Kaltpfad, es sei denn, Sie sandboxen die Skriptausführung und verifizieren Prüfsummen wiederhergestellter Artefakte.
| Signal | Policy | Mitigation |
|---|---|---|
post_install-Hooks ändern Pods |
Restore nicht über Jobs teilen | Hooks jeden Build ausführen; nur Download-Blobs cachen |
| Binäre Pods ohne Checksummenprüfung | Als nicht vertrauenswürdige Eingabe behandeln | Mit Content-Hashes im Repo vendoren |
| Fork-PR-Builds | Separater Cache-Namespace | Interne Monorepo-Cache-Pfade nie wiederverwenden |
Numerische Defaults, die Audits überstehen
- Hash-Algorithmus: SHA-256 normalisierter Lockfile-Bytes (CR/LF in der CI angleichen).
- LRU-Breite: die letzten 12 Hashes pro Ökosystem pro Host behalten.
- Maximalalter: unberührte Hashes nach 14 Tagen ohne Treffer verwerfen, unabhängig vom LRU.
- Alerting: pagern, wenn das Cache-Volumen 70 % der dedizierten CI-Disk überschreitet.
Sicherheitshinweis: Caches sind Teil Ihrer Lieferkette. Wenn ein kompromittiertes Lockfile einen geteilten Tarball-Cache vergiften könnte, bevorzugen Sie ephemeren Download + Verifikation gegen blinde Wiederverwendung.
Acht Rollout-Schritte
- Inventur: welche Repos fehlen committete Lockfiles—Caching blockieren, bis sie existieren.
- Digest emittieren als CI-Artefakt für jeden Build zur späteren Korrelation.
- Caches mounten auf schnelle APFS-Volumes, nicht Netzwerkfreigaben, für SPM-Auflösung.
- Metriken verdrahten für Trefferquote, Restore-Sekunden und Eviction-Zähler.
- Dokumentieren Kalt-Cache-Erwartungen in CONTRIBUTING.md.
- Fork-Workflows explizit testen—Caches nach Vertrauensstufe namespacen.
- Mit Checkout-Policy koppeln aus dem Worktree-Guide, um Doppel-Teilen zu vermeiden.
- Hardware skalieren bei Eviction-Thrash—NodeMac ergänzt dedizierte M4-Knoten pro Region ohne Beschaffungsverzögerung.
FAQ
Warum verursachen Branch-Caches Phantom-Grün?
Sie wiederverwenden Binaries über Lockfile-Änderungen hinweg. Lockfiles hashen, damit Hits identische Resolver-Ausgabe implizieren.
SPM-Caches mit DerivedData teilen?
Nein—getrennte Belange. SPM-Schlüssel gehören zur Auflösung; DerivedData zu Compile-Indizes und soll Job- oder Toolchain-Dimensionen enthalten.
Wie oft bereinigen?
LRU innerhalb einer Obergrenze plus Maximalalter-Eviction; immer mit Disk-Alarmen koppeln.