Handle flaky PR builds faster: real-time unstable-tests refresh + cross-PR detector#9536
Draft
mazhelez wants to merge 2 commits into
Draft
Handle flaky PR builds faster: real-time unstable-tests refresh + cross-PR detector#9536mazhelez wants to merge 2 commits into
mazhelez wants to merge 2 commits into
Conversation
The unstable-tests list only refreshed twice daily, so a newly-flaky test could block PRs for up to ~12h before it was tolerated. Add a workflow_run trigger on CI/CD completion that recomputes the list for the branch that just ran, reusing the existing sliding-window heuristic (self-healing intact). Scoped to official branches and to the trigger events the window includes, so it does no wasteful work. This also aligns the implementation with DESIGN.md, which already states the list is maintained 'after each CI/CD completion'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Correlate test failures across recent PR builds: a test failing on multiple distinct PRs in a short window is almost certainly an instability, not any one PR's regression. New hourly DetectUnstableTestsFromPrBuilds workflow lists PR builds completed in the last few hours, resolves each run's PR/base branch, and additively marks any test failing on >= minDistinctPrs (default 2) distinct PRs as unstable for that branch. Logic is split into a pure, unit-tested core (Select-CrossPrUnstableTests) and a thin gh wrapper (Find-CrossPrUnstableTests), driven by UpdateUnstableTestsFromPrBuilds.ps1. Add-FailedTestsToUnstableTests now honors a per-test reason. 7 new Pester tests; full suite green (46 passing). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
|
Could not find a linked ADO work item. Please link one by using the pattern 'AB#' followed by the relevant work item number. You may use the 'Fixes' keyword to automatically resolve the work item when the pull request is merged. E.g. 'Fixes AB#1234' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
PR builds on BCApps have been failing intermittently on known-unstable tests. The existing Test Tolerance feature is the right foundation (per-test, auditable reclassification of known-unstable failures), but its detection is slow: the
unstable-tests-<branch>list only refreshed twice daily from CI/CD runs, so a newly-flaky test could block unrelated PRs for up to ~12h before it was tolerated.This PR closes that latency gap with two additive, low-risk changes that reuse the existing tolerance machinery.
What changed
1. Refresh the unstable-tests list right after each CI/CD run (
UpdateUnstableTests.yaml)workflow_runtrigger onCI/CDcompletion that recomputes the list for just the branch that ran, reusing the exact existing sliding-window heuristic (self-healing intact).DESIGN.md, which already documents the list as maintained "after each CI/CD completion".2. Cross-PR unstable-test detector (
DetectUnstableTestsFromPrBuilds.yaml)Correlates failures across PR builds: a test failing on a single PR is ambiguous (could be that PR's own change), but the same test failing across multiple unrelated PRs in a short window is almost never caused by any one PR — it's an instability.
Pull Request Buildruns completed in the lastwindowHours(default 3), resolves each run's PR number + base branch (same-repo and fork PRs), downloads test results from failed runs, and additively marks any test failing on ≥minDistinctPrsdistinct PRs (default 2) as unstable.Select-CrossPrUnstableTests) and a thinghwrapper (Find-CrossPrUnstableTests), driven byUpdateUnstableTestsFromPrBuilds.ps1.Add-FailedTestsToUnstableTestsnow honors a per-test reason.unstable-tests-<branch>artifact PR builds already consume; becauseReceive-UnstableTestsArtifactalways takes the latest artifact by name, the hourly detector and the twice-daily recompute interleave correctly (latest wins).Self-healing & the confidence trade-off
Entries added by the detector are never removed by it; the scheduled recompute drops them if they stop failing in CI/CD, and the detector re-adds them if they keep recurring — the intended self-healing behavior.
The default threshold (
minDistinctPrs = 2, no base-branch guard) is deliberately aggressive for speed. Worst case: a real regression freshly landed on a base branch fails across many PRs and could be auto-tolerated until the next recompute. This is accepted for now because exposure is time-bounded by self-healing; raisingminDistinctPrsor adding a base-branch CI check would trade speed for lower masking risk.Testing
TestTolerance.Test.ps1(7 new tests covering threshold, distinct-PR dedupe, rerun dedupe, extensionId distinction, and reason formatting).ghwrapper short-circuits on unsupported branches with no API call.gh-facing paths are covered by mocked/pure unit tests and will run fully undergithub.tokenin CI.Files
.github/workflows/UpdateUnstableTests.yaml— newworkflow_runtrigger + branch scoping.github/workflows/DetectUnstableTestsFromPrBuilds.yaml— new detector workflowbuild/scripts/TestTolerance/TestTolerance.psm1—Select-CrossPrUnstableTests,Find-CrossPrUnstableTests, per-test reasonbuild/scripts/TestTolerance/UpdateUnstableTestsFromPrBuilds.ps1— detector driverbuild/scripts/TestTolerance/TestTolerance.Test.ps1— new unit testsdocs/features/test-tolerance/DESIGN.md— documents both paths