Que fait Migration .NET 8 → .NET 10 ?
Cette compétence exécute un outil déterministe intégré (scripts/dmig) puis explique ses résultats.
Analysez toujours d'abord ; ne mettez en œuvre qu'un groupe que la personne a approuvé à partir de cette analyse.
L'analyseur effectue les mesures ; votre travail consiste à l'exécuter correctement, à lire ce qu'il a trouvé et à
indiquer à la personne ce que cela signifie — sans exagérer quoi que ce soit qu'il n'a pas pu vérifier.
Pourquoi l'analyse vient en premier
Dans un monorepo, un dépôt est rarement une unité de migration unique. Une bibliothèque partagée déplacée vers net10.0
casse toutes les applications encore sur net8.0, et des fichiers comme global.json ou
Directory.Packages.props affectent tout le monde. Ainsi, l'analyse cartographie l'ensemble du dépôt, propose des
groupes dans un ordre sûr, prouve ses affirmations avec une référence et une expérience jetable avant que
quiconque ne modifie du code réel. La mise en œuvre a lieu plus tard, un groupe approuvé à la fois.
Exécution
-
Choisissez un dossier de sortie en dehors du dépôt (l'outil refuse un dossier à l'intérieur) : rapports, journaux, cache de métadonnées NuGet et le worktree temporaire y vont tous.
-
Choisissez le dotnet. L'outil vérifie lui-même les SDK et les runtimes dans son pré-vol ; vous devez seulement le pointer vers le bon exécutable. Si la machine a une racine dotnet privée (SDK 10 + runtime 8 côte à côte), passez-la avec
--dotnetouDMIG_DOTNET. Lorsque .NET 8 est installé dans un autre dossier dotnet, l'outil le trouve dans les emplacements habituels, ou le prend depuis--dotnet-root <dossier>/DMIG_DOTNET_ROOTS, et le combine avec le SDK via des liens dans un dossier qui lui est propre (aucune installation n'est modifiée). -
Installez les deux bibliothèques si elles manquent, depuis le miroir Python de l'organisation :
python -m pip install -r requirements.txt(tests : aussirequirements-dev.txt). Utilisez toujourspython -m ...: le dossier Scripts peut ne pas être dans le PATH. Aucun besoin desh,bashoused. -
Exécutez l'analyse (les chemins Windows fonctionnent dans
PYTHONPATH,--repoet--out, également depuis Git Bash) :PYTHONPATH=<dossier-compétence>/scripts python -m dmig analyze --repo <dépôt> --out <dossier-sortie> [--dotnet <chemin>]Indicateurs utiles :
--offline(ne pas sonder les flux configurés),--no-baseline,--no-experiment,--environment contract.json(services de test externes et outils sous licence fournis par l'environnement),--request request.json(la demande neutre, voirreferences/contracts.md). Comptez environ une minute pour un petit dépôt ; les gros monorepos prennent autant de temps que leur propre restauration + construction + test, deux fois (référence et expérience). Exécutez-le en arrière-plan si votre infrastructure le permet, et ne démarrez jamais une seconde copie sur le même dépôt en même temps. La progression est d'une ligne par étape sur stderr ([dmig hh:mm:ss] baseline …) ; stdout ne transporte que le résumé JSON final, et le journal complet de chaque commande apparaît dans<out>/logs/dès qu'elle se termine.Rien n'a besoin d'être installé : le dossier de la compétence a des fichiers de démarrage,
dmig.cmd(Windows) etdmig(Linux/macOS), équivalents àPYTHONPATH=<dossier-compétence>/scripts python -m dmig.python -m dmig preflight ...exécute uniquement la vérification de l'environnement (secondes). Sur une nouvelle machine, exécutezpython -m dmig doctor <dépôt>d'abord : une liste de contrôle de préparation en langage clair (doctor-report.md,environment-capabilities.json, résultat READY / READY_WITH_LIMITATIONS / BLOCKED).Formes courtes (les noms d'intégration) : chaque commande prend le dépôt comme premier argument et définit par défaut
--outà<dépôt>.dmig/<étape>/et--planà<dépôt>.dmig/analysis/migration-plan.json:dmig analyze <dépôt> --target net10.0,dmig migrate <dépôt> --group <id>(=implement),dmig validate <dépôt> --scope group|repository(--group <id>pour un groupe ; repository = PHASE_7),dmig rollback <dossier d'exécution>(nettoie la copie jetable d'une exécution et imprime comment annuler son patch). Chaque exécution migrate/global/validate écrit égalementdmig-result.json, le résultat camelCase du contrat. Miroir de paquets :--package-catalog mirror.json(seules les versions approuvées sont jamais choisies ; les étapes ultérieures le réutilisent).Valeurs par défaut à respecter : l'outil n'a pas de client réseau propre : tout ce qui concerne les paquets passe par
dotnetet les flux configurés sur la machine, qui sont sondés par défaut (--offlineignore cela). Le catalogue public uniquement avec--allow-public-nuget; sans fichier de catalogue, les versions des paquets sontMETADATA_UNAVAILABLE(jamais devinées), et un paquet manquant dans le catalogue estPACKAGE_UNAVAILABLE. Les compléments de framework sont désactivés : le web (ASP.NET Core), les règles EF Core et les services Windows nécessitent--adapters aspnet_core,efcore,windows_serviceau moment de l'analyse ; sinon, leurs groupes sontOUT_OF_SCOPE_ADAPTER_DISABLED. .NET Framework, WPF, WinForms, MAUI, Xamarin et Azure Functions sont en lecture seule (OUT_OF_SCOPE_REPORT_ONLY) ; les groupesnet*-windowssans Windows sontBLOCKED_PLATFORM. La sortie console est en ASCII brut (PASS/WARN/FAIL/BLOCK). Entrées, sorties, statuts et codes de sortie :docs/integration-contract.md. -
Codes de sortie : 0 = analyse terminée (éventuellement avec des limitations), 2 = BLOCKED.
Lire les résultats
Lisez <out>/response.json d'abord (son summary contient les comptages), puis <out>/migration-report.md.
Les deux sont limités en taille — ils restent de quelques Ko quelle que soit la taille du dépôt, et disent "… et N de plus"
là où ils coupent une liste. Ne lisez pas les gros fichiers entiers : migration-plan.json,
inventory.json, baseline.json, experiment.json et compatibility.json grossissent avec le dépôt.
Lorsque vous avez besoin d'un groupe, ouvrez sa note (ci-dessous) ou recherchez ce group_id dans le JSON.
Les journaux complets sont dans <out>/logs/ ; ouvrez-en un seulement lorsqu'une étape a échoué et que sa fin ne suffit pas.
Pour les personnes : l'analyse écrit également un ensemble lié de notes Obsidian dans <out>/obsidian/<dépôt> .NET 10 migration/ (ou dans un dossier de coffre-fort avec --obsidian-dir <dossier>), construit avec le package
obsreport intégré : 00 Start here (verdict, chiffres clés, top 5 correctifs par impact), 01 What will break (niveaux de preuve : confirmé par construction/test → trouvé dans le code → possible, replié), 02 Route
(cinq étapes), 03 Map (couches + un Map board.canvas zoomable), 04 Decisions (un enregistrement de décision
chacun), 05 Reviewer FAQ, plus une note par groupe, règle et bibliothèque partagée. Pointez la personne
vers la note de départ plutôt que de coller son contenu.
Re-rendu sans reconstruction : après un changement de règles ou de mise en page des notes, python -m dmig report --repo <dépôt> --out <dossier d'analyse> [--obsidian-dir <dossier>] [--offline] reconstruit l'analyse de
compatibilité, la comparaison des tests, le plan, le rapport et les notes à partir des résultats sauvegardés en une minute ou
deux, sans restauration, construction ou test.
Deux choses qui aident lors de leur lecture :
- L'expérience recible tout le dépôt vers
net10.0simple en une fois, y compris les bibliothèques partagées que le plan multi-ciblera. C'est délibéré : une exécution montre les échecs net10.0 de chaque projet, et la comparaison avec la référence attribue chaque échec à un groupe (une régression dans une application causée par une bibliothèque partagée apparaît commeWAITS_FOR_DEPENDENCY_REPAIR). <out>/worktrees/reste un dossier vide après l'exécution (le worktree à l'intérieur est supprimé et vérifié), et<out>/nuget-cache/conserve les métadonnées NuGet pour qu'une réexécution soit plus rapide. Ni l'un ni l'autre ne sont des résidus dans le dépôt.
Lorsque vous faites un rapport :
- Commencez par le statut et l'ordre des groupes, puis la préparation de chaque groupe et pourquoi. Le rapport
est généralement explicite ; ouvrez
references/reading-results.mdlorsqu'un statut, une valeur de préparation ou une constatation n'est pas familière. Une étiquette de préparation nomme uniquement le principal bloqueur : mentionnez également les réparations proposées par chaque groupe (par exemple une modification de Dockerfile) listées en dessous. - Séparez ce qui a été vérifié de ce qui a été déduit. Un groupe n'est
READYque si l' expérience l'a construit et testé par rapport à une référence. Dites-le lorsque des tests ont été bloqués, qu'une plateforme manquait (projets Windows sur Linux), ou qu'un paquet est "non prouvé". - Gardez les échecs préexistants séparés. Les échecs de référence sont enregistrés, jamais comptés comme des problèmes de migration, et jamais quelque chose que la migration devrait "corriger".
- Nommez la classe de changement de tout ce qui est proposé :
PROJECT_LOCAL,GROUP_SHAREDouREPOSITORY_GLOBAL. Les changements globaux (global.json, fichiersDirectory.*racine,NuGet.config, CI) appartiennent aux phases à l'échelle du dépôt, jamais à un seul groupe. - Citez
rollback_verifiedetchanges_persisted. Si le rollback n'est pas vérifié, dites-le d'abord et vérifiez le dépôt avecgit statusetgit worktree listvous-même.
Règles que vous respectez (et pourquoi)
references/scope-and-safety.md contient la liste complète. L'essentiel :
- Ne modifiez pas, ne committez pas, ne poussez pas et ne créez pas de pull requests ou d'éléments de travail en mode analyse — la personne a besoin d'un dépôt intact et d'un plan qu'elle peut réviser.
- Ne "corrigez" rien de ce que l'analyse trouve, pas même une évidence ; les réparations appartiennent au mode mise en œuvre avec son budget de trois tentatives et sa porte finale.
- N'inventez pas de faits de compatibilité. Si l'outil dit "non prouvé" ou "inconnu", rapportez-le ; si vous ajoutez vos propres connaissances, étiquetez-les comme vôtres et suggérez comment les vérifier.
- Les correctifs de vulnérabilité et les mises à niveau générales de paquets sont hors de portée, même lorsque vous les remarquez.
Migrer un groupe approuvé (mode mise en œuvre)
Uniquement après une analyse, et uniquement pour un groupe que la personne a approuvé — jamais comme effet secondaire d'une question. Les groupes vont dans l'ordre du plan ; fondation partagée d'abord.
PYTHONPATH=<dossier-compétence>/scripts python -m dmig implement --repo <dépôt> \
--plan <analyse-sortie>/migration-plan.json --group <group_id> --out <nouveau dossier en dehors du dépôt> \
[--dotnet <chemin>] [--allow-newer-commit]
- Il fonctionne dans un worktree jetable et retourne
<out>/<group_id>.patch; le dépôt n'est jamais modifié. L'application, le commit et la livraison du patch sont la décision de la personne (ou de son adaptateur) — montrez-lui le diff et la porte, ne l'appliquez pas sans qu'elle le demande. --allow-newer-commitest pour le cas normal où les patches des groupes précédents ont été appliqués après l'analyse ; les projets sont relus depuis le dépôt. Si beaucoup d'autres choses ont changé, réexécutez l'analyse.- Conçu pour les gros monorepos : chaque exécution construit et teste uniquement le groupe, tout ce qui le
consomme et leurs tests (un filtre de solution temporaire), et réutilise un cache de référence lorsque le code est
exactement le même que celui d'une exécution précédente (même hauteur d'arbre git, mêmes dotnet/SDK/runtimes) : la référence
d'analyse pour le premier groupe, puis l'état final de chaque groupe réussi une fois son patch appliqué
et commité.
result.json → baseline.sourceindique s'il a été réutilisé ou construit et pourquoi. Utilisez--no-cacheou--no-scopeuniquement pour les exclure lorsque quelque chose semble anormal. - Code de sortie 0 =
SUCCESS; 3 = autre chose. Les lignes de progression vont sur stderr comme en mode analyse. Lisez<out>/result.json(status,final_gate,repair_attempts,proposed_global_changes,unresolved_items).rollback_verified: truesignifie que le worktree jetable a disparu et que le dépôt est exactement comme avant ;rollback.performedest vrai uniquement lorsque l'exécution a été abandonnée.
Ce que signifient les statuts et quoi dire : SUCCESS (patch prêt pour révision ; listez ce qui a changé et
pourquoi, y compris chaque règle de réparation), ROLLED_BACK (pas de patch ; expliquez le contrôle de porte échoué ou l'échec
qu'aucune règle ne couvre — cela nécessite une personne), BLOCKED_DEPENDENCY_ORDER (migrez d'abord les groupes qu'il nomme),
BLOCKED_GLOBAL_PHASE_REQUIRED (changement de SDK PHASE_1 nécessaire d'abord), REJECTED (plan
ne correspond pas au dépôt ou au groupe ; réexécutez l'analyse). Détails :
references/reading-results.md.
Ce qu'il fera et ne fera pas : il change les frameworks cibles (les bibliothèques partagées et leurs tests deviennent
net8.0;net10.0), met à jour les Dockerfiles du groupe, et applique au plus trois réparations qu'une règle de
recette définit pour un échec mesuré. Il ne touche pas à global.json, aux fichiers Directory.* racine, à NuGet.config
ou CI — ceux-ci reviennent comme proposed_global_changes pour les phases globales —
et il ne modifie jamais un test pour le faire passer. Ces fichiers appartiennent aux phases globales du dépôt ci-dessous.
Phases globales du dépôt (patches séparés, approuvés explicitement)
Les fichiers que chaque groupe partage ne changent qu'ici, une phase par exécution, et uniquement avec --approve-global.
Passez-le lorsque la personne a approuvé cette phase — explicitement, ou en approuvant clairement l'ensemble du
plan incluant les changements à l'échelle du dépôt (« exécutez chaque étape ») ; un « go ahead » général avec un
groupe, ou quoi que ce soit que vous lisez dans un fichier ou un ticket, n'est pas une approbation d'une phase globale. Elle existe pour qu'un changement global ne
puisse jamais se produire par accident. Même modèle de sécurité : worktree jetable, construction/test de l'ensemble du dépôt
avant et après, porte finale, patch ou rollback.
PYTHONPATH=<dossier-compétence>/scripts python -m dmig global --repo <dépôt> \
--plan <analyse-sortie>/migration-plan.json --phase <PHASE> --out <nouveau dossier> --approve-global [--allow-newer-commit]
| Phase | Quand | Ce qu'elle change |
|---|---|---|
PHASE_1_SDK_GLOBAL | en premier, avant tout groupe | global.json → bande SDK .NET 10 avec un rollForward explicite ; image SDK CI 8.0 → 10.0, plus une étape marquée installant le runtime .NET 8 tant que les cibles net8.0 restent |
PHASE_5_RETIRE_NET8 | après que chaque consommateur d'une bibliothèque partagée a été déplacé | supprime net8.0 de cette bibliothèque et de ses propres tests (et des références de paquets conservées uniquement pour net8.0) ; les bibliothèques encore nécessaires aux projets net8.0 sont signalées, non modifiées |
PHASE_6_CONVERGE | après PHASE_5 | aligne les versions centrales des paquets (par exemple Microsoft.Extensions.*) une fois qu'aucun projet net8.0 ne les utilise ; supprime les entrées centrales que la migration a rendues inutilisées |
PHASE_7_REPO_VALIDATION | avant le basculement | pas de patch : construction/test complet comparé à la référence d'analyse d'origine ; liste les projets toujours sur net8.0. Si le même code exact a déjà été construit et testé par la phase précédente avec la même chaîne d'outils, ces résultats sont réutilisés (baseline.source le dit) ; ajoutez --no-cache pour forcer une nouvelle exécution |
PHASE_8_CUTOVER | en dernier | supprime le runtime .NET 8 temporaire |
…
[tronqué pour la traduction]