-
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
[Package Validation] We should support excluding tfms when running the validation #22901
Comments
While I agree this will become more common as time goes on and TFMs continue to go out of support, I have a few thoughts in terms of the design of the feature. Here are some of the things in my mind:
In general, I'm fine with adding this feature. As for your options in terms of execution, I probably wouldn't have a flag for
|
Thanks for the input. I completely agree that it is helpful to get errors and evaluate the impact and that is why I would lean torwards and itemgroup which at the end is like using
The problem is not the error that the tfm is suppressed, the problem is when we fallback to the latest compatible asset for an asset that was dropped, like in the example that I provided. For example, take we have a netcoreapp3.1 asset that has an API <PackageValidationBaselineIgnoreTfm Include="netcoreapp3.1" />
I don't imagine this feature being used as default values, but rather intentional opt-in from the user using the property or the item, so the workflow would be, I drop the tfm, I see the errors I get, I think the impact makes sense, but rather than writing a lot of suppressions into the suppressions file, I just include the tfm as part of the item group.
I believe the SDK has a list of EOL TFMs for the current .NET SDK Version, so i.e, the .NET 6 SDK knows about 1.0, 1.1, 2.0 and 2.1, then .NET 7 SDK will have those, plus 3.1 and 5.0. The .NET SDK already warns if you target and EOL tfm, so that is why I was thinking we could benefit from that list, but now that I give it a thought about your comments, I think it makes more sense for the user to explicitly list the TFMs to ignore as that is more intentional. |
Yeah but that is what I mean that really shows you what your customers will see if they target the dropped framework. For example, in your particular example you may have dropped netcoreapp3.1 thinking there wouldn't be many fallbacks, but by getting all of these warnings (like the |
It would also be nice if we could override the baseline tfm. Ie if I drop .net5 and add .net6, I could tell the baseline validator to compare my current .net6 with the old .net5 APIs and ensure that when people upgrade, the only breaking change is the TFM itself. |
Mmm that feels like a bit of a specific use case to me, so I'm not sure if this is something that should be inside package validation. There are two different layers of the Package Validation feature today:
Today, this feature is only exposed via PackageValidation, but the plan (and I believe this is still in scope for .NET 7 cc @ViktorHofer) is to have also an MSBuild tasks and targets to expose the second layer directly so it could be called from users targets. I think your scenario is a special case, so instead of adding this feature as a characteristic of the first layer (package validation) I think we should enable you to be able to easily run ApiCompat via targets directly for which you can then select whichever two assets you want from two different packages in order to perform the comparisons. @dotMorten thoughts? |
That could probably work, but I'm not sure I agree it is specific. Dropping older targets and replacing with new ones in major versions is pretty common. |
I guess that is fair. I probably chose my words incorrectly, I guess my thoughts were more that doing so is effectively breaking your previous package, whether that is common or not, and to me Package Validation's layer purpose was more to be objective and find all breaking changes between two packages. That said, your point is valid that it is becoming more common to drop support for some frameworks, so I think it is fine to consider adding this extensibility point. |
Example: So would be nice if I could just configure my tool to compare current net462 to net461 baseline. I believe that'll also take care of the scenario initially presented here, but with much better validation that nothing else was changed. And anything I do change, I'll have the suppression file to use as a basisfor my documentation about "hey this is what we removed in the new version when you target the new tfm" |
I'm curious if the tuple you're talking about would already be present in the comparison? Suppose the package previously had; netstandard2.0;net5.0 and the new package has netstandard2.0;net6.0. So I think your comparison should be covered in that case, and you're just saying you want to ignore the net5.0¹ -> netstandard2.0²` one since your new package no longer supports net5.0. I still think the tool should raise it, since you are breaking those customers who move. It'd be nice if the tool provided a succinct way to communicate that you no longer need the tuple -- that's what this issue is about. Then there's a different shape. Suppose the package previously had; netstandard2.0;net5.0;net6.0 and the new package has netstandard2.0;net6.0. You wouldn't get the net5.0¹ -> net6.0² comparison here as part of the baseline check, but you presumably did the regular compat check when you shipped the first package (net5.0¹ -> net6.0¹), and then you're doing a net6.0¹ -> net6.0² baseline check on the new package, so you get the net5.0¹ -> net6.0¹ -> net6.0² comparison transitively. I do think an interesting advanced feature for APICompat might be to both add and remove comparison tuples. I could see such a feature taking the form of describing the tuples as "calculate the applicable TFM for this left framework (optionally from the baseline package), and this right framework". Another scenario I can see this helping with is migration from a package that supported .NETFramework to .NET. |
Here's a much simpler case: That means a user who already targets .net 8 and uses v1.0, can easily move to v2.0 and know that nothing will break. Yes a user targeting .net6/7 will also have to change their TFM, but again they should have confidence that is it, and I should have confidence nothing else broke. Dropping older unsupported target frameworks is just a thing we all will be doing as we're going forward - it would be nice to be able to easily check this isn't causing any other issues, but currently every time we do make a TFM change, we basically have to disable baseline validation completely, risking we break something (this actually happened in the .NET MAUI SDK when moving from net6 to 7, and it wasn't caught, until I smashed into it and reported it!) |
Fixes #22901 Add frontend option to allow ignoring TFMs when performing baseline package validation.
Fixes #22901 Add frontend option to allow ignoring TFMs when performing baseline package validation.
Thanks for working at this. |
We still validate compatible TFMs inside the current package. I.e. the I.e. in dotnet/runtime we target the following TFM properties: https://github.com/dotnet/arcade/blob/576b0a6fca70266087aa247d68896376ecec8c6e/src/Microsoft.DotNet.Arcade.Sdk/tools/TargetFrameworkDefaults.props#L12-L21 While you probably don't want to target three .NETCoreApp TFMs, I would recommend to target the minimum officially supported .NETCoreApp version (for breadth) and the latest .NETCoreApp version (for max perf). |
My point is its normal to drop out of support targets. Like we dropped 3.1 a few years ago and by the end of the year net6 will be out of support and we'd naturally move to net8. By that time users of my package likely have already moved to net8, hopefully that version is a smooth upgrade with no breaking changes besides the tfm increase. However there's no way to have the validator ensure that today. With the PR merged it just simplifies ignoring all the apis that might be additional to what's in netstandard, but no way to check if net8 target is missing a member net6 had. So while I appreciate the work done here and simplifying it, it doesn't actually solve an issue that wasn't already solveable |
I definitely get your point. This happens quite often, yes. I was trying to provide a recommendation on how to solve this with multi-targeting. I would generally recommend to target at least two .NETCoreApp TFMs for the above stated reason (breadth and perf). I expect this pattern to become more popular in the future when people stop supporting .NET Standard. Redirection is non trivial as it would swap the "left" and the "right". Left is usually the baseline assembly and right is the current assembly. Now with redirection, net8.0 would become the baseline (left) and net6.0 the current (right). |
In dotnet/runtime we have been following a convention with our packages where we drop TFMs that are out of support from our packages. This results on a lot of errors that need to be suppressed because we are intentionally dropping these TFMs.
Also, when this happens, in baseline validation, if an asset is drop it will take another asset that is compatible for that TFM in the new package, i.e, if we had netcoreapp3.1 and netstandard2.0 asset, then we drop netcoreapp3.1, and now it will compare the netcoreapp3.1 asset from the baseline package vs the netstandard2.0 from the new version, resulting in a lot of errors as the API surface might be fairly different, so that comparison is not valuable in a lot of cases and it can become very noisy.
I suggest we add some support like an ItemGroup to specify ignored tfms for baseline validation, i.e:
Or we could introduce a flag to ignore out of support tfms and then we can use the list from the SDK for which tfms are out of support, i.e:
cc: @ericstj @joperezr
The text was updated successfully, but these errors were encountered: