Guide d’ingénierie

Optimiser le téléchargement d’un grand dépôt iOS sur Mac cloud

Optimiser le téléchargement d’un grand dépôt iOS sur Mac cloud

Lorsqu’un dépôt iOS accumule plusieurs années d’historique, des fichiers de conception sources, des enregistrements d’écran et des fixtures de test, sa première installation sur un Mac cloud peut facilement donner l’impression que la machine manque de puissance CPU ou que son disque est lent. En réalité, le principal goulot d’étranglement se situe souvent avant même la compilation : tous les objets Git ordinaires sont téléchargés, Git LFS récupère automatiquement l’ensemble des fichiers volumineux lors de l’extraction, alors que la CI ne compile finalement qu’une seule application. La bonne approche ne consiste pas à mettre aveuglément tout le répertoire en cache, mais à figer d’abord les entrées, puis à contrôler séparément les objets de commit, les chemins présents dans l’espace de travail et le contenu LFS.

Mesurer le coût de l’extraction

Ne mesurez pas uniquement la durée de git clone. Décomposez au minimum l’opération en trois phases : transfert réseau, matérialisation de l’espace de travail et téléchargement LFS. Conservez également les résultats suivants :

git --version
git lfs version
du -sh .git
du -sh .git/lfs 2>/dev/null || true
du -sh .
git count-objects -vH
git lfs ls-files | wc -l

Mesurez séparément une première exécution et une exécution réutilisant l’espace de travail. La première met en évidence le coût des transferts depuis le serveur distant ; la seconde révèle les nettoyages inefficaces, l’accumulation des objets historiques et la croissance du cache LFS. Enregistrez aussi le commit final, et pas seulement le nom de la branche :

git rev-parse HEAD
git status --short

L’objectif de l’optimisation n’est pas de réduire la taille apparente du répertoire, mais de pouvoir reconstruire de manière fiable le même commit, le même ensemble de répertoires et le même lot d’objets LFS.

Combiner clone partiel et extraction clairsemée

Dans un clone partiel, le filtre blob:none diffère le téléchargement du contenu des fichiers ordinaires, tandis que l’extraction clairsemée limite les répertoires effectivement matérialisés dans l’espace de travail. Ces deux mécanismes peuvent être combinés, mais ils ne restreignent pas automatiquement Git LFS. Il faut donc désactiver explicitement le smudge initial.

export GIT_LFS_SKIP_SMUDGE=1
git clone --filter=blob:none --no-checkout "$REPO_URL" app
cd app
git lfs install --local
git sparse-checkout init --cone
git sparse-checkout set App Packages Shared
git fetch --depth=1 origin "$BUILD_REF"
git checkout --detach FETCH_HEAD
git rev-parse HEAD

Le mode --cone convient aux projets organisés par répertoires. Ses règles sont simples et réduisent le risque de voir disparaître involontairement des fichiers situés dans les répertoires parents. App, Packages et Shared doivent être remplacés par les dépendances réellement requises pour la compilation. Si l’espace de travail Xcode, des scripts ou des fichiers de configuration se trouvent à la racine du dépôt, vérifiez qu’ils restent inclus.

Le clone partiel exige que le serveur distant prenne en charge le filtrage des objets. Si la commande affiche un avertissement concernant cette fonctionnalité, considérez que l’opération est revenue à un clone ordinaire et mesurez de nouveau la taille de .git. Ne partez pas du principe que l’optimisation a bien été appliquée.

Récupérer uniquement les objets LFS nécessaires à la tâche

Après l’extraction, certains fichiers LFS peuvent encore n’être que des pointeurs. Commencez par lister les objets référencés par le commit courant, puis récupérez-les en fonction des chemins nécessaires à la tâche :

git lfs ls-files
git lfs pull --include="App/Assets/**,Shared/Fixtures/**"
git lfs fsck

Le filtrage des chemins doit reposer sur les entrées réelles de la compilation, et non sur une supposition fondée sur les extensions de fichiers. Les tests d’interface peuvent dépendre d’images, de vidéos et de fixtures de localisation. Ne récupérer que les répertoires de code source peut permettre à la compilation de réussir, tout en provoquant l’échec des tests à l’exécution.

Vérification Résultat attendu Problème fréquent
git lfs ls-files Les éléments suivis par LFS dans le commit courant sont visibles .gitattributes n’a pas été extrait avec le commit cible
Vérification de l’en-tête du fichier Le fichier contient les véritables données binaires Le fichier reste un pointeur contenant oid sha256
git lfs fsck La validation des objets locaux réussit Téléchargement interrompu ou répertoire d’objets endommagé
git status --short L’espace de travail ne contient aucune modification inattendue Un outil réécrit des ressources après l’extraction

Ne placez pas git lfs pull sans restriction de chemin dans un script d’initialisation commun. Sinon, chaque tâche téléchargera des ressources sans rapport avec ses propres besoins. Il est plus fiable de faire déclarer à chaque pipeline son propre ensemble d’entrées LFS.

Gérer la concurrence et les identifiants dans la CI

Chaque tâche de CI doit disposer de son propre espace de travail. Lorsque plusieurs tâches partagent un même dépôt accessible en écriture, les règles d’extraction clairsemée, les verrous d’index et les fichiers temporaires LFS peuvent interférer. Même si elles utilisent le même code en lecture seule, ne laissez pas deux tâches modifier simultanément .git/info/sparse-checkout.

N’injectez les identifiants que pendant la phase de récupération et limitez leurs autorisations à celles requises par le dépôt cible. Après git fetch et git lfs pull, supprimez les variables d’environnement temporaires ainsi que la configuration auxiliaire des identifiants. Les journaux ne doivent pas afficher d’adresse distante contenant un jeton. Utilisez les commandes suivantes pour vérifier que les valeurs affichées ne divulguent rien de sensible :

git remote -v
git config --local --get-regexp 'credential|lfs' || true

Les sous-modules doivent être traités séparément. Les paramètres de clone partiel et les règles d’extraction clairsemée du dépôt principal ne leur sont pas transmis automatiquement. Si un sous-module utilise également LFS, installez sa configuration LFS locale dans son propre répertoire et exécutez-y la récupération correspondante.

Éviter les nettoyages dangereux

git lfs prune convient à un dépôt utilisé de manière exclusive, mais pas à un répertoire d’objets LFS partagé entre plusieurs tâches. Dans un environnement partagé, la stratégie la plus sûre consiste à créer un répertoire distinct pour chaque tâche, puis à le supprimer entièrement une fois celle-ci terminée. Si vous devez réutiliser l’espace de travail, vérifiez d’abord qu’aucune tâche concurrente n’est active avant de lancer le nettoyage et les contrôles d’intégrité.

Valider les entrées avant la compilation plutôt que diagnostiquer après coup

Avant de lancer réellement xcodebuild, ajoutez une étape de validation légère. Elle doit au minimum confirmer que le commit est correct, que l’espace de travail est propre, que les fichiers essentiels du projet sont présents et que les pointeurs LFS ont été remplacés, puis afficher l’espace disque utilisé. Par exemple :

test -f App/App.xcodeproj/project.pbxproj
test -s App/Assets/LaunchVideo.mov
if grep -q "oid sha256:" App/Assets/LaunchVideo.mov; then
  exit 1
fi
git diff --exit-code
git lfs fsck
du -sh . .git .git/lfs

Conservez enfin quatre informations : le hash du commit, la liste des répertoires de l’extraction clairsemée, les règles LFS include et le résultat de la validation. Ainsi, lorsqu’une tâche échoue sur un Mac cloud, vous pouvez d’abord vérifier que toutes les entrées sont présentes avant d’examiner les journaux du compilateur, de signature ou de test. Cela évite de présenter une préparation incorrecte du dépôt comme une panne de compilation aléatoire.

Questions fréquentes

Le clone partiel et l’extraction clairsemée remplacent-ils Git LFS ?

Non. Le clone partiel limite les objets Git ordinaires, l’extraction clairsemée contrôle les chemins du répertoire de travail et Git LFS fournit le contenu des fichiers volumineux suivis.

Pourquoi le dépôt contient-il encore des pointeurs Git LFS ?

Le téléchargement automatique a probablement été désactivé sans exécuter ensuite git lfs pull. Vérifiez le commit, les chemins inclus, les identifiants et la configuration LFS.

Peut-on lancer git lfs prune après chaque tâche CI ?

Oui uniquement dans un dépôt isolé réservé à cette tâche. Si le stockage LFS est partagé, supprimez plutôt l’espace de travail dédié pour ne pas affecter les tâches concurrentes.

Mac cloud dédié

Exécutez vos builds sur un nœud physique dédié

Choisissez MiniRents M4 ou MiniRents M4 Pro à la journée, à la semaine, au mois ou au trimestre, puis sélectionnez un nœud selon votre équipe et l’emplacement de votre dépôt de code. Chaque appareil est une machine physique dédiée, et non une machine virtuelle.

Choisir un modèle et commander