Normalize TFM platform versions when determining computed compatibility#9741
Conversation
Yes, that's my understanding too. Also, the CompatibilityMatrix uses a list of 'supported frameworks' that we maintain ourselves https://github.com/NuGet/NuGetGallery/blob/main/src/NuGetGallery.Core/Frameworks/SupportedFrameworks.cs#L66, so we would need to manually update this list with every platform and platform version combo in order to cover it that way. |
|
This seems reasonable. Would it be possible to get a TFM compat expert on client to sign off on the concept here? It makes sense based on my understanding but I was not involved in the design or implementation of net5.0+ platform specific TFMs. |
In the .NET world with platforms, TargetPlatformVersion is mandatory. It is unusual that there are packages without a target platform in their package. In fact we have pack validation that should prevent that: https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1012. Packages that contain assets like that were probably manually edited, and since restore tries not to be too opinionated and break it can work. I'm wondering if we should've blocked these packages from getting uploaded to nuget.org, but it's too late now I guess. Now focusing on the issue is that we want to show net8.0-android as a computed framework for net7.0-android31, I'm not really familiar with what versions are used, and how often people downgrade the default SDK platform version etc. In general, if the SDK defaults to net7.0-android31, for net8.0 it is likely the platform version is 32.0 or something like. The real concern is what is 31.0 wasn't the default, but a bumped version, and net8.0 defaults to a version 30.0, then this is a problem. I'd involve .NET folks here, as while I can speak on the technical correctness, they're the better authorities on what people would expect. Given net7.0-android31.0, I think showing net8.0-android31.0 is a good idea as a computed framework, which seems to what this PR is proposing. The only downside is that eventually certain framework versions and platform versions are incompatible/can't build against, but idk if Nuget.org should try to guess that. IE, there's a chance that net12.0-android31.0 simply cannot be targeted by a project and nuget.org might show that as a computed framework. |
|
@nkolev92 i talked to daniel and immo on this. but while you point out these problems, the android team will never publish a TFM with a lesser value as a TPV. they build against the latest version of android APIs. |
|
also i think uno or some other groups do the manual creation b/c they have the net8.0-android TFM: https://www.nuget.org/packages?q=&tfms=net8.0-android&prerel=true&sortby=relevance |
Should we track this issue to ensure people are using proper tooling that packs TPV? |
|
Some .NET responses earlier to help.
|
|
Does that feedback change the proposal in this PR? Fwiw, while android does that rule, I think windows tends to be different. Do we want to apply the same rules there? |
|
My only feedback here is to double check that the default major .NET version platform TPVs are right. i think it is perfectly fine to compute and normalize/simplify them too if we don't have a good way of getting mappings. they can lookup docs or similar. |
JonDouglas
left a comment
There was a problem hiding this comment.
added comments for consideration
This will not work, at least for Android. There is no such thing as You also cannot arbitrarily bump the platform version above what we have explicitly supported. For example, There are only a handful of valid combinations currently:
I think for Android (and perhaps iOS is the same), you are going to have to know the explicitly valid combinations, and only show TFMs where both the .NET and Platform versions are >= to the package specified versions. Alternatively, you could probably just ignore the platform version for Android and get "close enough" without maintaining an explicit list. For example, a The Android platform version for each subsequent release of .NET will be >= to the previous .NET. |
|
Note that for iOS, we're planning on supporting multi-targeting, where both of these would be valid (at the same time):
Same for iOS.
That's not really feasible for iOS, we ship new versions with updated TPVs all year, depending on what Apple does. I'd really like to avoid a solution where someone would have to (remember to) update NuGet's knowledge all the time about which .NET versions supports which iOS versions. We'll also change the default TPV even though we're not supposed to according to the spec, because the alternative is worse (customers' projects will stop compiling because Xcode was auto-updated by Apple, and they'd have to add the TPV manually to their project files to use the new Xcode, and we don't want people to use explicit TPV because then they'd have to update the TPV again for the subsequent version of Xcode, and now the whole point of having a default value becomes useless because nobody can use it).
I've seen more projects with the TPV than I'd expect, so I've wondered if the IDEs have been writing it out when saving csprojs without customers explicitly choosing it? I think there are a few alternatives here though.
|
Yeah I believe this was by design when packing w/ dotnet tooling. What we will likely do in this case then @advay26 correct if wrong is that we will show:
That way it is more likely dependent on the .NET SDK you are using at the time given TPVs can change. We can make a note of that in the docs somewhere. |
5156acb
|
As @JonDouglas said, I've changed the proposal so that we're just showing the normalized compatible frameworks, rather than asserting a specific platform version. So a package targeting It would be difficult to continually keep track of all supported TPVs for each platform, so we'll instead try to point to docs somewhere once they're set up: dotnet/docs#38554. |

Addresses #9711
Problem:
TFMs that contain platform monikers and versions, like

net6.0-android31.0, were not showing thenet7.0-androidandnet8.0-androidTFMs as users expected.https://www.nuget.org/packages/Xamarin.AndroidX.Lifecycle.Common/2.6.2.2#supportedframeworks-body-tab
If the TFM didn't have a platform version, say just

net6.0-android, then the correspondingnet7.0andnet8.0TFMs show up as expected.https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Extension.ONNX.Runtime/1.33.0#supportedframeworks-body-tab
Solution:
Currently, if a TFM (.NET 5+) has a platform version, it does not show any computed compatible TFMs. Our compatibility matrix only includes TFMs without platform versions.
To fix this, if we see a TFM with a platform version:
net6.0-windows7.0->net6.0-windowsnet6.0-windows->net6.0-windows,net7.0-windows,net8.0-windowsnet6.0-windows7.0), and remove the normalized TFM (net6.0-windows) from the setnet6.0-windows7.0,net7.0-windows,net8.0-windowsi.e.
net6.0-windows7.0->net6.0-windows7.0,net7.0-windows,net8.0-windowsSimilarly,
net6.0-windowsY.Znet6.0-windowsY.Z,net7.0-windows,net8.0-windowsnet6.0-windowsnet6.0-windows,net7.0-windows,net8.0-windowsnet6.0-windows7.0net6.0-windows7.0,net7.0-windows,net8.0-windowsnet6.0-windows99.0net6.0-windows99.0,net7.0-windows,net8.0-windowsnet7.0-windows7.0net7.0-windows7.0,net8.0-windowsnet6.0-iosnet6.0-ios,net7.0-ios,net8.0-iosnet6.0-ios15.0net6.0-ios15.0,net7.0-ios,net8.0-ios