dotnet restore sur un Mac distant (self-hosted runner, pool partagé) alors que nuget.org ou les flux amont traversent un lien longue distance ou un proxy d’entreprise. Ce guide fournit : une chaîne de miroirs ordonnée dans NuGet.Config, des valeurs de départ pour MaxHttpRequestsPerSource, le placement de globalPackagesFolder (ou NUGET_PACKAGES), le couple RestoreLockedMode + packages.lock.json, et une liste de paramètres pour la gestion centrale des packages (CPM). Parcourez d’abord l’index du blog, l’accueil MacPull et les guides voisins — lecture sans connexion.
- Liste de flux « plate » : chaque paquet interroge d’abord nuget.org, le miroir interne ne court-circuite jamais le graphe.
- HTTP sans limite : le fan-out par défaut sature un SSD NVMe partagé avec d’innombrables petites écritures aléatoires.
- Dérive sans verrou : la CI restaure « ce qui se résout aujourd’hui » ; les retries transfrontaliers masquent les glissements de version jusqu’à la release.
① Matrice de décision : choisir les défauts avant le parallélisme
Utilisez ce tableau comme checklist. Ne modifiez qu’une colonne à la fois : changer simultanément les miroirs et maxHttpRequestsPerSource complique le bissectage des régressions.
| Scénario | Stratégie miroir / flux | MaxHttpRequestsPerSource | globalPackagesFolder | RestoreLockedMode |
|---|---|---|---|---|
| Azure Artifacts + nuget.org | Amont nommé dans Artifacts ; packageSourceMapping fixe Microsoft.* sur l’amont, les ID internes sur Artifacts |
8 en pool partagé ; 4 si la file disque monte | /usr/local/ci/nuget/global-packages via NUGET_PACKAGES |
true en CI une fois packages.lock.json versionné |
| Nexus / BaGet auto-hébergé | Miroir en premier ; repli explicite vers nuget.org seulement si la politique l’autorise | 6–8 ; baisser si le CPU du miroir grimpe | Même chemin pool ; purge des anciens dossiers hors heures creuses | true sur branches release ; false possible sur branches expérimentales |
| OSS uniquement, liaison fragile | Miroir régional approuvé (si conformité), sinon nuget.org avec timeouts allongés | 4 au départ ; augmenter seulement si le p95 restore est stable | SSD local — jamais un home sur SMB | true dès que le graphe est stable ; régénérer le lock après chaque bump |
Monorepo CPM (Directory.Packages.props) |
Les mappages référencent les mêmes noms de sources que hors CPM | Identique aux lignes ci-dessus — la CPM ne réduit pas le nombre de requêtes HTTP | Le dossier global partagé reste le meilleur levier de déduplication | Associer lock par projet ou props centrales selon la version du SDK |
② Chaîne NuGet.Config : squelette exécutable
Nommez chaque flux, mappez explicitement les identifiants de paquets, et placez globalPackagesFolder à côté de vos racines de build sur le SSD du Mac mini. Le fragment ci-dessous est représentatif — remplacez les URL par vos points de terminaison approuvés.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value="/usr/local/ci/nuget/global-packages" />
<add key="maxHttpRequestsPerSource" value="8" />
</config>
<packageSources>
<clear />
<add key="corp" value="https://pkgs.dev.azure.com/votre-org/_packaging/main/nuget/v3/index.json" />
<add key="nugetorg" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="corp">
<package pattern="Contoso.*" />
</packageSource>
<packageSource key="nugetorg">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
</configuration>
En CI, préférez NUGET_PACKAGES ou dotnet restore --configfile ci.NuGet.Config pour laisser les postes de développement avec leurs réglages personnels. Sur les agents macOS, installez le même fournisseur d’identifiants que sur Windows ou Linux (par exemple pour Azure Artifacts) et injectez des jetons à courte durée via variables d’environnement ou un coffre — ne commitez jamais de PAT dans le fichier Config. Préchauffez le cache avec un restore minimal sur un projet témoin avant d’activer le mode verrouillé sur toute la solution : le premier ID bloquant apparaîtra clairement dans les journaux.
Pour aligner NuGet avec d’autres écosystèmes sur le même runner, croisez ce guide avec la matrice JVM Gradle & Maven sur Mac distant et l’article Git, npm et Homebrew en CI transfrontalière lorsque la même machine tire aussi des outils front-end ou des binaires système.
③ Propriétés MSBuild / CLI vs NuGet.Config
| Paramètre | Où le fixer | Valeur CI typique | Notes |
|---|---|---|---|
| maxHttpRequestsPerSource | NuGet.Config section <config> |
4–8 | Plafonne les requêtes par flux ; levier principal pour lisser la charge disque |
| RestoreMaxHttpRequestsPerSource | MSBuild / CLI -p: |
Reprend la Config ou surcharge par job | Utile quand les modèles de pipeline ne peuvent pas écrire de fichiers Config |
| RestoreLockedMode | CI uniquement : Directory.Build.props ou CLI |
true |
Exige packages.lock.json commité ; échec en cas de dérive — comportement voulu |
| RestorePackagesWithLockFile | Projet ou props | true |
Émet le fichier de verrou ; discipline de revue des PR indispensable |
| ContinuousIntegrationBuild | Environnement CI | true |
Stabilise les métadonnées d’assets ; à combiner avec restore verrouillé |
Ligne CI copiable (adapter le chemin des props) :
dotnet restore /p:RestoreLockedMode=true /p:ContinuousIntegrationBuild=true
④ Gestion centrale des packages (CPM) : liste de paramètres compatible verrou
La CPM déplace les versions vers Directory.Packages.props ; le téléchargement passe toujours par la même pile HTTP NuGet. Gardez les mappages et les noms de sources identiques à un dépôt « classique » pour que les revues sécurité restent prévisibles.
| Artefact | Rôle | Implication CI |
|---|---|---|
Directory.Packages.props |
Items PackageVersion centralisés |
Surface unique pour les bumps ; la santé du miroir reste critique |
ManagePackageVersionsCentrally |
Active la CPM dans Directory.Build.props |
À définir une fois à la racine du dépôt |
CentralPackageTransitivePinningEnabled |
Épinglage optionnel des transitives depuis le fichier central | Dépend du SDK ; n’activer qu’après des restores verts avec lock |
PackageVersionOverride par projet |
Échappatoire ciblée | Documenter chaque override — la CI verrouillée échouera sur toute entorse non revue |
Si le même pool exécute aussi des pipelines Go, comparez le profil IO avec la matrice GOPROXY pour modules Go sur Mac distant afin d’éviter que go mod download et dotnet restore se superposent à chaque heure pile.
⑤ Déploiement en cinq étapes sur un agent Mac distant
global.json avec une bande de fonctionnalités exacte pour que le comportement du lock et de la CPM reste identique entre machines.ci.NuGet.Config à côté du dépôt ou sous ~/.nuget/NuGet pour l’utilisateur CI ; exportez NUGET_PACKAGES dans le shell du job en premier.RestorePackagesWithLockFile, exécutez restore en local, commitez packages.lock.json, puis passez RestoreLockedMode=true en CI.maxHttpRequestsPerSource=8 ; surveillez la profondeur de file du SSD ; descendez à 4 avant d’incriminer le réseau.dotnet restore --verbosity minimal sur un petit projet avant le restore solution pour chauffer TLS et caches.⑥ Repères pour documents d’architecture
Huit requêtes concurrentes par source reste un plafond courant sur hôtes CI Apple Silicon partagés ; passez à quatre si le restore coïncide avec Git LFS ou Docker. Restore verrouillé détecte la dérive tout de suite — gardez un job hebdomadaire non verrouillé sur une branche maintenance. Un globalPackagesFolder par pool bat souvent un dossier par job si la conformité autorise public et privé sur le même volume.
⑦ FAQ : NuGet sur runners Mac distants
Faut-il partager le même globalPackagesFolder entre tous les jobs sur un Mac distant ? En général oui pour le débit : un dossier NVMe bien dimensionné déduplique les extractions .nupkg. Séparez uniquement si la conformité interdit de mélanger artefacts publics et privés sur le même volume.
Que se passe-t-il lorsque RestoreLockedMode est true ? Toute modification du graphe non reflétée dans packages.lock.json fait échouer le restore. Les développeurs régénèrent le fichier de verrou après une montée de version ; la CI ne doit pas forcer RestoreLockedMode sans lock à jour commité.
Comment MaxHttpRequestsPerSource interagit-il avec le parallélisme de dotnet restore ? Il limite les connexions HTTP simultanées par flux. Des valeurs trop élevées multiplient les poignées de main TLS et les petites écritures aléatoires sur SSD partagé ; associez des valeurs modérées à des miroirs sains avant d’augmenter la réutilisation de nœuds MSBuild ou le parallélisme des jobs.
La CPM remplace-t-elle RestoreLockedMode ? Non : la CPM centralise les versions ; le lock fige le graphe résolu. Combinez les deux lorsque vous voulez une CI reproductible et une surface unique pour les bumps de dépendances.
Pourquoi des paquets partent encore vers nuget.org malgré un miroir ? Vérifiez packageSourceMapping : un ID non couvert peut retomber sur une source publique, ou un NuGet.Config au niveau projet écrase l’ordre attendu. Utilisez dotnet nuget locals all --list et dotnet restore -v detailed pour voir l’URL réelle.
Comment rafraîchir le lock après un correctif de sécurité ? Exécutez dotnet restore --force-evaluate (selon la version du SDK) ou désactivez temporairement le mode verrou sur une branche, commitez le nouveau packages.lock.json, puis réactivez l’application stricte en CI.
Données structurées (HowTo / FAQPage)
Le <head> contient déjà BlogPosting, BreadcrumbList, HowTo et FAQPage. En fork : alignez le libellé des questions JSON-LD sur la FAQ affichée et n’y mettez ni secrets ni URL internes non publiques.
Synthèse
Ordonnez les flux avec packageSourceMapping, placez les paquets sur un NVMe via globalPackagesFolder ou NUGET_PACKAGES, plafonnez MaxHttpRequestsPerSource, et appliquez RestoreLockedMode dès que packages.lock.json fait partie de votre culture de revue. Louer un Mac distant proche de vos miroirs approuvés transforme ces réglages en gains de temps réels sur dotnet restore et sur les étapes de test en aval — surtout lorsque votre équipe déclenche des builds transfrontaliers plusieurs fois par heure.
Prochaines étapes sans connexion : accueil, tarifs, achat, centre d’aide, blog technique.
Colocalisez l’agent avec une sortie réseau saine, figez le graphe de dépendances, et traitez le parallélisme de restore comme un budget disque — pas comme un multiplicateur gratuit.
Mac distant pour restore .NET & CI
Des hôtes Apple Silicon avec cache sur SSD et accès SSH — adaptés lorsque vous voulez des restores NuGet plus rapides sans expédier de matériel. Parcourez l’accueil, les offres d’achat ou le centre d’aide sans vous connecter.