Improve /review tests: Opus engine, multi-build base diff, and readable grouped comments - #36533
Conversation
…on diff The Test Failure Analysis workflow's deterministic gate computed `legsRegressedVsBase` (the "Likely PR-caused" headline) by comparing each red PR leg against a SINGLE most-recent base build. Flaky UI test legs that happen to be green on that one base build produced false "regressed-vs-base / Likely PR-caused" positives, which made the generated comments untrustworthy. Changes: - Gather-TestFailureContext.ps1: sample several recent base builds of the PR's own base branch (main or net11.0) instead of one. New params RegressionBaseBuilds=5 and MinBaseGreenSamples=2; new Get-AggregatedBaseLegMap aggregator. A leg is only a regression if it is green across >= MinBaseGreenSamples base builds AND red on NONE of them. New leg states flaky-on-base / succeeded-on-base-unconfirmed and per-failure fields baseSampleCount / baseGreenCount / baseFailedCount. The false-GREEN (test-dismissal) side is intentionally left single-build-strict. - copilot-review-tests.md / .lock.yml: switch engine model claude-sonnet-4.6 -> claude-opus-4.8; recompiled lock. - SKILL.md / maui-ci-facts.md: document multi-build sampling, new states/fields, and soften the "green on base is proof" wording to require green across several base builds and red on none. Validated locally against PR #36478 (base main): 14 false legsRegressedVsBase -> 0; the ValidateDynamic*/CollectionViewInfiniteScroll/ Issue17400 legs now correctly classify as flaky-on-base (green 4/5, red 1/5). Extracted as a focused change from the broader improved-reviewer work (#36473). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ce857214-32ac-4ab0-afb8-f33ba35ae938
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36533Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36533" |
Skill Validation Results
✅ Skill Validation Results —
|
There was a problem hiding this comment.
Pull request overview
This PR improves the /review tests “Test Failure Analysis” workflow by making the job-level base-branch regression diff less sensitive to base-branch flakiness (sampling multiple recent base builds instead of a single build), and updates the workflow engine model to claude-opus-4.8.
Changes:
- Add multi-build base-branch leg aggregation in
Gather-TestFailureContext.ps1, with new parameters (RegressionBaseBuilds,MinBaseGreenSamples) and new leg states/fields to reflect base sampling confidence. - Update the
review-test-failuresskill + CI facts documentation to explain the new regression attribution rules and evidence fields. - Switch the workflow engine model to
claude-opus-4.8and regenerate the compiled lock workflow.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/copilot-review-tests.md | Switch engine model to Opus and update workflow guidance text to match multi-build base sampling. |
| .github/workflows/copilot-review-tests.lock.yml | Regenerated compiled workflow lock with the updated model metadata/env values. |
| .github/skills/review-test-failures/SKILL.md | Document new multi-build regression sampling behavior and evidence fields. |
| .github/skills/review-test-failures/scripts/Gather-TestFailureContext.ps1 | Implement multi-build base-leg aggregation and new leg states + per-failure base sampling counters. |
| .github/docs/maui-ci-facts.md | Update CI facts to describe multi-build leg diff semantics and new states/thresholds. |
The Test Failure Analysis runs across all platforms, so a single "Platform" badge on the summary comment is misleading and adds no signal. Drop the Platform badge from the posted-comment template (and the now-moot "No platform badges" note in the no-failures section), leaving the Overall / Failures / Baseline badge row. Recompiled the lock. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ce857214-32ac-4ab0-afb8-f33ba35ae938
Adopt the deep-UI-test-analysis comment shape for Tests Failure Analysis: a bold verdict line, a flat root-cause-grouped bullet list using subtle tokens (✗ PR-related / ℹ Uncertain / ● Unrelated), and an optional italic signal line — instead of a per-test Markdown table that becomes an unreadable wall of text on runs with hundreds of failures. Coverage counts and build/base-sampling evidence move into a collapsed block. Removes the now-unused badge row and the img.shields.io network allowlist entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ce857214-32ac-4ab0-afb8-f33ba35ae938
|
🔍 AI-generated update (GitHub Copilot CLI, on behalf of @kubaflo). @PureWeen — new review results are addressed based on the last commits: Base-leg regression diff (
Workflow prompt (
Accuracy follow-ups (auto-review)
Tests — added 7 Pester cases for |
The gate.unattributedFailures description in maui-ci-facts.md still listed only the old causes (ambiguous/missing base, non-build device-test). Bring it in line with the actual 'indeterminate' set after the multi-build base sampling changes: it now also lists flaky-on-base legs and succeeded-on-base-unconfirmed (green on too few base samples to confirm a regression). Matches the code comment, the emitted ceiling-reason string, and the workflow prompt prose. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 767d2d21-494b-41fb-8e8b-4410f9cc1b4b
The gate.legsRegressedVsBase description said a regression requires the leg GREEN "across several recent base builds", but the one-sample shortcut lets a DETERMINISTIC build break (crossgen/NativeAOT/linker/MSBuild — compiles or it doesn't) regress on a single green base build. Add that caveat where the agent consumes the definition (workflow prompt + SKILL.md rationale) and make the emitted ceiling-reason string say "GREEN on the sampled base builds" instead of "across several", so it stays accurate when baseGreenCount == 1. maui-ci-facts.md already documents the exception in its primary explanation. Recompiled copilot-review-tests.lock.yml (body_hash only). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 767d2d21-494b-41fb-8e8b-4410f9cc1b4b
The posted-comment template forced the agent to state that "several" recent
base builds were sampled, but baseSampleCount can be 1 (only one readable
base build, or the deterministic build-error one-sample shortcut). Reword the
Overall verdict placeholder and the Base sampling label to reference the real
baseSampleCount ("N recent build(s)" / "the single readable base build")
instead of hard-coding "several", so the published comment can't state an
inaccurate sample count.
Recompiled copilot-review-tests.lock.yml (body_hash only).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 767d2d21-494b-41fb-8e8b-4410f9cc1b4b
|
🔍 AI-generated update (GitHub Copilot CLI, on behalf of @kubaflo). @PureWeen — follow-up to my earlier summary. The Copilot auto-reviewer flagged a few cascading doc-consistency nuances caused by the base-leg changes; all are now fixed and every review thread is resolved (0 unresolved). Latest HEAD: Additional rounds since the first summary:
Validation each round: PS1 AST-parses clean, Pester 50/50 pass, |
PureWeen
left a comment
There was a problem hiding this comment.
Adversarial re-review
Result: Needs changes. One current-head logic issue remains; see the inline comment.
Required maui-pr is skipped, so CI coverage is undetermined.
Methodology: three independent reviewers plus two adversarial dispute rounds.
…exclude transient infra codes) Get-BuildErrorsFromLog marked a build break deterministicBuildError=$true for ANY coded `error XXnnnn:` line that was not one of four crash/OOM signatures. That blocklist let transient restore/network (NU1301) and MSBuild file-lock (MSB3021/MSB3027) errors qualify for the single-green-base regression shortcut: with one green base sample the leg loop marked the PR failure regressed-vs-base and hard-capped the verdict to "Not ready", bypassing multi-sample flake protection (MinBaseGreenSamples). Those are not compile-or-it-doesn't cases. Add Test-IsTransientBuildErrorCode -- a conservative, explicit, whole-code blocklist (NU1301, MSB3021, MSB3027) -- and require deterministicBuildError to be BOTH not-a-crash AND not-transient. Unknown coded errors still default to deterministic (genuine compile breaks are the majority and DO reproduce), and the NU/MSB prefixes are NOT blanket-excluded (NU1101, MSB4018 stay deterministic). Transient breaks now stay subject to MinBaseGreenSamples like a crash. Adds 8 Pester cases locking the boundary (3 for Test-IsTransientBuildErrorCode, 5 end-to-end through Get-BuildErrorsFromLog per the review request). Full suite 58 passed / 0 failed; both scripts AST-parse clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 767d2d21-494b-41fb-8e8b-4410f9cc1b4b
🔍 AI review round — transient-error boundary fixed (
|
| Input | deterministicBuildError |
|---|---|
NU1301 / MSB3021 / MSB3027 |
$false (transient) |
CS0246 |
$true |
NU1101 / MSB4018 |
$true (prefix not blanket-excluded) |
| native crash | $false (unchanged) |
Full suite 58 passed / 0 failed; both scripts AST-parse clean.
cc @PureWeen
🔍 AI-generated summary (GitHub Copilot CLI, on behalf of @kubaflo).
| # The most recent completed base build is the authoritative baseline (the doc | ||
| # compares against "the most recent base-branch build"). If its tip succeeded, | ||
| # base is currently healthy and matching failures are not pre-existing — even if | ||
| # an older build in the lookback window was red (it was since fixed). | ||
| $mostRecent = $completed[0] |
| have a known **reason conflict** (`baselineReasonConflict`). It is likewise **capped at `Not ready`** whenever | ||
| a leg is red on the PR | ||
| but green on the same leg of the most recent base build (`gate.legsRegressedVsBase > 0` — the | ||
| but green across several recent base builds and red on none of them (`gate.legsRegressedVsBase > 0` — the | ||
| computed job-level regression; a device-test BUILD break counts here, only device-test TEST |
PureWeen
left a comment
There was a problem hiding this comment.
Adversarial re-review
Result: No new issues found. The current transient-code boundary keeps NU1301, MSB3021, and MSB3027 out of the one-green-base shortcut, while retaining deterministic handling for the tested non-transient codes.
Test coverage: The new Pester cases execute the real build-error classification boundary for transient, deterministic, and crash signatures.
Prior review status: Existing feedback, including the prior transient-code finding and current automatic comments, was inspected without duplicating previously reported concerns.
Methodology: 3 independent reviewers with adversarial consensus + repo domain specialist.
…le grouped comments (dotnet#36533) <!-- 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 this changes The `/review tests` **Test Failure Analysis** workflow classifies whether a PR's CI failures are PR-caused or unrelated. Its deterministic gate computed `legsRegressedVsBase` — the "Likely PR-caused" headline — by comparing each red PR leg against **a single most-recent base build**. Flaky UI-test legs that happened to be green on that one base build produced false **"regressed-vs-base / Likely PR-caused"** positives, so the generated comments carried little signal. This PR makes the regression diff sample **several recent base builds of the PR's own base branch** (`main` or `net11.0`) and only calls a leg a regression when it is green across enough of them and red on none — and switches the LLM engine to Opus. It also **replaces the per-test result table with a skimmable, root-cause-grouped bullet list** (the deep-UI-test-analysis style) so a run with hundreds of failures collapses to a handful of readable groups inside the existing compact badge + collapsible header instead of a giant table. ### Changes - **`Gather-TestFailureContext.ps1`** — new `Get-AggregatedBaseLegMap` aggregator + params `RegressionBaseBuilds=5` and `MinBaseGreenSamples=2`. A leg is a regression only if it is green on **≥ `MinBaseGreenSamples`** base builds **and red on NONE**. Per base build, a leg that failed even one attempt counts RED (a retry that later passed does not clear a base flake). New leg states `flaky-on-base` / `succeeded-on-base-unconfirmed` and new per-failure fields `baseSampleCount` / `baseGreenCount` / `baseFailedCount`. - **Asymmetric conservatism (preserved)** — multi-build sampling widens **only** the false-RED (assert-a-regression) side. The test-level dismissal / false-GREEN side stays single-build-strict on purpose, so this change never turns a real failure green. - **`copilot-review-tests.md` / `.lock.yml`** — engine model `claude-sonnet-4.6` → `claude-opus-4.8`; **replaced only the per-test Markdown table** (an unreadable wall of text on runs with hundreds of failures) with a deep-UI-test-analysis style **root-cause-grouped** bullet list using subtle tokens (`✗ PR-related` / `ℹ Uncertain` / `● Unrelated`). The compact **badge row and the `Test Failure Review: [verdict] - click to expand` collapsible are kept** so the collapsed comment stays a one-glance summary; the badge set now surfaces the key multi-build signal — `Overall` / `Failures` / **`Regressed vs base`** (replacing the old `Platform` badge) / `Baseline on base`. Everything detailed (verdict sentence, grouped bullets, coverage counts, this-PR + base-sampling build links, recommended action) lives inside the collapsible. `img.shields.io` stays in the network allowlist. Lock recompiled (gh-aw v0.80.9). - **`SKILL.md` / `maui-ci-facts.md`** — document the multi-build sampling, the new states/fields, and soften the "green on base is proof" wording to require green across several base builds and red on none. ### Validation Ran the gatherer locally against **PR dotnet#36478** (base `main`), before vs after: | | `legsRegressedVsBase` | Verdict | |---|---|---| | **Before** (single base build) | **14** | Not ready | | **After** (5 base builds) | **0** | Needs human investigation | The `ValidateDynamic*` (×9), `CollectionViewInfiniteScroll`, and `Issue17400` legs — each green on 4/5 base builds and red on 1/5 — are now correctly classified as `flaky-on-base` instead of PR regressions. ### Notes - Extracted as a focused, standalone change from the broader `improved-reviewer` work (dotnet#36473). - CI-tooling-only change (`.github/`); no framework/runtime code is touched. --------- 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 from this PR and let us know in a comment if this change resolves your issue. Thank you!
What this changes
The
/review testsTest Failure Analysis workflow classifies whether a PR's CI failures are PR-caused or unrelated. Its deterministic gate computedlegsRegressedVsBase— the "Likely PR-caused" headline — by comparing each red PR leg against a single most-recent base build. Flaky UI-test legs that happened to be green on that one base build produced false "regressed-vs-base / Likely PR-caused" positives, so the generated comments carried little signal.This PR makes the regression diff sample several recent base builds of the PR's own base branch (
mainornet11.0) and only calls a leg a regression when it is green across enough of them and red on none — and switches the LLM engine to Opus. It also replaces the per-test result table with a skimmable, root-cause-grouped bullet list (the deep-UI-test-analysis style) so a run with hundreds of failures collapses to a handful of readable groups inside the existing compact badge + collapsible header instead of a giant table.Changes
Gather-TestFailureContext.ps1— newGet-AggregatedBaseLegMapaggregator + paramsRegressionBaseBuilds=5andMinBaseGreenSamples=2. A leg is a regression only if it is green on ≥MinBaseGreenSamplesbase builds and red on NONE. Per base build, a leg that failed even one attempt counts RED (a retry that later passed does not clear a base flake). New leg statesflaky-on-base/succeeded-on-base-unconfirmedand new per-failure fieldsbaseSampleCount/baseGreenCount/baseFailedCount.copilot-review-tests.md/.lock.yml— engine modelclaude-sonnet-4.6→claude-opus-4.8; replaced only the per-test Markdown table (an unreadable wall of text on runs with hundreds of failures) with a deep-UI-test-analysis style root-cause-grouped bullet list using subtle tokens (✗ PR-related/ℹ Uncertain/● Unrelated). The compact badge row and theTest Failure Review: [verdict] - click to expandcollapsible are kept so the collapsed comment stays a one-glance summary; the badge set now surfaces the key multi-build signal —Overall/Failures/Regressed vs base(replacing the oldPlatformbadge) /Baseline on base. Everything detailed (verdict sentence, grouped bullets, coverage counts, this-PR + base-sampling build links, recommended action) lives inside the collapsible.img.shields.iostays in the network allowlist. Lock recompiled (gh-aw v0.80.9).SKILL.md/maui-ci-facts.md— document the multi-build sampling, the new states/fields, and soften the "green on base is proof" wording to require green across several base builds and red on none.Validation
Ran the gatherer locally against PR #36478 (base
main), before vs after:legsRegressedVsBaseThe
ValidateDynamic*(×9),CollectionViewInfiniteScroll, andIssue17400legs — each green on 4/5 base builds and red on 1/5 — are now correctly classified asflaky-on-baseinstead of PR regressions.Notes
improved-reviewerwork (Improve maui-copilot reviewer: gate & deep-stage reliability fixes #36473)..github/); no framework/runtime code is touched.