Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Documentation/policies/package-servicing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# .NET Package Servicing Model

Most packages in the .NET ecosystem support only the latest version. Many packages from the .NET team operate on this same model. A subset of our packages operate on another model where multiple version bands are supported at the same time, matching in-support runtimes, offering more flexibility to users.

Users should aim to maintain their package references to be as close to the supported version as possible. Being close to a supported version means that you have most or all security fixes and likely have no latent compatibility risk that can be present when there is a big gap between your reference and the supported version.

## Latest version servicing

The default package servicing model is “latest version”. The team publishes an updated package with a security and/or functionality fix. Users can upgrade to the new latest version to get the fix.

The following libraries use this servicing model:

- [.NET Aspire](https://github.com/dotnet/aspire)
- [.NET Platform Extensions](https://github.com/dotnet/extensions)
- [ML.NET](https://github.com/dotnet/machinelearning)
- [Maintenance-packages](https://github.com/dotnet/maintenance-packages)
Copy link
Member

@eerhardt eerhardt Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to add dotnet/extensions here as well.

See https://dotnet.microsoft.com/en-us/platform/support/policy/extensions

One recurring point of confusion is that we have Microsoft.Extensions.* packages with different support models based on the repo it comes from. For MS.Ext libraries coming from runtime and aspnetcore, it uses Runtime-band servicing. For MS.Ext libraries in dotnet/extensions, it uses "Latest version servicing".


## Runtime-band servicing

Some packages match a library (in name and content) in the runtime. In this case, the team publishes fixes for the library in the runtime and the package at the same time. The version numbers will match. Users can upgrade to the new latest patch version to get the fix.

Users can upgrade to the latest library version (like 8.0.x) that matches a supported runtime (like 8.0). Users can also move to the latest patch of a newer major version (like 9.0.x) provided that the runtime is still in support.

The advantage of matching versions is that the runtime library will be used in place of the package, resulting in smaller deployments and servicing being provided by the runtime. The advantage of using a newer package version is getting access to newer functionality.

It common for .NET Standard libraries to have a reference to these libraries. Libraries and app projects only need a reference if they need access to newer features in a later major version (than their target framework exposes).

The following libraries use this servicing model:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add EF Core here?

cc @AndriySvyryd @SamMonoRT

Copy link
Member Author

@richlander richlander Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lists are not intended to be exhaustive. However, 3-6 examples would be great. Feel free to add in more via suggestion. It seems like an exhaustive list should be provided via a different approach. Same applies to your other comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if instead we could have a plan to represent this state somehow in the nuget gallery?

For instance -- through the support metadata -- or by observing the release cadence. Feels like it will be hard to make an exhaustive list here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One idea we had last week in a meeting in this area was:

  1. Mark old package versions as "deprecated" on nuget.org. (for example, all System.Text.Json 7.0.x versions would be marked as deprecated today.)
  2. Add tooling to let you know when you are using something is not supported any longer.

This way, you could see that the 8.x and 9.x versions were still in support. But the 7.x version isn't.

For "Latest version servicing" like .NET Aspire all 8.x versions would be marked as "deprecated".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exhaustive list

I'm not suggesting this list be exhaustive of all packages. What I am suggesting is to document the groups of packages that follow the same model. All Runtime, ASP.NET Core, EF Core follow this model. All Extensions, Aspire, ML.NET follow latest version model.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to write a doc for EF (in the EF repo) and we can link to it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love for support level to be exposed via the NuGet gallery and the NuGet API/client. That's clearly the best model. That's a good idea to follow merging this PR.

@OliaG @aortiz-msft

@richlander Long thread here. Would you please summarize the ask for us and open an issue in NuGet/Home?

cc @OliaG

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ask: There should be an E2E for deprecated/unsupported packages from producer marking existing packages as such and consumers getting warnings via the gallery, VS, and the NuGet/dotnet CLI. A team like ours isn't going to use the gallery to mark our packages as deprecated. We need an API for that (we're talking to @joelverhagen about that part). I can open an issue if there isn't one on that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That appears to be a match and I remember it now. Good find.

FYI: @JonDouglas

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it help to add dotnet/aspnetcore packages here as well? For example, Microsoft.AspNetCore.SignalR.Client and Microsoft.Extensions.Diagnostics.HealthChecks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk about HealthChecks, but SignalR.Client is not part of the shared framework, so it always requires a package reference.

Copy link
Member

@ericstj ericstj Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(some) Asp.NET packages are a special case of per-version servicing. I think in that case you must use the version that matches the .NET Version. They don't support other frameworks (like NetStandard, NETFramework, or the oldest LTS).
Then there's the old 2.x packages which do and follow "latest" servicing.


- [Microsoft.Extensions.DependencyInjection](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection)
- [System.Text.Json](https://www.nuget.org/packages/System.Text.Json)
- [System.Diagnostics.DiagnosticSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource)
- [ASP.NET Core Packages](https://github.com/dotnet/aspnetcore)
- [Entity Framework Core Packages](https://github.com/dotnet/efcore)

## Support

Users must be on the latest patch version of the package or a runtime-band to be supported.

## Compatibility

Packages retain compatibility for supported .NET versions. A package will not drop support for a .NET version that is in support. When a .NET version goes out of support, packages released after that point may drop support for that .NET version.

Mechanically, a package can support multiple target frameworks via either of two approaches:

- Multi-targeting: A project supports and is built for multiple target frameworks, resulting in assets supporting multiple .NET versions in a NuGet package.
- Branching: A project exists and is built in multiple branches, each targeting a specific target framework and resulting multiple packages that each include a single asset supporting a specific .NET version.

The differences in these approaches are user observable and require users to adopt different patterns with package references. It's the difference between the two versioning strategies defined earlier. They are also patterns that users can adopt for themselves with their own packages.

## End of Life

.NET packages are no longer supported when either of the following occurs:

- A new patch version of the package is available.
- The package exclusively includes implementations for out-of-support .NET versions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a package still supported if one of its (transitive) dependencies is not?

@GrabYourPitchforks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be a problem for that package to fix - more like an SDL issue for that package. Not something the customer is supposed to worry about.


Nuget.org includes [version](https://www.nuget.org/packages/System.Text.Json/#versions-body-tab) and [supported framework](https://www.nuget.org/packages/System.Text.Json/#supportedframeworks-body-tab) information that can be used to determine support status for packages.

It is important to avoid using packages that are no longer maintained. They may be missing security patches for known vulnerabilities.
17 changes: 5 additions & 12 deletions release-policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

The .NET team uses the following policies for [.NET releases](releases.md).

The NuGet packages that the team maintains are governed by [.NET Package Servicing](./Documentation/policies/package-servicing.md)

## Release cadence

New major .NET versions are released annually in November, at [.NET Conf](https://www.dotnetconf.net/).
Expand Down Expand Up @@ -55,22 +57,13 @@ Additionally, customers targeting an out-of-support .NET version in their projec

6 months after a .NET version goes out of support, newer in-support .NET SDK versions are updated to produce warning [NETSDK1138: The target framework is out of support](https://learn.microsoft.com/dotnet/core/tools/sdk-errors/netsdk1138) when targeting the out-of-support version.

### Packages

[.NET packages](https://www.nuget.org/profiles/dotnetframework) are no longer supported when either of the following occurs:

* A new version of the package is available. Some packages support multiple patches versions at once, one per major version matching a supported major .NET version.
* The package exclusively includes implementations for out-of-support .NET versions.

Nuget.org includes [version](https://www.nuget.org/packages/System.Text.Json/#versions-body-tab) and [supported framework](https://www.nuget.org/packages/System.Text.Json/#supportedframeworks-body-tab) information that can be used to determine support status for packages.

## Support requirements

To remain supported, you must do the following:

* Use a supported SDK
* Target a supported .NET version (via the `TargetFramework` property)
* Reference supported packages
* Use a [supported SDK](https://dotnet.microsoft.com/download)
* Target a [supported .NET version](./releases.md) (via the `TargetFramework` property)
* Reference [supported packages](./Documentation/policies/package-servicing.md)

## Operating System support

Expand Down