diff --git a/docs/core/install/upgrade.md b/docs/core/install/upgrade.md
index 8fa3fee613b96..c4159da908a94 100644
--- a/docs/core/install/upgrade.md
+++ b/docs/core/install/upgrade.md
@@ -1,7 +1,8 @@
---
title: Upgrade to a new .NET version
-description: Learn how to upgrade an app to a new .NET version. Upgrade .NET when the current version goes out of support or when you want to use new features of .NET.
-ms.date: 11/11/2024
+description: Learn how to upgrade an app to a new .NET version. Upgrade .NET when the current version goes out of support or when you want to use new features of .NET. Control versions of SDK, analyzers, and packages for predictable builds.
+ms.date: 10/28/2025
+ai-usage: ai-assisted
---
# Upgrade to a new .NET version
@@ -51,6 +52,165 @@ More resources:
- [Migrate an ASP.NET Core app](/aspnet/core/migration/)
- [Upgrade .NET MAUI from .NET 7 to .NET 8](https://github.com/dotnet/maui/wiki/Upgrading-.NET-MAUI-from-.NET-7-to-.NET-8)
+## Version pinning
+
+When you upgrade development tools like the .NET SDK, Visual Studio, or other components, you might encounter new behaviors, analyzer warnings, or breaking changes that affect your build process. By pinning to a version, you can upgrade your development environment while maintaining control over when specific components are updated in your projects.
+
+Version pinning provides several benefits:
+
+- **Predictable builds**: Ensures consistent build results across different machines and CI/CD environments.
+- **Gradual adoption**: Allows you to adopt new features incrementally rather than all at once.
+- **Avoid unexpected changes**: Prevents new analyzer rules, SDK behaviors, or package versions from causing build failures.
+- **Team coordination**: Enables teams to upgrade together at a planned time rather than individually when tools update.
+- **Debugging and troubleshooting**: Makes it easier to isolate issues when you control which versions changed.
+
+The following sections describe various mechanisms for controlling versions of different components in your .NET projects:
+
+- [Control SDK version with global.json](#control-sdk-version-with-globaljson)
+- [Control analyzer behavior](#control-analyzer-behavior)
+- [Control NuGet package versions](#control-nuget-package-versions)
+- [Control MSBuild version](#control-msbuild-version)
+
+### Control SDK version with global.json
+
+You can pin the .NET SDK version for a project or solution by using a *global.json* file. This file specifies which SDK version to use when running .NET CLI commands and is independent of the runtime version your project targets.
+
+Create a *global.json* file in your solution root directory:
+
+```dotnetcli
+dotnet new globaljson --sdk-version 9.0.100 --roll-forward latestFeature
+```
+
+This command creates the following *global.json* file that pins the SDK to version 9.0.100 or any later patch or feature band within the 9.0 major version:
+
+```json
+{
+ "sdk": {
+ "version": "9.0.100",
+ "rollForward": "latestFeature"
+ }
+}
+```
+
+The `rollForward` policy controls how the SDK version is selected when the exact version isn't available. This configuration ensures that when you upgrade Visual Studio or install a new SDK, your project continues to use SDK 9.0.x until you explicitly update the *global.json* file.
+
+For more information, see [global.json overview](../tools/global-json.md).
+
+### Control analyzer behavior
+
+Code analyzers can introduce new warnings or change behavior between versions. You can control analyzer versions to maintain consistent builds by using the [`AnalysisLevel` property](../project-sdk/msbuild-props.md#analysislevel). This property allows you to lock to a specific version of analyzer rules, preventing new rules from being introduced when you upgrade the SDK.
+
+```xml
+
+ 9.0
+
+```
+
+When set to `9.0`, only the analyzer rules that shipped with .NET 9 are enabled, even if you're using the .NET 10 SDK. This prevents new .NET 10 analyzer rules from affecting your build until you're ready to address them.
+
+For more information, see [AnalysisLevel](../project-sdk/msbuild-props.md#analysislevel).
+
+### Control NuGet package versions
+
+By managing package versions consistently across projects, you can prevent unexpected updates and maintain reliable builds.
+
+- [Package lock files](#package-lock-files)
+- [Central package management](#central-package-management)
+- [Package source mapping](#package-source-mapping)
+
+#### Package lock files
+
+Package lock files ensure that package restore operations use the exact same package versions across different environments. The lock file (`packages.lock.json`) records the exact versions of all packages and their dependencies.
+
+Enable lock files in your project file:
+
+```xml
+
+ true
+
+```
+
+To ensure builds fail if the lock file is out of date:
+
+```xml
+
+ true
+ true
+
+```
+
+After enabling lock files, run `dotnet restore` to generate the *packages.lock.json* file. Commit this file to source control.
+
+#### Central package management
+
+Central package management (CPM) allows you to manage package versions in a single location for all projects in a solution. This approach simplifies version management and ensures consistency across projects.
+
+Create a *Directory.Packages.props* file in your solution root:
+
+```xml
+
+
+ true
+
+
+
+
+
+
+
+```
+
+In your project files, reference packages without specifying a version:
+
+```xml
+
+
+
+
+```
+
+#### Package source mapping
+
+Package source mapping allows you to control which NuGet feeds are used for specific packages, improving security and reliability.
+
+Configure source mapping in your *nuget.config* file:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+This configuration ensures that all packages starting with `Contoso.` are only restored from the `contoso` feed, while other packages come from `nuget.org`.
+
+For more information, see [NuGet package restore](../tools/dotnet-restore.md).
+
+### Control MSBuild version
+
+Visual Studio supports side-by-side installation of multiple versions. For example, you can install Visual Studio 2026 and Visual Studio 2022 on the same machine. Each Visual Studio version includes a corresponding .NET SDK. When you update Visual Studio, the included SDK version is updated as well. However, you can continue using older SDK versions by installing them separately from the [.NET download page](https://dotnet.microsoft.com/download).
+
+MSBuild versions correspond to Visual Studio versions. For example, Visual Studio 2022 version 17.8 includes MSBuild 17.8. The .NET SDK also includes MSBuild. When you use `dotnet build`, you're using the MSBuild version included with the SDK specified by *global.json* or the latest installed SDK.
+
+To use a specific MSBuild version:
+
+- Use `dotnet build` with a pinned SDK version in *global.json*.
+- Launch the appropriate Visual Studio Developer Command Prompt, which sets up the environment for that Visual Studio version's MSBuild.
+- Directly invoke MSBuild from a specific Visual Studio installation (for example, `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MSBuild.exe"`).
+
+For more information, see [.NET SDK, MSBuild, and Visual Studio versioning](../porting/versioning-sdk-msbuild-vs.md).
+
## Update continuous integration (CI)
CI pipelines follow a similar update process as project files and Dockerfiles. Typically, you can update [CI pipelines](https://github.com/actions/setup-dotnet) by changing only version values.
@@ -68,3 +228,8 @@ FROM mcr.microsoft.com/dotnet/aspnet:9.0
```
In a cloud service like [Azure App Service](/azure/app-service/quickstart-dotnetcore), a configuration change is needed.
+
+## See also
+
+- [Breaking changes in .NET 10](../compatibility/10.0.md)
+- [Migrate an ASP.NET Core app](/aspnet/core/migration/)
diff --git a/docs/fundamentals/code-analysis/configuration-options.md b/docs/fundamentals/code-analysis/configuration-options.md
index 031c5a9a712f1..662aac41be0bd 100644
--- a/docs/fundamentals/code-analysis/configuration-options.md
+++ b/docs/fundamentals/code-analysis/configuration-options.md
@@ -78,14 +78,14 @@ Rule-specific options can be applied to a single rule, a set of rules, or all ru
The following table shows the different rule severities that you can configure for all analyzer rules, including [code quality](quality-rules/index.md) and [code style](style-rules/index.md) rules.
-| Severity configuration value | Build-time behavior |
-|-|-|
-| `error` | Violations appear as build *errors* and cause builds to fail.|
-| `warning` | Violations appear as build *warnings* but do not cause builds to fail (unless you have an option set to treat warnings as errors). |
-| `suggestion` | Violations appear as build *messages* and as suggestions in the Visual Studio IDE. (In Visual Studio, suggestions appear as three gray dots under the first two characters.) |
-| `silent` | Violations aren't visible to the user.
However, for code-style rules, Visual Studio code-generation features still generate code in this style. These rules also participate in cleanup and appear in the **Quick Actions and Refactorings** menu in Visual Studio. |
-| `none` | Rule is suppressed completely.
However, for code-style rules, Visual Studio code-generation features still generate code in this style. |
-| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [roslyn-analyzers repo](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |
+| Severity configuration value | Build-time behavior |
+|------------------------------|---------------------------------------------------------------|
+| `error` | Violations appear as build *errors* and cause builds to fail. |
+| `warning` | Violations appear as build *warnings* but do not cause builds to fail (unless you have an option set to treat warnings as errors). |
+| `suggestion` | Violations appear as build *messages* and as suggestions in the Visual Studio IDE. (In Visual Studio, suggestions appear as three gray dots under the first two characters.) |
+| `silent` | Violations aren't visible to the user.
However, for code-style rules, Visual Studio code-generation features still generate code in this style. These rules also participate in cleanup and appear in the **Quick Actions and Refactorings** menu in Visual Studio. |
+| `none` | Rule is suppressed completely.
However, for code-style rules, Visual Studio code-generation features still generate code in this style. |
+| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [roslyn-analyzers repo](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |
#### Scope