Skip to content

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

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

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

Conversation

@github-actions
Copy link
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:

  • rmarinho
  • PureWeen
  • jfversluis
  • rolfbjarne
  • StephaneDelcroix

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.

StephaneDelcroix and others added 7 commits February 26, 2026 07:37
…4137)

<!-- 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 #34075

The XAML source generator was generating setter assignments (e.g.,
`__source.ReadOnlyText = __value`) for getter-only properties when using
C# expression bindings like `{ReadOnlyText}`. This caused CS0200 build
errors at compile time.

### Root Cause

`ExpressionAnalyzer.IsSimplePropertyChain()` only checks whether the
expression is syntactically a simple property chain (member access,
identifier), but does not verify whether the terminal property actually
has a public setter. So `{ReadOnlyText}` where `ReadOnlyText` is `string
ReadOnlyText => "Hello"` was incorrectly marked as settable.

### Fix

Added `IsExpressionWritable()` in `SetPropertyHelpers.cs` that walks the
property chain on the `dataType` symbol and checks whether the terminal
property has a public, non-init setter. The setter lambda is only
generated when both the syntactic check (`IsSettable`) and the semantic
check (`IsExpressionWritable`) pass.

### Changes

- `src/Controls/src/SourceGen/SetPropertyHelpers.cs` — Added
`IsExpressionWritable()` helper and gated setter generation on it
- `src/Controls/tests/Xaml.UnitTests/Issues/Maui34075.*` — Regression
test with getter-only properties bound via C# expressions

### Testing

- New `.sgen.xaml` test inflates successfully via SourceGen with
read-only property bindings
- Existing `NullConditionalSettable` test (two-way binding to writable
properties) still passes
- Existing `TwoWayDecimalBinding_UIToVM` test still passes (setter works
for writable properties)

---------

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

Adds the current Azure DevOps CI pipeline names to
`.github/copilot-instructions.md` so that Copilot agents always
reference the correct pipelines:

| Pipeline | Name |
|----------|------|
| Overall CI | `maui-pr` |
| Device Tests | `maui-pr-devicetests` |
| UI Tests | `maui-pr-uitests` |

**Why:** Copilot CLI would wrongfully come up with old pipeline names
(e.g., `MAUI-UITests-public`) that it picked up from historical PR
comments. Adding the correct names to the instruction file ensures
agents use the current pipeline names going forward.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ss handling (#34259)

<!-- 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

Three fixes for the dogfooding infrastructure that was merged in #33198
but never worked correctly:

### 1. Workflow trigger fix (`dogfood-comment.yml`)
The workflow was changed from `pull_request_target` to `check_run`
trigger in #33198, but Azure DevOps check runs **never populate the
`pull_requests[]` array**. This means
`github.event.check_run.pull_requests[0] != null` was **always false**,
and the workflow never ran.

**Fix**: Reverted to `pull_request_target` trigger with a comment
explaining why `check_run` does not work.

### 2. AzDO direct fallback (both scripts)
When the GitHub Checks API does not return build info (which can happen
for merge commits or in certain timing windows), the scripts now fall
back to querying the Azure DevOps API directly using
`refs/pull/{PR}/merge` branch name.

This approach is modeled after the working implementation in
[maui-version](https://github.com/jfversluis/maui-version).

### 3. In-progress build detection (both scripts)
When no completed build is found, the scripts now query AzDO for builds
with `status in ("inProgress", "notStarted", "postponed")`. Instead of
the generic "no build found" error, users now see:
- **Build in progress**: "A build is currently in progress. Please wait
for it to complete."
- **Stale artifacts**: When an older build has artifacts but a newer
build is running, warns users

### Additional improvements
- Build ID numeric validation to prevent URL injection
- PR number validation in bash script  
- Protection against `set -e` crashes on invalid `jq` input
- Better error messages for all failure scenarios

## Testing

Tested locally with multiple real PRs across both scripts:
- ✅ PR #34216 (completed, successful) - both scripts find build and
apply artifacts
- ✅ PR #34250 (in-progress build) - correctly finds existing artifacts
with warning
- ✅ PR #99999999 (non-existent) - proper error handling
- ✅ Invalid PR number ("abc") - input validation works
- ✅ Multi-model code review (Claude Sonnet 4.5, GPT-5.1, Gemini 3 Pro) -
all findings addressed

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

When an app enters an infinite loop (e.g., layout cycle on iOS), WDA
(WebDriverAgent) blocks forever waiting for the main thread to become
idle. This causes Appium commands to hang indefinitely, which in turn
hangs the entire test run.

This PR adds resilience to prevent test hangs and allows graceful
failure with clear error messages.

## Changes

### HelperExtensions.cs
- Add `RunWithTimeout` wrapper (45s hard limit) around all Appium
commands
- Wrap `Tap()`, `Click()`, and `Wait()` query calls with timeout
- Uses `CancellationTokenSource` for proper cleanup hygiene
- Logs warning about orphaned threads when timeout occurs
- Throws clear `TimeoutException` when app is unresponsive
- Uses `Task.Run` + `GetAwaiter().GetResult()` to properly unwrap
exceptions

### AppiumLifecycleActions.cs
- Add `ForceCloseApp` command using OS-level termination:
  - iOS: `xcrun simctl terminate`
  - Android: `adb shell am force-stop`
  - Mac: `osascript quit`
- Wrap `CloseApp` with 15s timeout, auto-falls back to `ForceCloseApp`
- Bypasses WDA when normal Appium termination hangs

### UITestBase.cs
- Catch `TimeoutException` for unresponsive apps in TearDown
- Force-terminate and reset session when app freezes
- Allows subsequent tests to continue instead of hanging forever

## Result

**Before:** Tests hang indefinitely when app freezes, blocking entire CI
run

**After:** Tests fail gracefully after 45s with clear error message:
```
TimeoutException: An Appium command did not complete within 45s. 
The application may be unresponsive (e.g., due to an infinite layout loop).
```

## Testing

Tested with Issue32586 test case that triggers infinite layout cycle on
iOS:
- Test correctly times out after 45s (previously hung forever)
- Clear error message indicates app is unresponsive
- Subsequent tests can continue (session is reset via ForceCloseApp)

## Notes

- 45s timeout balances avoiding false positives on slow CI (normal
operations: 10-30s) while still failing reasonably fast when app is
truly frozen
- Thread leak is acceptable: background Task.Run threads may remain
blocked after timeout, but ForceCloseApp kills the process which
unblocks the socket
- Debug logging helps diagnose issues in CI

---------

Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
> [!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

Adds a concise command reference for the `maui` CLI — focused on
**Android**, **Apple/iOS**, and `--version`. This is a quick-review
companion to the full specification in [PR
#33865](#33865).

### What this covers

- `maui --version`
- All `maui android` subcommands (install, jdk, sdk, emulator)
- All `maui apple` subcommands (install, check, xcode, simulator,
runtime)
- Global options (`--json`, `--verbose`, `--interactive`, `--dry-run`)

### Key design points

- **Delegate to native toolchains** — wraps `sdkmanager`, `adb`, `xcrun
simctl`, etc.
- **Reuse shared libraries** — leverages
[`dotnet/android-tools`](https://github.com/dotnet/android-tools) for
SDK/JDK discovery and installation
- **Machine-first output** — every command supports `--json`
- **Interactive detection** — follows `dotnet` CLI pattern (auto-detects
CI via env vars, checks `Console.IsOutputRedirected`)

### What this intentionally omits

- Device listing (covered by `dotnet run --list-devices`)
- Install path defaults (handled by `dotnet/android-tools`)
- Windows commands (see full spec)
- Architecture, error contracts, JSON schemas, IDE integration,
elevation model

All omitted details are in the [full specification (PR
#33865)](#33865).

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/*
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.

5 participants