CommunityCodierung & Entwicklunggithub.com

dotnet-8-zu-10-migration

Planung und Durchführung einer .NET 8 → .NET 10 Migration eines Repositorys oder Monorepos in sicheren, überprüfbaren Schritten.

Was ist dotnet-8-zu-10-migration?

Diese Fähigkeit ermöglicht die Migration eines gesamten .NET 8 Repositorys auf .NET 10 in zwei Phasen: Analyse und Implementierung. In der Analysephase wird eine vollständige Projektstruktur erstellt, eine Umgebungsprüfung durchgeführt und die Migration in sichere Gruppen eingeteilt. Jede Gruppe wird durch eine Basislinie (Build/Test) und ein reversibles Experiment in einem temporären Git-Worktree validiert. Die Ergebnisse werden in einem geordneten Plan (JSON + Markdown-Bericht) dokumentiert. Für die Implementierung wird jeweils eine genehmigte Gruppe in einem isolierten Worktree mit maximal drei regelbasierten Reparaturversuchen migriert. Der Patch wird dann zur menschlichen Überprüfung bereitgestellt; bei Fehlschlag erfolgt ein automatischer Rollback. Die Fähigkeit ist für große Monorepos optimiert und unterstützt Windows, Linux und macOS über das Bundle `dmig`, ohne das Repository direkt zu bearbeiten oder Commits/Pull-Requests zu erstellen.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DmytroFlakac/dotnet-migration-skill/tree/HEAD/skill

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

.NET 8 → .NET 10 Migration

Diese Fähigkeit führt ein gebündeltes, deterministisches Tool (scripts/dmig) aus und erklärt dessen Ergebnisse. Führe immer zuerst eine Analyse durch; implementiere nur eine Gruppe, die die Person aus dieser Analyse genehmigt hat. Der Analysator misst; deine Aufgabe ist es, ihn korrekt auszuführen, seine Ergebnisse zu lesen und der Person zu erklären, was sie bedeuten – ohne etwas zu übertreiben, das er nicht verifizieren konnte.

Warum die Analyse an erster Stelle steht

In einem Monorepo ist ein Repository selten eine einzelne Migrationseinheit. Eine gemeinsam genutzte Bibliothek, die auf net10.0 umgestellt wird, zerbricht jede Anwendung, die noch auf net8.0 läuft, und Dateien wie global.json oder Directory.Packages.props betreffen alle. Daher kartiert die Analyse das gesamte Repository, schlägt Gruppen in einer sicheren Reihenfolge vor und belegt ihre Behauptungen mit einer Basislinie und einem Wegwerf-Experiment, bevor jemand echten Code ändert. Die Implementierung erfolgt später, eine genehmigte Gruppe nach der anderen.

Ausführung

  1. Wähle einen Ausgabeordner außerhalb des Repositorys (das Tool lehnt einen innerhalb des Repositorys ab): Berichte, Protokolle, NuGet-Metadaten-Cache und der temporäre Worktree werden dort abgelegt.

  2. Wähle das dotnet aus. Das Tool prüft SDKs und Laufzeiten selbst in seinem Preflight; du musst es nur auf die richtige ausführbare Datei verweisen. Wenn der Rechner ein privates dotnet-Root-Verzeichnis (SDK 10 + Laufzeit 8 nebeneinander) hat, übergib es mit --dotnet oder DMIG_DOTNET. Wenn .NET 8 in einem anderen dotnet-Ordner installiert ist, findet das Tool es an den üblichen Stellen oder übernimmt es von --dotnet-root <ordner> / DMIG_DOTNET_ROOTS und kombiniert es mit dem SDK über Links in einem eigenen Ordner (keine Installation wird geändert).

  3. Installiere die beiden Bibliotheken, falls nicht vorhanden, aus dem Python-Mirror der Organisation: python -m pip install -r requirements.txt (Tests: auch requirements-dev.txt). Verwende immer python -m ...: der Scripts-Ordner ist möglicherweise nicht im PATH. Es werden kein sh, bash oder sed benötigt.

  4. Führe die Analyse aus (Windows-Pfade funktionieren in PYTHONPATH, --repo und --out, auch von Git Bash):

    PYTHONPATH=<skill-verz>/scripts python -m dmig analyze --repo <repo> --out <ausgabe-verz> [--dotnet <pfad>]
    

    Nützliche Flags: --offline (keine Abfrage der konfigurierten Feeds), --no-baseline, --no-experiment, --environment contract.json (externe Testdienste und lizenzierte Tools, die die Umgebung bereitstellt), --request request.json (die neutrale Anfrage, siehe references/contracts.md). Erwarte etwa eine Minute für ein kleines Repository; große Monorepos brauchen so lange wie ihre eigene Wiederherstellung + Build + Test, zweimal (Basislinie und Experiment). Führe es im Hintergrund aus, wenn deine Umgebung dies erlaubt, und starte niemals eine zweite Kopie gleichzeitig im selben Repository. Der Fortschritt wird Zeile für Zeile auf stderr ausgegeben ([dmig hh:mm:ss] baseline …); stdout enthält nur die endgültige JSON-Zusammenfassung, und das vollständige Protokoll jedes Befehls erscheint in <out>/logs/, sobald er abgeschlossen ist.

    Es muss nichts installiert werden: Der Skill-Ordner enthält Startdateien, dmig.cmd (Windows) und dmig (Linux/macOS), äquivalent zu PYTHONPATH=<skill-verz>/scripts python -m dmig. python -m dmig preflight ... führt nur die Umgebungsprüfung durch (Sekunden). Auf einem neuen Rechner führe zuerst python -m dmig doctor <repo> aus: Eine Checkliste in Klartext (doctor-report.md, environment-capabilities.json, Ergebnis READY / READY_WITH_LIMITATIONS / BLOCKED).

    Kurzformen (die Integrationsnamen): Jeder Befehl nimmt das Repository als erstes Argument und setzt --out standardmäßig auf <repo>.dmig/<schritt>/ und --plan auf <repo>.dmig/analysis/migration-plan.json: dmig analyze <repo> --target net10.0, dmig migrate <repo> --group <id> (= implement), dmig validate <repo> --scope group|repository (--group <id> für eine Gruppe; repository = PHASE_7), dmig rollback <ausführungsordner> (bereinigt die Wegwerf-Kopie eines Durchlaufs und zeigt, wie man dessen Patch rückgängig macht). Jeder migrate/global/validate-Durchlauf schreibt auch dmig-result.json, das camelCase-Ergebnis des Vertrags. Paket-Mirror: --package-catalog mirror.json (nur genehmigte Versionen werden jemals ausgewählt; spätere Schritte verwenden es erneut).

    Standardeinstellungen, die zu respektieren sind: Das Tool hat keinen eigenen Netzwerkclient: Alles, was Pakete betrifft, läuft über dotnet und die auf dem Rechner konfigurierten Feeds, die standardmäßig abgefragt werden (--offline überspringt das). Der öffentliche Katalog nur mit --allow-public-nuget; ohne eine Katalogdatei sind Paketversionen METADATA_UNAVAILABLE (niemals erraten), und ein im Katalog fehlendes Paket ist PACKAGE_UNAVAILABLE. Framework-Add-ons sind ausgeschaltet: Web (ASP.NET Core), EF Core-Regeln und Windows-Dienste benötigen --adapters aspnet_core,efcore,windows_service zum Analysezeitpunkt; andernfalls sind ihre Gruppen OUT_OF_SCOPE_ADAPTER_DISABLED. .NET Framework, WPF, WinForms, MAUI, Xamarin und Azure Functions sind nur Bericht (OUT_OF_SCOPE_REPORT_ONLY); net*-windows-Gruppen ohne Windows sind BLOCKED_PLATFORM. Die Konsolenausgabe ist reines ASCII (PASS/WARN/FAIL/BLOCK). Eingaben, Ausgaben, Status und Exit-Codes: docs/integration-contract.md.

  5. Exit-Codes: 0 = Analyse abgeschlossen (möglicherweise mit Einschränkungen), 2 = BLOCKED.

Ergebnisse lesen

Lies zuerst <out>/response.json (seine summary enthält die Zählungen), dann <out>/migration-report.md. Beide sind in der Größe begrenzt – sie bleiben wenige KB, egal wie groß das Repository ist, und sagen „… und N mehr“, wo sie eine Liste abschneiden. Lies die großen Dateien nicht vollständig: migration-plan.json, inventory.json, baseline.json, experiment.json und compatibility.json wachsen mit dem Repository. Wenn du eine Gruppe benötigst, öffne ihre Notiz (unten) oder suche im JSON nach dieser group_id. Vollständige Protokolle sind in <out>/logs/; öffne eines nur, wenn ein Schritt fehlgeschlagen ist und das Ende nicht ausreicht.

Für Personen: Die Analyse schreibt auch einen Satz verknüpfter Obsidian-Notizen nach <out>/obsidian/<repo> .NET 10 Migration/ (oder in einen Vault-Ordner mit --obsidian-dir <ordner>), erstellt mit dem gebündelten obsreport-Paket: 00 Start hier (Urteil, Schlüsselzahlen, Top-5-Fixes nach Auswirkung), 01 Was wird brechen (Beweisstufen: bestätigt durch Build/Test → im Code gefunden → möglich, gefaltet), 02 Route (fünf Phasen), 03 Karte (Ebenen + eine zoombare Karte board.canvas), 04 Entscheidungen (jeweils eine Entscheidungsdokumentation), 05 Prüfer-FAQ, plus eine Notiz pro Gruppe, Regel und gemeinsam genutzter Bibliothek. Leite die Person zur Startnotiz, anstatt ihren Inhalt einzufügen.

Neu rendern ohne Neuerstellung: Nach Regel- oder Notiz-Layout-Änderungen erstellt python -m dmig report --repo <repo> --out <analyse-ordner> [--obsidian-dir <ordner>] [--offline] den Kompatibilitätsscan, Testvergleich, Plan, Bericht und Notizen aus den gespeicherten Ergebnissen in ein oder zwei Minuten neu, ohne Wiederherstellung, Build oder Test.

Zwei Dinge, die beim Lesen helfen:

  • Das Experiment zielt das gesamte Repository auf einmal auf einfaches net10.0 um, einschließlich gemeinsam genutzter Bibliotheken, die der Plan multi-targeten wird. Das ist beabsichtigt: Ein Durchlauf zeigt die net10.0-Fehler jedes Projekts, und der Vergleich mit der Basislinie ordnet jeden Fehler einer Gruppe zu (eine Regression in einer Anwendung, die durch eine gemeinsam genutzte Bibliothek verursacht wird, zeigt sich als WAITS_FOR_DEPENDENCY_REPAIR).
  • <out>/worktrees/ bleibt nach dem Durchlauf als leerer Ordner zurück (der darin enthaltene Worktree wird entfernt und überprüft), und <out>/nuget-cache/ behält NuGet-Metadaten, sodass ein erneuter Durchlauf schneller ist. Keines davon ist ein Überbleibsel im Repository.

Wenn du Bericht erstattest:

  • Beginne mit Status und Gruppenreihenfolge, dann die Bereitschaft jeder Gruppe und warum. Der Bericht ist normalerweise selbsterklärend; öffne references/reading-results.md, wenn ein Status, ein Bereitschaftswert oder ein Befund unbekannt ist. Ein Bereitschafts-Label nennt nur den Haupthinderungsgrund: Erwähne auch die eigenen vorgeschlagenen Reparaturen jeder Gruppe (z. B. eine Dockerfile-Änderung), die darunter aufgeführt sind.
  • Trenne, was verifiziert wurde, von dem, was abgeleitet wurde. Eine Gruppe ist nur dann READY, wenn das Experiment sie gegen eine Basislinie gebaut und getestet hat. Sage das, wenn Tests blockiert wurden, eine Plattform fehlte (Windows-Projekte auf Linux) oder ein Paket „nicht nachgewiesen“ ist.
  • Halte vorher bestehende Fehler getrennt. Basislinienfehler werden aufgezeichnet, nie als Migrationsprobleme gezählt und sind nie etwas, das die Migration „beheben“ sollte.
  • Nenne die Änderungsklasse von allem, was vorgeschlagen wird: PROJECT_LOCAL, GROUP_SHARED oder REPOSITORY_GLOBAL. Globale Änderungen (global.json, root Directory.*-Dateien, NuGet.config, CI) gehören zu den repository-weiten Phasen, niemals zu einer einzelnen Gruppe.
  • Zitiere rollback_verified und changes_persisted. Wenn der Rollback nicht verifiziert ist, sage das zuerst und überprüfe das Repository selbst mit git status und git worktree list.

Regeln, die du einhältst (und warum)

references/scope-and-safety.md enthält die vollständige Liste. Die Grundlagen:

  • Bearbeite, committe, pushe oder erstelle keine Pull-Requests oder Arbeitselemente im Analysemodus – die Person benötigt ein unberührtes Repository und einen Plan, den sie überprüfen kann.
  • „Behebe“ nichts, was die Analyse findet, nicht einmal einen offensichtlichen Einzeiler; Reparaturen gehören zum Implementierungsmodus mit seinem Budget von drei Versuchen und seiner finalen Prüfung.
  • Erfinde keine Kompatibilitätsfakten. Wenn das Tool „nicht nachgewiesen“ oder „unbekannt“ sagt, melde das; wenn du eigenes Wissen hinzufügst, kennzeichne es als deins und schlage vor, wie man es verifizieren kann.
  • Sicherheitslücken-Fixes und allgemeine Paket-Upgrades liegen außerhalb des Rahmens, selbst wenn du sie bemerkst.

Eine genehmigte Gruppe migrieren (Implementierungsmodus)

Nur nach einer Analyse und nur für eine Gruppe, die die Person genehmigt hat – niemals als Nebeneffekt einer Frage. Gruppen gehen in der Plan-Reihenfolge; gemeinsam genutzte Basis zuerst.

PYTHONPATH=<skill-verz>/scripts python -m dmig implement --repo <repo> \
  --plan <analyse-ausgabe>/migration-plan.json --group <group_id> --out <neuer Ordner außerhalb des Repos> \
  [--dotnet <pfad>] [--allow-newer-commit]
  • Es arbeitet in einem Wegwerf-Worktree und gibt <out>/<group_id>.patch zurück; das Repository wird nie modifiziert. Das Anwenden, Committen und Ausliefern des Patches ist die Entscheidung der Person (oder ihres Adapters) – zeige ihr den Diff und die Prüfung, wende ihn nicht ungefragt an.
  • --allow-newer-commit ist für den Normalfall, dass die Patches früherer Gruppen nach der Analyse angewendet wurden; Projekte werden aus dem Repository neu gelesen. Wenn sich viel anderes geändert hat, führe die Analyse erneut aus.
  • Für große Monorepos gebaut: Jeder Durchlauf baut und testet nur die Gruppe, alles, was sie konsumiert, und deren Tests (ein temporärer Lösungsfilter) und verwendet einen zwischengespeicherten Basislinienwert, wenn der Code exakt derselbe wie bei einem vorherigen Durchlauf ist (gleicher Git-Tree-Hash, gleiches dotnet/SDK/Laufzeiten): die Analyse-Basislinie für die erste Gruppe, dann der Endzustand jeder erfolgreichen Gruppe, sobald ihr Patch angewendet und committet ist. result.json → baseline.source sagt, ob es wiederverwendet oder gebaut wurde und warum. Verwende --no-cache oder --no-scope nur, um diese auszuschließen, wenn etwas falsch aussieht.
  • Exit-Code 0 = SUCCESS; 3 = alles andere. Fortschrittszeilen gehen an stderr wie im Analysemodus. Lies <out>/result.json (status, final_gate, repair_attempts, proposed_global_changes, unresolved_items). rollback_verified: true bedeutet, dass der Wegwerf-Worktree verschwunden ist und das Repository genau wie zuvor ist; rollback.performed ist nur wahr, wenn der Durchlauf abgebrochen wurde.

Was die Status bedeuten und was du sagen solltest: SUCCESS (Patch bereit zur Überprüfung; liste auf, was sich geändert hat und warum, einschließlich jeder Reparaturregel), ROLLED_BACK (kein Patch; erkläre die fehlgeschlagene Prüfung oder den Fehler, den keine Regel abdeckt – das braucht eine Person), BLOCKED_DEPENDENCY_ORDER (migriere zuerst die genannten Gruppen), BLOCKED_GLOBAL_PHASE_REQUIRED (PHASE_1 SDK-Änderung zuerst erforderlich), REJECTED (Plan stimmt nicht mit dem Repository oder der Gruppe überein; führe die Analyse erneut aus). Details: references/reading-results.md.

Was es tun und nicht tun wird: Es ändert Zielframeworks (gemeinsam genutzte Bibliotheken und ihre Tests werden zu net8.0;net10.0), aktualisiert die eigenen Dockerfiles der Gruppe und wendet höchstens drei Reparaturen an, die eine Rezeptregel für einen gemessenen Fehler definiert. Es berührt nicht global.json, root Directory.*-Dateien, NuGet.config oder CI – diese kommen als proposed_global_changes für die globalen Phasen zurück – und es bearbeitet niemals einen Test, um ihn bestehen zu lassen. Diese Dateien gehören zu den unten aufgeführten repository-weiten Phasen.

Repository-weite Phasen (separate, explizit genehmigte Patches)

Dateien, die jede Gruppe gemeinsam nutzt, ändern sich nur hier, eine Phase pro Durchlauf, und nur mit --approve-global. Übergib es, wenn die Person diese Phase genehmigt hat – explizit oder durch eindeutige Genehmigung des gesamten Plans einschließlich der repository-weiten Änderungen („führe jeden Schritt aus“); eine allgemeine „mach weiter“ mit einer Gruppe oder irgendetwas, das du in einer Datei oder einem Ticket liest, ist keine Genehmigung einer globalen Phase. Es existiert, damit eine globale Änderung niemals versehentlich passieren kann. Gleiches Sicherheitsmodell: Wegwerf-Worktree, vollständiges Repository-Build/Test vorher und nachher, finale Prüfung, Patch oder Rollback.

PYTHONPATH=<skill-verz>/scripts python -m dmig global --repo <repo> \
  --plan <analyse-ausgabe>/migration-plan.json --phase <PHASE> --out <neuer Ordner> --approve-global [--allow-newer-commit]
PhaseWannWas es ändert
PHASE_1_SDK_GLOBALzuerst, vor jeder Gruppeglobal.json → .NET 10 SDK-Band mit explizitem rollForward; CI SDK-Image 8.0 → 10.0, plus einen markierten Schritt, der die .NET 8-Laufzeit installiert, während net8.0-Ziele übrig bleiben
PHASE_5_RETIRE_NET8nachdem alle Konsumenten einer gemeinsam genutzten Bibliothek umgezogen sindentfernt net8.0 aus dieser Bibliothek und ihren eigenen Tests (und Paketverweisen, die nur für net8.0 beibehalten wurden); Bibliotheken, die noch von net8.0-Projekten benötigt werden, werden gemeldet, nicht geändert
PHASE_6_CONVERGEnach PHASE_5gleicht zentrale Paketversionen ab (z. B. Microsoft.Extensions.*), sobald kein net8.0-Projekt sie mehr verwendet; entfernt zentrale Einträge, die die Migration überflüssig gemacht hat
PHASE_7_REPO_VALIDATIONvor dem Cutoverkein Patch: vollständiger Build/Test verglichen mit der ursprünglichen Analyse-Basislinie; listet Projekte auf, die noch auf net8.0 sind. Wenn der exakt gleiche Code bereits von der vorherigen Phase mit derselben Toolchain gebaut und getestet wurde, werden diese Ergebnisse wiederverwendet (baseline.source sagt das); füge --no-cache hinzu, um einen frischen Durchlauf zu erzwingen
PHASE_8_CUTOVERals letztesentfernt die temporäre .NET 8-Laufzeitinstallation (entfernt rollForward aus global.json, installiert nur noch SDK 10 in CI) und ersetzt alle verbleibenden .NET 8-Containerimages durch .NET 10-Äquivalente; entfernt entfernte Paket-Quellen; archiviert die Analyse- und Migrationsartefakte in einen nicht standardmäßigen Pfad, sodass Ordner wie global.json und Directory.Build.props nicht mehr auf die Migration verweisen

Verwandte Skills