Skip to content

feat: add .NET 11 support and drop .NET 8 and .NET 9 - #5529

Draft
jamescrosswell wants to merge 29 commits into
version7from
net11-preview7
Draft

feat: add .NET 11 support and drop .NET 8 and .NET 9#5529
jamescrosswell wants to merge 29 commits into
version7from
net11-preview7

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Gets the SDK building and testing against .NET 11 preview 7, targeting version7.

Note

Lots of changes in this PR but it's mostly mechanical. The goal of this PR is just to get things building with the new TFMs.

I've left a few review comments myself to explain a few things that aren't obvious.

Closes #5527

TFMs

net11.0 becomes the latest TFM and net10.0 the previous; net8.0 and net9.0 are dropped (both lose LTS when .NET 11 ships). Platform TFMs follow the preview 7 workload set (11.0.100-preview.7.26410.2):

Latest Previous
base net11.0 net10.0
android net11.0-android37.0 net10.0-android36.0
ios net11.0-ios26.5 net10.0-ios26
maccatalyst net11.0-maccatalyst26.5 net10.0-maccatalyst26
windows net11.0-windows10.0.19041.0 net10.0-windows10.0.19041.0

iOS and MacCatalyst only publish a net11.0_26.5 ref pack, so those need the minor version — unlike the current net10.0-ios26.

Samples are bumped by hand rather than moved onto the central properties: they're documentation, and $(LatestTfm) doesn't resolve outside this repo.

What .NET 11 changed

  • Mono is gone for Android (NETSDK1242). RunAOTCompilation is Mono-only, so Mono-AOT APKs cannot be produced at all. The APK matrix in Sentry.Android.AssemblyReader.Tests builds the AOT variants for net10.0-android only.
  • The Cocoa bindings are nullable-annotated. This surfaced a latent bug: GetBundleValue did NSBundle.MainBundle.ObjectForInfoDictionary(key).ToString(), so a missing Info.plist key would have thrown while building the release/distribution string. NSObject.FromObject is also nullable now, and two conversions were storing its result straight into a Dictionary<NSString, NSObject>.
  • Minimum deployment targets rose: Android API 21 → 24, MacCatalyst 15.0 → 17.0. Both are applied to the net11.0 TFM only, so net10.0 consumers are unaffected. Android API 24 is a user-facing breaking change for .NET 11 — it drops Android 5.0, 5.1 and 6.0 — and wants a line in the 7.0.0 breaking changes.
  • The synchronous HttpClient.Send is annotated unsupported on iOS/MacCatalyst. Suppressed narrowly in the test helper, whose callers all supply a substitute inner handler.
  • MAUI 11's MSIX PRI expansion shells out to makepri.exe, so cross-building net11.0-windows from macOS/Linux fails. net10.0-windows is fine, so this is new. PRI expansion is skipped when the host isn't Windows; Windows CI still runs the full path.
  • Convert.FromBase64String now routes through System.Buffers.Text.Base64, changing the declaring type of the top stack frame. DebugStackTraceTests was asserting one specific type in a sanity check; it now checks the namespace, which is what InApp actually keys off.

Supported target frameworks

Per review feedback, .NET 8 and .NET 9 are retained for non-mobile targets. The policy this branch implements, now written down in CONTRIBUTING.md:

  • Mobile (-android, -ios, -maccatalyst, -windows): every version still supported by Microsoft - in practice the latest two, so net10.0 and net11.0.
  • Non-mobile: the latest two LTS releases plus every STS release after the older of them - so net8.0;net9.0;net10.0;net11.0 while .NET 10 is the latest LTS, becoming net10.0 and later when .NET 12 ships.

The split falls out of the existing properties at no structural cost: mobile projects reference $(LatestTfm)/$(PreviousTfm) while non-mobile ones reference $(CurrentTfms), so widening the non-mobile set does not pull mobile along with it. Verified: Sentry.Maui still packs net10.0/net11.0 only, while Sentry packs all four lib/ assets.

Cost is ~25% more build units on the macOS filter (259 to 325). No new CI jobs - no job is matrixed on the non-mobile TFM axis, and .github/actions/environment/action.yml already installed the 8.0 and 9.0 SDKs.

Known gaps

  • Android assembly store v4 is unsupported, so there is no Android symbolication on .NET 11. .NET 11 emits store format v4 (observed header 0x80030004), and v4 changed the header/index layout as well as the version number — adding the version alone gets past IsSupported() and then fails in Prepare(). This is already tracked in Port upstream AssemblyStore reader changes: v4/CoreCLR format, _assembly_store symbol, index-entry sizing (next major) #5454, which identifies the same root cause (a new content_id header field when the format number is >= 4). It degrades gracefully: AndroidHelpers.GetAndroidAssemblyReader catches, logs and returns null. 20 tests in AndroidAssemblyReaderTests are skipped on net11.0 with a reason pointing at Port upstream AssemblyStore reader changes: v4/CoreCLR format, _assembly_store symbol, index-entry sizing (next major) #5454, and must be re-enabled when that port lands. net10.0 still runs all 23.
  • Sentry.Samples.OpenTelemetry.AzureFunctions stays on net10.0. The Azure Functions Worker SDK has no .NET 11 support — 2.0.7 and the current 2.1.0 both reject the TFM with "Invalid combination of TargetFramework and AzureFunctionsVersion is set."
  • Microsoft.CodeAnalysis.Testing ships no ReferenceAssemblies.Net.Net110 (1.1.4 stops at Net100), so Sentry.Compiler.Extensions.Tests declares one locally, pinned to Microsoft.NETCore.App.Ref 11.0.0-preview.7.26381.103. Keep it in step with global.json.

Changelog Entry

feat: Add .NET 11 support. Mobile targets now require .NET 10 or later - net9.0-android, net9.0-ios, net9.0-maccatalyst and net9.0-windows are no longer supported. Non-mobile targets are unchanged and continue to support .NET 8 and later. On .NET 11 the minimum Android API level is now 24 (Android 7.0) and the minimum MacCatalyst version is 17.0, both required by the .NET 11 SDK - Android 5.0, 5.1 and 6.0 are no longer supported there. .NET 10 consumers are unaffected and keep API 21 / MacCatalyst 15.0.

Shifts the centralized TFM properties up one release: net11.0 becomes the
latest TFM and net10.0 the previous, dropping net8.0 and net9.0 (both lose
LTS when .NET 11 ships in November).

Platform TFMs follow the preview 7 workload set (11.0.100-preview.7.26410.2):
android 37.0.0-preview.7.2131, iOS/MacCatalyst/macOS 26.5.11997-net11-p7.
Note iOS and MacCatalyst only ship a net11.0_26.5 ref pack, so those TFMs
need the minor version, unlike the current net10.0-ios26.

Samples are bumped by hand rather than moved onto the central properties -
they are documentation for SDK users and stay conventional and literal.
Pins global.json to the preview 7 SDK and its workload set, and updates the
projects that don't consume the centralized TFM properties:

- Sentry.Maui.CommunityToolkit.Mvvm (+ tests) and Sentry.MauiTrimTest were
  pinned to exactly the Previous* TFM set, so they now use those properties
  and will track future bumps on their own.
- SingleFileTestApp and Sentry.TrimTest move to net11.0, so single-file
  bundle reading and trim/AOT analysis are exercised against the new runtime.
- The TFM switches in SingleFileAppTests and AndroidAssemblyReaderTests, and
  the APK build matrix in Sentry.Android.AssemblyReader.Tests, gain net11.0
  and drop net9.0/net8.0.
Works through what building against .NET 11 preview 7 surfaced:

- Android raised its minimum deployment target to API 24 and MacCatalyst to
  17.0. Both are applied only to the net11.0 TFM, so net10.0 consumers keep
  API 21 / 15.0. Raising Android's floor is user-facing: it drops Android
  5.0-6.0 for net11.0.
- Seven ItemGroups keyed on TargetFrameworkVersion v10.0 had no v11.0 sibling,
  leaving the new TFM with no packages at all. This is what produced the
  Sentry.Bindings.Android XA4242 Java dependency failures - the AndroidX and
  Kotlin references simply weren't there for net11.0-android37.0.
- The Cocoa bindings are now nullable-annotated. ObjectForInfoDictionary and
  NSObject.FromObject return nullable values, which exposed a latent NRE when
  an Info.plist key is missing, and two spots that could store null in a
  non-nullable NSObject dictionary. The marshal-exception delegates also
  declare a nullable sender now.
- .NET 11 Android defaults to CoreCLR, and RunAOTCompilation is Mono-only, so
  the APK build matrix now asks for Mono only on the AOT cases.
- The synchronous HttpClient.Send is annotated unsupported on iOS/MacCatalyst;
  suppressed at the test helper, whose callers all use a substitute handler.
- integration-test/net9-maui is renamed to maui-app - it's a generic MAUI
  template, and pinning a .NET version in the name has aged badly once.

Sentry.Samples.OpenTelemetry.AzureFunctions stays on net10.0: the Azure
Functions Worker SDK has no .NET 11 support yet (2.0.7 and 2.1.0 both reject
the TFM). Sentry.Compiler.Extensions.Tests compiles its analyzer snippets
against the .NET 10 reference assemblies, as Microsoft.CodeAnalysis.Testing
ships nothing newer than Net100.
- .NET 11 removes the Mono runtime for Android (NETSDK1242), so Mono AOT
  cannot be produced at all. The AOT APK variants are now built only for
  net10.0-android. No coverage is lost: AndroidAssemblyReaderTests already
  skips every AOT case, so those APKs were built but never read.
- MAUI 11's MSIX PRI expansion shells out to the Windows-only makepri.exe,
  which breaks cross-building net11.0-windows from macOS. net10.0-windows is
  unaffected, so PRI expansion is skipped when the host isn't Windows.
- MauiEventsBinderTests had no live branch left once net9 went, leaving
  navigatedToEventArgs undeclared on every TFM; the conditional is gone.
- LocalDbFixture gains its net11.0 name, and drops arms for TFMs we no longer
  build. Its #else is a hard #error - each TFM needs a distinct database name.
- The MAUI sample carried unused Frame and ListView styles from the project
  template, both obsolete in MAUI 11, and one EndAndExpand layout option.
- BL0012 is suppressed in the Blazor sample: the analyzer treats
  StateHasChanged as redundant after an event handler, but that handler always
  throws, so the automatic re-render never runs.

Drops the net8.0 and net9.0 verified snapshots. The net11.0 ones regenerate
themselves on a test run, and CI's Windows job produces the net48 files.
…ader tests

- ReferenceAssembliesExtensions declares a real net11.0 entry. Falling back to
  Net100 did not work: the analyzer snippets reference a net11.0-built
  Sentry.dll, so CS1705 fires against .NET 10 reference assemblies.
  Microsoft.CodeAnalysis.Testing has its own PackageIdentity, so this needs no
  extra package reference.
- DebugStackTraceTests asserted the top frame's declaring type was exactly
  System.Convert. .NET 11 routes Convert.FromBase64String through
  System.Buffers.Text.Base64. That was only the test's sanity check - what it
  actually asserts is keyed off the namespace, so it now checks that instead.
- AndroidAssemblyReaderTests skips the AOT permutations on net11.0. The
  existing Skip.If(isAot) is inside #if ANDROID, so on host runs every
  permutation executes and needs an APK - and .NET 11 cannot produce Mono-AOT
  APKs at all.
- StoreReader documents that .NET 11 emits assembly store v4, which changes the
  header/index layout and not just the version number. Bumping the constant
  alone gets past IsSupported() and then fails in Prepare().
Generated by a local test run. Content is byte-identical to the net10.0
snapshots in every case, so .NET 11 introduces no behavioural difference
here - Verify just keys these files by target framework.

The net48 snapshots can only be produced on Windows, so CI's verify-api job
will commit those.
jamescrosswell and others added 2 commits September 2, 2026 12:06
Sentry.MauiTrimTest ships empty Directory.Build.props and .targets stubs to
deliberately isolate itself from the repo's build customization, so it is a
realistic standalone consumer app for trim analysis. That means the
centralized $(Previous*Tfm) properties are not available to it - switching it
onto them left TargetFrameworks evaluating to ";", and MSBuild then treated it
as a cross-targeting project with no frameworks and recursed:

  Microsoft.NET.Sdk.Workloads.CrossTargeting.targets(25,5): error MSB4006:
  There is a circular dependency in the target dependency graph involving
  target "_GetRequiredWorkloads".

The TFMs go back to literals, with a comment so the next TFM bump doesn't
repeat it. Sentry.TrimTest and AndroidTestApp use the same isolation stubs but
were already left on literals.

This project is not in Sentry-CI-Build-macOS.slnf, which is why a local build
and test run of that filter didn't catch it - CI's workload restore covers
every project.
@jamescrosswell jamescrosswell linked an issue Sep 2, 2026 that may be closed by this pull request
Comment on lines +13 to +18
// Each .NET release bumps the assembly store format: v2 in .NET 9, v3 in .NET 10, v4 in
// .NET 11. v4 changes the header/index layout as well as the version number, so it needs
// the upstream reader changes ported, not just a new constant - bumping the version alone
// gets past IsSupported() and then fails with EndOfStreamException in Prepare().
// Until that port lands, .NET 11 stores are reported as unsupported, which
// AndroidHelpers.GetAndroidAssemblyReader handles by logging and returning null.

@jamescrosswell jamescrosswell Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be done as part of #5454

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAUI 11's XAML compilation produced CS0618 warning for these two styles:

CS0618: 'Frame' is obsolete: 'Frame is obsolete as of .NET 9. Please use Border instead.'

The MAUI 11 template already includes styles for Border so no need to include them in our sample.

@jamescrosswell
jamescrosswell marked this pull request as ready for review September 7, 2026 01:36
@github-actions github-actions Bot added the risk: high PR risk score: high label Sep 7, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d640105. Configure here.

Comment thread test/Sentry.MauiTrimTest/Platforms/iOS/Program.cs Outdated
Skip the assembly store v4 tests on Android device runs too. The guard was
NET11_0_OR_GREATER && !ANDROID, so the net11.0 leg of the Android device-test
matrix still ran them. On device GetSut uses AndroidHelpers.GetAndroidAssemblyReader,
which returns null for a v4 store, and the tests then dereference it - the
null-forgiving ! turns the known limitation into a NullReferenceException.
The v4 gap applies to any .NET 11 Android APK, host or device.

Revert the Android JNI constructor the format bot added to the iOS, MacCatalyst
and Tizen Program types in Sentry.MauiTrimTest (d640105). Those types have no
Android base class and Android.Runtime.JniHandleOwnership doesn't exist on
those platforms, so the TFMs failed to compile. MainApplication.cs already had
the correct constructor, so nothing was missing - the code fix was misapplied.
The format job only reached this project once MSB4006 was fixed in 85c3ce2,
which is why it appeared now.
@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.67%. Comparing base (b96ff3b) to head (3008e74).
⚠️ Report is 1 commits behind head on version7.

Additional details and impacted files
@@             Coverage Diff              @@
##           version7    #5529      +/-   ##
============================================
- Coverage     74.67%   74.67%   -0.01%     
============================================
  Files           515      515              
  Lines         18909    18897      -12     
  Branches       3691     3687       -4     
============================================
- Hits          14120    14111       -9     
+ Misses         3904     3903       -1     
+ Partials        885      883       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Four independent failures, all consequences of the preview:

- NU5104 (most jobs, at pack time): supporting a .NET 11 preview means
  depending on preview Microsoft.Extensions / Microsoft.AspNetCore packages,
  and pack refuses a stable version with prerelease dependencies. Demoted to a
  warning rather than silenced, and it disappears at GA when those references
  become stable. The .NET 10 work took the same approach of pinning rc
  packages, so this is inherent to tracking a preview rather than new.

- NETSDK1094/NETSDK1096 (Linux and Android device tests): .NET 11 Android
  defaults PublishReadyToRun to true - net10.0-android leaves it unset - and
  R2R can't be produced for the Android RIDs here. Turned off in the two app
  projects that build a net11.0 Android TFM, matching Sentry.Samples.Maui.

- NETSDK1242 (Android device tests): the integration test still ran its mono
  cases on net11.0, where the Mono runtime no longer exists. Mono cases now
  apply only below net11.0; coreclr runs everywhere.

- NETSDK1005 (ios-tests): device-test.ps1 defaulted to net10.0, so it asked
  for net10.0-ios, which the device test app no longer targets. The Android
  workflow passes -Tfm per matrix leg; the iOS one relies on the default.
- Install the .NET 10 runtime explicitly. global.json now pins the .NET 11 SDK,
  so the .NET 10 runtime no longer arrives with it, but net10.0 is still a
  target framework we build and test. Most runners have it preinstalled; the
  Alpine containers don't, so their net10.0 test hosts failed to start.

- Install the Android API 37 platform, which net11.0-android37.0 needs (XA5207).

- Pin ContainerBaseImage for the integration test. The SDK derives the tag from
  the runtime version, giving 11.0.0-preview.7-noble-chiseled, which doesn't
  exist: .NET 11 images moved from noble to resolute and previews only ship
  under floating 11.0-preview tags. The .NET 10 previews needed the same
  treatment - see the commented-out block just below.

- .NET 11 removed the Mono runtime for iOS as well as Android, so the iOS
  integration test now uses coreclr (NETSDK1242).

- The Android integration test app pinned its own deployment target of API 21,
  overriding Directory.Build.props, so it still tripped XA4216.
Mirrors what the net10.0-rc.1 work did (9e2f5f2): bump to the upcoming major
and mark the branch prerelease while it tracks a .NET preview.

This also removes the need for the NU5104 workaround added in the previous
commit. That warning fires because pack refuses a stable version with
prerelease dependencies, and supporting a .NET 11 preview means depending on
preview Microsoft.Extensions / Microsoft.AspNetCore packages. A prerelease
package may depend on prerelease packages, so the warning no longer occurs at
all rather than being demoted.
@jamescrosswell
jamescrosswell marked this pull request as draft September 7, 2026 04:16
getsentry-bot and others added 6 commits September 7, 2026 04:19
The format job adds an Android JNI constructor to the iOS, MacCatalyst and
Tizen Program types, which have no Android base type - so those TFMs stop
compiling. Reverting alone wasn't enough: the job re-applied it on the next
run (2e052b1), so the exclusion is the fix.

MAUI projects list every platform folder in every TFM's Compile items - the
SDK filters them later, during the build - so the tool analyses the iOS
sources in an Android context and misapplies the code fix. Sentry.Samples.Maui
shows the same item list, so this isn't specific to the trim test; it just
happens to be where the fix lands.
Reverts the Android JNI constructors the format job re-added to the iOS,
MacCatalyst and Tizen Program types.

The run that pushed them (34082068453) was triggered by b7b358e, before the
exclusion added in 9f173f7, and ran the old command without
./test/Sentry.MauiTrimTest/Platforms. It rebased onto the current tip when
pushing, which is why the commit appears on top of the exclusion. The next
format run picks up the exclusion.
.NET 11 removed the _CopyAotSymbols target that Sentry.targets hooks for
NativeAOT publishes. Diffing Microsoft.NETCore.Native.Publish.targets between
the .NET 10 and .NET 11 ILCompiler packages:

  + <Target Name="NativeCompile"      (added in .NET 11)
  - <Target Name="_CopyAotSymbols"    (removed in .NET 11)

.NET 10 copied native symbols to the publish directory in a post-Publish
target; .NET 11 instead adds them to ResolvedFileToPublish so Publish copies
them itself. With the target gone, AfterTargets never matched and
UploadDebugInfoToSentry silently never ran - a publish completes with no
symbols uploaded and no error. This ships in buildTransitive, so it affects
anyone publishing a NativeAOT app on .NET 11, not just our tests.

Hooks Publish instead from net11.0 onwards. Verified with the integration test
that caught it: "Preparing upload to Sentry for project 'console-app'
(Release/net11.0)" now appears, and both net10.0 and net11.0 pass.

Also splits restore from build in the Android integration test. UseMonoRuntime
is a global property, so during restore it reaches every framework in the
graph - including net11.0-android, where Mono no longer exists - which failed
the net10.0 leg with NETSDK1242 even though only net10.0-android36.0 is built.
- Set UseMonoRuntime on the Android integration test app itself, scoped to the
  framework under test, instead of passing it with -p. As a global property it
  reached every framework in the graph during restore, including
  net11.0-android where Mono no longer exists (NETSDK1242). Restoring without
  it wasn't the answer either - the property has to be set at restore time or
  the wrong runtime pack is downloaded (NETSDK1112). Verified locally: the
  net10.0-android36.0 mono build now succeeds.

- Add the net11.0 Windows snapshot for SentryOptionsTests. Taken from the
  win-x64-verify-test-results artifact rather than hand-written, since it can
  only be generated on Windows. Content is identical to the net10.0 one.

- The .NET 11 Android workload splits debug symbols out of libxamarin-app.so
  into a separate libxamarin-app.dbg.so, so the upload test sees both.
  Uploading it is correct, so the expectation now includes it.
RegisterLocalPackage packs with a build when not in CI, and a net11.0-windows
build can't run on macOS or Linux: MAUI 11 generates a .pri via the Windows-only
makepri.exe. It fails either way - with PRI generation on it's the makepri
"Exec format error", with it off it's NU5026 for the missing .pri - so this is
inherent to MAUI 11 off Windows rather than a consequence of disabling PRI
generation. CI is unaffected because it packs with --no-build.

Excluding the Windows TFMs via the existing NO_WINDOWS switch keeps the local
path working. Those assets aren't needed by the mobile and console apps these
tests build.

With this, "uploads symbols and sources for an Android build" runs locally and
passes. It reported 49 debug information files here against 25 on CI, which is
a good argument for the non-zero check that replaced the hard-coded count.
Renaming integration-test/net9-maui to maui-app put the source app exactly
where cli.Tests.ps1 generates one: DotnetNew does Remove-Item -Recurse -Force
before dotnet new, so running the CLI tests deletes this app and replaces it
with a bare MAUI template. integration-test/.gitignore also has a "*-app" rule,
so the directory was ignored and the generated leftovers were invisible.

CI survived it because the device-test workflows use their own checkout and
don't run cli.Tests.ps1, but running the integration tests locally destroyed
tracked source - which is how this was found.

maui-device avoids both problems: it isn't the generated name, and it doesn't
match "*-app". Comments in android.Tests.ps1 and ios.Tests.ps1 record why, so
it doesn't get renamed back.
Each .NET for iOS SDK pack pins an exact Xcode version - net10.0_26.0 wants
Xcode 26.0, net10.0_26.5 wants 26.5, and only net11.0_26.5 wants the 26.6 that
CI and local dev are on. So this test, which builds an app rather than a
library, failed with "requires Xcode 26.0. The current version of Xcode is
26.6". Bumping the iOS platform version within net10.0 would only swap one
mismatch for another, and lowering CI's Xcode would break the net11.0 iOS
builds that now pass. Libraries skip the check, which is why Sentry.Maui's
net10.0-ios26 target still builds.

That surfaced the second half: .NET 11 replaced Mono with CoreCLR on iOS, so
the uploaded native libraries are the CoreCLR set - libcoreclr, libclrjit,
libmscordaccore, libmscordbi, libxamarin-dotnet-coreclr* and maui-app.r2r -
rather than libmonosgen and the libmono-component-* family.

Both MAUI tests pass locally on macOS.
aot.Tests.ps1 is the file that has the Container test, and the Unsupported AOT
job runs it - so it needs the same pin already applied to the Integration test
step. The SDK derives 11.0.0-preview.7-noble-chiseled from the runtime version,
which doesn't exist: .NET 11 images moved from noble to resolute and previews
only ship under floating 11.0-preview tags.

The tag is multi-arch and its manifest covers linux/arm/v7, so it works for the
linux-arm leg; the win-x86 leg skips the Container test. Test MSBuild is the
only other step using this action in the build workflow and it runs
msbuild.Tests.ps1, which has no container test.
Comment thread .github/actions/environment/action.yml Outdated
Comment thread .github/workflows/build.yml Outdated
jamescrosswell and others added 2 commits September 9, 2026 12:42
Reinstates the "Integration test (musl)" step that was kept commented out for
exactly this situation, instead of the inline conditional I'd added to the
single step - that was a parallel mechanism for something the workflow already
had a shape for.

One difference worth noting against the retained comment: for .NET 11 the glibc
runtimes need a pin too, not just linux-musl. The images moved from noble to
resolute, so the derived 11.0.0-preview.7-noble-chiseled doesn't exist - that's
what failed on .NET (linux-arm64), while linux-musl-arm64 saw no CONTAINER1015
at all. So both steps carry a pin this time.

Coverage is unchanged: the two conditions union to everything except
linux-musl-x64, which stays excluded per #4788.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uncommenting the musl integration test step removed the memory device that was
carrying this knowledge, so replace it with something sturdier.

The container base image pins move to a single workflow-level env block, and
the three steps that need them reference it. At GA you blank two strings in one
place; the steps stay live, so there is nothing to "clean up" and nothing to
uncomment again next preview. An empty value is already ignored by
aot.Tests.ps1, so blanking restores the SDK-derived tag.

CONTRIBUTING.md gains "Upgrading to a new .NET major version": the failures that
recur every year as symptom -> location -> fix (NU5104, CONTAINER1015, the
exact-match v{N}.0 ItemGroups, XA5207, the previous runtime disappearing once
global.json moves, platform minimums, ReadyToRun on Android, the Xcode exact-pin
rule, Verify snapshots), the places that don't follow the usual rules, and the
local checks that catch most of it - which have to run serially, since
build-sentry-native.ps1 -Clean wipes the CMake cache out from under a concurrent
build.

AGENTS.md points at it and drops net9.0 from its target list, which this branch
made stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread .github/workflows/build.yml Outdated
Comment thread .github/workflows/format-code.yml Outdated
Comment thread integration-test/maui-device/Sentry.Maui.Device.IntegrationTestApp.csproj Outdated
Comment thread integration-test/android.Tests.ps1 Outdated
Comment thread integration-test/cli.Tests.ps1 Outdated
Comment thread integration-test/cli.Tests.ps1 Outdated
Comment thread integration-test/cli.Tests.ps1 Outdated
Comment thread integration-test/cli.Tests.ps1 Outdated
Comment thread Directory.Build.props
Comment thread integration-test/common.ps1 Outdated
Comment thread integration-test/ios.Tests.ps1 Outdated
Comment thread integration-test/ios.Tests.ps1 Outdated
Comment thread scripts/device-test.ps1 Outdated
Comment thread Directory.Build.targets Outdated
Comment thread Directory.Build.props Outdated
Comment thread Directory.Build.targets Outdated
Comment thread Directory.Build.props Outdated
jamescrosswell and others added 2 commits September 9, 2026 14:07
Applies all seventeen review suggestions on #5529. Comment-only changes:
ten rewrites that shorten the explanatory comments added by this branch,
and seven that drop comments judged redundant with the code they sit above
(the two paired SupportedOSPlatformVersion lines in Directory.Build.props
and .targets, the setup-dotnet version list, and the CoreCLR-on-iOS note in
cli.Tests.ps1).

No functional change: no MSBuild property, condition, workflow step or test
assertion is touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Per review feedback on #5529 (@bruno-garcia), keep supporting .NET 8 and
.NET 9 on non-mobile targets rather than dropping them alongside the
mobile ones.

The policy, now documented in CONTRIBUTING.md so it survives to next
year's upgrade:

- Mobile: every version still supported by Microsoft - in practice the
  latest two, so net10.0 and net11.0.
- Non-mobile: the latest two LTS releases plus every STS release after
  the older of them - so net8.0;net9.0;net10.0;net11.0 while .NET 10 is
  the latest LTS, becoming net10.0 and later when .NET 12 ships.

The split needs no new machinery: mobile projects already reference
$(LatestTfm)/$(PreviousTfm) while non-mobile ones reference
$(CurrentTfms), so widening the non-mobile set leaves mobile alone.
Sentry.Maui still packs net10.0/net11.0 only; Sentry packs all four
lib/ assets.

Also adds a net8.0/net9.0 arm to the three exhaustive TFM switches that
#error on an unknown framework, and restores the verified snapshots for
both TFMs. The net8-only #elif arms in src/ were never deleted, so they
become live again with no source change.

No CI changes: no job is matrixed on the non-mobile TFM axis, and the
environment action already installs the 8.0 and 9.0 SDKs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for .net 11 preview 7

2 participants