Skip to content

Add Microsoft.Testing.Extensions.GitHubActionsReport (groups, annotations, step summary, slow-test notices)#9541

Open
azat-msft wants to merge 29 commits into
microsoft:mainfrom
azat-msft:feature/github-actions-report
Open

Add Microsoft.Testing.Extensions.GitHubActionsReport (groups, annotations, step summary, slow-test notices)#9541
azat-msft wants to merge 29 commits into
microsoft:mainfrom
azat-msft:feature/github-actions-report

Conversation

@azat-msft

Copy link
Copy Markdown
Member

Summary

Fixes #9142.

Adds a new Microsoft.Testing.Extensions.GitHubActionsReport extension package (sibling of the existing Microsoft.Testing.Extensions.AzureDevOpsReport) that emits GitHub Actions-native workflow commands so test runs on GitHub Actions produce a first-class experience. This PR implements all four requirements from the issue.

What's included

All four building blocks from #9142:

  1. Per-assembly log groups — emits ::group:: / ::endgroup:: so each test assembly's output is collapsed by default in the runner UI (GitHubActionsReporter.cs).
  2. Failure annotations — emits an ::error file=…,line=…,title=…:: command for each failing test, so failures appear in the workflow Annotations tab and, when the source location can be resolved, on the pull request's Files changed diff gutter (GitHubActionsAnnotationReporter.cs).
  3. Job summary — appends a markdown roll-up (per-assembly totals, failures, slowest tests) to the file pointed to by GITHUB_STEP_SUMMARY, which GitHub renders on the workflow run summary page (GitHubActionsSummaryReporter.cs).
  4. Slow-test notices — emits a ::notice command for any test still running past a threshold, default 60s (GitHubActionsSlowTestReporter.cs).

Supporting pieces:

  • GitHubActionsEscaper.cs — escapes special characters per GitHub workflow-command rules.
  • GitHubActionsCommandLineProvider.cs / GitHubActionsCommandLineOptions.cs — the master switch plus per-feature toggles.
  • GitHubActionsRepositoryRoot.cs / TestNodeIdentity.cs / TargetFrameworkMonikerHelper.cs — source-location and identity helpers used for annotations.
  • Extensions entry point + MSBuild builder hook, resources (.resx + regenerated .xlf for all locales), PublicAPI, BannedSymbols, PACKAGE.md, build props.
  • Wired into TestFx.slnx, Platform InternalsVisibleTo, and the unit-test project.

Behaviour

  • Auto-activates when GITHUB_ACTIONS=true; otherwise silently no-ops.
  • Can be forced on outside GitHub Actions with the --report-gh master switch.
  • Each feature is individually toggleable:
Option Description Default
--report-gh Master switch to enable the extension outside GitHub Actions off
--report-gh-groups on|off Per-assembly log groups on
--report-gh-annotations on|off Failure annotations on
--report-gh-step-summary on|off Markdown job summary on
--report-gh-slow-test-notices on|off Slow-test notices on
--report-gh-slow-test-threshold <seconds> Seconds before a slow-test notice is emitted 60

Tests

New unit tests in test/UnitTests/Microsoft.Testing.Extensions.UnitTests/:

  • GitHubActionsEscaperTests.cs
  • GitHubActionsCommandLineProviderTests.cs
  • GitHubActionsReporterTests.cs (group emission)
  • GitHubActionsAnnotationReporterTests.cs
  • GitHubActionsSummaryReporterTests.cs
  • GitHubActionsSlowTestReporterTests.cs

Related

azat-msft and others added 9 commits June 16, 2026 00:20
…y log groups

Implements the first requirement of microsoft#9142: a new GitHub Actions report extension that emits ::group:: / ::endgroup:: workflow commands per test assembly so the runner UI collapses each assembly's output. Auto-activates when GITHUB_ACTIONS=true; controllable via --report-gh-groups on/off and --report-gh.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Emit a ::error workflow command for each failing test via a new
GitHubActionsAnnotationReporter (IDataConsumer), mirroring the
AzureDevOpsReport structure. Resolves the source file/line from the
exception stack trace relative to GITHUB_WORKSPACE (or the .git root),
skipping MSTest assertion-implementation frames, and falls back to a
title-only annotation when no location is available.

Adds the --report-gh-annotations on|off knob (default on) and a shared
GitHubActionsFeature activation helper. Includes unit tests for the
annotation formatting/escaping and option validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add GitHubActionsSummaryReporter that collects per-test outcomes and, at
session end, appends a markdown roll-up (totals table, failures list,
slowest tests) to the file named by GITHUB_STEP_SUMMARY, mirroring the
AzureDevOpsSummaryReporter structure. Adds the --report-gh-step-summary
on|off knob (default on) plus unit tests for the markdown shape.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add GitHubActionsSlowTestReporter that tracks in-progress tests and, on a
1s scan loop with exponential backoff, emits a ::notice workflow command
for any test still running past a threshold (default 60s), mirroring the
AzureDevOpsSlowTestReporter. Adds the --report-gh-slow-test-notices on|off
knob (default on) and a --report-gh-slow-test-threshold seconds option,
plus deterministic ScanOnce-driven unit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update PACKAGE.md to describe failure annotations, the job summary, and
slow-test notices alongside log groups, with a table of all --report-gh
options. Minor test cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In CI the terminal output device uses SimpleAnsi mode and emits a color
reset ('ESC[m') without a trailing newline after the colored failed-test
block. The failure annotation, emitted immediately after via the same
output device, inherited that dangling reset as a line prefix ('ESC[m::error
...'). GitHub only recognizes a workflow command when the line begins with
'::', so the annotation was silently dropped (groups and notices are emitted
at clean line boundaries and were unaffected).

Emit the annotation on a fresh line so '::error' always starts at column 0.
Verified end-to-end via the gh-report-validation harness: the failure
annotation now surfaces in the GitHub Actions Annotations panel and on the
file's diff gutter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The property was set twice in the same PropertyGroup; keep the single
copy with the descriptive comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 08:30

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

Adds a new Microsoft.Testing.Extensions.GitHubActionsReport extension (parallel to AzureDevOpsReport) that emits GitHub Actions workflow commands to improve CI UX (log grouping, ::error annotations, step summary markdown, and slow-test ::notice messages). It also wires the extension into the solution and unit-test project, and updates packaging behavior in TestFramework.Extensions.

Changes:

  • Introduces the new GitHub Actions report extension package (reporters, command-line options, resources, packing hooks, PublicAPI).
  • Adds unit tests covering escaping, CLI validation, group emission, annotations, markdown summary shape, and slow-test notices.
  • Updates solution/project wiring and adds pack-time adjustment logic for analyzer dependency handling.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
TestFx.slnx Adds the new GitHub Actions extension project to the solution.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj References the new extension project for unit testing.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsSummaryReporterTests.cs Tests markdown step-summary generation (totals, failures, slowest tests).
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsSlowTestReporterTests.cs Tests slow-test notice formatting, thresholding, and backoff behavior.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsReporterTests.cs Tests GitHub Actions group command emission and enablement logic.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsEscaperTests.cs Tests escaping rules for workflow command data/properties.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsCommandLineProviderTests.cs Tests CLI option validation behavior for on/off and thresholds.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/GitHubActionsAnnotationReporterTests.cs Tests ::error annotation construction and escaping, with/without source location.
src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj Adds pack-time tweak intended to ensure MSTest analyzers flow to consumers without running during repo build.
src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj Grants InternalsVisibleTo for the new extension.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Microsoft.Testing.Extensions.GitHubActionsReport.csproj New extension project definition + packing layout + platform reference.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsExtensions.cs Registers reporters and CLI provider on the test application builder.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsFeature.cs Centralizes master/knob enablement rules (env + --report-gh + --report-gh-*).
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsReporter.cs Emits per-assembly ::group:: / ::endgroup::.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsAnnotationReporter.cs Emits ::error ...::... failure annotations with optional file/line resolution.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsSummaryReporter.cs Appends step summary markdown to GITHUB_STEP_SUMMARY.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsSlowTestReporter.cs Emits ::notice for long-running tests with exponential backoff.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsEscaper.cs Implements GitHub workflow-command escaping rules.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsCommandLineProvider.cs Defines CLI options and validation for the extension’s features.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsCommandLineOptions.cs Declares option names and defaults.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/GitHubActionsRepositoryRoot.cs Resolves workspace/git root to convert absolute paths into repo-relative annotation paths.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/TestNodeIdentity.cs Resolves stable test identity (FQN property fallback to DisplayName).
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/TargetFrameworkMonikerHelper.cs Computes a short TFM/moniker for display.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/TestingPlatformBuilderHook.cs MSBuild hook entry point for adding the extension at build time.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/buildMultiTargeting/Microsoft.Testing.Extensions.GitHubActionsReport.props Declares the MSBuild builder hook item for multi-targeting.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/build/Microsoft.Testing.Extensions.GitHubActionsReport.props Imports multi-targeting props for build/TFM-specific consumption.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/buildTransitive/Microsoft.Testing.Extensions.GitHubActionsReport.props Imports multi-targeting props transitively.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/BannedSymbols.txt Enforces testability conventions (IClock/ITask/RoslynString, etc.).
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/PACKAGE.md Package documentation and CLI options.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/PublicAPI/PublicAPI.Shipped.txt Initializes shipped public API baseline.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/PublicAPI/PublicAPI.Unshipped.txt Declares new public API surface for the extension.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/GitHubActionsResources.resx Adds localized resource strings for CLI/help/error messages.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.cs.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.de.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.es.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.fr.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.it.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.ja.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.ko.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.pl.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.pt-BR.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.ru.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.tr.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.zh-Hans.xlf Generated XLF for localization.
src/Platform/Microsoft.Testing.Extensions.GitHubActionsReport/Resources/xlf/GitHubActionsResources.zh-Hant.xlf Generated XLF for localization.

Comment on lines +103 to +107
<Target Name="_UnprivatizeAnalyzersForPack" BeforeTargets="_GetPackageDependencies">
<ItemGroup>
<PackageReference Update="MSTest.Analyzers" PrivateAssets="none" />
</ItemGroup>
</Target>
azat-msft and others added 3 commits July 1, 2026 12:44
…mpositeExtensionFactory

The log-group GitHubActionsReporter is only registered under one host hook (AddTestSessionLifetimeHandler), so wrapping it in a CompositeExtensionFactory provided no benefit -- that factory only matters for extensions registered under multiple hooks that must share a single instance (the summary and slow-test reporters). Register it directly, matching the GitHubActionsAnnotationReporter and the AzureDevOpsReporter precedent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file's MSTest.Analyzers PackageReference + _UnprivatizeAnalyzersForPack target were an accidental leftover unrelated to the GitHub Actions extension. They duplicated the existing MSTest.Analyzers.Package ProjectReference already present upstream (which correctly flows analyzer/build assets to consumers via PrivateAssets=none ExcludeAssets=compile;runtime), and the added block was buggy (ExcludeAssets=all would leak into the nuspec and block analyzer flow). Restore the file to match microsoft/main.

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

Copy link
Copy Markdown
Member

Review remarks

Nice work — escaping, slow-test threading, and localization all look solid. Collecting the remaining points from my pass below (the multi-assembly dotnet test output-forwarding topic is intentionally left out — we'll handle that separately). Grouped by severity.


Major

1. No help/info acceptance coverage for the new options
HelpInfoAllExtensionsTests generates the AllExtensionsInfoTest.csproj asset with a fixed <ItemGroup> of extension PackageReferences, and Microsoft.Testing.Extensions.GitHubActionsReport isn't in that list. So the provider never loads in that host, --report-gh* never renders, and the golden --help/--info expectations keep matching — the tests pass only because the options are absent, i.e. there's zero coverage for them. Fix is two-part: add the package to the asset and add the six options to both the --help and --info expectation blocks (kept alphabetical). (Side note: VideoRecorder is in the same situation — has a CLI provider but isn't in the asset — whereas AzureFoundry/PackagedApp/Telemetry are absent but add no options, so those are harmless.)

2. GitHubActionsAnnotationReporter.ConsumeAsync lacks the defensive try/catch its siblings have
GitHubActionsSlowTestReporter and GitHubActionsSummaryReporter wrap their per-node work in try/catch (log a warning, keep going). ConsumeAsync in the annotation reporter doesn't, and it can throw on user-influenced data:

  • TestNode.Properties.SingleOrDefault<TestNodeStateProperty>() throws InvalidOperationException if a node ever carries more than one state property — prefer FirstOrDefault.
  • source-location resolution / IFileSystem.ExistFile(...) can throw on a malformed path.

An exception here propagates into the platform's data-consumer dispatch instead of degrading to "no annotation for this test". Please mirror the sibling consumers' try/catch + LogWarning.


Moderate

3. GITHUB_STEP_SUMMARY concurrent-writer hazard
GitHubActionsSummaryReporter opens the summary file with FileMode.Append, FileAccess.Write, FileShare.Read. When several assemblies run in the same job/step (a multi-project dotnet test over one solution), they append to the same file concurrently; FileShare.Read denies other writers, so it throws IOException → caught → the summary is silently dropped with only a warning. The AzDo sibling avoids this by writing each run to a uniquely-named file. Suggest FileShare.ReadWrite + a short bounded retry on IOException (or a cross-process mutex), or at minimum document the single-assembly-per-step assumption.

4. TargetFrameworkMonikerHelper.cs duplicates a shared helper instead of linking it
src/Platform/SharedExtensionHelpers/TargetFrameworkMonikerHelper.cs already exists and the AzDo project links it (<Compile Include="$(RepoRoot)src\Platform\SharedExtensionHelpers\TargetFrameworkMonikerHelper.cs" .../>). This project copies it instead. Please delete the copy and link the shared file. (TestNodeIdentity.cs being copied is consistent with AzDo keeping its own copy — acceptable, though a future shared helper would be nicer.)

5. Brittle, checkout-coupled annotation test assertions
GitHubActionsAnnotationReporterTests hard-codes line=19 / line=40 — the positions of the throw statements in the test file itself — and resolves the source path via GitHubActionsRepositoryRoot.FindGitRoot() against the real checkout. Any edit to the top of the file shifts those numbers, and a relocated/packaged layout breaks source resolution. Suggest computing the expected line dynamically ([CallerLineNumber] or search-for-throw) and injecting a fake IFileSystem/git-root so the test doesn't depend on physical repo layout.

6. Not wired into the MSTest.Sdk AllMicrosoft profile
AzureDevOpsReport is auto-referenced under TestingExtensionsProfile == 'AllMicrosoft' via EnableMicrosoftTestingExtensionsAzureDevOpsReport (ClassicEngine.targets, with the matching VSTest.targets guard and NativeAOT.targets warning). There's no equivalent EnableMicrosoftTestingExtensionsGitHubActionsReport wiring, so MSTest.Sdk users on the "all Microsoft extensions" profile get AzDo reporting but not GitHub Actions reporting. If deferring is intended, could you file a follow-up issue; otherwise add the parallel Enable…/version/PackageReference block in the three targets files.

7. Group ::endgroup:: ordering guard dropped vs. the AzDo sibling
AzureDevOpsLogGroupReporter deliberately also implements IDataConsumer (no-op ConsumeAsync) and guards with a _groupOpened flag so ::endgroup:: is ordered into the consumer phase and provably wraps all output. GitHubActionsReporter implements only ITestSessionLifetimeHandler, emits ::endgroup:: unconditionally (no guard, no try/catch in OnTestSessionStartingAsync), and relies on registration order. In practice it's probably fine here (annotations emit during ConsumeAsync before session-finishing; the summary writes to a file; slow notices stop mid-session), but the sibling's intentional engineering was silently dropped — either mirror the pattern or add a comment explaining why the simpler ordering is sufficient.


Low / nit

8. GitHubActionsRepositoryRoot.s_cachedGitRoot is process-static, written without synchronization and never reset. Benign (idempotent, derived from a constant base dir) but it's mutable static state touched directly by unit tests — consider computing per-instance or documenting the intentional process-lifetime cache.

9. No docs/Changelog-Platform.md entry for the new package — add one when it's ready to ship.

10. GetThresholdSeconds in the slow-test reporter re-parses/validates the threshold already validated by the command-line provider. Minor DRY — consider passing the parsed value through.

11. AzDo links RootFinder.cs for git-root discovery; this package hand-rolls GitHubActionsRepositoryRoot.FindGitRoot(). If the semantics match, reuse RootFinder; if they differ, a one-line comment on why would help.

azat-msft and others added 3 commits July 1, 2026 17:21
Register the Microsoft.Testing.Extensions.GitHubActionsReport package in the AllExtensionsInfoTest fixture and add its six --report-gh* options to both the --help and --info expected output blocks in HelpInfoAllExtensionsTests. Verified with build.cmd -pack + the acceptance test (9/9 passing).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wire Microsoft.Testing.Extensions.GitHubActionsReport into the MSTest.Sdk AllMicrosoft profile, mirroring AzureDevOpsReport: default-enable property + conditional PackageReference/PackageVersion in ClassicEngine.targets, a VSTest unsupported-option guard, and a NativeAOT unsupported warning. Extend SdkTests with a per-extension selectively-enabled row and add --report-gh to the EnableAll command line.

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

The GitHubActionsReport extension carried its own copies of TargetFrameworkMonikerHelper and TestNodeIdentity that duplicated logic already present in (or alongside) SharedExtensionHelpers. Merge them into src/Platform/SharedExtensionHelpers so both AzureDevOpsReport and GitHubActionsReport share one implementation:

- TargetFrameworkMonikerHelper: the two divergent methods are merged under distinct names -- GetTargetFrameworkMonikerIncludingPlatform (existing shared behavior) and GetTargetFrameworkMonikerWithRuntimeFallback (former GitHub behavior); all call sites repointed with behavior preserved.

- TestNodeIdentity: the two copies were identical, so they collapse to a single shared GetTestName; the AzureDevOpsReport copy is moved to the shared folder and the GitHub copy deleted, with the shared file compile-linked into both extensions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 16:07

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

Copilot reviewed 57 out of 57 changed files in this pull request and generated 4 comments.

azat-msft and others added 3 commits July 1, 2026 19:22
…s-report

# Conflicts:
#	src/Platform/SharedExtensionHelpers/TestNodeIdentity.cs
…perimental and pack as 1.0.0-alpha

Task 1 - Split slow-test reporter into shared + pipeline-specific:
- Extract the common plumbing (in-progress tracking, background scan loop,
  exponential backoff, session lifecycle) into
  SharedExtensionHelpers/SlowTestReporterBase.cs, linked into both the Azure
  DevOps and GitHub Actions report extensions. Each host now only supplies
  IsEnabled, GetTestName, threshold resolution, an optional activation gate,
  and the host-specific line rendering.

Task 2 - Make the GitHub Actions reporter API experimental:
- Mark GitHubActionsExtensions with [Experimental("TPEXP")] and flag the
  matching PublicAPI entries with [TPEXP], mirroring JUnitReport.

Task 3 - Pack Microsoft.Testing.Extensions.GitHubActionsReport as 1.0.0-alpha:
- Add version-prefix/prerelease-label properties (Directory.Build.props),
  wire them through the csproj, MSTest.Sdk.csproj template properties and
  Sdk.props.template, and drop the CommonVersion default in
  ClassicEngine.targets, mirroring JUnitReport.

Merge fix - Resolve TestNodeIdentity cross-assembly ambiguity introduced by
merging main (which added AzureDevOpsTestNodeIdentityTests) with the branch's
shared-namespace TestNodeIdentity consolidation: give GitHubActionsReport its
own TestNodeIdentity so the shared type is not duplicated across two
test-visible assemblies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…n in acceptance tests

The GitHubActionsReport project was present in TestFx.slnx and wired into the
MSTest SDK / acceptance tests, but was missing from the solution filters the
CI builds and packs from (Microsoft.Testing.Platform.slnf, NonWindowsTests.slnf),
so the package was never produced. This caused NU1101 (package not found) in the
HelpInfoAllExtensionsTests and MSTestSdk acceptance assets.

- Add Microsoft.Testing.Extensions.GitHubActionsReport to both solution filters
  (alongside AzureDevOpsReport) so it gets built and packed in CI.
- Because the package now ships as 1.0.0-alpha (not the platform common version),
  reference it via a dedicated $MicrosoftTestingExtensionsGitHubActionsReportVersion$
  placeholder read from the packed nupkg (mirroring JUnitReport/CtrfReport),
  instead of $MicrosoftTestingPlatformVersion$.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 18:50

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

Copilot reviewed 67 out of 67 changed files in this pull request and generated 3 comments.

azat-msft and others added 8 commits July 1, 2026 23:44
…crosoft#2)

- Wrap per-node work in try/catch + LogWarning, mirroring the sibling
  GitHubActionsSlowTestReporter/GitHubActionsSummaryReporter so a failure while
  building/emitting an annotation (e.g. a malformed stack-trace path making
  IFileSystem.ExistFile throw) degrades to "no annotation for this test" instead
  of propagating into the platform's data-consumer dispatch.
- Use FirstOrDefault instead of SingleOrDefault for the test-node state so a
  malformed node carrying multiple state properties does not throw.
- Drop the dead testDisplayName parameter and compute GetTestName once.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…iew microsoft#7)

GitHubActionsReporter previously implemented only ITestSessionLifetimeHandler and
emitted ::endgroup:: unconditionally, relying purely on registration order. Mirror
the deliberate engineering of AzureDevOpsLogGroupReporter:
- Also implement IDataConsumer with a no-op ConsumeAsync so OnTestSessionFinishingAsync
  runs in the consumer phase (after producer-only handlers), and register it last as a
  data consumer so the closing ::endgroup:: wraps all other reporters' output.
- Add a _groupOpened flag so ::endgroup:: is only emitted when a matching ::group:: was
  opened, and wrap both lifecycle callbacks in try/catch + LogWarning.

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

The known-extension registration acceptance test covered AzureDevOpsReport but not
the new GitHubActionsReport, leaving the extension's MSBuild self-registration hook
unvalidated. Add it (alphabetically): the package reference + version patch in the
generated asset, a --report-gh --help assertion, and an assertion that
Microsoft.Testing.Extensions.GitHubActionsReport.TestingPlatformBuilderHook.AddExtensions
is emitted into the generated SelfRegisteredExtensions source.

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

The two source-location tests hard-coded the physical line numbers of their throw
statements (line=19/40) and relied on the real repo checkout + SystemFileSystem, so
any edit above the throws or a relocated/packaged layout would break them.

- Compute the throw line dynamically via a CaptureException helper + [CallerLineNumber]
  so edits elsewhere in the file no longer shift a hard-coded expectation.
- Inject a mock IFileSystem (every file "exists") so resolution no longer depends on
  the source file physically being present.
- Assert the resolved file suffix / line / escaping instead of a full checkout-coupled
  absolute path.

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

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eview microsoft#8)

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

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…iew microsoft#10)

The slow-test threshold is validated by the command-line provider and re-read here.
Document that this mirrors the sibling AzureDevOpsSlowTestReporter (which reads its
options straight from ICommandLineOptions) rather than threading a parsed value
through, keeping the two reporters consistent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
azat-msft added a commit to azat-msft/gh-report-validation that referenced this pull request Jul 1, 2026
The extension is now packed as an experimental 1.0.0-alpha package (1.0.0-dev in dev
builds) instead of following the platform version, matching the finalized PR
microsoft/testfx#9541. Refresh the locally-built packages and bump the extension
reference from 2.3.0-dev to 1.0.0-dev.
azat-msft and others added 3 commits July 2, 2026 12:16
… requirement

The extension now requires BOTH GITHUB_ACTIONS=true and the --report-gh master switch
to be enabled. Seed the master switch in the GitHubActionsReporter/SlowTestReporter test
helpers so the "enabled" tests reflect the new precondition (the env/knob behavior is
exercised on top of it).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eview microsoft#11)

Instead of duplicating the git-root walk, FindGitRoot now calls the shared
Microsoft.Testing.TestInfrastructure.RootFinder.Find() (linked into the project, as the
Azure DevOps extension already does) and translates its InvalidOperationException into
null so a reporter running outside a git checkout still degrades to "no source location".

Because RootFinder is now compiled into both the AzureDevOpsReport and GitHubActionsReport
assemblies (both InternalsVisibleTo the extensions unit tests), the unqualified RootFinder
reference in the GitHub test files becomes ambiguous. Expose the GitHubActionsReport
reference under a `ghactions` extern alias and qualify the GitHub test files' usings so the
AzureDevOps tests keep binding to their copy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 2, 2026 11:00
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.

New extension: Microsoft.Testing.Extensions.GitHubActionsReport (groups, annotations, step summary)

3 participants