-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] .NET Tools should default to running on the latest available Runtime #30336
Comments
Pinging @richlander and @vitek-karas because this behavior change would technically limit the flexibility of the runtime to make breaking changes. |
I think it would be really unfortunate if this caused use to change the bar on breaking changes in .NET (it doesn't feel important enough to do that). So far we've been pretty specific about developers making an explicit decision to roll forward over major versions. That said I agree that for the tools this makes a lot of sense. I think we should be very explicit about this - meaning that installing the tool will "force roll-forward" and what are the ways for tool's developers to avoid that. Basically still trying to keep our existing major version compatibility stance, and .NET tools would be an explicit exception to the rule - where developing a tool is in itself an opt-in to this behavioral change. |
This other proposal is getting at much of the same thing, but in a different way. I'd rather see us focus on making it easier to move projects forward to new .NET versions. I think this other proposal has less of the issues that Vitek is concerned about. I also agree that changing our roll-forward policy (for any binaries) is going to cause us pain. I think it is good we have an opt-in, for both producer and consumer of code. |
My understanding is that this issue is trying to solve the problem that we have a slew of tools already on NuGet, but when we release 8.0 P1, only a few of them will work (those who added rollforward manually). I agree that it would be really nice to have a majority of the tools working from day 1 (especially since we rarely break people anymore). #29949 will only make it easier to test the update (note that I can't publish the tool with that, since it would modify the min supported version). So the two are only related to the extent that latter makes it easier for people to test major versions. |
As a single data point, if this automatic roll-forward was applied to .NET tools, the dotnet-monitor tool (which is an ASP.NET application that ships as a .NET tool) would likely opt-out of it. There was a change (I believe it was this) between .NET 6 and .NET 7 regarding the NTAuthentication class on which the Microsoft.AspNetCore.Authentication.Negotiate assembly used reflection to access internal APIs. It was changed in .NET 7 in such a way that the Negotiate assembly could no longer lookup the API it was attempting to reflect over. We had to disable roll-forward due to this change. We're okay with disabling roll-forward because we are actively working on dotnet-monitor and are releasing previews in lock-step with .NET 8 all up. |
You are right @vitek-karas. The thing I'm getting at doesn't solve the problem. However, one of the reasons why some people have pushed back on my proposal is compatibility. If we cannot enable an easier source upgrade option, then binary roll-forward is off the table. The two options are on a compatibility spectrum. |
Our compat bar is based on the idea that no scenarios auto roll-forward. I think we should keep to that. Otherwise, we probably need to reframe our compat bar, which I believe hasn't happened. An alternate premise to tools auto rollforward is that users lack sufficient UX to make on-demand rollforward tenable. Said differently, the tools auto roll-forward change is a band-aid change over poor UX. We should fix the UX and hold fixing the experience (by reverting the roll-forward change) until we can invest in changes like the ones proposed as follows. Another philosophy point is that we've tried to make tools just a opinionated delivery of an app, but everything else is the same. If tools need some improved UX (beyond delivery), it is almost certain that general apps need that too. If we make those more general changes, everyone wins. I propose we do the following (somewhat of a repeat of the OP).
Roll-forward with a single gestureWhen I run a .NET 7 app in a .NET 8 Preview environment, I have to do the following: export DOTNET_ROLL_FORWARD=LatestMajor
export DOTNET_ROLL_FORWARD_TO_PRERELEASE=1 Note: There are some cases where an app with just I find this requirement to be over the top and requires a lot of extra knowledge of users. I also find that the harm it is saving me from to not be all that compelling. We have two choices here:
We want installing pre-release versions to be pretty safe, so the first option is a little too scary. That leaves that last option. The following proposal isn't perfect, but is basically the same with a short suffix. Perhaps someone can come up with a better name. export DOTNET_ROLL_FORWARD=TestLatest The idea is select a name that describes the intent and is clearly not prod oriented. Roll-forward on installThis should be similar for
% cat hello-world.csproj | grep Target
<TargetFramework>net6.0</TargetFramework>
% dotnet run --roll-forward LatestMajor --
Hello, World!
.NET 7.0.8
% cat ./bin/Debug/net6.0/hello-world.runtimeconfig.json
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
}
}
} The problem with this experience is that it is just affects that one launch, since it is a host function, but doesn't affect The following also doesn't work. dotnet run /p:RollForward=LatestMajor However, that same approach works fine with % dotnet build /p:RollForward=LatestMajor
% cat bin/Debug/net6.0/hello-world.runtimeconfig.json
{
"runtimeOptions": {
"tfm": "net6.0",
"rollForward": "LatestMajor",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
}
}
}
% dotnet build /p:RuntimeFrameworkVersion=8.0.0-preview.5.23280.8
% cat bin/Debug/net6.0/hello-world.runtimeconfig.json
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.0-preview.5.23280.8"
}
}
} It should work with Clearly, adding Ideally, the following would work for tools: dotnet tool install --roll-forward=LatestMajor
dotnet tool install --roll-forward Note: The two commands would be equivalent. The intent is that We could also (additionally) consider shipping a tool for rewriting
|
Random comments :-) (this should be a PR so that I can comment on specific sections)
I would be OK introducing
Problem: rollforward on install fixes the old tools on a new machine problem. But it doesn't fix a problem with tools on a new (typically) preview install of SDK. Asking people to reinstall the tools in that case feels wrong. Maybe the env variable is the solution then? Other than the scenario you already described above I think there are two interesting cases:
|
If only .NET 8 is installed (common in CI scenarios) the tool won't run because it requires .NET 6 or 7. Instead of adding another target framework for .NET 8, add the `<RollForward>major</RollForward>` property to the package so that the tool can run on newer runtimes if required. See https://learn.microsoft.com/en-us/dotnet/core/tools/global-json#rollforward for general information about `rollForward`. See dotnet/sdk#10375 for additional details about rolling dotnet tools forward, and KirillOsenkov/MSBuildStructuredLog#721 for an example of other developer tools setting roll foward, and dotnet/sdk#30336 for more discussion on what the defaults should be.
If only .NET 8 is installed (common in CI scenarios) the tool won't run because it requires .NET 6 or 7. Instead of adding another target framework for .NET 8, add the `<RollForward>major</RollForward>` property to the package so that the tool can run on newer runtimes if required. See https://learn.microsoft.com/en-us/dotnet/core/tools/global-json#rollforward for general information about `rollForward`. See dotnet/sdk#10375 for additional details about rolling dotnet tools forward, and KirillOsenkov/MSBuildStructuredLog#721 for an example of other developer tools setting roll foward, and dotnet/sdk#30336 for more discussion on what the defaults should be.
Is your feature request related to a problem? Please describe.
Currently, .NET applications use a runtimeConfig to determine which runtime they run on. This is something that is determined at build time, but non-tool .NET applications can override this with various flags and environment variables given to the .NET runtime host. The default rollforward policy is
LatestPatch
, which allows an application to run on any runtime of the same major/minor version that is at least as high a version as the application was built against..NET (local) Tools are a specific kind of .NET application that are intended to be distributed and managed via SDK commands. They are generally development tools/utilities. We think the semantics of tools are such that tools should be able to run on any .NET runtime equal or greater than the runtime the application originally targeted. This will reduce friction for users adopting new SDKS/Runtimes by not completely blocking their workflows without some explicit proof on incompatibility.
Without this change, tool authors must either explicitly set a more flexible roll-forward policy, or multitarget. Multitargeting has the side effect of increasing the overall size of the tool, and still not solving the issue - a tool that multitargets net6.0 and net7.0 will still not run on net8.0 runtimes.
Describe the solution you'd like
There are two places we could address this mismatch:
Build Time changes
We would change the
RollForward
of all tools fromLatestPatch
toLatestMajor
. This would cause the desired behavior for all newly-built apps. We would also track a sentinel value that we set the RollForward, so that at install time we could tell if the user explicitly requested a change to the RollForward.Install Time changes
We would ensure that tools that did not explicitly override to force a certain RollForward behavior would be written with
LatestMajor
behavior. This helps us plug the existing behavior gap for tools that haven't been authored with an SDK containing these changes.Additional context
The text was updated successfully, but these errors were encountered: