Skip to content

Flaky-test workflow: reassure on empty PR list + drop local reproduction (quarantine-first) - #13938

Merged
ViktorHofer merged 12 commits into
mainfrom
flaky-detector-empty-pr-list
Jun 5, 2026
Merged

Flaky-test workflow: reassure on empty PR list + drop local reproduction (quarantine-first)#13938
ViktorHofer merged 12 commits into
mainfrom
flaky-detector-empty-pr-list

Conversation

@ViktorHofer

@ViktorHofer ViktorHofer commented Jun 3, 2026

Copy link
Copy Markdown
Member

Improvements to the scheduled Flaky Test Triage and Fix agentic workflow, batched onto one PR.

1. Empty open-flaky-PR list is normal (original)

Reassure the agent that gh pr list --label flaky-test returning [] is the expected case (no flaky-test PR in flight), not a tool failure to re-investigate.

2. Stop local flaky-test reproduction — quarantine-first

Local reproduction on the single Linux/.NET agent runner is structurally unreliable: it cannot run Windows-only or net472-only tests, and isolated single-method loops miss the ordering/shared-state/parallel-contention flakes that dominate. The scheduled quarantine pipeline (AzDO definition 344, azure-pipelines/quarantine.yml) already re-runs quarantined tests on Windows/Linux/macOS twice daily to gather repeat-failure signal over time, so in-workflow reproduction is redundant.

  • Remove the up-front whole-repo build, the parallel 25× reproduction screening, and the determinism-fix authoring (old Steps 6 / 7a / 7b / 7c).
  • New flakes are now simply quarantined with [ActiveIssue]. Backlog tests still flaking in def 344 stay quarantined (no local fix attempt). Only consistently-green backlog tests are un-quarantined.
  • ./build.sh moves to a post-edit validation step that only confirms the [ActiveIssue] edits compile. On an environmental/network build failure the mechanical edits are low-risk, so the draft PR is opened anyway (its CI is the first real compile); a genuine error CS... reverts the offending edit.
  • Strengthen the diff gate so every changed path must be a selected test's source file (the workflow never edits product code now).
  • Lower timeout-minutes 120 → 60, refresh the frontmatter description/comments, and recompile the lock.

3. Add a separate evidence-based auto-fixer workflow

A new scheduled workflow .github/workflows/flaky-test-fixer.agent.md (compiled to …/flaky-test-fixer.agent.lock.yml) complements the detector. Where the detector quarantines/un-quarantines, the fixer proposes test-only fixes for tests that are already [ActiveIssue]-quarantined but still flaking in def 344.

  • It diagnoses each candidate from the accumulated def-344 failure evidence (consistent error signatures + stack traces over many builds/days) — no local reproduction.
  • It keeps the [ActiveIssue] in place (the PR is a candidate fix; def 344 validates it on main over the following days, then the detector un-quarantines once green). It never closes the tracking issue (Tracked by #N, never Fixes).
  • It opens one individual draft PR per fixed test (not a combined PR), capped at 3/run, each editing only that test's own .cs file. allowed-files is scoped to test projects (*UnitTests* / *.Tests) and .github/** is excluded, so product code can never be touched. A forbidden-changes list blocks weakening assertions, sleep/retry/timeout-bump-only fixes, swallowing exceptions, etc.
  • It dedups against open flaky-test PRs (marker + issue number + edited file) so it never collides with the detector or its own prior runs. The whole repo is built once (./build.sh) to validate the fixes compile before opening PRs.

Supporting change: Get-FlakyTests.ps1 gains a gated, default-off -IncludeErrorDetails switch that emits per-test errorSamples (distinct failure signatures with truncated message + source-frame-preferring stack excerpt) for diagnosis. Additive only — the detector's output shape is unchanged.

Run 26883332898 (otherwise a clean two-run-model success: quarantined 4
pre-existing tracked tests in one PR, 2.85M effective tokens, no firewall
blocks) wasted ~8 tool calls when the Step 5 dedup query
'gh pr list --label flaky-test --json number,body' correctly returned an
empty array. With no flaky-test PR in flight, [] is the expected result, but
the agent read it as a broken command -- re-running it, inspecting the file
with xxd/wc, toggling 2>/dev/null, and finally switching to gh api -- partly
because open flaky-test *issues* (the tracking issues) did exist and it
conflated issues with PRs.

Add a note to Step 5 that an empty [] is the normal case (no cross-run
duplicates to skip), must not be treated as a tool failure, and that
'gh pr list --label flaky-test' lists only PRs -- so returning [] while
flaky-test-labeled issues exist is correct, not a bug.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 3, 2026 12:36
@ViktorHofer
ViktorHofer requested a review from a team as a code owner June 3, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the flaky-test-detector agent workflow instructions to explicitly document that Step 5’s cross-run dedup query can legitimately return an empty JSON array ([]) when there are no open flaky-test PRs, and that this should not be treated as a tool failure.

Changes:

  • Add explicit guidance that [] from gh pr list --label flaky-test --json ... is the expected common case.
  • Clarify that gh pr list only returns pull requests, so it can be empty even when flaky-test-labeled issues exist.
  • Instruct the agent not to waste tool calls re-running/validating the empty result via xxd/wc/stderr tweaks/gh api.
Show a summary per file
File Description
.github/workflows/flaky-test-detector.agent.md Adds Step 5 documentation clarifying empty PR dedup output ([]) is normal and should not trigger retries or alternative queries.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread .github/workflows/flaky-test-detector.agent.md Outdated
ViktorHofer and others added 2 commits June 3, 2026 14:49
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…build validation

Local reproduction on the single Linux/.NET agent runner is unreliable: it
cannot run Windows-only or net472-only tests, and isolated single-method
loops miss the ordering/shared-state/parallel-contention flakes that
dominate. The scheduled quarantine pipeline (AzDO def 344) already re-runs
quarantined tests on Windows/Linux/macOS twice daily to gather repeat-failure
signal over time, so in-workflow reproduction is redundant.

- Remove the up-front whole-repo build, the parallel 25x reproduction
  screening, and the determinism-fix authoring (old Steps 6/7a/7b/7c).
- New flakes are now simply quarantined with [ActiveIssue]; backlog tests
  still flaking in def 344 stay quarantined (no local fix attempt); only
  consistently-green backlog tests are un-quarantined.
- Move ./build.sh to a post-edit validation step that only checks the
  [ActiveIssue] edits compile; on an environmental/network build failure the
  mechanical edits are low-risk so the draft PR is opened anyway (its CI is
  the first real compile), while a genuine compile error reverts the edit.
- Strengthen the Step 8 diff gate to require each changed path be a selected
  test's source file (the workflow never edits product code now).
- Lower timeout 120->60 min and refresh frontmatter description/comments;
  recompile the lock.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ViktorHofer ViktorHofer changed the title Stop the flaky detector from re-testing an empty open-PR dedup list Flaky-test workflow: reassure on empty PR list + drop local reproduction (quarantine-first) Jun 3, 2026
ViktorHofer and others added 9 commits June 3, 2026 15:30
Adds a new scheduled gh-aw workflow (flaky-test-fixer) that proposes
test-only fixes for tests that are already quarantined ([ActiveIssue])
but still flaking in the quarantine pipeline (AzDO definition 344). It
diagnoses root causes from accumulated def-344 failure evidence (no local
reproduction), keeps the [ActiveIssue] in place, and opens one individual
draft PR per confidently-fixable test. The separate detector workflow
un-quarantines once def 344 proves the test green.

Also adds a gated -IncludeErrorDetails switch to Get-FlakyTests.ps1 that
emits per-test errorSamples (distinct failure signatures with message +
stack excerpts) for diagnosis. The switch is additive and default-off, so
the detector's output shape is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run the auto-fixer at 12:38 UTC, ~1 hour after the detector's 11:38 UTC
run, so it sees the detector's latest quarantine/un-quarantine state
before proposing fixes. Use an explicit cron (not 'daily') so the time
stays fixed and is not re-scattered on recompile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename the detector workflow "Flaky Test Triage and Fix" -> "Flaky Test
Triage" since authoring fixes moved to the separate flaky-test-fixer
workflow. Update the body to state the detector only quarantines/
un-quarantines and to reference flaky-test-fixer.agent.md as the place a
determinism fix is proposed (from accumulated def-344 evidence).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enable the quarantine re-validation pipeline (def 344) on pull requests
targeting main, in addition to its twice-daily schedule. This lets a fix
PR's effect on the quarantined tests be validated directly on the PR
(the quarantined tests are excluded from normal CI). Still never runs on
CI pushes (trigger: none).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Now that the quarantine pipeline (def 344) also runs on PRs targeting
main, a PR build runs the quarantined tests against unmerged changes and
can pass incidentally (or via an in-flight fix). Counting those greens
toward un-quarantine would re-enable a test on main before the
responsible change is actually merged, re-disrupting CI.

Get-FlakyTests.ps1 -IncludePassed now tags each passed observation with
its source type and bases the un-quarantine signal fields
(distinctBuilds/buildIds/distinctDays/legs/tfms, totalPassed) on
scheduled-main (rolling) observations ONLY. PR greens are surfaced as a
separate informational prDistinctBuilds; a test seen green solely on PR
builds is dropped from passedTests so it neither drives an un-quarantine
nor looks 'trending green' to the fixer.

Body-only doc updates in both workflows clarify that passedTests green
counts are scheduled-main only (runtime-imported; no recompile needed).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The quarantine pipeline now triggers on main's rolling (batched) builds for
fresh per-commit signal, keeps a once-daily schedule as a fallback for quiet
periods, and continues to run on PRs targeting main. Consumers already treat
rolling and scheduled main runs identically (reasons batchedCI/individualCI/
schedule), so existing scheduled data stays valid. Updated detector and fixer
body wording and Get-FlakyTests.ps1 comments to describe the un-quarantine
signal as main-branch (rolling + scheduled) rather than scheduled-only.

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

The auto-fixer now has two tiers. By default it keeps the [ActiveIssue]
quarantine as before (candidate fix validated by def 344 after merge). When
confidence is very high -- a single dominant signature explaining essentially
all current def-344 failures, a deterministic textbook root cause fully removed
by a minimal test-only change, full-scope PR-CI coverage, and a cleanly
removable attribute (new Step 5b) -- it also deletes the single [ActiveIssue]
line in the same file, so normal PR CI runs the test as additional pre-merge
validation. The PR body states which variant applies; the tracking issue is
still never closed. Updated the frontmatter description, intro invariant,
overall shape, Step 5 forbidden list, new Step 5b, Step 6, the PR-body caveat
(conditional) and markers, and the Important section accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…idence un-quarantine

Make the quality/understanding bar explicit in Step 5b: the agent must be able
to state the exact causal chain from its change to why the dominant failure
signature can no longer occur, target that mechanism (not a symptom or mask),
and preserve the test's coverage. A category-match or a 'should help' rationale
is not sufficient to also remove the [ActiveIssue].

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

@JanKrivanek JanKrivanek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@ViktorHofer
ViktorHofer merged commit 73ee6dd into main Jun 5, 2026
14 checks passed
@ViktorHofer
ViktorHofer deleted the flaky-detector-empty-pr-list branch June 5, 2026 12:02
ViktorHofer added a commit that referenced this pull request Jun 5, 2026
…es section from PR body (#13958)

Follow-up to #13938, addressing two pieces of feedback on how the
flaky-test **detector** opens its combined quarantine/un-quarantine PR.

### 1. Open quarantine/un-quarantine PRs ready-for-review (not draft)
The detector previously opened its PR as a draft (`draft: true`). dnceng
AzDO build validation does not run on draft PRs, so CI only kicked in
once a maintainer marked the PR ready for review (observed on #13952).
Since these PRs are mechanical `[ActiveIssue]` add/removes that benefit
from immediate CI validation, switch to `draft: false` so CI runs as
soon as the PR is opened.

### 2. Don't list newly-filed tracking issues in the PR body
On an un-quarantine PR (#13952), the agent appended a "New flaky test
issues filed this run" section referencing freshly-filed issues (e.g.
#13949-#13951). Those issues are **not** acted on by the PR (they only
become quarantine-eligible on a later run), so the `#number` references
created a misleading issue<->PR cross-link. Step 8 now explicitly
instructs the agent to reference only the issues for tests it actually
quarantines or un-quarantines in that PR.

Frontmatter changed (`draft` + `description`), so the lock file was
regenerated; cron is preserved at `38 11`.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Aug 12, 2026
WarperSan pushed a commit to WarperSan/ThunderPipe that referenced this pull request Aug 12, 2026
Updated
[Microsoft.Build.Utilities.Core](https://github.com/dotnet/msbuild) from
18.8.2 to 18.9.6.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Build.Utilities.Core's
releases](https://github.com/dotnet/msbuild/releases)._

## 18.9.6

## What's Changed
* [vs18.6] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13793
* [vs18.0] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13859
* [vs18.6] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13858
* [vs18.7] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13863
* CsWin32 follow-up: CLR metadata + TypeLib interop migration by
@​JeremyKuhne in dotnet/msbuild#13853
* Update vmr-sb-validation.yml for Azure Pipelines by @​meghnave in
dotnet/msbuild#13871
* Test: keep shell alive 15s in ToolTaskCanChangeCanonicalErrorFormat
(#​13734) by @​jankratochvilcz in
dotnet/msbuild#13878
* Add vs18.8 to merge-flow config by @​OvesN in
dotnet/msbuild#13877
* Stable branding for 18.8 release by @​OvesN in
dotnet/msbuild#13883
* Bump main to 18.9.0 after vs18.8 snap by @​OvesN in
dotnet/msbuild#13880
* Avoid checkout in insertion pipeline by @​rainersigwald in
dotnet/msbuild#13887
* Report actual launch path in MSB4216 for Runtime="NET" task host by
@​ViktorHofer in dotnet/msbuild#13889
* Migrate Tlblmp and AxImp to Multithreaded Execution by @​AlesProkop in
dotnet/msbuild#13708
* Replace ErrorUtilities assertion methods with Assumed API and BCL
throw helpers by @​DustinCampbell in
dotnet/msbuild#13790
* Fix CLR_E_SHIM_RUNTIMELOAD in RAR's IMetaDataDispenser activation by
@​JeremyKuhne in dotnet/msbuild#13899
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#13905
* [main] Update dependencies from dotnet/arcade by @​dotnet-maestro[bot]
in dotnet/msbuild#13907
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#13910
* [vs17.14] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13908
* [vs18.0] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13906
* Fix ToolTask output loss: increase EOF pipe timeout from 2s to 30s by
@​huulinhnguyen-dev in dotnet/msbuild#13767
* Improve symlink cycle condition by @​GangWang01 in
dotnet/msbuild#13901
* [vs18.6] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13904
* Add flaky-test detection and auto-fix agentic workflows by
@​ViktorHofer in dotnet/msbuild#13915
* Quote --ignore-exit-code values so the quarantine pipeline does not
shell-split on Unix by @​ViktorHofer in
dotnet/msbuild#13918
* Fix flaky-test detector PR-evidence loss and raise scan limits by
@​ViktorHofer in dotnet/msbuild#13919
* Tighten the pr review agent by @​JanKrivanek in
dotnet/msbuild#13921
* Add environment variables for governance detection by @​ViktorHofer in
dotnet/msbuild#13920
* Change IsPackable to true and add IsShipping flag by @​ViktorHofer in
dotnet/msbuild#13924
* [vs18.7] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13911
* Make flaky detector verify recurrence postdates the fix before
commenting by @​ViktorHofer in
dotnet/msbuild#13930
* Fix AbsolutePath.GetCanonicalForm process state leak on Windows by
@​OvesN in dotnet/msbuild#13788
* Fix flaky detector: unblock dnceng feed, fail fast, and defer
quarantine to a second run by @​ViktorHofer in
dotnet/msbuild#13936
* Update documentation for ImplicitUsings element by @​drewnoakes in
dotnet/msbuild#13900
* [vs18.6] Point OptProf bootstrapper at rel/stable instead of int.main
by @​AlesProkop in dotnet/msbuild#13923
* Add CS8618 suppressor for required MSBuild task properties by
@​AArnott in dotnet/msbuild#13926
* Tighten NodeLaunchData.EnvironmentOverrides nullability to
IDictionary<string, string?>? by @​OvesN with @​Copilot in
dotnet/msbuild#13815
* Fix ToolTask EOF wait to be STA-safe via CountdownEvent (MSB4018 in
AspNetCompiler) by @​YuliiaKovalova in
dotnet/msbuild#13917
* [automated] Merge branch 'vs18.6' => 'vs18.7' by @​github-actions[bot]
in dotnet/msbuild#13941
* Localized file check-in by OneLocBuild Task: Build definition ID 9434:
Build ID 14192258 by @​dotnet-bot in
dotnet/msbuild#13849
* Bumping to 10.0.8 runtime packages by @​OvesN in
dotnet/msbuild#13898
* Flaky-test workflow: reassure on empty PR list + drop local
reproduction (quarantine-first) by @​ViktorHofer in
dotnet/msbuild#13938
* [Flaky Test] Un-quarantine 5 consistently-green tests by
@​github-actions[bot] in dotnet/msbuild#13952
* Flaky-test detector: open PRs ready-for-review; drop
newly-filed-issues section from PR body by @​ViktorHofer in
dotnet/msbuild#13958
* [Flaky Test] Quarantine 4 flaky tests by @​github-actions[bot] in
dotnet/msbuild#13937
* Flaky-test: fix duplicate-issue bug by switching dedup key to a
visible code-block key by @​ViktorHofer in
dotnet/msbuild#13963
* CsWin32 follow-up: WindowsNative + VS Setup Configuration + remaining
hand-rolled interop by @​JeremyKuhne in
dotnet/msbuild#13872
* Add the reviewer release skill checking if the Learn article Change
waves is updated by @​GangWang01 in
dotnet/msbuild#13840
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#13977
 ... (truncated)

Commits viewable in [compare
view](dotnet/msbuild@v18.8.2...v18.9.6).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Microsoft.Build.Utilities.Core&package-manager=nuget&previous-version=18.8.2&new-version=18.9.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@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.

3 participants