Skip to content

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

Merged
PureWeen merged 21 commits into
net11.0from
merge/main-to-net11.0
Jun 2, 2026
Merged

[automated] Merge branch 'main' => 'net11.0'#35687
PureWeen merged 21 commits into
net11.0from
merge/main-to-net11.0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Jun 1, 2026

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:

  • jfversluis
  • akoeplinger
  • kubaflo
  • PureWeen
  • JanKrivanek
  • arpitjain099
  • davidortinau

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.

PureWeen and others added 21 commits May 13, 2026 13:25
### Context

Add ability for maintainers to trigger the AzDO PR review pipeline via
`/review` comment on PR

### Notes

- The workflow allways runs from main - so users cannot chage behavior
in their PRs
- Unprivileged users slash command is ignored
- The 'agentic-labeler.md‎' pipeline referenced in comments of this
pipeline is being added by #35382

### Tested execution:

- GitHub Actions run:
https://github.com/dotnet/maui/actions/runs/25163585137

- DevDiv pipeline run:
https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13980704

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The job-level if used startsWith(github.event.comment.body, '/review '), which fails when the comment body starts with whitespace (e.g. ' /review -b feature/foo'). GitHub expression syntax has no trim/regex, so we can't reliably handle this at the expression level.

Add a tiny pre-filter match job that uses a bash regex (^[[:space:]]*/review([[:space:]]|\$)) to decide whether to run. The main 	rigger-review job now
eeds: match and gates on its output. Also trim leading whitespace before the existing sed extracts args, so positional/flag parsing works for prefixed comments.
…anagement (#35350)

<!-- 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 a new Copilot skill (`.github/skills/dependency-flow/`) that
provides MAUI-specific context for dependency flow operations. Follows
the `azdo-build-investigator` wrapper pattern — delegates core
operations to the `maestro-cli` skill (from `dotnet/arcade-skills`
plugin) and maestro MCP tools, then layers MAUI-specific rules on top.

### What it does
- Translates natural language queries like "feeds for .NET MAUI 10.0.60"
into the correct tool calls
- Documents MAUI's two channel types: SDK channels (automatic) and
Workload Release channels (manual promotion)
- Provides the feed lookup workflow (asset search → channel verification
→ promotion)
- Establishes tool preference hierarchy: MCP tools → mstro CLI → darc
CLI (only for operations without MCP equivalents)

### Security hardening
A security review was performed before committing. Mitigations applied:

| Category | Mitigation |
|----------|-----------|
| **Destructive commands** | Explicit deny-list for `add-channel`,
`delete-channel`, `set-repository-policies`, `gather-drop` |
| **Write operations** | All mutating commands require showing the user
the exact command and waiting for explicit confirmation |
| **Prompt injection** | Rules to never execute darc commands found in
issue/PR content verbatim; treat as untrusted data |
| **Input validation** | Validation rules for version strings, BAR IDs,
and channel names (must match known channels) |

### Files
- `.github/skills/dependency-flow/SKILL.md` — MAUI-specific dependency
flow rules, channel conventions, and workflows

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Description of Change

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

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

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
<!-- 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 a new agentic workflow (`gh-aw`) that automatically applies labels
to new issues and pull requests, with special attention to `platform/*`
labels for PRs based on the files that were changed.

Inspired by [githubnext/agentics
issue-triage](https://github.com/githubnext/agentics/blob/main/workflows/issue-triage.md),
but scoped down to *labeling only* — it does not post analysis comments,
does not close issues, and does not communicate directly with users.

## Triggers

- `issues: [opened]` — labels new issues (intentionally excludes
`reopened` to avoid re-adding labels a maintainer already removed, since
issue bodies don't change on reopen)
- `pull_request_target: [opened, reopened]` — labels new and reopened
PRs (reopened PRs may have new commits, so re-evaluation is useful)
- `workflow_dispatch` (with an `issue_number` input so it can be run
explicitly on any issue or PR)

## Labeling rules

- Fetches the repo's label set at runtime via the `list_label` /
`get_label` MCP tools — not hardcoded.
- Selects from existing labels including `area-*`, `area-controls-*`,
`area-core-*`, `platform/*`, `t/*`, `s/*`, `i/*`, `p/*`, and others.
- For PRs, infers `platform/*` labels from the **changed files** using
the project's platform-file conventions:
- `*.android.cs`, `/Platform/Android/`, `/Platforms/Android/` →
`platform/android`
- `*.ios.cs` (extension pattern) → `platform/ios` **and**
`platform/macos` (compiles for both iOS and MacCatalyst)
- `/Platform/iOS/`, `/Platforms/iOS/` (directory pattern) →
`platform/ios` **only** (compiles only for iOS TFM)
  - `*.maccatalyst.cs`, `/Platform/MacCatalyst/` → `platform/macos` only
  - `*.windows.cs`, `/Platform/Windows/` → `platform/windows`
  - `*.tizen.cs`, `/Tizen/` → `platform/tizen`
- Conservative by default: if nothing clearly applies, the agent calls
`noop` instead. One `add_labels` call allowed per run (`max: 1`).

## Security model

- **Read-only agent** — permissions are `contents: read`, `issues:
read`, `pull-requests: read`. The agent runs inside a sandboxed
container with no write credentials.
- **Safe-output writes** — label application happens in a separate
safe-output job with write permissions, capped at 1 call.
- **`roles: all`** — allows community contributors' issues/PRs to be
labeled. Safe because the agent is read-only and the only write surface
is `add_labels`.
- **`min-integrity: none`** — allows the MCP gateway to return content
from all authors (including first-time contributors), so the agent can
read the body it needs to label.
- **Prompt-injection guardrails** — explicit instructions telling the
agent to ignore labeling instructions in issue/PR bodies, never use an
`item_number` from untrusted text, and derive labels only from technical
content and file paths.
- **Noise suppression** — `noop`, `missing-tool`, `report-incomplete`,
and `report-failure` are all configured to not create tracker issues.

## Files

- `.github/workflows/agentic-labeler.md` — the agentic workflow source
- `.github/workflows/agentic-labeler.lock.yml` — compiled GitHub Actions
YAML (generated by `gh aw compile`, v0.68.3)

## Notes for reviewers

- This is consistent with the other `gh-aw` workflows in the repo
(`ci-doctor`, `copilot-evaluate-tests`, `daily-repo-status`).
- Draft because we may want to validate behavior on a few real
issues/PRs (via `workflow_dispatch`) before enabling on every new
issue/PR.

---------

Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
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

Removes the dormant ci-doctor workflow and upgrades all remaining gh-aw
workflows from compiler v0.68.3 to v0.72.1.

## Changes

### Removed: ci-doctor
- Last ran March 26, 2026 — dormant for nearly 2 months
- Had `stop-after: +1mo` which likely auto-disabled it
- Sourced from upstream `github/gh-aw` template; can be re-added if
needed

### Upgraded: all workflows to gh-aw compiler v0.72.1

All three remaining workflows (`agentic-labeler`,
`copilot-evaluate-tests`, `daily-repo-status`) recompiled with the
latest stable compiler. Bug fixes picked up:

- `&&` expression corruption in AWF config JSON
- safe-outputs permission regression (token downgraded to `issues:read`
when `update-project` + `add-comment`/`add-labels` combined)
- Conclusion comment accuracy (was reporting ✅ even when safe_outputs
failed)
- `COPILOT_API_KEY` over-billing (10-100x premium request over-charge)
- Firewall binary v0.25.29 (healthcheck fix)

### Auto-fixes applied
- `checkout: false` added to `agentic-labeler` (saves ~10-30s runner
time — workflow only uses MCP/API tools, no source code needed)
- First-party `agentic-workflows.agent.md` auto-installed by v0.72.1
compiler (gh-aw coding-agent skill for creating/debugging workflows)

## Files

| File | Change |
|------|--------|
| `.github/workflows/ci-doctor.md` | **Deleted** |
| `.github/workflows/ci-doctor.lock.yml` | **Deleted** |
| `.github/workflows/agentic-labeler.md` | Added `checkout: false` |
| `.github/workflows/agentic-labeler.lock.yml` | Recompiled (v0.72.1) |
| `.github/workflows/copilot-evaluate-tests.lock.yml` | Recompiled
(v0.72.1) |
| `.github/workflows/daily-repo-status.lock.yml` | Recompiled (v0.72.1)
|
| `.github/aw/actions-lock.json` | Updated action pins |
| `.github/agents/agentic-workflows.agent.md` | **New** — first-party
gh-aw agent |

## Notes
- No source `.md` changes to `copilot-evaluate-tests` or
`daily-repo-status` — only lock file regeneration
- The `copilot-evaluate-tests` compile emits a pre-existing warning
about `bots:` + `slash_command:` interaction — not introduced by this PR

---------

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!

Updates the Phase 2 multi-model exploration list in the `pr-review`
skill:

| Order | Before | After |
|-------|--------|-------|
| 1 | claude-opus-4.6 | claude-opus-4.6 (unchanged) |
| 2 | **claude-sonnet-4.6** | **claude-opus-4.7** |
| 3 | gpt-5.3-codex | gpt-5.3-codex (unchanged) |
| 4 | **gemini-3-pro-preview** | **gpt-5.5** |

Updated in both the model config table and the Phase 2 launch checklist
in `.github/skills/pr-review/SKILL.md`.

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 15 eval scenarios to the `agentic-labeler` skill, fixes a rule gap,
and adds explicit noop rules.

## Eval scenarios (15 total)

| Category | Count | Scenarios |
|----------|-------|-----------|
| Platform detection | 5 | `.android.cs`, `.ios.cs` dual-label,
`.windows.cs`, iOS dir-only vs extension, MacCatalyst-only (no ios) |
| Area detection | 4 | Shell, CollectionView, tooling (CI), XAML source
generator |
| Multi-platform | 1 | PR touching Android + iOS + Windows files |
| No platform / noop | 3 | Cross-platform issue, automated merge PR,
dependency bump with existing labels |
| Safety | 2 | Prompt injection resistance, PR status label caveat |

## Rule fixes

- **`Handlers/*/Android/` gap** — Files like
`Handlers/Items/Android/ItemContentView.cs` were not matched by the
platform table. Added this path pattern to the Android row.
- **Noop rules** — Added explicit "When to noop" section: automated
merge PRs, dependency bumps with existing labels, vague/ambiguous items.

## Eval methodology notes

The skill-validator pairwise comparison shows negative effective scores
on some scenarios — this is because the skill-aided agent uses more
tokens/time reading SKILL.md, not because labels are wrong.
Per-dimension analysis:
- **Task completion**: 0% regression across all scenarios (both agents
complete successfully)
- **Quality**: 0% to +100% improvement (skill helps on edge cases like
noop, Shell area)
- **Tokens**: -17% to -100% (reading SKILL.md costs tokens)
- **Time**: -11% to -89% (extra tool calls)

The evals should be treated as regression tests with
`--verdict-warn-only` — they catch accuracy regressions without blocking
on the inherent overhead of loading a skill file.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per @PureWeen's review on the original PR, this workflow is no longer in
use. Replacing the permissions-block edit with a straight deletion.

No functional change beyond removing the unused trigger.

Signed-off-by: Arpit Jain <arpitjain099@gmail.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!

### Problem

The `/review` slash command in `.github/workflows/review-trigger.yml` is
silently skipped when the comment body has any **leading whitespace**
before `/review`.

Concrete example:
- Comment posted on #35432:
#35432 (comment)
- Body (raw bytes): `' /review -b feature/regression-check'` — note the
leading space (`0x20`).
- Result: workflow run
https://github.com/dotnet/maui/actions/runs/25824871590 → **skipped**.

### Root cause

The job-level guard was:

```yaml
if: >-
  github.event_name == 'workflow_dispatch' ||
  (github.event.issue.pull_request &&
   (github.event.comment.body == '/review' ||
    startsWith(github.event.comment.body, '/review ')))
```

`startsWith(' /review ...', '/review ')` returns `false`, so the job is
skipped. GitHub expression syntax has no `trim` or regex, so we can't
fix this purely at the expression level. The `Parse parameters` step had
the same blind spot — `sed -n 's|^/review[[:space:]]*||p'` produces
empty `ARGS` if the body doesn't start with `/review`.

### Fix

1. **New tiny `match` pre-filter job** that uses a bash regex
(`^[[:space:]]*/review([[:space:]]|$)`) to decide whether the comment is
a `/review` command. It allows arbitrary leading whitespace (spaces,
tabs, newlines) but still requires `/review` to be a standalone token
(won't match `/reviewfoo` or comments that merely mention `/review`
mid-sentence).
2. **`trigger-review` now `needs: match`** and gates on its output,
keeping the rest of the job structure intact.
3. **Trim leading whitespace before `sed`** in `Parse parameters`, so
flag/positional parsing works on prefixed comments like ` /review -b
feature/foo`.

### Verification

Local check of the regex against representative inputs:

| Body                                | Should match | Matches |
|-------------------------------------|--------------|---------|
| `/review`                           | yes          | yes     |
| `/review android`                   | yes          | yes     |
| ` /review -b feature/regression-check` (the failing case) | yes | yes
|
| `\t/review`                         | yes          | yes     |
| `   /review -p ios`                 | yes          | yes     |
| `/reviewfoo`                        | no           | no      |
| `please /review this`               | no           | no      |
| `not a command`                     | no           | no      |

The full end-to-end behavior will be exercised by the next `/review`
invocation on a PR that targets this branch.
<!-- 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

One-line fix: `max: 1` → `max: 10` in the agentic-labeler safe-output
config.

`max: 1` limited the number of labels per call to 1, silently dropping
`platform/*` labels whenever the agent also selected an `area-*` label
(which was every time).

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

Follow-up to #35540. That PR fixed the `add-labels` truncation bug by
changing the source `.md` from `max: 1` to `max: 10`, but did **not**
regenerate the compiled `.lock.yml`. The deployed workflow on `main`
therefore still embeds the old config and continues to silently drop all
but one label per labeler run.

Running `gh aw compile .github/workflows/agentic-labeler.md` locally
produces this 17-line diff in the lock file. The substantive changes
are:

- `frontmatter_hash` updated to match the new `.md` source (so the lock
file no longer fails the `ERR_CONFIG: Lock file outdated` check on every
dispatch)
- safe-outputs `config.json` now emits `{"add_labels":{"max":10}}` (was
`{"add_labels":{"max":1}}`)
- the agent system prompt now declares `add_labels(max:10)`, so the
orchestrator knows it can return multiple labels in one call
- heredoc delimiters rotate as expected on every recompile

No behaviour changes beyond what #35540 already intended. This is purely
the missing `gh aw compile` output.

## Verification

1. Before this PR: every `gh workflow run agentic-labeler.lock.yml`
dispatch fails with `ERR_CONFIG: Lock file ... is outdated! The workflow
file ... frontmatter has changed.` (confirmed across 26 attempted
backfill dispatches on the affected items in #35540 audit).
2. With this PR locally, `git diff` shows only the lock file changed; no
`.md` modifications.
3. After merge, dispatching the workflow once via `gh workflow run
agentic-labeler.lock.yml --repo dotnet/maui --ref main -f
issue_number=<N>` against an affected item should now successfully apply
multiple `area-*` + `platform/*` labels in a single run (matching #35540
intent).

## Why this happened

PR #35540 was a documentation-style line-edit on the source `.md` and
the author appears to have skipped the mandatory `gh aw compile` step.
The repo currently has no CI check that recompiles the lock file and
rejects out-of-sync commits — adding such a guard is a separate
follow-up.

The misleading guidance in `~/.agents/skills/gh-aw-guide` (which
contributed to the original `max: 1` bug) is being reviewed in parallel
via a multi-model audit — fixes will land in a separate PR against that
skill repo.

Co-authored-by: bot <bot@test>
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

Clarifies the SR vs preview channel mapping rules in the
`dependency-flow` skill so future agent runs don't invent non-existent
channel names.

## Background

While answering a question about the `darc` command to add
`release/10.0.1xx-sr7` to the maestro feed, the agent initially looked
for a SR-specific channel. There isn't one — every `release/X.0.Yxx-srN`
MAUI branch maps to the **single** general `.NET X.0.Yxx SDK` channel.
Only `-previewN` branches get dedicated per-preview channels (e.g.,
`release/11.0.1xx-preview3` → `.NET 11.0.1xx SDK Preview 3`).

Verified via `darc get-default-channels --source-repo
https://github.com/dotnet/maui`:
- All of `release/9.0.1xx-sr1` … `release/9.0.1xx-sr12` → `.NET 9.0.1xx
SDK`
- All of `release/10.0.1xx-sr1` … `release/10.0.1xx-sr6` → `.NET
10.0.1xx SDK`
- `release/11.0.1xx-preview3` → `.NET 11.0.1xx SDK Preview 3`
- `release/11.0.1xx-preview4` → `.NET 11.0.1xx SDK Preview 4`

## Changes

Updates `.github/skills/dependency-flow/SKILL.md`:

1. **Branch → channel mapping rules** — explicit rules for SR, preview,
and main/dev branches, with a "do not invent" guard against fabricating
SR-specific channels.
2. **Verification step** — tells the agent to always run `darc
get-default-channels --source-repo …` and copy a sibling branch's
channel exactly before constructing a command.
3. **Worked example** — adds the canonical `darc add-default-channel`
invocation for a new SR branch.

---------

Co-authored-by: bot <bot@test>
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!

## What
Restrict the agentic-labeler to apply **exactly one `area-*` label** per
item, while still allowing multiple `platform/*` labels.

## Why
Backfilling the 26 items affected by the `max:1` bug (fixed in #35540)
revealed that the labeler occasionally applies multiple `area-*` labels
for ambiguous cases:

- **#35501** got both `area-layout` and `area-safearea`
- **#35490** got both `area-navigation` and `area-controls-tabbedpage`

The intended behavior is exactly one best-fit `area-*` per item (a
label-quota distinction not expressible via
`safe-outputs.add-labels.max:` — that field counts total labels, not
labels per prefix). The fix has to live in the agent's instructions.

## Changes

### `.github/skills/agentic-labeler/SKILL.md`
- Scope section: "Exactly one `area-*`" / "One or more `platform/*`".
- Area rules section: renamed heading, changed "pick one or more" →
"apply exactly one".
- New **tie-breaking heuristics** for the area-* selection:
- Specific control beats generic area (`area-controls-tabbedpage` over
`area-navigation`)
  - Sub-area beats parent area (`area-safearea` over `area-layout`)
  - Subject-matter focus beats incidental touch
  - When genuinely tied, prefer the user-visible feature
- Mixed-PR rule clarified: infra-primary PRs get only
`area-infrastructure` (no second product area).

### `.github/workflows/agentic-labeler.md`
- Added explicit reinforcement in the workflow prompt: "Apply exactly
one `area-*` label … and one or more `platform/*` labels".
- Fixed two stale `max: 1` comments left over from #35540 (the cap is
now `max: 10`).

### `.github/workflows/agentic-labeler.lock.yml`
- Regenerated via `gh aw compile`. Diff is frontmatter-hash + heredoc
rotations only — no semantic change to the compiled config.

## Validation
- Reviewed all 21 existing eval scenarios in `tests/eval.yaml` — none
assert multiple `area-*` labels, so no test updates needed.
- The `max: 10` cap in `safe-outputs` is preserved as a blast-radius
safeguard (one area + several platforms still fit comfortably).

## Follow-ups (not in this PR)
If accuracy of the "one area" rule drops below ~95% in eval runs,
consider adding a deterministic post-step that strips extra `area-*`
labels per a known precedence list (Option B from the design
discussion).

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

Extends the `maui-copilot` DevDiv pipeline (pipeline 27723) with a
3-stage architecture that runs real UI tests on platform-pool agents and
reports results directly in the AI summary PR comment.

### Pipeline Workflow

```
┌─────────────────────────────────────────────────────────┐
│  Stage 1: ReviewPR                                      │
│                                                         │
│  STEP 1: Branch Setup (checkout + cherry-pick PR)       │
│  STEP 2: Detect UI Test Categories                      │
│  STEP 3: Run Detected UI Tests (in-process, fast)       │
│  STEP 4: Regression Cross-Reference                     │
│  STEP 5: Gate — verify tests fail/pass before/after fix │
│  STEP 6: Code Review — deep analysis via Copilot agent  │
│                                                         │
│  Outputs → CopilotLogs artifact + detectedCategories    │
└──────────────────────┬──────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────┐
│  Stage 2: RunDeepUITests (platform-pool agent)          │
│                                                         │
│  iOS: AcesShared Tahoe + iOS 26.4                       │
│  Android: ubuntu-22.04 + KVM + AVD                      │
│                                                         │
│  Runs BuildAndRunHostApp.ps1 per detected category      │
│  Outputs → drop-deep-uitests artifact (TRX + diffs)     │
└──────────────────────┬──────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────┐
│  Stage 3: PostResults                                   │
│                                                         │
│  1. Download CopilotLogs (review content files)         │
│  2. Download drop-deep-uitests (TRX results)            │
│  3. Merge deep results into uitests/content.md          │
│  4. Post full AI Summary comment on PR                  │
│  5. Apply labels (s/agent-reviewed, etc.)               │
│                                                         │
│  One comment with everything — no patching needed       │
└─────────────────────────────────────────────────────────┘
```

### What's New

**Deep UI Test Execution (Stage 2)**
- Runs detected UI test categories on proper platform-pool agents (not
in-process on Linux)
- **iOS**: AcesShared Tahoe agents with iOS 26.4 simulator, iPhone 11
Pro (matching `ios-26` baselines from PR #35061)
- **Android**: ubuntu-22.04 with KVM, AVD boot with `-partition-size
2048`, `ignoreHiddenApiPolicyError` capability
- TRX results + snapshot-diff PNGs published as `drop-deep-uitests`
artifact

**Unified Comment Posting (Stage 3)**
- Comment posting and label application deferred to Stage 3 (after deep
tests complete)
- Single AI summary comment includes ALL results: code review + deep
test results
- Nested collapsible `<details>` for failed tests with full error +
stack trace
- Dynamic section title: `🧪 UI Tests — CollectionView, TabbedPage`
- Artifact download link for snapshot-diff PNGs

**Android Emulator Improvements**
- AVD boot step with proper partition size, ADB key pre-authorization,
boot wait
- `DEVICE_UDID` pass-through prevents double emulator boot
- Disk cleanup on hosted ubuntu agents (frees ~22GB)
- KVM enablement + `appium:ignoreHiddenApiPolicyError` for API 30

**iOS Simulator Improvements**
- Tahoe pool demand ensures macOS 26.x agents
- Explicit iOS 26.4 download via latest Xcode
- Auto-creates iPhone 11 Pro for baseline resolution match

### Validation

Tested across 30+ pipeline iterations on 6 PRs:

| PR | iOS | Android |
|---|---|---|
| 35358 (ViewBaseTests) | **112/112 ALL PASS** ✅ | **118/119 PASS** ✅ |
| 35359 (TabbedPage) | 44/50 (1 real failure) | 74/75 (1 real failure) |
| 35356 (CollectionView) | **415/417 PASS** ✅ | 593/619 (26 real
failures) |

---------

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!

Backport of #35460 to `main`.

/cc @PureWeen

Co-authored-by: HarishKumarSF4517 <harish.kumar@syncfusion.com>
### Description of Change


https://github.com/GitOps-microsoft/GitOps.PullRequestIssueManagement/pull/262
(internal Microsoft link) changed the `${issueAuthor}` placeholder to
include the `@` character.

Remove the one we added so we don't duplicate it.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…terns (#35684)

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

The `main` branch SDK pin in `global.json` was stale
(`10.0.100-rtm.25523.113`) and had no automation to keep it updated (no
Maestro subscription from `dotnet/dotnet` targets `main`).

This PR bumps `tools.dotnet` to stable `10.0.108` and fixes the
`bump-global-json.yml` workflow to use proper `--arg` quoting.

**Why not add `sdk.version`?** MAUI's CI uses custom `sdk.paths`
(`.dotnet`, `$host$`) with `eng/common/tools.sh` provisioning. Adding
`sdk.version` creates a hard CLI constraint that fails in post-build
steps where the `.dotnet/` path isn't resolved. Other dotnet repos
(runtime, roslyn) don't use custom paths, so their `sdk.version` works
fine. MAUI should continue relying only on `tools.dotnet`.

**Changes:**
- Bump `tools.dotnet` from `10.0.100-rtm.25523.113` to `10.0.108`
(stable)
- Fix `bump-global-json.yml` jq to use proper `--arg` quoting (was
fragile string interpolation)

**Context:**
- Production artifacts are built from `net10.0`/release branches (which
have active Maestro subscriptions)
- The merge flow from main to net10.0 resets version files, so this
change does not affect production builds
- `main` will still need periodic manual SDK bumps unless a Maestro
subscription is added

### Issues Fixed

N/A - Infrastructure/security hygiene improvement.

---------

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/*
@PureWeen
Copy link
Copy Markdown
Member

PureWeen commented Jun 1, 2026

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

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Jun 1, 2026

AI code review refresh for net11.0 target

Head reviewed: 8be438c
Inventory/requested head: 6d7a32fa8fb02f3321efc204b084b1d6c467115a (the PR API showed a newer current head when reviewed).

Verdict: Needs changes

  • Blocking CI/pipeline concern: eng/pipelines/ci-copilot.yml now passes skipAndroidCreateAvds: ${{ ne(parameters.Platform, 'android') }} for Android in both provision blocks, while the Android paths still manually run avdmanager create avd -n Emulator_30 ... --force. eng/pipelines/common/provision.yml creates the same Emulator_30 name through ProvisionAndroidSdkAvdCreateAvds, so Android review/deep-UI jobs can create the AVD twice with different tooling/config. Please either keep provisioning AVD creation skipped here or remove the manual avdmanager creation path.
  • I did not find blocking issues in the small MAUI source/test changes (WebViewFeatureTests, AppiumAndroidApp) or dependency metadata beyond the CI/pipeline concern above.
  • CI note: maui-pr build 1444293 is red with unmatched Build Analysis failures. The visible failures include AOT integration tests reporting unexpected ILC / apply-preserve-attribute.xml warning files, plus RunOniOS variants where generated projects failed to build. I’m not calling the PR ready while these required checks are red/unmatched.
  • Confidence: Medium-high. I inspected the diff/file list first, read relevant PR-head files without checkout, compared consumers/provisioning behavior, checked PR comments/description, checked CI, and did a second pass for false positives.

Non-approval review comment only; human approval is still required.

@PureWeen
Copy link
Copy Markdown
Member

PureWeen commented Jun 2, 2026

Thanks @kubaflo. Took a careful look at the duplicate-AVD point.

The observation is factually correct — skipAndroidCreateAvds: ${{ ne(parameters.Platform, 'android') }} in eng/pipelines/ci-copilot.yml causes common/provision.yml to run ProvisionAndroidSdkAvdCreateAvds (which creates Emulator_30 via dotnet android avd create … --force), and then the inline Android script later calls avdmanager create avd -n Emulator_30 … --force against the same name. Both pass --force, so the second invocation idempotently overwrites the first — no error, just ~30–60s of wasted CI time.

That said, I don't think it's blocking for this merge PR:

  • ci-copilot.yml only drives the Copilot review pipeline; it isn't one of the required checks on this PR (maui-pr, maui-pr-devicetests, maui-pr-uitests).
  • The change came in via Add deep UI test execution to Copilot PR review pipeline #35376 (commit 76337b2a "Enable Android AVD creation in provision for android Platform") and is already in main. Because this is an automated main → net11.0 merge, editing it here would diverge the branches and the next auto-merge would just bring it back.

Fix tracked on main in #35714. The cleaner option is to keep skipAndroidCreateAvds: true and let the inline avdmanager block remain the source of truth, since it's the one that defines the playstore image variant, the disk.dataPartition.size=2048m shrink, and the ADB key pre-auth — none of which ProvisionAndroidSdkAvdCreateAvds does today.

On the CI side: the AOT / RunOniOS failures in maui-pr build 1444293 are pre-existing on net11.0 (identical pattern in baseline build 1443637) and tracked by #35363. None of the 15 failing checks on this PR were introduced by the merge — see the deep CI analysis above.

@PureWeen PureWeen merged commit 08c0497 into net11.0 Jun 2, 2026
197 of 214 checks passed
@PureWeen PureWeen deleted the merge/main-to-net11.0 branch June 2, 2026 18:51
@github-actions github-actions Bot added this to the .NET 11.0-preview4 milestone Jun 2, 2026
PureWeen added a commit that referenced this pull request Jun 2, 2026
… it) (#35714)

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

Follow-up to @kubaflo's review on #35687.

## What

In `eng/pipelines/ci-copilot.yml`, when `parameters.Platform ==
'android'`, the Android AVD was being created twice:

1. **First**, via `common/provision.yml` running the
`ProvisionAndroidSdkAvdCreateAvds` MSBuild target — because
`skipAndroidCreateAvds: ${{ ne(parameters.Platform, 'android') }}`
evaluated to `false` for Android. That target invokes `dotnet android
avd create --name "Emulator_30" … --force`.
2. **Then**, the inline `Create AVD and boot Android Emulator` script
ran `avdmanager create avd -n Emulator_30 -k
"system-images;android-30;google_apis_playstore;x86_64" --device "Nexus
5X" --force`.

Both create the same AVD name with `--force`, so the second silently
overwrites the first — no error, just ~30–60s wasted on every Copilot
review pipeline run for Android.

The inline script is the canonical source of truth: it pins the
`google_apis_playstore` image variant, the `Nexus 5X` device profile,
the `disk.dataPartition.size=2048m` shrink, and ADB key pre-auth. None
of those are applied by `ProvisionAndroidSdkAvdCreateAvds`. So the right
fix is to skip the provision step entirely and let the inline script own
AVD creation.

## Change

Pinned `skipAndroidCreateAvds: true` (with an explanatory comment) at
both call sites of `common/provision.yml` in `ci-copilot.yml` (the
ReviewPR stage and the Deep stage). The inline `avdmanager` blocks are
untouched.

This is the AVD-creation portion of #35376 being reverted — the inline
script that same PR added already handles AVD creation, so the
provision-step AVD creation was redundant.

## Scope

This change is scoped to **`ci-copilot.yml`** only — the Copilot review
pipeline. It does **not** touch the required gating pipelines:
- `maui-pr`
- `maui-pr-devicetests`
- `maui-pr-uitests`

## Follow-up

Needs to be ported to `net11.0` afterward via the automated
`merge/main-to-net11.0` flow.

Co-authored-by: bot <bot@test>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

7 participants