Honor minimumMSBuildVersion when global.json rollforward resolves an incompatible SDK#53616
Honor minimumMSBuildVersion when global.json rollforward resolves an incompatible SDK#53616
Conversation
…ard picks MSBuild-incompatible SDK Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/c3d20d77-0e1d-483a-8ff4-c53ac5669e03 Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/c3d20d77-0e1d-483a-8ff4-c53ac5669e03 Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adjusts the MSBuild SDK resolver’s selection logic so that when global.json rollforward causes hostfxr to resolve an SDK whose minimumMSBuildVersion is higher than the running MSBuild, the resolver falls back to the best MSBuild-compatible SDK (instead of surfacing a confusing MSBuild version error). Exact-version pins that were successfully matched keep the current “fail with a clear error” behavior.
Changes:
- Update
NETCoreSdkResolver.ResolveNETCoreSdkDirectoryto trigger MSBuild-compatibility fallback even whenglobal.jsonis present, except when an exact requested version was resolved. - Add a new test covering rollforward selecting an MSBuild-incompatible SDK (validated for both
DisallowPrereleaseByDefault = true/false). - Extend the test helper
CreateGlobalJsonto support emitting arollForwardproperty (and update call sites accordingly).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Resolvers/Microsoft.DotNet.SdkResolver/NETCoreSdkResolver.cs | Removes the GlobalJsonPath == null restriction on MSBuild-compat fallback, with an explicit “exact pin matched” exception. |
| test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnMSBuildSdkResolver.cs | Adds rollforward regression coverage and extends CreateGlobalJson to write rollForward. |
|
I tested this locally by building and replacing my VS 2022 resolver. In cases where dotnet --version would resolve to a 10.0.3xx SDK, we end up finding the most compatible one in the 10.0.100 or 9.0.3xx band. The one flaw of this solution is that if a customer has 10.0.100, 10.0.200, and 10.0.300 bands, a global.json that points to 10.0.200 with a rollforward, we end up using the 10.0.100 which while it works, is not what a customer has described. I'll see if there's a way to solve that. |
When
global.jsonspecifies a rollforward policy (e.g.latestMajor), the native hostfxr resolver may select a newer SDK whoseminimumMSBuildVersionexceeds the currently running MSBuild. Previously the managed fallback (find best MSBuild-compatible SDK) only triggered when there was noglobal.jsonat all, so rollforward users got a cryptic MSBuild version error instead of gracefully landing on the best compatible SDK.Changes
NETCoreSdkResolver.ResolveNETCoreSdkDirectory: Removes theGlobalJsonPath == nullguard on the MSBuild-compatibility fallback. The fallback now fires whenever the resolved SDK is MSBuild-incompatible, except when the user explicitly pinned an exact version that was matched — detected by comparingRequestedVersion(fromglobal.json) against the resolved SDK directory name. An exact match preserves the current behavior: surface a clear error so the user knows their pinned SDK requires a newer MSBuild.Tests: Added
rollForwardparameter toCreateGlobalJsonhelper (ordered beforepaths). AddedItReturnsHighestSdkAvailableThatIsCompatibleWithMSBuildWhenGlobalJsonRollForwardPicksIncompatibleSdkcovering the rollforward-to-incompatible-SDK scenario with bothdisallowPreviews = true/false.Behavior matrix
global.json, resolved SDK needs higher MSBuildglobal.jsonrollforward picks newer incompatible SDKglobal.jsonexact pin, pinned SDK needs higher MSBuildglobal.jsonversion not found, running in VS