Skip to content

[automated] Merge branch 'main' => 'net11.0'#34502

Closed
github-actions[bot] wants to merge 238 commits intonet11.0from
merge/main-to-net11.0
Closed

[automated] Merge branch 'main' => 'net11.0'#34502
github-actions[bot] wants to merge 238 commits intonet11.0from
merge/main-to-net11.0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

I detected changes in the main branch which have not been merged yet to net11.0. I'm a robot and am configured to help you automatically keep net11.0 up to date, so I've opened this PR.

This PR merges commits made on main by the following committers:

  • PureWeen
  • StephaneDelcroix
  • devanathan-vaithiyanathan
  • noiseonwires
  • sheiksyedm
  • sbomer
  • Vignesh-SF3580
  • jpd21122012
  • jfversluis
  • kubaflo
  • mattleibow
  • rmarinho
  • rolfbjarne
  • Copilot

Instructions for merging from UI

This PR will not be auto-merged. When pull request checks pass, complete this PR by creating a merge commit, not a squash or rebase commit.

merge button instructions

If this repo does not allow creating merge commits from the GitHub UI, use command line instructions.

Instructions for merging via command line

Run these commands to merge this pull request from the command line.

git fetch
git checkout main
git pull --ff-only
git checkout net11.0
git pull --ff-only
git merge --no-ff main

# If there are merge conflicts, resolve them and then run git merge --continue to complete the merge
# Pushing the changes to the PR branch will re-trigger PR validation.
git push https://github.com/dotnet/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git push git@github.com:dotnet/maui HEAD:merge/main-to-net11.0

After PR checks are complete push the branch

git push

Instructions for resolving conflicts

⚠️ If there are merge conflicts, you will need to resolve them manually before merging. You can do this using GitHub or using the command line.

Instructions for updating this pull request

Contributors to this repo have permission update this pull request by pushing to the branch 'merge/main-to-net11.0'. This can be done to resolve conflicts or make other changes to this pull request before it is merged.
The provided examples assume that the remote is named 'origin'. If you have a different remote name, please replace 'origin' with the name of your remote.

git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull https://github.com/dotnet/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push https://github.com/dotnet/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull git@github.com:dotnet/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push git@github.com:dotnet/maui HEAD:merge/main-to-net11.0

Contact .NET Core Engineering (dotnet/dnceng) if you have questions or issues.
Also, if this PR was generated incorrectly, help us fix it. See https://github.com/dotnet/arcade/blob/main/.github/workflows/scripts/inter-branch-merge.ps1.

rmarinho and others added 30 commits February 11, 2026 20:56
Clarify the Copilot PR-review prompt to execute five explicit phases (Understanding, Test Review, Fix Exploration, Alternative Comparison, Final Review). Add a new pipeline step that invokes a Copilot "post-comment" skill, captures its exit code, logs output to $(Build.ArtifactStagingDirectory)/copilot-logs, and sets a PostCommentFailed variable on failure. Ensure artifacts dir exists, surface warnings on failure, and make the original post-comment fallback step run only when the skill step failed. Update step display names and preserve artifact publishing.
Add a pipeline step (Cache Prompt File) that loads eng/pipelines/prompts/pr-review-prompt.md and copies it to /tmp/copilot-prompts/pr-review-prompt.md before the PR branch checkout. Update the later Copilot step to read the prompt from the cached location and adjust the error message. This prevents failures when the prompt file is absent on the PR branch by ensuring a stable copy is available for the review step.
Replace brittle iPhone Xs + iOS 18.5 lookup with a prioritized selection routine. The script now iterates preferred iOS versions and device models, picks the first available preferred device or falls back to the first available iPhone, and finally falls back to any available simulator. It also surfaces runtime info when listing available simulators and reports the selected device name and UDID before booting.
Replace direct checkout of the PR branch with logic that fetches the PR, computes the merge-base against the current branch, and cherry-picks commits from the merge-base..PR_HEAD onto the current branch (using --no-commit). Adds commit counting, a warning when no commits are found, conflict handling with status and diff output, and extra logging (current branch, merge base, commit count, last commit and status). Also updates the pipeline step display name to 'Cherry-pick PR Changes' and tweaks the fetch message.
Add a CI step to run ./build.ps1 --target=dotnet-buildtasks (Release, diagnostic) to compile MSBuild tasks required for MAUI builds. The step includes a retry on failure and sets DOTNET_TOKEN and PRIVATE_BUILD environment variables for accessing internal artifacts. Placed before the simulator/emulator listing to ensure tasks are available for subsequent MAUI jobs.
Add provisioning steps to eng/pipelines/common/provision.yml to create an iPhone Xs simulator with iOS 18.5 (falling back to iOS 18.x if 18.5 is not available). The script finds the appropriate runtime and device type, checks for an existing simulator to avoid duplicates, attempts creation if missing, and prints available iPhone simulators. This ensures the required simulator is present for UI tests and logs useful diagnostics if runtimes or device types are not available.
SyedAbdulAzeemSF4852 and others added 17 commits March 6, 2026 12:23
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes #33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
### Description of Change

Backgrounds are everywhere in our apps, so we must be fast when drawing
android views, and `Java -> C#` is not.

This PR tries to do its best to completely move the logic into a java
`PlatformDrawable` class.


### Benchmarks (~50% improvements in mapping, ~60% improvement in
rendering time)

I used #24414 as main page wrapped into a `Shell` component given it has
a `drawChild` method which shows the cumulative draw time.

The results are impressive and will for sure make an impact!


[24414-net10.json](https://github.com/user-attachments/files/22296183/24414-net10.json)
<img width="754" height="144" alt="image"
src="https://github.com/user-attachments/assets/834b59e0-77f9-457c-9867-179b91f116d0"
/>
<img width="749" height="46" alt="image"
src="https://github.com/user-attachments/assets/5ecf5252-10c8-42e8-85f0-b94dfd60746b"
/>
<img width="752" height="124" alt="image"
src="https://github.com/user-attachments/assets/04d78a16-f22d-4ff1-ab5f-b34316c7240a"
/>


[24414-pr-final2.json](https://github.com/user-attachments/files/22403331/24414-pr-final2.json)
<img width="1106" height="122" alt="image"
src="https://github.com/user-attachments/assets/bc59bef4-9e2f-4626-b399-7ab0b3b44cd0"
/>
<img width="918" height="104" alt="image"
src="https://github.com/user-attachments/assets/caca6cba-69c4-4949-b7df-cac5ceccb6d9"
/>
<img width="903" height="123" alt="image"
src="https://github.com/user-attachments/assets/2b6e9b52-c347-43d8-abec-061263739724"
/>

---------

Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
…urce While Scrolled (#34153)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Issue Details
The offsets (VerticalOffset and HorizontalOffset) were being calculated
incrementally and did not reset properly when the ItemsSource changed,
leading to incorrect offset values.

### Description of Change

<!-- Enter description of the fix in this section -->
The change resets the VerticalOffset and HorizontalOffset to 0 when the
ItemsSource is updated. This ensures correct offset values after adding
or removing items, fixing the issue of incorrect offsets while
scrolling.

### Regarding test case
The test case was added in PR #26782 , so this PR includes only the iOS
fix.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #26798 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

---------

Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
… explicit TemplateBinding (#34332)

This fix PR #30880 in the candidate
branch causes the
`DoesNotInheritBindingContextToContentFromControlTemplate` unit test to
fail.

So reverted the PR #30880 to resolve
the failure in the inflight/candidate PR
#34294 and will look the proper fix
later
… - 1 (#34334)

This PR addresses the UI test image failures that occurred in the
inflight/candidate branch #34294 and
includes updates to improve rendering and test stability across
platforms.

### Controls Handler Registration

* Simplified the logic for registering handlers for controls like
`Label`, `Editor`, `Picker`, `RadioButton`, and `TimePicker` in
`AppHostBuilderExtensions.cs`. The new approach registers all fallback
handlers together, reducing duplicated code and improving
maintainability.

### 
* In the NavigationRootManager class, the line
_rootView.SetTitleBar(null, null); was added in this PR
#34032 by a contributor due to an AI
minor suggestion, but this line causes an issue when swapping pages, so
the TitlebarWorksWhenSwitchingPage test fails. Setting SetTitleBar to
null is already implemented in the WindowHandler class in the
[DisconnectHandler](https://github.com/dotnet/maui/blob/main/src/Core/src/Handlers/Window/WindowHandler.Windows.cs#L55)
method, so I have removed this line _rootView.SetTitleBar(null, null);
from the PR [34032](#34032).

### Image Resave:
* Resaved images: DownSizeImageAppearProperly,
Material3CheckBoxFeatureTests, Material3CheckBox_DefaultAppearance,
DownSizeImageAppearProperly,
VerifyLinearGradientBrushWithStrokeAndOpacity,
VerifyRadialGradientBrushWithOpacity,
VerifyRadialGradientBrushWithShadowAndOpacity,
VerifyLinearGradientBrushWithOpacity,
VerifyLinearGradientBrushWithShadowAndOpacity,
DarkTheme_VerifyVisualState. These PR fixes address the issues:
#33173,
#31567,
#33590,
#34036
* Added the base images for iOS 26, Mac, and Windows.

### Test Stability and Platform-Specific Handling

* Added a platform-specific ignore for a Shell flyout test on iOS 26 due
to a known bug, improving test reliability and clarity about platform
limitations.
* Updated a CollectionView scroll test to wait for specific elements on
Windows, ensuring the test works correctly across platforms.

### DatePicker Handler Tests

* Introduced a helper method `EnsureDialogCreated` in
`DatePickerHandlerTests.Android.cs` to reliably create the native dialog
before reading min/max values, addressing issues caused by lazy dialog
creation after a recent PR. This helper is now used in relevant tests to
improve robustness.
[[1]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R26)
[[2]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R54)
[[3]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R131-R146)
* Clarified the DatePicker test logic in `DatePickerTests.cs` to ensure
the `DateSelected` event fires correctly regardless of dialog state,
improving test reliability on Android.

### Test Case Organization

* Removed the obsolete `VerifyFlyoutPage_IsEnabled` test and renumbered
the remaining FlyoutPage tests in `FlyoutPageFeatureTests.cs` to
maintain sequential order and consistency.
[[1]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L176-R177)
[[2]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L204-R191)
[[3]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L222-R209)
[[4]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L240-R227)
[[5]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L254-R241)
[[6]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L268-R255)
[[7]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L284-R271)
[[8]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L299-R286)
[[9]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L310-R297)
[[10]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L327-R314)
[[11]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L340-R327)
[[12]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L357-R344)
[[13]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L376-R363)
[[14]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L387-R374)
[[15]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L400-R387)
…nd pixel-level comparison (#34024)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root Cause

`SafeAreaInsetsDidChange` fires repeatedly during iOS animations (e.g.,
`TranslateToAsync`, bottom sheet transitions) as views move relative to
the window. This caused two distinct infinite loop patterns:

1. **Sub-pixel oscillation** (#32586, #33934): Animations produce
sub-pixel differences in `SafeAreaInsets` (e.g., `0.0000001pt`). Exact
equality fails, triggering `InvalidateAncestorsMeasures` → layout pass →
position change → new `SafeAreaInsetsDidChange` → infinite loop.

2. **Parent-child double application** (#33595): A `ContentPage`
(implementing `ISafeAreaView`) and its child `Grid` both independently
apply safe area adjustments. When the `ContentPage` adjusts its layout
for the notch/status bar, it repositions the `Grid`. The `Grid`'s new
position fires `SafeAreaInsetsDidChange`, causing it to re-apply its own
adjustment — creating a ping-pong loop.

### Description of Change

**Primary fix — `IsParentHandlingSafeArea` (parent hierarchy walk):**

In both `MauiView.ValidateSafeArea` and
`MauiScrollView.ValidateSafeArea`, before applying safe area
adjustments, we now check whether an ancestor `MauiView` is already
applying safe area for the **same edges**. If so, the child skips its
own adjustment to avoid double-padding.

The check is **edge-aware**: a parent handling `Top` does not block a
child from independently handling `Bottom`. Only overlapping edges cause
deferral. The `_parentHandlesSafeArea` result is cached per layout cycle
and cleared on `SafeAreaInsetsDidChange`, `InvalidateSafeArea`, and
`MovedToWindow`.

**Secondary fix — `EqualsAtPixelLevel`:**

Safe area values are compared at device-pixel resolution (rounding to `1
/ ContentScaleFactor`) before deciding whether to trigger a layout
invalidation. This absorbs sub-pixel animation noise and prevents the
oscillation loops in #32586 and #33934.

**MauiScrollView bug fixes:**
- Inverted condition: `!UpdateContentInsetAdjustmentBehavior()` was
incorrectly gating behavior; corrected to
`UpdateContentInsetAdjustmentBehavior()`.
- The `_appliesSafeAreaAdjustments` flag now correctly incorporates
`!IsParentHandlingSafeArea()`.

**What was removed:**
- The "Window Guard" approach (comparing `Window.SafeAreaInsets` to
filter noise) was tried and removed. It was fragile: on macCatalyst with
a custom TitleBar, `WindowViewController` repositions content by pushing
it down, which changes the view's own `SafeAreaInsets` without changing
`Window.SafeAreaInsets`. The guard blocked this legitimate change,
causing a 28px content shift regression in CI.

### Issues Fixed
Fixes #32586
Fixes #33934
Fixes #33595
Fixes #34042

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Tamilarasan-Paranthaman <Tamilarasan-Paranthaman@users.noreply.github.com>
The MauiXamlHotReload MSBuild property was introduced in #34028 but was
not registered as a compiler-visible property. Without this entry,
Roslyn source generators cannot read the property value via
AnalyzerConfigOptions.GlobalOptions. This change makes it accessible so
IDE and source generators can adjust their behavior based on the
configured hot reload mode (Legacy or SourceGen).

Co-authored-by: Kirill Ovchinnikov <kovchinnikov@microsoft.com>
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Description of Change

<!-- Enter description of the fix in this section -->

This pull request updates the image URLs used in the `President` objects
within the `Init()` method of `Issue2354.cs` to ensure that they
reference the correct raw image files directly from GitHub. This change
improves reliability and consistency in how images are loaded for test
cases.

Image URL updates:

* Changed all image URLs for `President` objects to use the
`raw.githubusercontent.com` domain, removing the `?raw=true` query
parameter and ensuring direct access to the image files.

**Instead of:**
https://github.com/.../avatar.png?raw=true

**use the resolved target:**

https://raw.githubusercontent.com/dotnet/maui/refs/heads/main/src/Controls/tests/TestCases.HostApp/Resources/Images/avatar.png

This removes the cross‑host redirect entirely and is the most robust
option for in‑app fetching. The raw.githubusercontent.com which hosts
the actual raw files.

**References:**
[Issue16032](https://github.com/dotnet/maui/blob/6c123d72970865ccb1312e118f5098ef6c44e892/src/Controls/tests/TestCases.HostApp/Issues/Issue16032.cs#L88),
[Bugzilla35733](https://github.com/dotnet/maui/blob/6c123d72970865ccb1312e118f5098ef6c44e892/src/Controls/tests/TestCases.HostApp/Issues/Bugzilla/Bugzilla35733.cs#L30),
[Bugzilla37625](https://github.com/dotnet/maui/blob/6c123d72970865ccb1312e118f5098ef6c44e892/src/Controls/tests/TestCases.HostApp/Issues/Bugzilla/Bugzilla37625.cs#L12)
has a url that used form raw.githuusercontent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Description

The `dotnet-maui-build` internal pipeline (definition 1536) has been
**failing on every single build since ~Jan 27** (~5+ weeks) because
`BUILD.BUILDNUMBER` changed format to `10.0.50+azdo.XXXXX`.

Arcade's `Version.BeforeCommonTargets.targets` tries to do arithmetic on
`OfficialBuildId` using `[MSBuild]::Add/Multiply/Subtract`, but the `+`
character in the new format causes `MSB4186: Invalid static method
invocation syntax`.

### Fix

Change the internal pipeline's `_OfficialBuildIdArgs` from
`$(BUILD.BUILDNUMBER)` to `$(_BuildOfficialId)` (the `yyyyMMdd.counter`
format already used by all other pipeline configurations).

### Impact

- **Internal (`dotnet-maui-build`)**: Fixed — uses `_BuildOfficialId`
(`yyyyMMdd.counter`)
- **Public (`maui-pr`)**: Unchanged — already uses `_BuildOfficialId`  
- **PR builds**: Unchanged — already uses `_BuildOfficialId`
- Publishing and signing args are untouched

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## What's Coming

.NET MAUI inflight/candidate introduces significant improvements across
all platforms with focus on quality, performance, and developer
experience. This release includes 46 commits with various improvements,
bug fixes, and enhancements.


## Button
- [Android] Implemented material3 support for Button by @Dhivya-SF4094
in #33173
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Button](#33172)
  </details>

## CollectionView
- [Android] Fix RemainingItemsThresholdReachedCommand not firing when
CollectionView has Header and Footer both defined by @SuthiYuvaraj in
#29618
  <details>
  <summary>🔧 Fixes</summary>

- [Android : RemainingItemsThresholdReachedCommand not firing when
CollectionVew has Header and Footer both
defined](#29588)
  </details>

- [iOS/MacCatalyst] Fix CollectionView ScrollTo for horizontal layouts
by @Shalini-Ashokan in #33853
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS/MacCatalyst] CollectionView ScrollTo does not work with
horizontal Layout](#33852)
  </details>

- [iOS & Mac] Fixed IndicatorView Size doesnt update dynamically by
@SubhikshaSf4851 in #31129
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Catalyst] IndicatorView.IndicatorSize does not update
dynamically at runtime](#31064)
  </details>

- [Android] Fix for CollectionView Scrolled event is triggered on the
initial app load. by @BagavathiPerumal in
#33558
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] CollectionView Scrolled event is triggered on the initial
app load.](#33333)
  </details>

- [iOS, Android] Fix for CollectionView IsEnabled=false allows touch
interactions by @praveenkumarkarunanithi in
#31403
  <details>
  <summary>🔧 Fixes</summary>

- [More issues with CollectionView IsEnabled, InputTransparent, Opacity
via Styles and code behind](#19771)
  </details>

- [iOS] Fix VerticalOffset Update When Modifying
CollectionView.ItemsSource While Scrolled by @devanathan-vaithiyanathan
in #34153
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS]VerticalOffset Not Reset to Zero After Clearing ItemSource in
CollectionView](#26798)
  </details>

## DateTimePicker
- [Android] Fix DatePicker MinimumDate/MaximumDate not updating
dynamically by @HarishwaranVijayakumar in
#33687
  <details>
  <summary>🔧 Fixes</summary>

- [[regression/8.0.3] [Android] DatePicker control minimum date
issue](#19256)
- [[Android] DatePicker does not update MinimumDate / MaximumDate in the
Popup when set in the viewmodel after first
opening](#33583)
  </details>

## Drawing
- Android drawable perf by @albyrock87 in
#31567

## Editor
- [Android] Implemented material3 support for Editor by
@SyedAbdulAzeemSF4852 in #33478
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
Editor](#33476)
  </details>

## Entry
- [iOS, Mac] Fix for CursorPosition not updating when typing into Entry
control by @SyedAbdulAzeemSF4852 in
#30505
  <details>
  <summary>🔧 Fixes</summary>

- [Entry control CursorPosition does not update on TextChanged event
[iOS Maui 8.0.7] ](#20911)
- [CursorPosition not calculated correctly on behaviors events for iOS
devices](#32483)
  </details>

## Flyoutpage
- [Android, Windows] Fix for FlyoutPage toolbar button not updating on
orientation change by @praveenkumarkarunanithi in
#31962
  <details>
  <summary>🔧 Fixes</summary>

- [Flyout page in Android does not show flyout button (burger)
consistently](#24468)
  </details>

- Fix for First Item in CollectionView Overlaps in FlyoutPage.Flyout on
iOS by @praveenkumarkarunanithi in
#29265
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] CollectionView not rendering first item correctly in
FlyoutPage.Flyout](#29170)
  </details>

## Image
- [Android] Fix excessive memory usage for stream and resource-based
image loading by @Shalini-Ashokan in
#33590
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Unexpected high Bitmap.ByteCount when loading image via
ImageSource.FromResource() or ImageSource.FromStream() in .NET
MAUI](#33239)
  </details>

- [Android] Fix for Resize method returns an image that has already been
disposed by @SyedAbdulAzeemSF4852 in
#29964
  <details>
  <summary>🔧 Fixes</summary>

- [In GraphicsView, the Resize method returns an image that has already
been disposed](#29961)
- [IIMage.Resize bugged
behaviour](#31103)
  </details>

## Label
- Fixed Label Span font property inheritance when applied via Style by
@SubhikshaSf4851 in #34110
  <details>
  <summary>🔧 Fixes</summary>

- [`Span` does not inherit text styling from `Label` if that styling is
applied using `Style` ](#21326)
  </details>

- [Android] Implemented material3 support for Label by
@SyedAbdulAzeemSF4852 in #33599
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
Label](#33598)
  </details>

## Map
- [Android] Fix Circle Stroke color is incorrectly updated as Fill
color. by @NirmalKumarYuvaraj in
#33643
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Circle Stroke color is incorrectly updated as Fill
color.](#33642)
  </details>

## Mediapicker
- [iOS] Fix: invoke MediaPicker completion handler after
DismissViewController by @yuriikyry4enko in
#34250
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Media Picker UIImagePickerController closing
issue](#21996)
  </details>

## Navigation
- Fix ContentPage memory leak on Android when using NavigationPage
modally (fixes #33918) by @brunck in
#34117
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Modal TabbedPage whose tabs are NavigationPage(ContentPage)
is retained after
PopModalAsync()](#33918)
  </details>

## Picker
- [Android] Implement material3 support for TimePicker by
@HarishwaranVijayakumar in #33646
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
TimePicker](#33645)
  </details>

- [Android] Implemented Material3 support for Picker by
@SyedAbdulAzeemSF4852 in #33668
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Picker](#33665)
  </details>

## RadioButton
- [Android] Implemented material3 support for RadioButton by
@SyedAbdulAzeemSF4852 in #33468
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
RadioButton](#33467)
  </details>

## Setup
- Clarify MA003 error message by @jeremy-visionaid in
#34067
  <details>
  <summary>🔧 Fixes</summary>

- [MA003 false positive with
9.0.21](#26599)
  </details>

## Shell
- [Android] Fix TabBar FlowDirection not updating dynamically by
@SubhikshaSf4851 in #33091
  <details>
  <summary>🔧 Fixes</summary>

- [[Android, iOS] FlowDirection RTL is not updated dynamically on Shell
TabBar](#32993)
  </details>

- [Android] Fix page not disposed on Shell replace navigation by
@Vignesh-SF3580 in #33426
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] [Shell] replace navigation leaks current
page](#25134)
  </details>

- [Android] Fixed Shell flyout does not disable scrolling when
FlyoutVerticalScrollMode is set to Disabled by @NanthiniMahalingam in
#32734
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Shell.FlyoutVerticalScrollMode="Disabled" does not disable
scrolling](#32477)
  </details>

## Single Project
- Fix: Throw a clear error when an SVG lacks dimensions instead of a
NullReferenceException by @Shalini-Ashokan in
#33194
  <details>
  <summary>🔧 Fixes</summary>

- [MAUI Fails To Convert Valid SVG Files Into PNG Files (Object
reference not set to an instance of an
object)](#32460)
  </details>

## SwipeView
- [iOS] Fix SwipeView stays open on iOS after updating content by
@devanathan-vaithiyanathan in #31248
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] - Swipeview with collectionview
issue](#19541)
  </details>

## TabbedPage
- [Windows] Fixed IsEnabled Property not works on Tabs by
@NirmalKumarYuvaraj in #26728
  <details>
  <summary>🔧 Fixes</summary>

- [ShellContent IsEnabledProperty does not
work](#5161)
- [[Windows] Shell Tab IsEnabled Not
Working](#32996)
  </details>

- [Android] Fix NavigationBar overlapping StatusBar when NavigationBar
visibility changes by @Vignesh-SF3580 in
#33359
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] NavigationBar overlaps with StatusBar when mixing
HasNavigationBar=true/false in TabbedPage on Android 15 (API
35)](#33340)
  </details>

## Templates
- Fix for unable to open task using keyboard navigation on windows
platform by @SuthiYuvaraj in #33647
  <details>
  <summary>🔧 Fixes</summary>

- [Unable to open task using keyboard: A11y_.NET maui_User can get all
the insights of
Dashboard_Keyboard](#30787)
  </details>

## TitleView
- Fix for NavigationPage.TitleView does not expand with host window in
iPadOS 26+ by @SuthiYuvaraj in #33088

## Toolbar
- [iOS] Fix toolbar items ignoring BarTextColor on iOS/MacCatalyst 26+
by @Shalini-Ashokan in #34036
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS 26] ToolbarItem color with custom BarTextColor not
working](#33970)
  </details>

- [Android] Fix for ToolbarItem retaining the icon from the previous
page on Android when using NavigationPage. by @BagavathiPerumal in
#32311
  <details>
  <summary>🔧 Fixes</summary>

- [Toolbaritem keeps the icon of the previous page on Android, using
NavigationPage (not shell)](#31727)
  </details>

## WebView
- [Android] Fix WebView in a grid expands beyond it's cell by
@devanathan-vaithiyanathan in #32145
  <details>
  <summary>🔧 Fixes</summary>

- [Android - WebView in a grid expands beyond it's
cell](#32030)
  </details>

## Xaml
- ContentPresenter: Propagate binding context to children with explicit
TemplateBinding by @HarishwaranVijayakumar in
#30880
  <details>
  <summary>🔧 Fixes</summary>

- [Binding context in
ContentPresenter](#23797)
  </details>


<details>
<summary>🔧 Infrastructure (1)</summary>

- [Revert] ContentPresenter: Propagate binding context to children with
explicit TemplateBinding by @Ahamed-Ali in
#34332

</details>

<details>
<summary>🧪 Testing (6)</summary>

- [Testing] Feature Matrix UITest Cases for Shell Flyout Page by
@NafeelaNazhir in #32525
- [Testing] Feature Matrix UITest Cases for Brushes by
@LogishaSelvarajSF4525 in #31833
- [Testing] Feature Matrix UITest Cases for BindableLayout by
@LogishaSelvarajSF4525 in #33108
- [Android] Add UI tests for Material 3 CheckBox by
@HarishwaranVijayakumar in #34126
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Add UI tests for Material 3
CheckBox](#34125)
  </details>
- [Testing] Feature Matrix UITest Cases for Shell Tabbed Page by
@NafeelaNazhir in #33159
- [Testing] Fixed Test case failure in PR 34294 - [03/2/2026] Candidate
- 1 by @TamilarasanSF4853 in #34334

</details>

<details>
<summary>📦 Other (2)</summary>

- Bumps Syncfusion.Maui.Toolkit dependency to version 1.0.9 by
@PaulAndersonS in #34178
- Fix crash when closing Windows based app when using TitleBar by
@MFinkBK in #34032
  <details>
  <summary>🔧 Fixes</summary>

- [Unhandled exception "Value does not fall within the expected range"
when closing Windows app](#32194)
  </details>

</details>
**Full Changelog**:
main...inflight/candidate
…hot fallback (#34340)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Description

This PR brings together three improvements to the Copilot CI
infrastructure:

1. **Auto-trigger uitests and device-tests on `darc-*` branches** —
Major rework of `ci-copilot.yml` to support UI tests and device tests
triggered on darc branches.

2. **Make emulator startup and provisioning more robust** — Improvements
to `Start-Emulator.ps1` and `provision.yml` for more reliable Android
emulator handling.

3. **Support fallback environment for snapshots** — Changes to
`UITest.cs` and `VisualRegressionTester.cs` to support snapshot
environment fallback.

## Changes

- `eng/pipelines/ci-copilot.yml` — Reworked CI pipeline for Android
device test support
- `.github/scripts/shared/Start-Emulator.ps1` — More robust emulator
startup
- `eng/pipelines/common/provision.yml` — Provisioning improvements
- `src/Controls/tests/TestCases.Shared.Tests/UITest.cs` — Snapshot
fallback support
- `src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs` —
Snapshot fallback support

---------

Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
#34449)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Description

Cherry-pick of
[`5d6e5a20`](5d6e5a2)
from `net11.0`, adapted for `main`.

Fixes #34428

### Problem

Release 10.0.50 introduced a performance optimization (`_isSubscribed`
flag) in `TypedBinding` that prevented re-subscribing to intermediate
INPC objects when they changed. This caused compiled bindings with
nested property paths (e.g. `{Binding ViewModel.Text}`) to stop updating
when the intermediate object was replaced.

### Fix

Remove the `_isSubscribed` guard and always call `Subscribe()` on every
`Apply`. The `Subscribe()` implementation is already idempotent — it
diffs old vs new subscription targets — so calling it repeatedly is safe
with minimal overhead.

### Tests

Two regression tests added to `TypedBindingUnitTests.cs`:
-
`TypedBinding_NestedProperty_ResubscribesAfterNullIntermediateBecomesNonNull`
- `TypedBinding_NestedProperty_ResubscribesAfterIntermediateReplaced`

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…xt skill (#34438)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

This PR adopts the
[`dotnet/arcade-skills`](https://github.com/dotnet/arcade-skills) plugin
system for CI investigation in dotnet/maui, replacing the need for
custom in-repo PowerShell scripts.

Two files are added:
1. **`.github/copilot/settings.json`** — repo-level plugin declaration
that auto-installs the `dotnet-dnceng` plugin for all users
2. **`.github/skills/azdo-build-investigator/SKILL.md`** — thin
MAUI-specific context supplement (~60 lines, no scripts)

---

## Background & Motivation

### The Problem

When investigating CI failures on dotnet/maui PRs, contributors and AI
agents need to:
- Query Azure DevOps builds across 3 pipelines (`maui-pr`,
`maui-pr-devicetests`, `maui-pr-uitests`)
- Dig into Helix test logs for device test failures
- Analyze MSBuild binlogs for obscure build failures
- Detect hidden test failures caused by XHarness exiting with code 0
even when tests fail

PR #34335 (`feature/azdo-ci-instructions`) addressed this with ~700
lines of custom PowerShell scripts. During review of that PR, we
discovered
[`dotnet/arcade-skills`](https://github.com/dotnet/arcade-skills) — a
.NET engineering-maintained plugin that provides native MCP tooling for
exactly this problem space, and already lists `dotnet/maui` as a
supported repository.

### Why arcade-skills Instead of Custom Scripts

The `dotnet-dnceng` plugin in arcade-skills provides:

| MCP Server | Tool | Replaces |
|------------|------|---------|
| `ado-dnceng-public` | Native ADO queries via `@azure-devops/mcp` |
`Get-BuildInfo.ps1`, `Get-BuildErrors.ps1`, `Get-PrBuildIds.ps1` |
| `hlx` | Helix test infrastructure via `lewing.helix.mcp` |
`Get-HelixLogs.ps1` |
| `mcp-binlog-tool` | MSBuild binlog analysis via `baronfel.binlog.mcp`
| `Get-BuildBinlogs.ps1` + manual `binlogtool` |

MCP tools are first-class AI primitives — the AI calls them directly
with structured parameters rather than running shell scripts and parsing
text output. This is more reliable and maintainable.

### Auto-Loading (No User Action Required)

The key mechanism that makes this work seamlessly:

**`.github/copilot/settings.json`** supports `enabledPlugins`
(introduced in Copilot CLI v0.0.422) — a "declarative plugin
auto-install" that runs at session startup when a user opens this
repository. Every user who opens dotnet/maui gets the `dotnet-dnceng`
plugin with all its MCP servers automatically. No `/plugin install`
command needed.

```json
{
  "extraKnownMarketplaces": [
    { "url": "https://github.com/dotnet/arcade-skills" }
  ],
  "enabledPlugins": ["dotnet-dnceng@dotnet-arcade-skills"]
}
```

---

## What the MAUI Context Skill Adds

The arcade-skills `ci-analysis` skill is excellent but contains outdated
MAUI-specific information (it lists `maui-public` as the pipeline name,
which is wrong). The thin `azdo-build-investigator/SKILL.md` provides
corrections and MAUI-specific domain knowledge:

### Correct Pipeline Names/IDs

| Pipeline | Definition ID | Purpose |
|----------|--------------|---------|
| `maui-pr` | **302** | Main build — check first |
| `maui-pr-devicetests` | **314** | Helix device tests |
| `maui-pr-uitests` | **313** | Appium UI tests |

### XHarness Exit-0 Blind Spot

XHarness (used in `maui-pr-devicetests`) **exits with code 0 even when
tests fail**. The ADO job shows ✅ "Succeeded" while actual test failures
hide inside Helix work items. The SKILL.md documents how to detect this
via the Helix `ResultSummaryByBuild` API.

This quirk was discovered while investigating PRs with the
`s/agent-gate-failed` label where CI appeared green but tests were
actually failing.

### Container Artifact Quirk for Binlogs

MAUI build artifacts are **Container type** (not `PipelineArtifact`), so
standard `az pipelines runs artifact download` does not work for
binlogs. The SKILL.md documents the correct download approach using the
ADO File Container API with Bearer auth.

---

## Relationship to PR #34335

PR #34335 (`feature/azdo-ci-instructions`) adds the same investigation
capability via 5 custom PowerShell scripts. This PR supersedes that
approach. The knowledge gained building those scripts (XHarness exit-0
discovery, Container artifact API approach, pipeline IDs) is preserved
in the SKILL.md here.

We recommend closing #34335 in favor of this approach, which:
- Has ~5% of the code to maintain
- Uses MCP tooling that will improve over time as arcade-skills evolves
- Auto-loads for all contributors without any setup

---

## Files Changed

```
.github/copilot/settings.json                    (new) — repo-level plugin auto-install
.github/skills/azdo-build-investigator/SKILL.md  (new) — MAUI-specific CI context
```

## Testing

- Verified `.github/copilot/settings.json` schema matches Copilot CLI
v0.0.422+ `enabledPlugins` format
- Verified `dotnet-dnceng@dotnet-arcade-skills` resolves against the
marketplace at
`https://github.com/dotnet/arcade-skills/.github/plugin/marketplace.json`
- SKILL.md pipeline IDs verified against live ADO builds: maui-pr=302,
maui-pr-devicetests=314, maui-pr-uitests=313

/cc @PureWeen

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reset patterns:
- global.json
- NuGet.config
- eng/Version.Details.xml
- eng/Versions.props
- eng/common/*
…d.txt conflicts

Union-merged all PublicAPI.Unshipped.txt entries from both branches,
preserving #nullable enable header and sorting entries.

Bump MicrosoftExtensionsAI packages from 10.0.1 to 10.3.0 to match
main, required for FunctionCallContent.InformationalOnly API used
by Essentials.AI code merged from main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor Author

github-actions bot commented Mar 16, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34502

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34502"

@PureWeen
Copy link
Copy Markdown
Member

/azp run maui-pr-uitests, maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

github-actions bot and others added 3 commits March 16, 2026 20:50
Add MicrosoftAgentsAIWorkflowsVersion, MicrosoftAgentsAIWorkflowsGeneratorsVersion,
and MicrosoftAgentsAIHostingVersion to match main. Update MicrosoftAgentsAIVersion
from 1.0.0-preview.251204.1 to 1.0.0-rc2.

Fixes NU1015 build errors in Essentials.AI.Sample.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OnlyAndroid was removed from BaseTemplateTests on net11.0 by PR #33576
because the MAUI template now uses MSBuild conditions to restrict
TargetFrameworks to Android-only on Linux. The calls in AOTTemplateTest
(added on main by PR #33756) are no longer needed and cause CS0103
build errors when merging main into net11.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…34460)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## 🏗️ Overview

This PR replaces the **monolithic PR agent** with a modular, skill-based
**PR review orchestrator**. The legacy 2-file agent is decomposed into 4
dedicated phase skills, each with clear boundaries, inputs, and outputs.

> **TL;DR** — One big agent file → four focused skills. Cleaner,
composable, easier to maintain.

---

## 🔀 Before → After

```
┌─────────────────────────────────┐       ┌─────────────────────────────────────────────┐
│          BEFORE (Agent)         │       │              AFTER (Skills)                  │
├─────────────────────────────────┤       ├─────────────────────────────────────────────┤
│                                 │       │                                             │
│  agents/pr.md (310 lines)      │       │  skills/pr-review/SKILL.md  (orchestrator)  │
│         +                      │  ──►  │     ├─ skills/pr-preflight/SKILL.md         │
│  agents/pr/post-gate.md (331)  │       │     ├─ skills/pr-gate/SKILL.md              │
│  agents/pr/SHARED-RULES.md     │       │     ├─ try-fix  (existing skill)            │
│  agents/pr/PLAN-TEMPLATE.md    │       │     └─ skills/pr-report/SKILL.md            │
│                                 │       │                                             │
│  5 comment scripts              │       │  2-section unified comment                  │
│                                 │       │                                             │
└─────────────────────────────────┘       └─────────────────────────────────────────────┘
```

---

## ✨ Key Changes

### 1️⃣ Agent → Skill Architecture

| Phase | Skill | Responsibility |
|:-----:|:------|:---------------|
| **0** | `pr-review` | 🎯 Master orchestrator — sets up branch, invokes
phases |
| **1** | `pr-preflight` | 📋 Context gathering — reads issue, PR,
comments, classifies files |
| **2** | `pr-gate` | 🚦 Test verification — tests must FAIL without fix,
PASS with fix |
| **3** | `try-fix` _(existing)_ | 🔧 Multi-model fix exploration (Sonnet
→ Opus) |
| **4** | `pr-report` | 📊 Final recommendation — APPROVE or REQUEST
CHANGES |

### 2️⃣ Decoupled Comment Posting

`pr-review` produces **output files only**
(`CustomAgentLogsTmp/PRState/`). Comments are posted separately via
`ai-summary-comment` — no tight coupling.

### 3️⃣ Unified Comment Model

Consolidated from **5 separate comment scripts** → **2 sections** in a
single unified comment:

| ❌ Removed Script | ✅ Now Part Of |
|:-----------------|:--------------|
| `post-try-fix-comment.ps1` | PR-REVIEW section |
| `post-verify-tests-comment.ps1` | PR-REVIEW section |
| `post-write-tests-comment.ps1` | PR-REVIEW section |

`post-pr-finalize-comment.ps1` now injects into the unified comment by
default (use `-Standalone` for legacy behavior).

### 4️⃣ Simplified CI & Orchestration

**`Review-PR.ps1`** went from complex 3-phase script → clean 4-step
orchestrator:

```
Step 1 → pr-review skill     (all 4 phases)
Step 2 → pr-finalize skill   (verify title/description)
Step 3 → ai-summary-comment  (post unified comment)
Step 4 → Update-AgentLabels  (apply labels)
```

**`ci-copilot.yml`** — removed explicit `-RunFinalize
-PostSummaryComment` flags (all phases run automatically).

---

## 📁 Files Changed

<details>
<summary><b>✅ Added (4 files)</b></summary>

| File | Purpose |
|:-----|:--------|
| `.github/skills/pr-review/SKILL.md` | Master orchestrator (Phase 0–4)
|
| `.github/skills/pr-preflight/SKILL.md` | Phase 1: Context gathering |
| `.github/skills/pr-gate/SKILL.md` | Phase 2: Test verification gate |
| `.github/skills/pr-report/SKILL.md` | Phase 4: Final recommendation |

</details>

<details>
<summary><b>❌ Deleted (7 files)</b></summary>

| File | Reason |
|:-----|:-------|
| `.github/agents/pr.md` | Replaced by `pr-review` skill |
| `.github/agents/pr/PLAN-TEMPLATE.md` | Skills use direct output files
|
| `.github/agents/pr/SHARED-RULES.md` | Rules distributed to phase
skills |
| `.github/agents/pr/post-gate.md` | Replaced by `pr-gate` + `pr-report`
|
| `post-try-fix-comment.ps1` | Merged into unified PR-REVIEW comment |
| `post-verify-tests-comment.ps1` | Merged into unified PR-REVIEW
comment |
| `post-write-tests-comment.ps1` | Not part of main review workflow |

</details>

<details>
<summary><b>🔧 Modified (14 files)</b></summary>

| File | Change |
|:-----|:-------|
| `.github/scripts/Review-PR.ps1` | Major refactor → 4-step skill
orchestration |
| `.github/skills/ai-summary-comment/SKILL.md` | Simplified to 2-section
model |
| `.github/skills/ai-summary-comment/.../post-ai-summary-comment.ps1` |
Updated for unified comment |
| `.github/skills/ai-summary-comment/.../post-pr-finalize-comment.ps1` |
Injects into unified comment |
| `.github/copilot-instructions.md` | Replaced agent entry with skill
entries |
| `.github/README-AI.md` | Updated architecture docs |
| `.github/docs/agent-labels.md` | Terminology: "Gate" → "Validate" |
| `.github/scripts/shared/Update-AgentLabels.ps1` | Updated for phase
structure |
| `.github/scripts/shared/Start-Emulator.ps1` | Minor utility updates |
| `.github/skills/pr-finalize/SKILL.md` | Minor context update |
| `.github/skills/verify-tests-fail-without-fix/SKILL.md` | Minor
context update |
| `.github/skills/ai-summary-comment/NO-EXTERNAL-REFERENCES-RULE.md` |
Updated for 2-section model |
| `.github/instructions/sandbox.instructions.md` | Updated references |
| `eng/pipelines/ci-copilot.yml` | Simplified invocation |

</details>

---

## 📊 Impact

```
 25 files changed
 843 insertions(+)
 3,271 deletions(-)
```

Net reduction of **~2,400 lines** — less code, better structure. 🎉

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
@PureWeen
Copy link
Copy Markdown
Member

PureWeen commented Mar 17, 2026

CI Failure Analysis: AOT Integration Tests

The AOT integration tests (AOT windows and AOT macOS) are failing with error XAGNALLAS7009 — this is an Android SDK bug, not a MAUI issue.

Error

error XAGNALLAS7009: System.InvalidOperationException: Internal error: 
assembly 'Microsoft.Maui.Controls.resources.dll' lacks RuntimeIdentifier metadata

Stack trace points to Xamarin.Android.Tasks.MonoAndroidHelper.GetAssemblyRid()GenerateNativeAotLibraryLoadAssemblerSources.RunTask() in Microsoft.Android.Sdk.NativeAOT.targets(214,5).

Root Cause

The crash occurs because satellite resource assemblies (e.g., ar/Microsoft.Maui.Controls.resources.dll) don't have RuntimeIdentifier metadata, and the Android SDK's NativeAOT task doesn't handle this case.

This is specific to the bleeding-edge Android SDK on net11.0:

Branch Android SDK Version AOT Android Tests
main 36.1.2 (stable) ✅ Pass
net11.0 36.1.99-ci.main.174 (CI build) ❌ XAGNALLAS7009

The same PublishNativeAOTRootAllMauiAssemblies test cases with Android RIDs (android-arm64, android-x64) pass on main with the stable SDK but fail on net11.0 with the CI SDK.

Why This Surfaces Now

On net11.0, AOTTemplateTest previously had no Android test cases — only iOS, macCatalyst, and Windows. PR #33756 on main added the Android NativeAOT test cases. This merge brings those test cases into net11.0 for the first time, where they hit the SDK bug.

Fix

This is already fixed upstream in dotnet/android (commit 9198f638) which adds a workaround to stamp RuntimeIdentifier metadata on assemblies that lack it. Our pinned SDK (36.1.99-ci.main.174) is 10 commits behind this fix.

✅ Merging #34314 will resolve this — that Maestro PR bumps the Android SDK from .174.217, which includes the fix.

StephaneDelcroix and others added 4 commits March 18, 2026 10:19
…34501)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Description

Fixes #34490

When `Source={x:Reference}` is used in a binding inside a
`DataTemplate`, the XAML source generator incorrectly resolves the
`Path` against the DataTemplate's `x:DataType` instead of the referenced
element's type. This causes a false **MAUIG2045** warning for patterns
like `Path=BindingContext.SelectItemCommand`.

### Example triggering the false positive

```xml
<DataTemplate x:DataType="models:ItemModel">
    <Button Command="{Binding Source={x:Reference PageRoot},
                             Path=BindingContext.SelectItemCommand}" />
</DataTemplate>
```

The source generator tries to find `BindingContext` on `ItemModel` (the
DataTemplate's `x:DataType`) instead of recognizing that the binding
source is the referenced element.

## Root Cause

`HasRelativeSourceBinding()` in `KnownMarkups.cs` only checked for
`RelativeSourceExtension`/`RelativeSource` when deciding whether to skip
compiled binding generation. It did not account for
`ReferenceExtension`/`Reference` (`x:Reference`), so bindings with
`Source={x:Reference}` were still compiled against the current
`x:DataType` scope.

## Fix

Extended `HasRelativeSourceBinding()` to also detect
`ReferenceExtension` and `Reference` (the two forms of `x:Reference`).
When detected, the source generator skips compiled binding and falls
back to runtime binding — the same behavior already used for
`RelativeSource` bindings.

## Tests

- **SourceGen.UnitTests**:
`BindingWithXReferenceSourceInDataTemplate_DoesNotReportPropertyNotFound`
— verifies no MAUIG2045 diagnostic is emitted
- **Xaml.UnitTests**: `Maui34490` — XAML page reproducing the exact
issue scenario, tested across all inflators (Runtime, XamlC, SourceGen)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Description

Adds a new Copilot skill (`evaluate-pr-tests`) that evaluates the
quality, coverage, and appropriateness of tests added in PRs.

## Why This Is Useful

**Problem:** When reviewing PRs, evaluating test quality is one of the
most time-consuming and inconsistent parts of the process. Common issues
slip through:

- Tests that only verify a page loads but never exercise the actual fix
- UI tests for behavior that could be caught by a unit test (which runs
in seconds vs minutes)
- Missing edge cases (null inputs, boundary values, repeated actions)
that lead to regressions later
- Convention violations (wrong base class, missing attributes, obsolete
APIs) that cause CI failures
- Flaky patterns (arbitrary delays, missing `WaitForElement`) that waste
CI time

These issues are tedious to catch manually and easy to miss — especially
across 4 platforms, 4 test types (unit, XAML, device, UI), and hundreds
of existing test patterns.

**Solution:** This skill automates the mechanical checks and guides the
agent through deeper analysis:

1. **Automated (script):** File categorization, convention compliance,
anti-pattern detection, AutomationId consistency, existing similar test
search, platform scope analysis
2. **Agent-guided (SKILL.md):** Fix coverage analysis, edge case gap
identification, test type recommendation (prefer unit > XAML > device >
UI), assertion quality review

**Real-world example:** Running against PR #34324 (Android Shell TabBar
fix), the skill:
- ✅ Correctly identified 1 fix file + 1 UI test + 1 HostApp page + 1
snapshot
- ⚠️ Flagged an inline `#if` platform directive (real convention
violation)
- ℹ️ Noted 3 HostApp AutomationIds not exercised by the test
(informational)
- ✅ Found existing Shell tests for cross-reference
- ✅ Identified this as Android-only based on fix file paths

**Quality bar:** This skill went through 3 rounds of multi-model review
(10 total reviews across Opus, GPT-5.1, Gemini, Sonnet 4.5) to catch
regex bugs, false positive/negative edge cases, and documentation
mismatches.

## Evaluation Criteria (9 checks)

| # | Criterion | What It Checks |
|---|-----------|---------------|
| 1 | **Fix Coverage** | Does the test exercise the actual code paths
changed by the fix? |
| 2 | **Edge Cases & Gaps** | Boundary conditions, null handling,
async/timing, repeated actions |
| 3 | **Test Type Appropriateness** | Could a lighter test type work?
(unit > XAML > device > UI) |
| 4 | **Convention Compliance** | Naming, attributes, base classes,
obsolete APIs |
| 5 | **Flakiness Risk** | Delays, missing WaitForElement, screenshot
hygiene |
| 6 | **Duplicate Coverage** | Does a similar test already exist? |
| 7 | **Platform Scope** | Does test coverage match platforms affected
by the fix? |
| 8 | **Assertion Quality** | Are assertions specific enough to catch
regressions? |
| 9 | **Fix-Test Alignment** | Do test and fix target the same code
paths? |

## Components

- **`SKILL.md`** — Evaluation criteria with decision trees, examples,
and structured report template
- **`Gather-TestContext.ps1`** — Automated convention checks,
anti-pattern detection, AutomationId consistency, platform scope
analysis
- **`copilot-instructions.md`** — Skill registration with trigger
phrases

## Usage

```bash
# Auto-detect PR context
pwsh .github/skills/evaluate-pr-tests/scripts/Gather-TestContext.ps1

# Or ask the agent
# "evaluate the tests in this PR"
# "are these tests good enough?"
# "review test quality for PR #XXXXX"
```

- Fixes #34139

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
@PureWeen PureWeen closed this Mar 18, 2026
@PureWeen PureWeen deleted the merge/main-to-net11.0 branch March 18, 2026 19:25
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

Successfully merging this pull request may close these issues.