2026 Builds reproductibles sur Mac distant
Empreintes Xcode · DerivedData · Frontières du trousseau

Les responsables plateforme et iOS échouent rarement sur SSH : ils échouent quand le même commit dérive sur des semaines ou des sessions sur un Mac distant dédié. Ce guide décompose les builds reproductibles en empreintes Xcode, versions côte à côte, politique DerivedData et isolation du trousseau, avec tableau comparatif, extraits shell et checklist pré-vol. À lire avec les billets runner, SSH/VNC et comparaison Xcode Cloud.

01

Ce que signifie « reproductible » : empreintes de chaîne d'outils contre « ça a compilé »

« Ça a compilé » est une observation ponctuelle. La reproductibilité fige l'état de la chaîne d'outils, la résolution des dépendances et la vue du matériel de signature dans une base auditable. Les nœuds distants ajoutent des variables : mises à jour d'images fournisseur, résidus multi-utilisateurs et jobs sans surveillance mélangés au débogage interactif.

Six points douloureux pour garder des revues honnêtes :

  1. 01

    Empreintes seulement dans le chat : xcodebuild -version et swift --version n'atteignent jamais les journaux de build, donc vous ne pouvez pas prouver quelle chaîne a tourné.

  2. 02

    Dérive de xcode-select : mises à jour OS ou bascules manuelles orientent les jobs nocturnes vers un autre Xcode, changeant le compilateur et les bords de signature.

  3. 03

    Crosstalk DerivedData : les branches partagent un préfixe de cache et les builds incrémentaux transportent l'état des macros entre contextes.

  4. 04

    Décalage de vue du trousseau : utilisateurs interactifs et CI sur un même hôte voient des chemins de signature différents ; SSH marche, le runner non.

  5. 05

    Bruit de permissions : les invites TCC bloquent les jobs headless par timeouts au lieu d'erreurs de confidentialité claires.

  6. 06

    Nettoyage trop agressif : les scripts suppriment des dossiers « qui ressemblent au cache » et forcent des cold builds incomparables.

Si deux ou plus reviennent en deux semaines, capturez les empreintes à l'étape un du pipeline et documentez la politique DerivedData et trousseau dans un runbook : c'est de la gouvernance de nœud, pas du détail vendeur CI.

02

Baseline Mac distant : utilisateurs, répertoires, disque et frontières de permission

Traitez la machine comme un nœud CI contractuel : figez l'identité d'exécution—utilisateur CI, layout home, racines d'outils, chemins de logs. Planifiez tôt le niveau disque : plusieurs Xcode et simulateurs grossissent plus vite que les débats CPU.

DimensionMachine de dev interactive partagéeMac distant dédié (priorité CI)
Identité d'exécutionSouvent mélangée avec sessions personnelles et état GUIPréférer un utilisateur CI dédié ; partitionner SSH/runner et débogage manuel
Verrouillage toolchainLes upgrades suivent l'habitude individuelleÉpingler un mineur Xcode approuvé par l'org ; changements via change control
DerivedDataLes chemins par défaut mélangent plusieurs produitsSéparer les racines par dépôt ou pipeline ; nettoyage auditable
Matériel de signatureCertificats éparpillés dans les trousseaux de sessionTrousseaux/utilisateurs ou nœuds séparés ; isoler release et expérimentations
ObservabilitéDépend de la mémoireImprimer les commandes d'empreinte en tête de chaque journal de build

La reproductibilité n'est pas « ne jamais mettre à jour »—c'est « chaque upgrade part avec empreintes avant/après et chemin de retour arrière ».

03

DerivedData et cache : quand partager, quand isoler

DerivedData accélère jusqu'à ce qu'il masque la dérive. Le partage convient à une mainline unique avec caches chauds durables ; l'isolation convient aux branches expérimentales, modules sensibles à l'ABI ou clean builds de semaine de release. Écrivez la politique au lieu de débattre des suppressions.

  1. 01

    Choisir une racine par pipeline critique : ex. ~/DerivedData/$REPO/$BRANCH_SAFE plutôt que les défauts implicites.

  2. 02

    Le passer explicitement : injecter -derivedDataPath ou variables d'env CI—pas de « quel était le défaut déjà ».

  3. 03

    Comparer chaud vs propre avant release : le même commit ne devrait différer que dans une bande attendue.

  4. 04

    Échelonner le nettoyage : séparer « sûr à purger » de « forcera de gros téléchargements » avec propriétaires et cadence.

  5. 05

    Seuils disque : avant que l'espace libre touche la ligne rouge, passer à une rétention conservative ou caches objet.

  6. 06

    Aligner avec les labels runner : des labels différents mappent vers des racines de cache différentes pour que release et expérimentation ne se battent pas ; voir le guide runner.

shell
# En-tête de journal : empreinte toolchain (exemple)
xcodebuild -version
xcode-select -p
swift --version
/usr/bin/xcrun --show-sdk-path --sdk iphoneos

# DerivedData explicite (remplacer par votre convention repo/branche)
DERIVED="$HOME/DerivedData/${REPO_SLUG}/${BRANCH_SAFE}"
mkdir -p "$DERIVED"
xcodebuild -scheme "App" -destination 'platform=iOS Simulator,name=iPhone 16' \
  -derivedDataPath "$DERIVED" build
info

Astuce : avec SwiftPM plus Xcode, enregistrez aussi la sortie de swift package resolve ou les hash de lockfile pour que « le même graphe » ne masque pas la dérive du cache du résolveur.

04

Trousseau et signature : configuration headless minimale viable

La plupart des échecs de signature headless ne sont pas de « mauvais certificats »—ce sont des vues de trousseau différentes ou des politiques de déverrouillage qui n'ont jamais tourné sur le chemin sans surveillance. Minimal viable signifie réduire l'exposition, sortir le débogage interactif du chemin critique et partitionner la release.

Si débogage GUI et runners doivent partager le matériel, isolez par labels ou fenêtres temporelles et documentez les approbations VNC ponctuelles—même idée que resserrer la surface VNC dans la checklist SSH/VNC.

warning

Avertissement : évitez de laisser des clés privées de distribution dans des emplacements globaux lisibles par tous sur des remotes partagés ; préférez comptes, nœuds ou fichiers de trousseau séparés et faites tourner lors des changements d'équipe.

05

Chiffres pour les revues et mentalité pré-vol

Ces fourchettes viennent de docs publiques et de pratique terrain—servez-vous-en pour aligner les parties prenantes ; vérifiez facturation et empreinte contre votre contrat.

  • Xcodes et runtimes parallèles : la planification commence souvent en centaines de gigaoctets ; budgétisez DerivedData et données simulateur, pas seulement les apps.
  • Coût empreinte : préfixer avec xcodebuild -version coûte typiquement des secondes par rapport au temps de compilation mais rapporte massivement en triage.
  • Concurrence vs IO : sur Apple Silicon, les jobs parallèles stables sont souvent bornés par la bande passante mémoire et le disque ; plafonnez la concurrence dans le runbook pour protéger le P95.

Les portables et Mac « empruntés » économisent à court terme mais introduisent politiques de veille, invites de mise à jour et sessions mélangées qui cassent le contrôle des empreintes et du trousseau. macOS imbriqué sur VPS Linux sacrifie souvent Metal et la stabilité de signature. Pour des environnements 24/7 prévisibles, une isolation auditable et un disque contractible en CI/CD iOS et agents d'automatisation, un Mac distant dédié est en général plus proche de la réalité production. La location cloud Mac mini NodeMini correspond à cette empreinte : choisissez région et disque, durcissez SSH pour l'automatisation, et traitez empreintes et politique de cache comme actifs d'exploitation transférables.

FAQ

FAQ

L'article runner couvre files, labels et workflows. Cet article couvre l'intérieur du nœud. Reliez la ligne directrice avec le guide runner, puis appliquez ici les empreintes et règles de cache.

Comparez les SKU sur la page tarifs de location, puis ajoutez une marge interne pour double Xcode et rétention DerivedData.

Commencez par le centre d'aide, puis croisez xcode-select et les comptes de signature avec cette checklist.