Default .NET 11 to target net11.0-android36.1 only#10829
Merged
jonathanpeppers merged 12 commits intomainfrom Feb 24, 2026
Merged
Default .NET 11 to target net11.0-android36.1 only#10829jonathanpeppers merged 12 commits intomainfrom
jonathanpeppers merged 12 commits intomainfrom
Conversation
Stop building API 36.0 as a separate stable target and make net11.0-android36.1 the sole default target framework for .NET 11. Targeting net11.0-android36 (36.0) is no longer supported on .NET 11; it remains valid for net10.0. Changes: - Configuration.props: Set AndroidLatestStableApiLevel to 36.1, update framework version to v16.1, comment out AndroidLatestStableApiLevel2 with a 37.1 example for future use - SupportedPlatforms.targets: Default TargetPlatformVersion changed to 36.1, mark 36.0 as DefineConstantsOnly (no targeting pack) - BundledVersions.targets: Update generated _AndroidLatestStableApiLevel - Mono.Android.csproj: Adjust IsUnstableVersion to handle the commented-out AndroidLatestStableApiLevel2 gracefully - AndroidToolchain.cs: Remove isLatestStable from platform-36 - Xamarin.Android.Common.props: Update AndroidSdkPlatformVersion - Tests: Remove android36 (Major-only) test case from Get_DotNetTargetFrameworks_Data, replace hardcoded .1 references with XABuildConfig.AndroidLatestStableApiLevel
The v16.1 assembly has expected attribute differences from v16.0: - ObsoletedOSPlatformAttribute removed from WifiConfiguration members that were undeprecated in API 36.1 - RequiresPermissionAttribute removed from TelephonyManager members where permission requirements changed
…nyManager The net11.0 reference assembly was built against API 36.0, but the implementation now targets 36.1 where WifiConfiguration was undeprecated and TelephonyManager permission attributes changed.
The android workload packs list referenced API 36 packs (Ref, Runtime, Mono, CoreCLR, NativeAOT) but the build now only produces 36.1 packs. Update the packs list to reference 36.1 and add 36.1 pack definitions for all Mono/CoreCLR/NativeAOT runtime flavors. The 36 pack definitions are retained for net10 resolution via KnownFrameworkReference.
When multiple API versions share the same ApiLevel (e.g. 36.0 and 36.1 both have ApiLevel=36), GetIdFromApiLevel(36) can return '36.1' if that entry appears first in installedVersions. This causes the manifest merger to reject the non-integer targetSdkVersion value. TargetSdkVersion is already resolved to the integer API level string by GenerateMainAndroidManifest, so return it directly instead of round-tripping through GetIdFromApiLevel which can pick the wrong version's Id.
Use MonoAndroidHelper.TryParseApiLevel to parse AndroidApiLevel into a System.Version, preserving the minor version (e.g. 36.1). Use GetIdFromVersionCodeFull to get the correct platform directory name. Make AndroidApiLevel [Required] and remove unused TargetFrameworkVersion property since _AndroidApiLevel is always set by ResolveAndroidTooling.
…etFrameworkVersion
Update the test to use XABuildConfig.AndroidLatestStableApiLevel for minSdkVersion instead of XABuildConfig.AndroidDefaultTargetDotnetApiLevel with a ".0" suffix. This aligns the manifest test with the latest stable Android API level and removes the redundant ".0" formatting.
TargetSdkVersionName now returns TargetSdkVersion directly instead of calling GetIdFromApiLevel, so it must not be null when Merge() creates the uses-sdk element.
Same issue as TargetSdkVersionName: MinSdkVersion is already resolved to an integer API level string by GenerateMainAndroidManifest. Round-tripping through GetIdFromApiLevel() returns '36.1' for input '36' when both 36.0 and 36.1 share ApiLevel=36, which then fails int.TryParse and falls back to AndroidMinimumDotNetApiLevel (21).
There was a problem hiding this comment.
Pull request overview
Updates the .NET 11 Android API-level defaults to treat 36.1 as the sole “latest stable” target (stopping separate stable targeting for 36.0), and adjusts build logic/tests to correctly handle minor API levels such as 36.1.
Changes:
- Update API-compat baselines for
net11.0and add a new baseline forv16.1. - Fix manifest generation to avoid incorrectly emitting
targetSdkVersion="36.1"when the manifest should contain the integer API level (e.g."36"). - Update dependency calculation and workload manifest entries to align with minor API-level platform IDs (e.g.
android-36.1) and remove36.0“latest stable” wiring.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/api-compatibility/acceptable-breakages-vReference-net11.0.txt | Adds new acceptable API-compat breakages for net11.0 reference validation. |
| tests/api-compatibility/acceptable-breakages-v16.1.txt | Introduces acceptable API-compat breakages for the v16.1 contract comparison. |
| src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets | Removes passing TargetFrameworkVersion into CalculateProjectDependencies task invocation. |
| src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs | Ensures targetSdkVersion/minSdkVersion are emitted as integer API levels (avoids incorrect minor IDs). |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs | Removes the major-only android<Major> test case for target frameworks. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetDependenciesTests.cs | Updates tests to set AndroidApiLevel instead of TargetFrameworkVersion. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs | Updates SupportedOSPlatformVersion test data and adds a regression test for 36.1 → manifest 36. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs | Uses AndroidLatestStableApiLevel consistently instead of hardcoded .1 assumptions. |
| src/Xamarin.Android.Build.Tasks/Tasks/CalculateProjectDependencies.cs | Switches to required AndroidApiLevel and adds logic to resolve minor platform directory IDs. |
| src/Xamarin.Android.Build.Tasks/Microsoft.NET.Sdk.Android/WorkloadManifest.in.json | Renames workload packs from 36 to 36.1 for ref/runtime packs. |
| src/Mono.Android/Mono.Android.csproj | Adjusts unstable-version detection condition to tolerate an empty AndroidLatestStableApiLevel2. |
| build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs | Removes isLatestStable from platform-36 and assigns it to platform-36.1. |
| Configuration.props | Sets latest stable API/framework to 36.1 / v16.1 and comments out AndroidLatestStableApiLevel2. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stop building API 36.0 as a separate stable target and make net11.0-android36.1 the sole default target framework for .NET 11. Targeting net11.0-android36 (36.0) is no longer supported on .NET 11; it remains valid for net10.0.
Changes: