.NET: Python: Add dotnet integration test report to CI#5515
.NET: Python: Add dotnet integration test report to CI#5515
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds CI visibility for .NET integration test outcomes by publishing JUnit XML from the existing dotnet-test matrix legs and reusing the existing Python trend-aggregation script to generate a Job Summary report with cached history.
Changes:
- Update the .NET integration test step to emit JUnit XML into a dedicated
IntegrationTestResults/directory and upload those XML files as per-matrix artifacts. - Add a new
dotnet-integration-test-reportjob that downloads the artifacts, aggregates them into a trend report, posts it to the GitHub Actions Job Summary, and caches history. - Refactor
python/scripts/flaky_report/aggregate.pyto discover bothpytest.xmland*.junit.xml, derive dotnet “provider” labels, and avoid nodeid collisions across providers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
python/scripts/flaky_report/aggregate.py |
Extends report discovery/parsing to support dotnet xUnit JUnit XML and multi-provider collision handling. |
.github/workflows/dotnet-build-and-test.yml |
Generates/uploads dotnet integration JUnit XML and adds a reporting job to aggregate and publish a trend report. |
| run: | ||
| working-directory: python | ||
| steps: | ||
| - uses: actions/checkout@v6 |
There was a problem hiding this comment.
In this workflow, other checkout steps explicitly set persist-credentials: false to avoid leaving the GITHUB_TOKEN credentials in the local git config. This new job’s checkout doesn’t set it, so credentials will persist by default. Consider adding with: persist-credentials: false here for consistency and to reduce the blast radius of any later step that might invoke git.
| - uses: actions/checkout@v6 | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false |
| # Use provider-qualified key when the same test runs under | ||
| # multiple providers (e.g. dotnet net10.0 vs net472). This | ||
| # prevents later results from silently overwriting earlier ones. | ||
| raw_id = test["nodeid"] | ||
| key = raw_id | ||
| if key in combined_results and combined_results[key]["provider"] != provider: | ||
| # Collision: re-key existing entry and use qualified key for new one | ||
| existing = combined_results.pop(key) | ||
| combined_results[f"{existing['provider']}::{raw_id}"] = existing | ||
| key = f"{provider}::{raw_id}" | ||
| elif f"{provider}::{raw_id}" in combined_results: | ||
| # Provider-qualified key already exists (previous collision) | ||
| key = f"{provider}::{raw_id}" | ||
|
|
There was a problem hiding this comment.
The nodeid collision handling here is order-dependent when the same raw_id appears under 3+ providers in a single run. After the first collision, the unqualified raw_id key is removed, so a later provider can reintroduce the unqualified key (because key in combined_results is false), which makes run-to-run keys unstable and can skew trend history. Consider always keying results as f"{provider}::{raw_id}" (or track a collided_raw_ids set and always use qualified keys once any collision is detected for that raw_id).
| "# 🔬 Integration Test Report", | ||
| "", | ||
| f"*Generated: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}*", |
There was a problem hiding this comment.
This changes the report header from “Flaky Test Report” to “Integration Test Report” for all consumers of this script, including the existing Python CI jobs that are still named “Flaky Test Report” and upload artifacts like flaky-test-report.md. To avoid confusion, either keep the original heading for the Python flaky report, or make the title configurable (e.g., via a CLI arg/env var) and set it appropriately from each workflow.
- Add --report-junit flag to dotnet integration test step to generate
JUnit XML alongside TRX, with explicit --results-directory to
centralize output in IntegrationTestResults/
- Upload JUnit XML artifacts from each matrix leg (net10.0/ubuntu,
net472/windows) as dotnet-test-results-{framework}-{os}
- Add dotnet-integration-test-report job that downloads artifacts,
runs the existing aggregate.py script, posts markdown to Job Summary,
and saves trend history via actions/cache
- Refactor aggregate.py to discover JUnit XML files recursively,
supporting both pytest (pytest.xml) and xunit (*.junit.xml) layouts
- Handle provider name derivation for dotnet artifact naming convention
- Fix nodeid collision when same test runs under multiple frameworks
by qualifying keys with provider when collisions are detected
- Improve module extraction for dotnet C# classnames (recognizes
IntegrationTests/UnitTests namespace segments)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
584a2ae to
450eab4
Compare
xUnit v3 generates files with .junit extension, not .junit.xml. Update upload glob and aggregate.py discovery to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Always prefix dotnet test keys with provider (e.g. net10.0 (ubuntu)::TestName) to ensure stable, comparable counts across runs regardless of file parse order. Also show Executed (passed+failed) instead of Total in summary table. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Dotnet tests run on multiple frameworks (net10.0, net472). Instead of one combined table with unstable totals, show separate sections per framework — each with its own summary row and per-test table. Python reports retain the original single-table format. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Motivation and Context
Add visibility into dotnet integration test results across CI runs, mirroring the Python integration test report already in place.
Description
Changes
*Workflow: \dotnet-build-and-test.yml*
et10.0/ubuntu,
et472/windows)
*Script: \python/scripts/flaky_report/aggregate.py*
Architecture
\
dotnet-test (net10.0/ubuntu) ──┐
├──> dotnet-integration-test-report
dotnet-test (net472/windows) ──┘ (downloads JUnit XML artifacts,
runs aggregate.py, posts to
Job Summary, caches history)
\\
The report job:
Key design decisions
Checklist