Skip to content

Commit 3c35807

Browse files
committed
second iteration
1 parent f67cb20 commit 3c35807

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed
Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,38 @@
11
# SDK Breaking Change and Diagnostic Guidelines
22

3-
Teams may want to add new diagnostics or breaking changes to the SDK. This document provides guidelines for how to introduce a new diagnostic or breaking change, which configuration knobs are available to teams, and what criteria should guide the decision around severity, timeline for introduction, and deprecation of diagnostics.
3+
This document provides guidelines for introducing new diagnostics or breaking changes to the .NET SDK, which configuration knobs are available, and what criteria should guide the decision around severity, timeline for introduction, and deprecation of diagnostics.
44

55
## Overall procedure
66

7-
In general, we want to make updating the SDK as smooth as possible for users. This means as much as possible
8-
not rocking the boat unnecessarily. This means
7+
In general, we want to make updating the .NET SDK as smooth as possible for developers. This means:
98

109
* introducing new changes in a staged/gradual way
11-
* trying to tie opinionated analyzers/changes to a mechanism that requires explicit user input
10+
* trying to tie opinionated analyzers/diagnostics to a mechanism that requires explicit user opt-in
1211
* providing a way to opt out of a change entirely
1312

1413
## Kinds of changes
1514

16-
There are a bunch of kinds of changes that can ship in the SDK, and they have different implications for users. Here are some examples:
15+
There are many kinds of breaking changes that can ship in the .NET SDK, such as:
1716

18-
* MSBuild warnings and errors
19-
* Directly triggered in MSBuild logic (props/targets)
20-
* directly in the SDK props/targets
21-
* indirectly via codeflow, just shipped in the SDK
22-
* Directly written by MSBuild Task implementations
23-
* Including those surfaced by key partners like NuGet (e.g. NuGet Audit, Package Source Mapping)
17+
* * New MSBuild warnings and errors (props/targets)
18+
* New NuGet warnings and errors.
19+
* For example, NuGet Audit.
2420
* Roslyn Analyzers and CodeFixes
2521
* This includes trimming/ILLink analyzers and codefixes
2622
* Behavioral/implementation changes
2723
* MSBuild engine changes like MSBuild Server
2824
* Implementation changes for MSBuild Tasks
2925
* NuGet Restore algorithm enhancements
30-
* Changes to CLI grammar
26+
* Changes to DotNet CLI grammar
3127
* Changes to defaults in CLI flags that impact behavior
32-
* `--configuration` flag defaulting to `Release` instead of `Debug`
28+
* For example, `--configuration` flag defaulting to `Release` instead of `Debug`
3329

3430
## Configuration Knobs
3531

36-
The following knobs are available to teams to configure various changes (some may not apply to all kinds of changes):
32+
The following knobs are available to enable/disable these changes (some may not apply to all kinds of changes):
3733

38-
* TargetFramework (TFM)
39-
* SDK version (via SdkAnalysisLevel)
34+
* [TargetFramework](https://learn.microsoft.com/en-us/dotnet/standard/frameworks)
35+
* [SdkAnalysisLevel](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#sdkanalysislevel)
4036
* EditorConfig (for Analyzers)
4137
* AnalysisLevel (for Analyzers/CodeFixes)
4238
* WarningLevel
@@ -45,7 +41,7 @@ The following knobs are available to teams to configure various changes (some ma
4541

4642
* Implement changes in an informational/non-blocking way initially
4743

48-
What this means will vary change-to-change. For a change expressed as an Analyzer or MSBuild diagnostic, consider
44+
What this means will vary change-to-change. For example, for a change expressed as an Analyzer or MSBuild diagnostic, consider
4945
Informational level severities initially. For a behavioral change on a CLI, consider an informational message written to the
5046
stderr channel on the console instead of making the stdout output un-parseable by tools.
5147

@@ -54,9 +50,7 @@ the old command was still the default supported and a warning was written to the
5450

5551
* Gradually increase severity over each release
5652

57-
If a change in introduced in an informational/non-blocking way, determine the time frame where it is safe to increase the severity. For Analyzers, this may mean tying it to the next value of AnalysisLevel (which is downstream of TFM). For
58-
MSBuild diagnostics, this may mean tying it to the next Warning Level or SdkAnalysisLevel. For CLI changes, this may mean tying it to the next LTS major version of the SDK. Ideally the way you would structure this increase would be automated and
59-
documented so that users know what's coming down the pipe.
53+
If a change in introduced in an informational/non-blocking way, determine the time frame where it is safe to increase the severity. For Analyzers, this may mean tying it to the next value of AnalysisLevel (which is downstream of TFM). For small MSBuild and NuGet diagnostics, this may mean tying it to the next Warning Level or SdkAnalysisLevel. For CLI changes, this may mean tying it to the next LTS major version of the SDK. Ideally the way you would structure this increase would be automated and documented so that users know what's coming down the pipe.
6054

6155
* Cut-over to new behavior after a long introduction period
6256

@@ -68,11 +62,20 @@ provide enough time for users to adapt - for example the `dotnet new --list` exa
6862
Have some kind of knob that allows users to opt out of the change entirely. This could be a flag, an environment variable, or a global.json setting. This allows users to continue using the old behavior if they need to in exceptional situations. It is
6963
important to document this knob and its behavior in the SDK documentation. It is also important to define a timeline for when this knob will be removed entirely, forcing users to adopt the new behavior.
7064

71-
For systems like Analyzers that time may be 'never', because the cost of detection is so low. This is a product-level decision
72-
that is hard to give universal guidance for.
65+
For systems like Analyzers that time may be 'never', because the cost of detection is so low. This is a product-level decision that is hard to give universal guidance for.
7366

7467
* Hook into the unified SdkAnalysisLevel knob to allow users to easily opt out of all changes
7568

7669
This knob exists so that users can safely and consistently say "for whatever reason, I just need you to act like SDK version X". This is the one-stop shop - users no longer need to know about all the individual knobs that are available to them.
7770

78-
## Worked examples of changes
71+
* Tie potentially impactful changes to the TFM targeted by the application/library.
72+
73+
Changes that are expected to cause significant disruption should only be introduced behind the Target Framework knob. This eliminates business continuity and allows developers to address changes needed as part of scheduled work to migrate a codebase to a new TFM.
74+
75+
Concrete example: NuGet warnings for vulnerable transitive dependencies were introduced only for applications targeting .NET 10 and higher.
76+
77+
## Other recommendations
78+
79+
* If possible, introduce significant breaking changes in a non-LTS release.
80+
* Publish blog posts and update public documentation as appropriate as early as possible.
81+
* Consider creating and pinning an issue in the corresponding GitHub repository where customers can provide feedback.

0 commit comments

Comments
 (0)