Skip to content

[release/8.0] Helix reporter: add portable JSON output (#16774) - #17383

Open
wfurt wants to merge 1 commit into
release/8.0from
backport/16774-to-release/8.0
Open

[release/8.0] Helix reporter: add portable JSON output (#16774)#17383
wfurt wants to merge 1 commit into
release/8.0from
backport/16774-to-release/8.0

Conversation

@wfurt

@wfurt wfurt commented Aug 21, 2026

Copy link
Copy Markdown
Member

Backport of #16774 to release/8.0.

Description

The current format uses Python's Pickle that is not portable. The reporter also depends on helix scripts that may or may not be present anymore. This change preserves the existing Pickle serialization when possible but makes it optional. It adds portable JSON serialization that can be consumed by anyone in any language.

Copilot AI lite review requested due to automatic review settings August 21, 2026 19:45

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 portable JSON test-result output while retaining legacy pickle reporting when helix-scripts is available.

Changes:

  • Adds compatibility types and a versioned JSON reporter.
  • Makes Helix imports optional across parsers and runner.
  • Documents the JSON schema and file location.

Reviewed changes

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

Show a summary per file
File Description
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/test_results_reader/init.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/RESULTS_FORMAT.md Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/formats/xunit.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/formats/trx.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/formats/result_format.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/formats/junit.py Updated as part of this pull request.
src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/_helix_compat.py Updated as part of this pull request.
Suppressed comments (4)

src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/RESULTS_FORMAT.md:17

  • Although _results_dir() falls back to the current directory, run.py still calls get_env("HELIX_WORKITEM_UPLOAD_ROOT") before reaching JsonReporter. Thus the documented ad-hoc invocation with HELIX_WORKITEM_ROOT unset and no upload-root variable exits without writing the promised cwd file. Make that environment variable optional for this path or remove the ad-hoc fallback claim.
If `HELIX_WORKITEM_ROOT` is unset (e.g. ad-hoc local invocation), the
file is written to the current working directory.

src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/_helix_compat.py:167

  • When no XML files are found and _commandExitCode is 0, read_results emits the synthetic pass whose failure_message is built as u'{}'.format(None), i.e. the string "None". This serializer therefore emits a non-null failure message for a passing result, contradicting the schema and potentially confusing consumers; fix the synthetic result or normalize this value before serialization.
            "failure_message": self._failure_message,

src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py:103

  • read_results is a generator, and the legacy reporter consumes all_results at line 89. Consequently, on machines with helix-scripts installed this call receives an exhausted iterator and writes results: [], so the new JSON output loses every parsed test. Materialize the results once before passing them to both reporters, while preserving the existing None filtering.
        _helix_compat.JsonReporter(azdo_parameters, log=log).report_results(all_results)

src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py:103

  • The new documentation recommends emitting __test_report_v2.json directly and says the reporter is a no-op when that file already exists, but read_results only discovers the XML formats and this call unconditionally rewrites the JSON file. A direct producer's results are therefore discarded (or replaced by the synthetic no-results result); either implement loading/preserving the existing JSON or remove this recommendation.
        _helix_compat.JsonReporter(azdo_parameters, log=log).report_results(all_results)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +34 to +37
Recommended use: write `__test_report_v2.json` to `$HELIX_WORKITEM_ROOT`
from your test runner's own reporting hook, then either omit
`EnableAzurePipelinesReporter` or let it run — the reporter is a no-op
on a missing/empty results XML when the JSON file already exists.
Comment on lines +257 to +258
with open(path, "w", encoding="utf-8") as f:
json.dump(payload, f, ensure_ascii=False)
Comment on lines +90 to +91
except Exception:
log.exception("Legacy pickle reporter failed; continuing to write JSON results")
@wfurt
wfurt requested a review from mmitche August 24, 2026 17:42
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.

2 participants