Skip to content
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

.NET 9 RC manifests were not updated to reference the .NET 8 iOS 18 / macOS 15 workloads #21335

Closed
filipnavara opened this issue Sep 30, 2024 · 18 comments

Comments

@filipnavara
Copy link
Contributor

Apple platform

iOS, macOS, Mac Catalyst, tvOS

Framework version

net8.0-, net9.0-

Affected platform version

.NET 9 RC1

Description

Last week iOS workload on .NET 8 was updated to support iOS 18 / Xcode 16. The unfortunate consequence of that is that net8.0-ios now implicitly means net8.0-ios18.0 when you recompile with this version. The workload manifest for .NET 9 RC 1 was not updated though, so if you have both SDKs installed, then compiling with .NET 9 SDK means that net8.0-ios still means net8.0-ios17.5 and that the iOS 18 workloads are not used even if they are installed.

CommunityToolkit.Maui update was released last week. It was recompiled with the latest .NET 8 SDK at that time, so the NuGet was produced with net8.0-ios18.0 assets. Now if you try to use it with .NET 9 SDK installed it will fail to compile (NativeAOT) or run (MonoVM) because it will pick the net8.0 asset instead of the net8.0-ios18.0 asset since it only understands net8.0-ios17.5 and thus does a fallback...

Steps to Reproduce

  1. Create app with net8.0-ios18.0 TFM.
  2. Try to build the app with .NET 9 RC 1 SDK on the machine.

Did you find any workaround?

No response

Relevant log output

No response

@rolfbjarne
Copy link
Member

This will be fixed with .NET 9 RC 2, which will contain Xcode 16 support as well.

Unfortunately the .NET 9 releases and not coordinated with .NET 8 service releases, so it's hard to make everything line up properly without breakages like this in between :/

Eventually I believe CommunityToolkit.Maui will switch to targeting a fixed OS versions (so they'll specifically build for net9.0-ios18.0, in which case this won't happen again next year with iOS 19).

@rolfbjarne rolfbjarne closed this as not planned Won't fix, can't repro, duplicate, stale Sep 30, 2024
@filipnavara
Copy link
Contributor Author

filipnavara commented Sep 30, 2024

I realize that it will be self-fixed with .NET 9 RC 2 release. There are few thing that worry me though.

Firstly, I had an understanding that the implicit SDK version is pinned with each version of .NET TFM, ie. every version of .NET 8 SDK would interpret net8.0-iosX.Y the same, where X.Y would be fixed for all servicing releases. This principle has been violated and I would appreciate an official stance and documentation on it.

Secondly, this broke pretty much everyone on our team since we all have .NET 9 RC SDKs installed, either explicitly or as a side effect of having side-by-side installation of Visual Studio Preview.

Thirdly, all our DevOps pipelines also immediately ingest the new .NET SDK and workload versions. This release happened out of the regular monthly schedule (second Tuesday of a month) which caused a two week delay until .NET 9 RC2 lands.

@filipnavara
Copy link
Contributor Author

Also, note that I am explicitly not asking for update of .NET 9 workloads, just the manifest which points to .NET 8 workloads that were already released. It would be nice to make sure that this doesn’t happen in future since I already wasted a day on it.

@rolfbjarne
Copy link
Member

Firstly, I had an understanding that the implicit SDK version is pinned with each version of .NET TFM, ie. every version of .NET 8 SDK would interpret net8.0-iosX.Y the same, where X.Y would be fixed for all servicing releases. This principle has been violated and I would appreciate an official stance and documentation on it.

Yes, this is a really ugly problem for us, because not upgrading means that everybody who got their Xcode auto-updated overnight is broken (and this happens to a lot of people every year).

An additional problem this year is that if you upgrade to macOS Sequoia, you'd be stuck, because macOS 15.4 doesn't work on Sequoia :/

You can see for yourself the havoc we had until we released Xcode 16 support (sorted by number of comments, it's 3rd on our all time list): #20802

Now, you could argue that we should still keep the original default for the lifetime of .NET X (so net8.0-ios17.0 for .NET 8), but you'd have to update that manually if you want to use a newer Xcode, which after a year pretty much everybody would have to do. At that time very few would be using the default, and the value of having a default is gone.

For these reasons we've decided to not follow what the rest of .NET does.

Also, note that I am explicitly not asking for update of .NET 9 workloads, just the manifest which points to .NET 8 workloads that were already released.

This command should get you the previous version:

dotnet workload install <workload id(s)> --version 8.0.402

I've also just added this to our release notes.

@filipnavara
Copy link
Contributor Author

filipnavara commented Sep 30, 2024

I understand the unfortunate situation that happened with Xcode / macOS Sequoia and so on. I'm not mad about the out of band update per se but it caused some unintended consequences and I would like to make sure that doesn't happen again.

Now, you could argue that we should still keep the original default for the lifetime of .NET X (so net8.0-ios17.0 for .NET 8), but you'd have to update that manually if you want to use a newer Xcode, which after a year pretty much everybody would have to do. At that time very few would be using the default, and the value of having a default is gone.

I am still arguing for that. or rather, any general solution that does any of the following:

  • enforces stable inferred TFMs for libraries,
  • enforces using netX.Y-iosV.W format of TFM for NuGet packed libraries, or,
  • updates workload manifests for ALL supported .NET SDK versions to be consistent between each other (.NET 9 RC 1 is supported with go-live license)

The unintended consequence of bumping to net8.0-ios18.0 is not a problem for end user apps but it's absolutely a problem for libraries and NuGets. What happened here is that CommunityToolkit.Maui got the workload update in their CI pipeline and they released an updated NuGet. Without any intervention on their side the package now contains net8.0-ios18.0 assets (and ONLY those, not anything for net8.0-ios17.x). They don't require newer SDK functionality and it's managed only code that has no dependency on the new iOS SDK version. This is exacerbated by the fact that NuGet doesn't give any warning at all about using the net8.0 fallback asset instead of the net8.0-ios[TOONEW] one.

This command should get you the previous version:

That's too late. The problem is not the workload versions on our machines. The issue is that there are now NuGets in the wild that only contain net8.0-ios18.0 assets where they previously had net8.0-ios17.X assets. The ship has sailed on that and no amount of workload reverts on our machines will solve that.

We didn't notice the problem until 3 days later because our CI machines are configured to only install .NET 8 SDKs. They got the updated workloads and compiled just fine. Dependabot sent an alert about new CommunityToolkit.Maui NuGet version, it passed the CI and it got ingested.

It only failed on the dev machines today because most of our devs had the .NET 9 SDK installed. The .NET 8 SDK on the very same machines had the same workload updates as the CI machines. They are just not used unless you force .NET 8 SDK by global.json or similar approach.

@dalexsoto
Copy link
Member

The unintended consequence of bumping to net8.0-ios18.0 is not a problem for end user apps but it's absolutely a problem for libraries and NuGets. What happened here is that CommunityToolkit.Maui got the workload update in their CI pipeline and they released an updated NuGet. Without any intervention on their side the package now contains net8.0-ios18.0 assets (and ONLY those, not anything for net8.0-ios17.x). They don't require newer SDK functionality and it's managed only code that has no dependency on the new iOS SDK version. This is exacerbated by the fact that NuGet doesn't give any warning at all about using the net8.0 fallback asset instead of the net8.0-ios[TOONEW] one.

Library authors probably need to be using net8.0-ios17.0 (instead of plain net8.0-ios) always in their TFMs and only bump to newer on .NET vNext ie. net9.0-18.0 so it is explicit and do not get broken by vNext workload update, I would prefer to pass the price to library authors to know how to do this than to every single app user knowing why they need the iOS version in their TFM to use a newer Xcode SDK.

@filipnavara
Copy link
Contributor Author

I would prefer to pass the price to library authors to know how to do this

...and I am generally fine with that if there's some enforcement for this. The original netX.Y-os[V.W] design proposal had a bound V.W pair to the X.Y version number that doesn't change in servicing (AFAIK). If you break that assumption then you need to somehow tell the library authors that they need to do something else. There's no warning or other enforcement to use the long version for libraries, and so they unknowingly bump the TFM versions by just running the default CI pipeline and no explicit change.

@last-Programmer
Copy link

I had a crash using community toolkit with .net 9 rc when setting the statusbar color and style and i was getting the error Platform not supported. This explains the reason why i was getting the error. As workaround since i was uisng only this from community toolkit i copied the statusbar sources to my project.

@rolfbjarne
Copy link
Member

I would prefer to pass the price to library authors to know how to do this

...and I am generally fine with that if there's some enforcement for this. The original netX.Y-os[V.W] design proposal had a bound V.W pair to the X.Y version number that doesn't change in servicing (AFAIK). If you break that assumption then you need to somehow tell the library authors that they need to do something else. There's no warning or other enforcement to use the long version for libraries, and so they unknowingly bump the TFM versions by just running the default CI pipeline and no explicit change.

I'm looking into whether we can have a different default between executable projects and library projects, I believe that would solve the problem you ran into.

@bijington
Copy link

As a maintainer of the Community Toolkit is there anything that we can do today in order to stop seeing this issue? This isn't actually the first time it has happened. It is great to finally know what the cause was and special thanks to @filipnavara for diagnosing it.

I have tried changing the TFM to net8.0-17.0 in this PR CommunityToolkit/Maui#2243 but that is failing to build making me question whether I am missing something

@filipnavara
Copy link
Contributor Author

I have tried changing the TFM to net8.0-17.0

The proper name would be net8.0-ios17.0.

@bijington
Copy link

I have tried changing the TFM to net8.0-17.0

The proper name would be net8.0-ios17.0.

Sorry I mistyped in my previous comment I did use net8.0-ios17.0 --> https://github.com/CommunityToolkit/Maui/pull/2243/files

@bijington
Copy link

net8.0-ios17.5 is working locally for me

@bijington
Copy link

bijington commented Oct 1, 2024

Given this might be the approach that we need to take moving forwards are there other TFMs that we should be doing this for?

  • MacCatalyst
  • Android
  • Windows
  • Tizen

@filipnavara
Copy link
Contributor Author

Given this might be the approach that we need to take moving forwards are there other TFMs that we should be doing this for?

The short answer is iOS and Mac Catalyst. Android keeps the OS version in servicing, and to my best understanding so do Windows.

@bijington
Copy link

I appreciate this is a closed issue and this might be noise on the topic but a thought has just dawned on me... If we are now targeting a specific version and after reading this article https://learn.microsoft.com/en-us/dotnet/standard/frameworks#precedence we have seen some issues in the past/present where developers are complaining unsupported features when they should be supported.

As an example issue CommunityToolkit/Maui#1374 basically there is a class StatusBarBehavior which is only supported on iOS and Android, in the net8.0 target we throw an InvalidOperationException which developers report seeing on iOS or Android at times. It sounds to me that this could have been an artefact of the workload/SDK mismatching going on and the compiler somehow taking net8.0 over net8.0-ios. The part that I can't find understand yet is whether changing to the specific TFM e.g. net8.0-ios17.5 will make this any better/worse. It definitely feels like it could be related though.

@filipnavara
Copy link
Contributor Author

It sounds to me that this could have been an artefact of the workload/SDK mismatching going on and the compiler somehow taking net8.0 over net8.0-ios

That's exactly what was happening and what is happening for us now...

The part that I can't find understand yet is whether changing to the specific TFM e.g. net8.0-ios17.5 will make this any better/worse.

It will make it better. The released NuGet always uses the expanded full TFM version, which happened to be net8.0-ios18.0 for CommunityToolkit.Maui 9.1.0. You can check that with https://nuget.info/packages/CommunityToolkit.Maui/9.1.0. Setting the version back to -ios17.5 will make it work with older workloads and the current .NET 9 RC 1 workloads.

@bijington
Copy link

Brilliant thanks! It is all making much more sense now!

And a second thanks for sharing nuget.info, how did I not know that existed?!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants