Skip to content

[Android] Fix Shell SearchHandler toolbar icon tint - #36016

Merged
kubaflo merged 13 commits into
dotnet:inflight/currentfrom
erikzhang:fix/searchhandler-toolbar-icon-tint
Jun 20, 2026
Merged

[Android] Fix Shell SearchHandler toolbar icon tint#36016
kubaflo merged 13 commits into
dotnet:inflight/currentfrom
erikzhang:fix/searchhandler-toolbar-icon-tint

Conversation

@erikzhang

Copy link
Copy Markdown
Contributor

Description of Change

Fixes Android Shell SearchHandler toolbar icon tinting when SearchBoxVisibility is Collapsible.

After the Android Shell flyout icon tint changes, ShellToolbarTracker.TintColor can remain unset. The collapsible SearchHandler menu icon and the search action view navigation button still used TintColor.ToPlatform(Colors.White), which caused them to fall back to white even when Shell.ForegroundColor was set.

This change keeps the flyout icon behavior intact and resolves the SearchHandler-specific path by deriving SearchHandler toolbar icon tint from:

  1. explicit ShellToolbarTracker.TintColor
  2. current page Shell.ForegroundColor
  3. Shell Shell.ForegroundColor
  4. existing white fallback

It also refreshes the SearchHandler menu item tint when Shell.ForegroundColor changes.

Issues Fixed

Fixes #36015

PureWeen and others added 13 commits June 15, 2026 12:15
…liest-release-wins milestone validation (dotnet#35858)

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

Three related, surgical changes to `.github/scripts/` around MAUI
release/milestone tooling:

1. **Extract a shared `MauiReleaseVersioning` PowerShell module** from
`Fix-MilestoneDrift.ps1` so other release tooling can reuse the same
version/milestone helpers.
2. **Add a `-CloseFixedIssues` flag** to `Fix-MilestoneDrift.ps1` (and
wire it into the workflow) so issues fixed by PRs merged to non-default
branches like `net11.0` actually get closed.
3. **Add "earliest release wins" milestone validation** so the auditor
never overwrites an issue's existing earlier-release milestone (e.g.
`.NET 10 SR6`) just because a later follow-up PR on `net11.0` also fixes
it.

No behavior change unless you opt into the new flag, and the new
validation only ever turns a would-be mutation into a no-op — it can
never create writes that didn't exist before.

## Motivation (net11.0 close-issue gap)

GitHub only auto-closes "fixes #NNN" linked issues for PRs merged to the
**default branch** (`main` for `dotnet/maui`). When work targets
`net11.0` (the .NET 11 development branch), the PR merges fine and the
milestone gets set, but the linked issue stays open — so the team has to
manually close issues for every fix shipped on `net11.0`.

This PR adds a deliberate, opt-in closing action. The auto-trigger turns
it on automatically only when the PR's base ref matches `net*.0`, and
leaves `main`, `release/*`, and `inflight/*` alone (those either already
auto-close or need human judgment).

## Motivation (earliest-release-wins)

When a bug was first fixed in (say) `.NET 10 SR6` and a follow-up
clean-up landed on `net11.0`, the linked issue is correctly milestoned
to `.NET 10 SR6` to record where the fix first shipped. Running the
auditor against an `11.0` tag was then re-milestoning that issue to
`.NET 11.0-previewN`, erasing the "first shipped in" signal.

The fix: before overwriting an **issue's** existing real-release
milestone, verify a fix-linking PR in the current milestone actually
exists. If yes, leave it alone (KEEP). If the current milestone is
`null`/`Backlog`/`Planning` or a *later* release than the target,
behavior is unchanged.

## Commit 1 — Extract shared `MauiReleaseVersioning` module

- **New:** `.github/scripts/shared/MauiReleaseVersioning.psm1` exporting
helpers used across release tooling (`Get-CurrentMajorVersion`,
`Get-MainBranchForVersion`, `Get-VersionFromGitRef`,
`ConvertTo-Milestone`, `ConvertBranchToMilestone`, `Get-TagSortKey`,
`Find-PreviousTag`).
- **Modified:** `.github/scripts/Fix-MilestoneDrift.ps1` — removes the
in-script copies of those helpers and `Import-Module`s the new psm1
instead.
- Module uses `Set-StrictMode -Version Latest` internally (import
doesn't leak strict mode out, unlike dot-sourcing) and has an explicit
`Export-ModuleMember` block.
- 4 helpers use `[AllowEmptyString()][AllowNull()]` on string params for
back-compat with existing positional-parameter tests.
- No release-readiness files are included.

## Commit 2 — `-CloseFixedIssues` flag

**Script (`Fix-MilestoneDrift.ps1`)**
- New `[switch]$CloseFixedIssues` parameter (default off; behavior
unchanged when not passed).
- New `Close-LinkedIssue` function:
- Checks current issue state via `gh issue view --json
state,number,title`.
  - **Already closed** → no-op, log message.
- **Open + `-Apply`** → `gh issue close N --reason completed --comment
"Closed by #PR (merged to <baseRef>). GitHub only auto-closes for PRs
merged to the default branch; this issue was fixed by a PR merged to a
non-default branch."`.
  - **Open + no `-Apply`** → dry-run path (log only, no `gh` call).
- `gh` failures → warn and continue, do not throw (one bad issue mustn't
fail the whole script).
- New `Invoke-GhCli` thin wrapper around `gh` so Pester can mock CLI
calls without spawning real processes.
- Reuses the existing `Get-LinkedIssues` regex (no duplicated
`fix(es|ed)?|close[sd]?|resolve[sd]?` parsing).
- Wired into **both** the single-PR path (`Invoke-AnalyzeSinglePr`) and
the tag-based audit path (`Invoke-AnalyzeRelease`), gated on
`-CloseFixedIssues`.

**Workflow (`fix-milestone-drift.yml`)**
- New `close_fixed_issues` `workflow_dispatch` input (boolean, default
`false`).
- On the `pull_request_target` auto-trigger, `-CloseFixedIssues` is
appended automatically when `github.event.pull_request.base.ref` matches
`net*.0`:
  ```bash
  if [[ "$PR_BASE_REF" == net*.0 ]]; then
    ARGS+=('-CloseFixedIssues')
  fi
  ```
- Deliberately **not** auto-enabled for `main`, `release/*`, or
`inflight/*`.
- Manual-trigger path passes `-CloseFixedIssues` when
`inputs.close_fixed_issues == 'true'`.

## Commit 3 — Earliest-release-wins milestone validation

**Shared module additions**
- `Get-MilestoneSortKey` — converts a milestone name to a sortable
integer (`major * 1000 + phase`), where phase: `preview = 100+N`, `rc =
200+N`, GA = `300`, SR = `400 + (sr * 10) + sub`. Returns `$null` for
non-release buckets like Backlog/Planning/Future.
- `Compare-MauiMilestone` — returns `-1 / 0 / 1` (earlier / equal /
later) using the sort key.

**Script (`Fix-MilestoneDrift.ps1`)**
- `Test-MilestoneValidForIssue` — for an issue already on a real earlier
release, searches `gh search prs "#$n in:body"` for a PR with a fix verb
(`fixes/closes/resolves #N`) that itself sits on the current milestone.
Hit → milestone is "valid earlier", KEEP. Miss → fall through to the
existing apply path.
- Results cached in `$script:milestoneValidationCache` keyed by
`"$IssueNumber|$Milestone"` so the same issue checked via multiple
linking PRs only hits `gh` once.
- Only applies to **issues**, never to PRs (PRs land in exactly one
branch — no ambiguity).
- Gated: current milestone must be a real release (not
null/Backlog/Planning/Future/etc.) and *earlier* than target. Otherwise
existing behavior is unchanged.
- Adds a `Kept` bucket to the report — surfaced in console output, JSON
report (`kept[]` + `summary.kept_earlier`), and the rolled-up GitHub
issue summary.
- Bonus: declared `[object[]]$keptItems = @()` then conditional assign
in `Save-ReportJson` so a report with zero KEEPs no longer collapses to
`$null` under StrictMode.

## Tests

Added Pester coverage for everything new — totals went from 91 → 152
tests across the three review rounds, all green.

- 7 tests for `Close-LinkedIssue` (already-closed both cases, dry-run,
apply with comment text check, `gh view`/`close` failures, empty
BaseRef).
- 11 tests for `Get-MilestoneSortKey` (each phase, sub-revisions,
Backlog/Planning/Future return `$null`, malformed input).
- 5 tests for `Compare-MauiMilestone` (-1/0/1 across phases, `$null`
handling).
- 4 tests for `Test-MilestoneValidForIssue` (valid earlier KEEP, no
linking PR → fall through, `gh` failure → fall through, cache hit).

## How to verify

```bash
# Run all Pester tests
pwsh -NoProfile -Command "Import-Module Pester -Force; \
  Invoke-Pester .github/scripts/Fix-MilestoneDrift.Tests.ps1"

# Confirm only the expected files changed
git diff --stat origin/main..HEAD
# Expected: 4 files —
#   .github/scripts/Fix-MilestoneDrift.ps1
#   .github/scripts/Fix-MilestoneDrift.Tests.ps1
#   .github/scripts/shared/MauiReleaseVersioning.psm1  (new)
#   .github/workflows/fix-milestone-drift.yml

# Dry-run the new flag against a real net11.0 PR (replace with a real PR number)
pwsh -File .github/scripts/Fix-MilestoneDrift.ps1 \
  -PrNumber <PR#> -RepoPath . -CloseFixedIssues -Verbose
# Expected: "ℹ️  --CloseFixedIssues mode ... (dry-run — pass -Apply to actually close)"
# Plus a "[dry-run] would close issue #N" line per linked issue.
```

## Production validation

Ran the new tooling live across every shipped `net11.0` preview tag —
full PR/issue milestone audit + opt-in closes + earliest-release-wins:

| Tag | PR milestones fixed | Issues closed | Earlier-release KEEPs |
| --- | --: | --: | --: |
| `11.0.0-preview.5` | 20 | 4 | — |
| `11.0.0-preview.4` | 16 | 5 | — |
| `11.0.0-preview.3` | 50 | 12 | 2 |
| `11.0.0-preview.2` | 19 | 6 | 0 |
| `11.0.0-preview.1` | 28 | 0 | 0 |

The 2 KEEPs on preview3 (`dotnet#34490` on `.NET 10 SR6`, `dotnet#31280` on `.NET 10
SR7`) were both manually verified as correct: each issue was first fixed
by a main → SR PR and the net11.0 PR was a follow-up — exactly the case
the validation is designed to catch.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: bot <bot@test>
…net#35661)

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

Several request-interception device tests were running an
`[InlineData("https://echo.free.beeceptor.com/...")]` row on Windows and
Android Helix queues even though that external service is known to be
flaky (tracked in dotnet#33927). The sibling tests in the same files already
skip that scenario; these four were missed:

-
`BlazorWebViewTests.RequestsCanBeInterceptedAndCustomDataReturnedForDifferentHosts`
-
`BlazorWebViewTests.RequestsCanBeInterceptedAndCancelledForDifferentHosts`
-
`BlazorWebViewTests.RequestsCanBeInterceptedAndCaseInsensitiveHeadersRead`
-
`HybridWebViewTests_Interception.RequestsCanBeInterceptedAndCancelledForDifferentHosts`

Reflection on the built `Microsoft.Maui.Controls.DeviceTests.dll`
(net10.0-windows10.0.19041.0) confirmed each of these methods had a
`Microsoft.Maui.TheoryAttribute` with **no** `Skip` and the
`https://echo.free.beeceptor.com/` `InlineData` attached — they would
attempt a real outbound TLS request from the Helix worker whenever
interception did not fire.

### Fix

Split the single `[Theory]` into two: one inside the `#if !ANDROID &&
!WINDOWS` block (paired with the `app://echoservice/` row) and one
inside the `#if !IOS && !MACCATALYST` block carrying `Skip = "Flaky due
to external service dependency (echo.free.beeceptor.com). See
https://github.com/dotnet/maui/issues/33927"` (paired with the
`https://` row).

This matches the convention already used by the three other sibling
methods (`CustomDataReturned`, `HeadersAdded`,
`CaseInsensitiveHeadersRead` in `HybridWebViewTests_Interception.cs`).

Importantly, **iOS / MacCatalyst coverage is preserved** — only the
`https://` rows are skipped. The `app://echoservice/` rows are fully
self-contained (the OS cannot resolve the `app://` scheme, so the
request never touches the network — it is satisfied entirely by the
`WebResourceRequested` handler inside the test).

### Per-TFM safety check

The custom `Microsoft.Maui.TheoryAttribute` has `AllowMultiple = false`,
and the `#if` guards make the two `[Theory]` attributes mutually
exclusive across every TFM in `MauiDeviceTestsPlatforms`:

| TFM | `[Theory]` (app://) | `[Theory(Skip)]` (https://) |
|---|---|---|
| net10.0-android | excluded | included |
| net10.0-windows10.x | excluded | included |
| net10.0-ios | included | excluded |
| net10.0-maccatalyst | included | excluded |

### Issues Fixed

Related to dotnet#33927.

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

Restricts `/review rerun` eligibility so PRs are only queued for rerun
when there is new PR-author activity after the latest AI Summary or
previous rerun checkpoint:

- new non-command comments from the PR author
- new commits / head changes

Reviewer or maintainer reminder comments no longer satisfy the rerun
evidence check.

### Issues Fixed

Prevents `/review rerun` from applying `s/agent-ready-for-rerun` when
only a reviewer/maintainer comment was added after the latest AI
Summary.

---------

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

Updates the `Skill Validation Results` PR comment to match the visual
style used by AI Summary and Test Failure Review comments:

- stable marker plus `## Skill Validation Results` title
- PR author/commit context
- status badges for overall, static checks, LLM evaluation, skills, and
agents
- a single expandable session with commit metadata
- existing static-check and LLM-evaluation details preserved inside the
session

### Issues Fixed

No issue filed.

### Validation

- Extracted and syntax-checked the `actions/github-script` post-comment
JavaScript with `node --check`
- `git diff --check`

---------

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

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

Adds a deterministic, evidence-backed release-readiness skill that
produces a single "Is `release/X.Y.Zxx-srN` (or preview) ready to ship?"
report for .NET MAUI release branches — both **Servicing Releases (SR)**
and **Previews**, in both **in-flight** and **candidate** (pre-cut)
modes.

Supersedes dotnet#35754.

## What it does

`Get-ReleaseReadiness.ps1` walks the SR branch, classifies open
`regressed-in-*` issues against branch contents, computes the source-PR
list (handling cherry-pick number swaps + non-main forward-flow), and
rolls up an "is this ready to ship?" verdict with a **Blocking** summary
hoisted to the top of the report.

Posts/refreshes a single `[Release Readiness]` GitHub tracking issue per
release lane (idempotent via a semantic hash marker — only reposts when
something meaningfully changed). See **[issue dotnet#35876
(SR8)](dotnet#35876 for a live
example.

## Ship-readiness checks

A release captain sees these surface as 🟢 READY / 🟡 WATCH / 🔴 BLOCKED /
⚪ UNKNOWN rows. All BLOCKED rows roll up into the **Blocking** summary
at the top.

| Check | Catches |
|-------|---------|
| **Versions.props bump** | SR cycle hasn't been bumped on the SR branch
|
| **Versions.props servicing flip** | `PreReleaseVersionLabel=servicing`
+ `StabilizePackageVersion=true` not applied — branch silently builds
prerelease packages |
| **Bug template lists SR version** | Users can't file bugs against the
new version |
| **Main bumped to next SR cycle** | Post-SR-cut PRs on main would
falsely claim to ship in the SR being shipped |
| **BAR default-channel mapping** | SR branch not wired to `.NET <band>
SDK` in BAR — caught the real SR8 outage |
| **BAR build for SR HEAD** | No published build at the SR HEAD commit |
| **Milestone for current cycle** | Fixed issues have nowhere to land |
| **Milestone for next cycle** | Open issues can't roll forward when
current ships |
| **Stale open milestones** | Already-shipped releases accumulating
untriaged issues (scoped to same major + same cycle type, 7-day grace) |
| **CI Failure Scanner signals** | Fresh ci-scan issues filed in the
last 24h |
| **Known Build Errors** | Open KBE issues that may explain background
CI noise |

Each check that needs external tooling (darc, gh, milestone API)
degrades to **UNKNOWN** with the exact verification command embedded —
the report never silently skips.

## Expected ship date

Header line surfaces the deadline. Cadence is patch-aware:
- `PatchVersion` ends in 0 (`80`, `90`, `100`…) or `0` (previews) → 2nd
Tuesday of the month
- Anything else (`81`, `82`, `91`…) → **ASAP** hotfix, no cadence

## Custom agent

`.github/agents/release-readiness-agent.agent.md` wraps the skill —
handles regression-label confirmation, runs the script, then uses
**WorkIQ** + **maestro MCP** to:
- Patch UNKNOWN BAR rows live (e.g. when darc isn't on CI's PATH)
- Add narrative context for `rejected-from-sr` PRs (chat history, review
feedback)
- Present the final READY / Conditionally Ready / Not Ready verdict with
citations

## Testing

```bash
pwsh .github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
# 447 pass / 0 fail
```

Dogfooded live against SR7 + SR8 + the .NET 11 preview lane. Caught
real-world bugs:
- **SR8** missing from BAR default-channel mappings (verified via
`maestro_default_channels` MCP)
- `.NET 10 SR6` + `.NET 10 SR7` milestones open with 76 + 63 open
issues, past due
- `.github/ISSUE_TEMPLATE/bug-report.yml` missing `10.0.80` entry

## Methodology gotchas (documented in `references/methodology.md`)

1. **Cherry-pick number swap** — SR backports get NEW PR numbers; can't
naively grep source PR numbers
2. **Timeline cross-references** — `closedByPullRequestsReferences`
returns empty for most MAUI issues; must walk `gh api
.../issues/N/timeline` cross-referenced events
3. **Forward-flow / non-main merges** — a fix can merge into
`inflight/current` only, not `main` (real example: PR dotnet#35609)

## Files

- `.github/skills/release-readiness/SKILL.md` — skill entry point +
reference docs
- `.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1` —
main orchestrator (deterministic, no MCP)
- `.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1` —
447-assertion test suite
- `.github/skills/release-readiness/references/methodology.md` — gotchas
and patterns
- `.github/agents/release-readiness-agent.agent.md` — MCP-enriched agent
wrapping the skill

---------

Co-authored-by: bot <bot@test>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: VSC Agent <vsc-agent@example.com>
…otnet#35942)

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

Migrates the `skill-validation.yml` workflow from the legacy
`dotnet/skills` binary (`skill-validator check` + `skill-validator run`)
to
**[@microsoft/vally-cli@0.6.0](https://github.com/nicknow-ms/vally)**.
All 5 skill-eval suites are ported and validated green in CI.

## What Changed

### Workflow (`skill-validation.yml`)
- Replaced `skill-validator` install/check/run steps with `vally lint
--strict` and `vally run --eval-spec`
- Added **hermeticity negative-control gate** that verifies the sandbox
doesn't have unauthorized network access (rate-limit auth detection)
- Added `workflow_dispatch` manual trigger with `skills` and `runs`
inputs for on-demand evaluation
- Changed fixture fetch depth from `--depth=1` to `--depth=2` so `git
diff HEAD^ HEAD` works in worktree environments
- Removed all `skill-validator` references and legacy `eval.yaml` files

### Eval Specs Ported (all in `.github/skills/<skill>/tests/`)
| Skill | File | Stimuli | Status |
|-------|------|---------|--------|
| code-review | `eval.capability.vally.yaml` | 9 capability scenarios |
✅ 9/9 |
| code-review | `eval.vally.yaml` | 2 regression scenarios | ✅ 2/2 |
| code-review | `hermeticity.vally.yaml` | 1 negative control | ✅ |
| agentic-labeler | `eval.vally.yaml` | 3 labeling scenarios | ✅ |
| try-fix | `eval.vally.yaml` | 2 fix scenarios | ✅ |
| verify-tests-fail-without-fix | `eval.vally.yaml` | 2 verification
scenarios | ✅ |
| evaluate-pr-tests | `eval.vally.yaml` | 2 evaluation scenarios | ✅ |

### Key Design Decisions
- **Structural graders** (output-matches, output-not-contains) verify
hard behavioral requirements (e.g., never approve via API, verdict
markers present)
- **LLM prompt graders** (scale_1_5) assess quality and depth with
calibrated thresholds
- Regression stimuli use **frozen git worktrees** pinned to
known-regressing commits — no network calls, fully reproducible
- Capability stimuli target **real merged PRs** to test against actual
code review scenarios

## Validation

Final CI run
[#27635665319](https://github.com/dotnet/maui/actions/runs/27635665319):
**11/11 stimuli pass, 0 failures**.

Iteratively validated across 9 CI runs, fixing:
- Fixture fetch depth (parent commit needed for `git diff`)
- Structural floor regex (added 🔴 marker, broadened to accept
`Verdict`/`Finding`)
- Merged-PR prompt engineering (agents short-circuit reviews on merged
PRs)
- Environment constraints (Vally sandbox lacks GH_TOKEN — adjusted
rubrics accordingly)
- LLM judge threshold calibration (structural graders verify
correctness; LLM judges assess quality)

## Removed
- All `eval.yaml` files (legacy skill-validator format)
- `skill-validator` binary installation steps
- `--allow-repo-traversal` flag usage (Vally worktrees provide full repo
access natively)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…compile all to v0.79.8 (dotnet#35951)

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

Adds top-level `environment: gh-aw-agents` gating to the 4 gh-aw
workflows that have write capabilities or uncapped inference spend,
following the [gh-aw best
practice](https://github.github.com/gh-aw/reference/cost-management/):
*"Gate any write-capable or spendy agentic workflow behind such an
environment."*

Uses a **single shared environment** (`gh-aw-agents`) since the AzDO
federation secrets are also used by `review-trigger.yml`, so
per-workflow secret isolation isn't achievable.

Also brings **all 7** gh-aw workflow lock files to the current compiler
(v0.79.8 / AWF 0.27.2).

**Validated:** triggered `ci-status-main` on this branch — activation ✅,
agent job running ✅ (confirms `COPILOT_GITHUB_TOKEN` from environment is
accessible).

## Changes

### Commit 1: Environment gating + deprecated field migration

| Workflow | Write surface |
|----------|---------------|
| `rerun-review-scanner` | Labels, reactions, AzDO pipeline triggers,
federation secrets |
| `ci-status-main` | Creates up to 5 tracking issues/run |
| `ci-status-net11` | Creates up to 5 tracking issues/run |
| `daily-repo-status` | Creates issues + closes older ones |

All 4 now use `environment: gh-aw-agents`. Also migrates the deprecated
`max-effective-tokens: -1` → `max-ai-credits: -1` in both CI scanner
workflows.

### Commit 2: Lock freshness

Recompiles `agentic-labeler.lock.yml` and
`copilot-review-tests.lock.yml` to current gh-aw v0.79.8 / AWF 0.27.2.
No source `.md` changes — lock-only refresh.

### Commit 3: Fix copilot-evaluate-tests + recompile

Fixes `workflow_dispatch.inputs.pr_number.required: true` → `false` —
v0.79.8 correctly rejects `required: true` when `slash_command:` is also
configured (auto-dispatch can't fill required inputs). The workflow
already falls back to `github.event.issue.number` from slash command
context.

## Intentionally NOT gated

| Workflow | Reason |
|----------|--------|
| `agentic-labeler` | Uses `roles: all` for community auto-labeling;
gating would require approval per issue/PR |
| `copilot-evaluate-tests` | Comment-only (max 1), already role-gated to
`[admin, maintain, write]` |
| `copilot-review-tests` | Same as above |

## Environment setup (already done ✅)

The `gh-aw-agents` environment has been created with:
- ✅ `COPILOT_GITHUB_TOKEN` — Copilot inference auth
- ✅ `AZDO_TRIGGER_TENANT_ID` — AzDO Workload Identity Federation
- ✅ `AZDO_TRIGGER_CLIENT_ID` — AzDO Workload Identity Federation
- No required reviewers (scheduled automation would stall)
- No branch restrictions yet (can be added post-merge for `main` +
`net11.0`)

---------

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

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

## Problem

The milestone-drift automation (`Fix-MilestoneDrift.ps1`) maps a commit
found on an SR release branch to a milestone using **only the branch
name** — `release/10.0.1xx-sr7` → `.NET 10 SR7`. But a single SR release
branch ships **many servicing drops** over its lifetime (`10.0.70` =
SR7, `10.0.71` = SR7.1, `10.0.72` = SR7.2, …), so the base SR is too
coarse.

A revert/hotfix that lands **after** the base SR shipped actually goes
out in a later sub-patch. Milestoning it as the base SR is wrong — and
can even **downgrade** an already-correct SR7.1 issue back to SR7.

### Concrete case that motivated this

- PR dotnet#35694 is a backport to `release/10.0.1xx-sr7`; its commit is
contained only in tag `10.0.71` → it ships in **SR7.1**.
- It directly links the issue via `Fixes dotnet#35584`.
- Before this change the script resolved dotnet#35694 → **SR7** (branch name),
which would *downgrade* issue dotnet#35584 from SR7.1 → SR7.

## Root cause

`Find-ReleaseBranchForCommit` resolved the milestone via
`ConvertBranchToMilestone` (branch-name only), which has no notion of
sub-patches.

## Fix (general — no special-casing)

Add `Get-RefinedReleaseMilestone`: for a commit found on an **SR**
branch, resolve the milestone from the **earliest SR-family tag**
(`X.0.{sr}{sub}`) that actually contains the commit (git ancestry).
Rules:

- **Earliest release wins** — return the earliest family tag that
contains the commit.
- If no family tag contains it yet (the drop isn't tagged), use the
**next sub-patch** after the latest shipped family tag — **clamped to
the SR family** so it never crosses into the next SR (an exhausted SR7
at `.79` falls back to base SR7, never predicts SR8).
- **Non-SR** milestones (preview/rc/GA) are returned unchanged.

It's wired into both match paths of `Find-ReleaseBranchForCommit`. The
PR-number grep fallback now captures the **oldest** on-branch SHA
(`--reverse`, so a later revert that re-mentions `(#NNN)` can't hijack
the result) and is hardened against stderr noise (`2>$null` + strict
40-hex SHA filter).

Result: dotnet#35694 → **SR7.1**, so its existing `Fixes dotnet#35584` link marks
the issue **SR7.1**. The existing earliest-release-wins guard reconciles
the issue regardless of merge order.

Note: PR dotnet#35625 (the same revert on `inflight/current`) intentionally
stays **SR9** — a PR's milestone tracks the physical branch it merged
into; the *issue* converges to the earliest customer-facing release
(SR7.1).

## Verification

- ✅ Dry-run dotnet#35694 → `.NET 10 SR7.1` (was SR7); issue dotnet#35584
already-correct (no downgrade).
- ✅ Regression dry-runs unchanged: dotnet#34620 → SR6, dotnet#35016 → SR6, dotnet#30132 →
preview3.
- ✅ Pester suite: **162 passed, 0 failed** (9 new unit tests for the
helper, incl. the family-boundary clamp).

## Review

Reviewed with three independent models (GPT-5.5, Gemini 3.1 Pro, Claude
Opus 4.8). Consensus on correctness and contained blast radius
(refinement only ever moves *within* one SR family). Their concrete
findings — boundary clamp, stderr hardening, oldest-match grep, and a
dead parameter — were all addressed in this PR.

---------

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!

## Summary

Follow-up to dotnet#35951 — extends `environment: gh-aw-agents` gating to the
**remaining 4 workflows** that were not included in the initial PR:

| Workflow | Type | Change |
|----------|------|--------|
| `agentic-labeler.md` | gh-aw | Added `environment: gh-aw-agents` |
| `copilot-evaluate-tests.md` | gh-aw | Added `environment:
gh-aw-agents` |
| `copilot-review-tests.md` | gh-aw | Added `environment: gh-aw-agents`
|
| `review-trigger.yml` | Regular GHA | Added `environment: gh-aw-agents`
to `trigger-review` job |

## Why

After dotnet#35951 merged, repo-level secrets (`COPILOT_GITHUB_TOKEN`,
`AZDO_TRIGGER_TENANT_ID`, `AZDO_TRIGGER_CLIENT_ID`) were deleted in
favor of environment-scoped secrets on the `gh-aw-agents` environment.
These 4 workflows need the `environment:` reference to access those
secrets.

## Details

- All 3 gh-aw workflow locks recompiled with `gh aw v0.79.8`
- `environment: gh-aw-agents` verified on agent + safe-outputs +
threat-detection jobs in all lock files
- `review-trigger.yml` is a regular GHA workflow — environment added at
job level, no compile needed
- Pre-existing compile warnings (agentic-labeler `pull_request_target`,
copilot-evaluate-tests `slash_command` + `bots:`) are unchanged and
intentional

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… as resolved (dotnet#35895)

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

When a maintainer comments `/review`, `/review rerun`, or `/review
tests` on a PR, the command comment lingers and clutters the
conversation. This change **hides the command comment as resolved**
(collapses it) **once the command is recognized and the commenter is
authorized** (i.e. once we accept and act on it). Unauthorized or
invalid attempts are left fully visible.

### Why hide instead of delete?

The rerun scanner reconstructs review/rerun state by replaying the PR's
comment history through the **REST list endpoint**
(`Resolve-RerunEligibility.ps1`, `Query-RerunReadyPRs.ps1`,
`Get-LatestRerunCommentBefore`). **Deleting** the command comments would
erase that durable checkpoint — re-qualifying unchanged commits and
dropping `--branch`/`--platform` options on later reruns.

Minimizing (GraphQL `minimizeComment(classifier: RESOLVED)`) collapses
the comment in the web UI but **keeps it in the REST comment history**,
so the scanner keeps working. This addresses the data-loss findings from
review without losing the decluttering benefit.

### Changes

| Command | Workflow | Where it's hidden |
|---|---|---|
| `/review` | `review-trigger.yml` (`trigger-review`) | after the AzDO
pipeline is triggered (`trigger_azdo == success`) |
| `/review rerun` | `review-trigger.yml` (`mark-rerun-ready`) | after
eligibility resolution, only when `eligible == 'true'` |
| `/review tests` | `copilot-review-tests.md` (gh-aw) | pre-activation
step |

All three call `minimizeComment(input: { subjectId: <comment node_id>,
classifier: RESOLVED })`.

**`review-trigger.yml`**
- `trigger-review`: hides the `/review` comment as the last step, gated
on `steps.trigger_azdo.outcome == 'success'` so a lock-skip or failed
trigger leaves the command (and its `--branch`/`--platform` options)
visible for retry. The job already has `issues: write`.
- `mark-rerun-ready`: hides the `/review rerun` comment **after**
`Resolve-RerunEligibility.ps1` runs and only when a rerun was actually
triggered (`eligible == 'true'`). Ineligible reruns keep the comment
fully visible.

**`copilot-review-tests.md` (gh-aw)**
- Keeps `on.permissions: issues: write` so the deterministic
pre-activation job token can minimize the comment (the AI agent job
stays read-only).
- The `github-script` pre-activation step minimizes the `/review tests`
comment only when the command is exactly `/review tests` (`should_run`),
the event is `created` (not `edited`), **and** the commenter is an
authorized collaborator (`write`/`maintain`/`admin`).
- Recompiled `copilot-review-tests.lock.yml` in the same commit (gh-aw
v0.77.5). `frontmatter_hash` updated; `body_hash`, the concurrency
block, and the read-only agent-job permissions are unchanged.

### Token / permissions

No special token is required. Minimizing uses the same `issues: write`
scope deletion did, via the default `github.token`. (Minimizing is the
same moderation tier as the previous deletion — if the token could
delete the comment, it can minimize it.)

### Safety
- **No double-hide** — each command activates exactly one minimize path
(`/review tests` is gated on the exact-match that `review-trigger.yml`
explicitly skips).
- Minimizing only runs on `issue_comment` `created` events (never
`workflow_dispatch`, never `edited`).
- A failed minimize emits a `::warning::` and never fails the
review/rerun/tests trigger.
- History is preserved: the REST comment list still returns minimized
comments, so the rerun scanner and option/checkpoint recovery are
unaffected.

### Validation
- `gh aw compile` → 0 errors / 0 warnings; lock diff verified (only the
step body + `frontmatter_hash` change; concurrency intact; agent job
still `issues: read`).
- `review-trigger.yml` and the regenerated lock parse as valid YAML.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…anches from the tracker matrix (dotnet#35971)

> [!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 dotnet#35807. Two independent release-readiness fixes.

---

## Fix 1 — Surface p/0-labelled PRs as Preview release blockers

### Summary

The Preview readiness engine (`Get-PreviewReadiness.ps1`) only treated
**p/0 issues** as release blockers. **p/0-labelled PRs** targeting a
preview/candidate branch were silently bucketed into the generic
"Release branch PRs" WATCH count and rendered as "Needs review or
triage" rows — never hoisted, never blocking.

The root cause is structural: the p/0 blocker path used `gh issue list
--label p/0`, which **by design never returns PRs**. So p/0 PRs were
invisible to the blocker logic.

This was observed live on the **net11.0 preview6** tracker (dotnet#35866),
where dotnet#34758, dotnet#35626, and dotnet#34600 (all `p/0`, base `net11.0`) appeared
only as generic WATCH rows instead of blockers.

### What changed

Carves p/0-labelled PRs out of the generic human-PR bucket — the label
data is **already fetched** by `Get-OpenPullRequests`, so no extra API
call — and:

- adds a **BLOCKED `P/0 release-branch PRs`** check (parallel to the
p/0-issues check) so the overall verdict turns red when one is open;
- itemizes each p/0 PR as a **`🔥 P/0 PR`** row in the hoisted **🔴
High-priority items** section (with base ref + age + per-PR next
action);
- **excludes** the new check from the **🔴 Blocking** summary (its PRs
are already enumerated in the hoist) — exactly matching the p/0-issues
treatment;
- updates the WATCH note + hoist header/intro text from 3 → 4
high-priority categories.

A PR whose base **is** the survey ref is release-relevant by definition,
so — unlike issues — no title/milestone relevance filter is applied.

### Testability

Adds a small **StrictMode-safe `Test-IsP0Pr`** helper plus a
**dot-source guard** on the engine (mirroring
`Find-ReleaseReadinessTrackers.ps1`) so the predicate can be unit-tested
without invoking the full git/gh-backed report flow.

---

## Fix 2 — Drop stale below-watermark SR branches from the tracker
matrix

### Summary

The Lane 1 in-flight detector (`Find-ReleaseReadinessTrackers.ps1`)
treated **tag-absence** as the sole in-flight signal. Abandoned hotfix
leftovers like **SR2** (patch 21) and **SR3** (patch 33) — which never
published their stable tags and sit far below the shipped watermark
(**SR7** patch 71) — were still emitted as trackers. The workflow then
spun up a **no-op matrix job** per branch: the per-job activity gate
skipped issue creation, but the job still ran.

### What changed

Adds a secondary **`Test-IsStaleSrBranch`** disambiguator applied **only
after** `Test-IsBranchInFlight` returns true. A branch is stale when
**both**:

- its patch is **strictly below** the highest shipped patch, **and**
- it has had **no commits** within the activity window (idle).

Tag-existence stays the **primary** signal; the idle requirement
preserves the out-of-order / security-hotfix case — a real reset branch
below the watermark has recent commits and is therefore **not** dropped.
Freshly-cut live SRs sit at/above the watermark and are never affected.

Dropping these at the detector removes them from the workflow matrix
**entirely**. Verified safe: SR2/SR3 have no open tracker issues, so
nothing is stranded (only SR8/SR9/preview6 have open trackers).

---

### Tests

`Test-ReleaseReadiness.ps1`:
- **12** new unit assertions for `Test-IsP0Pr` (predicate: p/0
present/absent, missing/null/empty labels, hashtable-shaped labels, null
PR; carve-out semantics: p/0 subset selected, generic bucket excludes
them).
- **7** new unit assertions for `Test-IsStaleSrBranch` (below-watermark
idle → stale; above/equal watermark → not stale; below-watermark but
active → not stale; no shipped tags → never fires).
- Live-repo E2E expectations updated: net10 now surfaces **2** SR
trackers (SR8 + SR9) instead of 4.

```
Passed: 517   Failed: 0
```

---------

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!

## Summary

Removes `environment: gh-aw-agents` from the `trigger-review` job in
`review-trigger.yml`.

## Why

PR dotnet#35974 added `environment: gh-aw-agents` to `review-trigger.yml`,
which changed the GitHub OIDC token subject from
`repo:dotnet/maui:ref:refs/heads/main` to
`repo:dotnet/maui:environment:gh-aw-agents`. The managed identity
(`Testing-MI-gh2zdo`) behind `AZDO_TRIGGER_CLIENT_ID` has no federated
credential for that environment subject, so every `/review` command
fails with:

```
AADSTS700213: No matching federated identity record found for presented
assertion subject 'repo:dotnet/maui:environment:gh-aw-agents'
```

The `AZDO_TRIGGER_*` secrets have been re-added at the repo level. Once
the federated credential is updated (requires Azure access to the
managed identity), the environment gating can be re-added.

## What changed

- Removed `environment: gh-aw-agents` from the `trigger-review` job (1
line)
- All gh-aw workflows remain gated — only `review-trigger.yml` (regular
GHA) is affected

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

Copy link
Copy Markdown
Contributor

🚀 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 -- 36016

Or

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

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jun 19, 2026
@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jun 19, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 1 findings

See inline comments for details.

else if (e.Is(Shell.ForegroundColorProperty))
{
UpdateLeftBarButtonItem();
UpdateToolbarItemsTintColors();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[moderate] Logic and Correctness — This foreground-color refresh only retints the collapsible SearchHandler menu item. If Shell.ForegroundColor changes while the SearchHandler action view is already expanded, the visible AppCompatImageButton retinted in OnSearchViewAttachedToWindow keeps its old color because that attach hook will not run again. Please also retint the expanded action-view navigation button, or centralize the retint logic so both the placeholder item and expanded button are updated.

@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jun 19, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@erikzhang — new AI review results are available based on this last commit: 17eee4a. To request a fresh review after new comments or commits, comment /review rerun.

Gate Skipped Code Review In Review Confidence Low Platform Android

Review Sessions — click to expand
Gate — Test Before & After Fix

Gate Result: ⚠️ SKIPPED

No tests were detected in this PR.

Recommendation: Add tests to verify the fix using the write-tests-agent.


UI Tests — Shell

Detected UI test categories: Shell

Deep UI tests — 307 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
Shell 307/307 ✓
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)

Pre-Flight — Context & Validation

Issue: #36015 - [regression/10.0.60] Android Shell SearchHandler toolbar icons ignore Shell.ForegroundColor
PR: #36016 - [Android] Fix Shell SearchHandler toolbar icon tint
Platforms Affected: Android
Files Changed: 1 implementation, 0 test

Key Findings

  • Android Shell collapsible SearchHandler toolbar icons used TintColor.ToPlatform(Colors.White), so unset TintColor fell back to white instead of effective Shell.ForegroundColor.
  • PR changes only src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs and adds no tests; gate was already skipped because no tests were detected.
  • GitHub CLI is unauthenticated in this environment, so pre-flight used public GitHub API data and local git diff; required CI status is undetermined.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: low
Errors: 0 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • ⚠️ Missing regression test for Android Shell SearchHandler foreground-color tinting and dynamic foreground-color updates.
  • 💡 Nearby regular ToolbarItem icon tinting remains TintColor-only and appears intentionally outside this SearchHandler-specific fix.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #36016 Add SearchHandler-specific effective tint helper in ShellToolbarTracker, use it at SearchHandler icon call sites, and refresh placeholder icon on foreground changes. ⚠️ SKIPPED (Gate: no tests detected) ShellToolbarTracker.cs Original PR

Code Review — Deep Analysis

Code Review — PR #36016

Independent Assessment

What this changes: Android Shell SearchHandler icon tinting now resolves from explicit ShellToolbarTracker.TintColor, then page Shell.ForegroundColor, then Shell Shell.ForegroundColor, then the existing white fallback. It also refreshes the collapsible menu item tint when foreground color changes.
Inferred motivation: TintColor can remain unset after recent Android Shell flyout icon tint changes, causing SearchHandler-specific toolbar icons to remain white even when Shell foreground color is non-white.

Reconciliation with PR Narrative

Author claims: Fixes Android Shell SearchHandler toolbar icon tinting when SearchBoxVisibility is Collapsible by deriving tint from effective foreground colors and refreshing on foreground changes.
Agreement/disagreement: The code matches the claim. The changed call sites are the collapsed search menu icon and the expanded action-view navigation button path.

Prior Review Reconciliation

No prior ❌ Error findings found in available public issue/review comments. gh is unauthenticated, so public API/local data were used.

Blast Radius Assessment

  • Runs for all instances: No; behavior change is limited to Android Compatibility Shell toolbar SearchHandler icon paths, primarily collapsible SearchHandler.
  • Startup impact: No direct startup impact; runs during toolbar/search-handler updates and SearchView attach.
  • Static/shared state: No new static/shared state.

CI Status

  • Required-check result: undetermined
  • Classification: undetermined; local gh pr checks unavailable because GitHub CLI is unauthenticated.
  • Action taken: Confidence capped low for CI coverage gap. Gate was already skipped by caller because no tests were detected.

Findings

⚠️ Warning — Missing regression test

The PR modifies Android platform Shell toolbar behavior but adds no regression test for the SearchHandler icon color or dynamic foreground color update. Gate was skipped because no tests were detected.

💡 Suggestion — ToolbarItem icon tint remains separate

UpdateMenuItemIcon still uses TintColor.ToPlatform(Colors.White) for regular ToolbarItem icons. That appears outside the SearchHandler-specific scope, but it is a nearby color-resolution path worth documenting as intentionally unchanged.

Failure-Mode Probing

  • What happens when no foreground color is set? The helper returns null and ToPlatform(Colors.White) preserves the previous white fallback.
  • What happens when page and Shell foreground colors differ? Page-level foreground wins, consistent with nearby UpdateLeftBarButtonItem tint resolution.
  • What happens when foreground color changes after render? The PR updates the current placeholder SearchHandler item through UpdateToolbarItemsTintColors() on Shell/page foreground changes.

Verdict: NEEDS_DISCUSSION

Confidence: low
Summary: The implementation is narrowly scoped and logically matches the bug, but CI status is unavailable in this environment and the PR has no detected tests. The main review concern is regression coverage, not the production code approach.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Restore ShellToolbarAppearanceTracker propagation of ShellToolbarTracker.TintColor so existing SearchHandler TintColor.ToPlatform(Colors.White) call sites use foreground color. ⚠️ BLOCKED 1 file Android script timed out; self-review found major regression risk because this broadens behavior and may reintroduce flyout icon tinting from #27502.
2 try-fix Use existing Toolbar.IconColor as SearchHandler tint source and refresh on Toolbar.IconColor changes. ⚠️ BLOCKED 1 file Initial compile error fixed by casting _toolbar as Toolbar; build/deploy then succeeded but UI test command timed out. Self-review found fallback-color semantics risk.
3 try-fix Rebuild SearchHandler toolbar item/action view on Shell/page foreground-color changes instead of retinting existing icon. ⚠️ BLOCKED 1 file Build/deploy succeeded but UI test command timed out. Self-review found this is broader than necessary and may disturb active SearchHandler state.
PR PR #36016 SearchHandler-specific effective tint helper (TintColor → page foreground → Shell foreground → white fallback) plus in-place retint on foreground changes. ⚠️ SKIPPED (Gate) 1 file Original PR; no tests detected by gate. Expert review found the logic narrow and safer than alternatives, but requested regression coverage.

Cross-Pollination

Model Round New Ideas? Details
expert-reviewer 1 Yes Candidate 1 explored upstream tint propagation. Failed self-review because it broadens behavior to flyout/custom toolbar icon tinting.
expert-reviewer 2 Yes Candidate 2 explored using Toolbar.IconColor as the existing abstraction. Compiled after fix but has fallback semantics risk.
expert-reviewer 3 Yes Candidate 3 explored lifecycle rebuild on foreground changes. Compiles but is broader than the PR's in-place retint and may disturb active search state.
expert-reviewer 4 No Remaining variations either reproduce the PR's direct SearchHandler-specific helper/retint strategy or are trivial rearrangements of failed approaches.

Exhausted: Yes
Selected Fix: PR #36016 — It is the narrowest candidate: it scopes the color resolution to SearchHandler, preserves the historical white fallback when no foreground color is set, avoids restoring global TintColor behavior, and retints the existing menu item instead of rebuilding SearchHandler UI. It still needs regression tests.


Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the current description accurately explains the raw PR, but the winning fix includes the reviewer enhancement to retint an already-expanded SearchHandler action-view button on foreground-color changes.

Recommended title

[Android] Shell: Fix SearchHandler toolbar icon tint

Recommended description

### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when `SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes, `ShellToolbarTracker.TintColor` can remain unset. The collapsible SearchHandler menu icon and the search action view navigation button still used `TintColor.ToPlatform(Colors.White)`, which caused them to fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the SearchHandler-specific path by deriving SearchHandler toolbar icon tint from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes SearchHandler toolbar tint when `Shell.ForegroundColor` changes, including the collapsible menu item and the already-expanded SearchHandler action-view navigation button.

### Issues Fixed

Fixes #36015

Report — Final Recommendation

Comparative Report — PR #36016

Candidates compared

Rank Candidate Result Assessment
1 pr-plus-reviewer ⚠️ Not regression-tested; static review best Keeps the PR's narrow SearchHandler-specific tint resolution and adds the missing dynamic retint for the expanded SearchHandler action-view button. Best balance of correctness and blast radius.
2 pr ⚠️ Gate skipped; expert review found one issue Correctly fixes initial collapsed SearchHandler icon tint by resolving from explicit tint, page foreground, Shell foreground, then white fallback. However, dynamic foreground changes do not retint an already-expanded SearchHandler action-view button.
3 try-fix-2 ⚠️ BLOCKED Built after correction and is scoped to SearchHandler, but using Toolbar.IconColor risks changing fallback semantics from historical white to default foreground color when no foreground is explicitly set.
4 try-fix-3 ⚠️ BLOCKED Compiled/deployed but handles foreground-color changes by rebuilding toolbar items, which is broader than necessary and can disturb active SearchHandler state.
5 try-fix-1 ⚠️ BLOCKED Restores broad ShellToolbarTracker.TintColor propagation. This is the highest regression risk because it may reintroduce flyout/custom icon tint behavior the PR intentionally avoids.

Winning candidate

Winner: pr-plus-reviewer

pr-plus-reviewer wins because it preserves the raw PR's narrow, SearchHandler-specific fix while addressing the expert reviewer's concrete dynamic-update gap. None of the try-fix candidates passed regression tests, and each alternative has a larger semantic or lifecycle risk than the PR-lineage fix.

Notes on test ranking

No candidate has a confirmed passing regression test result. The gate for the PR was skipped because no tests were detected, and all try-fix attempts were recorded as blocked/timeouts rather than passes. Because there are no passing candidates to prioritize, ranking is based on static correctness, blast radius, and regression risk.


Future Action — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@kubaflo
kubaflo changed the base branch from main to inflight/current June 20, 2026 12:01
@kubaflo
kubaflo merged commit 14ca81c into dotnet:inflight/current Jun 20, 2026
7 of 9 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR9 milestone Jun 20, 2026
@erikzhang
erikzhang deleted the fix/searchhandler-toolbar-icon-tint branch June 20, 2026 12:14
PureWeen pushed a commit that referenced this pull request Jun 22, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
SubhikshaSf4851 pushed a commit to SubhikshaSf4851/maui that referenced this pull request Jun 23, 2026
Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

Fixes dotnet#36015

---------
SubhikshaSf4851 pushed a commit to SubhikshaSf4851/maui that referenced this pull request Jun 24, 2026
Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

Fixes dotnet#36015

---------
kubaflo pushed a commit that referenced this pull request Jun 25, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
kubaflo pushed a commit that referenced this pull request Jul 3, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
@kubaflo kubaflo mentioned this pull request Jul 6, 2026
kubaflo pushed a commit that referenced this pull request Jul 6, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
kubaflo pushed a commit that referenced this pull request Jul 10, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
kubaflo pushed a commit that referenced this pull request Jul 15, 2026
### Description of Change

Fixes Android Shell `SearchHandler` toolbar icon tinting when
`SearchBoxVisibility` is `Collapsible`.

After the Android Shell flyout icon tint changes,
`ShellToolbarTracker.TintColor` can remain unset. The collapsible
SearchHandler menu icon and the search action view navigation button
still used `TintColor.ToPlatform(Colors.White)`, which caused them to
fall back to white even when `Shell.ForegroundColor` was set.

This change keeps the flyout icon behavior intact and resolves the
SearchHandler-specific path by deriving SearchHandler toolbar icon tint
from:

1. explicit `ShellToolbarTracker.TintColor`
2. current page `Shell.ForegroundColor`
3. Shell `Shell.ForegroundColor`
4. existing white fallback

It also refreshes the SearchHandler menu item tint when
`Shell.ForegroundColor` changes.

### Issues Fixed

Fixes #36015

---------
# Conflicts:
#	.github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
#	.github/skills/release-readiness/tests/Test-ReleaseReadiness.ps1
#	.github/workflows/copilot-review-tests.lock.yml
#	.github/workflows/copilot-review-tests.md
#	.github/workflows/review-trigger.yml
#	.github/workflows/skill-validation.yml
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-shell Shell Navigation, Routes, Tabs, Flyout platform/android s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[regression/10.0.60] Android Shell SearchHandler toolbar icons ignore Shell.ForegroundColor

6 participants