.NET Upgrade Workflow
Purpose
Upgrade .NET projects without losing track of compatibility, validation, or language-specific behavior.
The practical job is to inventory SDK and target framework state, choose the upgrade boundary, apply the smallest coherent change, run staged validation, and document migration notes when users or package consumers need them.
When To Use
- Use this skill when changing
TargetFramework or TargetFrameworks.
- Use this skill when changing
global.json.
- Use this skill when upgrading package versions across a .NET solution.
- Use this skill when moving between .NET major versions.
- Use this skill when F# or C# language behavior may change with the SDK or target framework.
Source Check
Use repo-local files, checked-out dependency sources, Dash MCP or Dash HTTP for installed docsets, and then official project documentation when Dash/local coverage is missing or stale:
Upgrade Workflow
- Inventory current state:
rg -n "TargetFramework|TargetFrameworks|LangVersion|PackageReference|PackageVersion|Sdk=" .
rg --files -g 'global.json' -g 'Directory.Build.props' -g 'Directory.Packages.props' -g '*.fsproj' -g '*.csproj' -g '*.sln' -g '*.slnx'
- Check installed SDKs when local validation is required:
dotnet --list-sdks
dotnet sdk check
- Decide upgrade boundary:
- SDK only
- target framework only
- package versions only
- SDK plus target framework
- package plus framework compatibility pass
- Read breaking-change notes for the source and target versions.
- Apply one coherent upgrade slice.
- Run staged validation:
dotnet restore
dotnet build
dotnet test
dotnet pack when package surfaces exist
- Update docs or release notes when public behavior, package requirements, or contributor setup changes.
F# Upgrade Notes
For F#:
- check compiler or language-version behavior before changing project defaults
- inspect
.fsproj ordering after automated edits
- watch for APIs that become more awkward across async/task boundaries
- run tests that cover discriminated union, option, and record serialization when those are public contracts
C# Upgrade Notes
For C#:
- check nullable and analyzer behavior after SDK changes
- avoid broad warning suppression after analyzer updates
- decide whether new language features belong in the repo style before using them
- check source generators or analyzers when present
Output Shape
Return:
Upgrade boundary: SDK, target framework, packages, or combination.
Before: current SDK, TFM, package, and language state.
After: target SDK, TFM, package, and language state.
Compatibility notes: breaking changes or migration concerns checked.
Validation: exact commands and results.
Docs: README, contributing, release notes, or package guidance updated.
Guardrails
- Do not upgrade multiple unrelated surfaces in one commit without a clear reason.
- Do not ignore official breaking-change notes for major upgrades.
- Do not commit machine-local SDK paths or private package feeds.
- Do not suppress new analyzer warnings without explaining the rule and reason.
- Do not call an upgrade complete until build and tests have run or the blocker is explicit.
1---2name: upgrade-workflow3description: Plan and validate .NET SDK, target framework, package, and language-version upgrades for F#, C#, and mixed solutions with compatibility checks and staged validation.4license: Apache-2.05---67# .NET Upgrade Workflow89## Purpose1011Upgrade .NET projects without losing track of compatibility, validation, or language-specific behavior.1213The practical job is to inventory SDK and target framework state, choose the upgrade boundary, apply the smallest coherent change, run staged validation, and document migration notes when users or package consumers need them.1415## When To Use1617- Use this skill when changing `TargetFramework` or `TargetFrameworks`.18- Use this skill when changing `global.json`.19- Use this skill when upgrading package versions across a .NET solution.20- Use this skill when moving between .NET major versions.21- Use this skill when F# or C# language behavior may change with the SDK or target framework.2223## Source Check2425Use repo-local files, checked-out dependency sources, Dash MCP or Dash HTTP for installed docsets, and then official project documentation when Dash/local coverage is missing or stale:2627- [.NET breaking changes reference](https://learn.microsoft.com/dotnet/core/compatibility/breaking-changes)28- [Breaking changes may occur when porting code](https://learn.microsoft.com/dotnet/core/porting/breaking-changes)29- [`global.json` documentation](https://learn.microsoft.com/dotnet/core/tools/global-json)30- [`dotnet sdk check` documentation](https://learn.microsoft.com/dotnet/core/tools/dotnet-sdk-check)31- [.NET CLI documentation](https://learn.microsoft.com/dotnet/core/tools/)3233## Upgrade Workflow34351. Inventory current state:36 ```bash37 rg -n "TargetFramework|TargetFrameworks|LangVersion|PackageReference|PackageVersion|Sdk=" .38 rg --files -g 'global.json' -g 'Directory.Build.props' -g 'Directory.Packages.props' -g '*.fsproj' -g '*.csproj' -g '*.sln' -g '*.slnx'39 ```402. Check installed SDKs when local validation is required:41 ```bash42 dotnet --list-sdks43 dotnet sdk check44 ```453. Decide upgrade boundary:46 - SDK only47 - target framework only48 - package versions only49 - SDK plus target framework50 - package plus framework compatibility pass514. Read breaking-change notes for the source and target versions.525. Apply one coherent upgrade slice.536. Run staged validation:54 - `dotnet restore`55 - `dotnet build`56 - `dotnet test`57 - `dotnet pack` when package surfaces exist587. Update docs or release notes when public behavior, package requirements, or contributor setup changes.5960## F# Upgrade Notes6162For F#:6364- check compiler or language-version behavior before changing project defaults65- inspect `.fsproj` ordering after automated edits66- watch for APIs that become more awkward across async/task boundaries67- run tests that cover discriminated union, option, and record serialization when those are public contracts6869## C# Upgrade Notes7071For C#:7273- check nullable and analyzer behavior after SDK changes74- avoid broad warning suppression after analyzer updates75- decide whether new language features belong in the repo style before using them76- check source generators or analyzers when present7778## Output Shape7980Return:81821. `Upgrade boundary`: SDK, target framework, packages, or combination.832. `Before`: current SDK, TFM, package, and language state.843. `After`: target SDK, TFM, package, and language state.854. `Compatibility notes`: breaking changes or migration concerns checked.865. `Validation`: exact commands and results.876. `Docs`: README, contributing, release notes, or package guidance updated.8889## Guardrails9091- Do not upgrade multiple unrelated surfaces in one commit without a clear reason.92- Do not ignore official breaking-change notes for major upgrades.93- Do not commit machine-local SDK paths or private package feeds.94- Do not suppress new analyzer warnings without explaining the rule and reason.95- Do not call an upgrade complete until build and tests have run or the blocker is explicit.