Add Azure DevOps flaky-history annotations and quarantine awareness#8298
Draft
Evangelink wants to merge 1 commit into
Draft
Add Azure DevOps flaky-history annotations and quarantine awareness#8298Evangelink wants to merge 1 commit into
Evangelink wants to merge 1 commit into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds opt-in Azure DevOps flaky-history annotations and quarantine awareness to the Microsoft.Testing.Extensions.AzureDevOpsReport extension. Failures can now be annotated with historical flake context, demoted from error to warning when known-flaky, and demoted with a [quarantined] tag when listed in a quarantine file (which also emits a one-shot ##vso[build.addbuildtag]has-quarantined-test-failure).
Changes:
- New CLI options
--report-azdo-flaky-history,--report-azdo-quarantine-file,--report-azdo-demote-known-flakywith cross-option validation inAzureDevOpsCommandLineProvider. - New
AzureDevOpsHistoryService+AzureDevOpsHistoryClient(AOT-safeJsonSerializerContext) that queries the AzDO RESTRuns/ResultsAPIs under a 30 s wall-clock budget, with retries, 429Retry-Afterhonoring, paging caps, and a regression-annotation min-sample threshold. AzureDevOpsReporternow annotates errors with[flaky: failed K/N in last Md]/[REGRESSION]/[quarantined], and demotes severity per the quarantine file and known-flaky rule.
Show a summary per file
| File | Description |
|---|---|
| src/.../AzureDevOpsCommandLineOptions.cs | Adds 3 new option name constants. |
| src/.../AzureDevOpsCommandLineProvider.cs | Registers new options and adds cross-option validation. |
| src/.../AzureDevOpsExtensions.cs | Wires AzureDevOpsHistoryService as data consumer + session lifetime handler. |
| src/.../AzureDevOpsHistoryClient.cs | New REST client (auth, paging, retries, AOT JSON). |
| src/.../AzureDevOpsHistoryClientJsonContext.cs | Source-generated JSON context for DTOs. |
| src/.../AzureDevOpsHistoryService.cs | Loads/aggregates flaky stats with a bounded budget; exposes TryGetStats/IsLikelyFlaky. |
| src/.../AzureDevOpsReporter.cs | Adds annotation suffix building, severity demotion, one-shot quarantine build tag. |
| src/.../FlakyStats.cs | Struct holding pass/fail counts and failure rate. |
| src/.../IAzureDevOpsHistoryService.cs | Internal abstraction over the history service. |
| src/.../QuarantineFile.cs | Parses quarantine file (globs, # comments, caps) into regex matchers. |
| src/.../Microsoft.Testing.Extensions.AzureDevOpsReport.csproj | Adds System.Text.Json dependency and DynamicProxyGenAssembly2 IVT for Moq. |
| Directory.Packages.props | Pins System.Text.Json version. |
| src/.../Resources/AzureDevOpsResources.resx | New strings for options, warnings, and annotation templates; fixes prior Eanble/AzureDev Ops typos. |
| src/.../Resources/xlf/*.xlf (12 locales) | Regenerated XLFs for new strings; Description/OptionDescription flipped to needs-review-translation after the English typo fix. |
| test/.../AzureDevOpsHistoryClientTests.cs | Asserts URL composition (definitions=), headers, and run-paging behavior. |
| test/.../AzureDevOpsHistoryServiceTests.cs | Covers aggregation, paging, time-budget timeout, regression threshold, demote, quarantine tag-once. |
| test/.../AzureDevOpsCommandLineProviderTests.cs | Validates cross-option error messages. |
| test/.../AzureDevOpsCommandLineTests.cs | Acceptance-style test for invalid CLI argument errors. |
| test/.../HelpInfoAllExtensionsTests.cs | Updates --help / --info expectations for new options. |
Copilot's findings
- Files reviewed: 31/31 changed files
- Comments generated: 0
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.
Part 2 of the brainstorm in #5951 — adds opt-in flaky-test history annotations and quarantine awareness to
Microsoft.Testing.Extensions.AzureDevOpsReport. Decorates AzDO log issues with historical flake context and lets known-noisy failures be downgraded so PR gates aren't blocked.Why
Today every failure in an AzDO log looks equally bad. There's no way for the build to say "this test failed 4/20 times in the last 14 days — known noise" vs "this test had zero failures in 14 days and just broke — likely regression". Teams that have moved to MTP currently mark failures as warnings manually with a separate task or live with red PR checks for known-flaky tests.
What
Three new opt-in CLI options on
Microsoft.Testing.Extensions.AzureDevOpsReport:--report-azdo-flaky-history <days>[flaky: failed K/N in last Md]or[REGRESSION](only when ≥5 prior samples).--report-azdo-quarantine-file <path>#comments allowed) listing tests considered quarantined. Their failures are demoted towarningand tagged[quarantined]; emits##vso[build.addbuildtag]has-quarantined-test-failureexactly once.--report-azdo-demote-known-flaky--report-azdo-flaky-history, auto-demote failures whose flake-rate ≥25% in the window towarning. Default OFF (annotate-only). Requires--report-azdo-flaky-history.All three are opt-in; missing AzDO env vars (
SYSTEM_ACCESSTOKEN/SYSTEM_COLLECTIONURI/SYSTEM_TEAMPROJECT/BUILD_DEFINITIONID) → log warning and no-op.How it works
Authorization: Basic base64(":<SYSTEM_ACCESSTOKEN>")(noMicrosoft.TeamFoundationServer.Clientdependency; justHttpClient+ a source-generatedJsonSerializerContextso it's AOT-safe).GET {project}/_apis/test/Runs?definitions={pipelineDefinitionId}&minLastUpdatedDate=…&maxLastUpdatedDate=…&automated=true&$top=200paginated with$skipup toMaxRunsToInspect = 200. Per run,GET …/results?api-version=7.1&outcomes=Failed,Passedpaged with continuation token. Aggregated intoDictionary<automatedTestName, FlakyStats>.Retry-After). Response bodies truncated to 500 chars in error messages. All callbacks catch everything exceptOperationCanceledException; history/quarantine failures never fail the test run.#comments), case-sensitive ordinal matching against FQN, glob patterns (*,?) compiled to a single alternation regex. Capped at 10 000 patterns / 4 KB per pattern with a logged warning.##vso[build.addbuildtag]has-quarantined-test-failureguarded byInterlocked.Exchangeso concurrent failure events emit it exactly once.Highlights from the expert-reviewer round
Implementation went through one full round of
expert-reviewer. Critical issues addressed:buildIds=<pipelineDefinitionId>(the wrong AzDO parameter —buildIdsfilters by individual build run id, not pipeline). Switched todefinitions=<pipelineDefinitionId>so the query actually returns data. Unit test now asserts the URL containsdefinitions=.$top=501was silently capped server-side. Now properly pages runs via$skipuntilMaxRunsToInspectis reached.[REGRESSION]previously fired on a single prior sample, generating false positives everywhere. Now requiresTotalCount >= 5(configurable viaMinSamplesForRegressionAnnotation).Major items also addressed:
User-Agent/Acceptheaders added (prevents AzDO WAF-side 403s), source-generatedJsonSerializerContext(AOT-safe), error-body truncation, inner-exception preservation on retry exhaustion, quarantine pattern caps, ordinal-case-sensitive matching,IAzureDevOpsHistoryServiceinterface + proper DI registration, guard-clause CLI validation, acceptance tests for invalid-value error paths.Tests
546 unit tests pass. New coverage:
AzureDevOpsHistoryServiceTests.cs— history aggregation, paging, time budget, regression boundary (4 vs 5 samples), quarantine tag-emitted-once.AzureDevOpsHistoryClientTests.cs— URL composition (definitions=parameter),User-Agent/Acceptheaders, 429 retry honoringRetry-After.AzureDevOpsCommandLineProviderTests.cs— cross-product validation (e.g.--demote-known-flakywithout--flaky-history,--quarantine-filewithout--report-azdo).AzureDevOpsCommandLineTests.cs— acceptance-style coverage.HelpInfoAllExtensionsTestsexpectations updated for the new options (both--helpand--infoblocks, alphabetical order preserved).Build status (local)
.\.dotnet\dotnet.exe build src\Platform\Microsoft.Testing.Extensions.AzureDevOpsReport\Microsoft.Testing.Extensions.AzureDevOpsReport.csproj -c Debug— 0 warnings, 0 errors..\.dotnet\dotnet.exe test test\UnitTests\Microsoft.Testing.Extensions.UnitTests\Microsoft.Testing.Extensions.UnitTests.csproj— 546/546 passed..\build.cmd -pack— 0 warnings, 0 errors.Out of scope (deliberate)
Checklist
/t:UpdateXlf, not hand-edited)IAzureDevOpsHistoryService).\build.cmdgreen (0 warnings, 0 errors)Refs #5951