Skip to content
Merged
12 changes: 12 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"microsoft.dotnet.helix.jobmonitor": {
"version": "11.0.0-beta.26458.103",
"commands": [
"dotnet-helix-job-monitor"
]
}
}
}
19 changes: 19 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ parameters:
type: boolean
default: false

variables:
# This entrypoint has one implicit stage. Keep asynchronous sends paired with its monitor.
- name: EnableHelixJobMonitor
value: true
Comment thread
LoopedBard3 marked this conversation as resolved.
# Matrix legs share a phase and queue. Keep their monitor identities distinct across channels.
- name: TestRunNamePrefix
value: '$(Agent.JobName)_'

@akoeplinger akoeplinger Sep 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

none of your workitems today upload test results into AzDO so this doesn't seem to be necessary

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My agent ended up finding another place that this was important (copilot response):
"""
This isn’t needed for naming uploaded benchmark results; it addresses the monitor’s job identity bookkeeping. Even when work items don’t upload TRX/xUnit results, the pinned monitor uses TestRunName as a fallback in its logical stream key, alongside the stage, submitter phase, and queue.

The SDK channel matrix shares a phase and queue across independent legs such as main, 9.0, and 8.0. Without the prefix, they also share the queue-only TestRunName, so the monitor groups them as incarnations of the same stream rather than tracking each independently. We hit this in run 3072829: 88 submissions collapsed into 31 logical streams, and 51 job-processing records had zero work items.

With the matrix-expanded Agent.JobName prefix, run 3073057 tracked all 89 submitted jobs and 304 work items, with no zero-work-item processing records. Local checks against the pinned monitor binary also confirmed that retries of the same leg still group correctly. So I’d keep this for completion/failure tracking, independently of whether the workload produces test-result files.
"""

Looking at the jobs, this did seem to be a real finding so I am leaning toward keeping the TestRunNamePrefix for now. Can you let me know if you think this is unexpected or if you know there is a different, more correct approach? Otherwise, I will keep this in for now for the properly broken out workitems in the monitor.

- template: /eng/common/templates/variables/pool-providers.yml
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
# The standalone monitor does not inherit the submitter jobs' variable groups.
- group: DotNet-HelixApi-Access
Comment thread
LoopedBard3 marked this conversation as resolved.

resources:
containers:
- container: ubuntu_x64_build_container
Expand Down Expand Up @@ -67,3 +79,10 @@ jobs:
jobParameters:
${{ if parameters.onlySanityCheck }}:
onlySanityCheck: true

- template: /eng/common/core-templates/job/helix-job-monitor.yml
parameters:
timeoutInMinutes: 360
helixAccessToken: ${{ iif(eq(variables['System.TeamProject'], 'internal'), '$(HelixApiAccessToken)', '') }}
# Manual runs can legitimately select no workloads.
allowNoHelixJobs: true
Comment thread
Copilot marked this conversation as resolved.
Outdated
41 changes: 41 additions & 0 deletions docs/sdk-scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,47 @@ An introduction of how to run scenario tests can be found in [Scenarios Tests Gu

- [SDK Build Throughput Scenario](#sdk-build-throughput-scenario)

## SDK performance pipeline

The repository's [azure-pipelines.yml](../azure-pipelines.yml) entrypoint uses
[sdk-perf-jobs.yml](../eng/pipelines/sdk-perf-jobs.yml) for SDK-based scenario and
benchmark jobs. It backs the internal `dotnet-performance` pipeline (definition 306)
and the public `performance-ci` pipeline (definition 38).

The entrypoint always enables asynchronous submission and includes the standalone
Helix Job Monitor, its pool provider, and its parameters, including on public and PR
runs. The monitor runs alongside submitters in the same implicit stage, waits for
their Helix work items, and reports failures to Azure DevOps. The existing manual
job-selection parameters and schedules are unchanged: public runs always select
correctness jobs, while internal manual runs can select no workloads. Such runs still
include the monitor and may succeed without Helix jobs (`allowNoHelixJobs: true`).
This permits an empty stage; it does not suppress submitter or work-item failures.

The monitor job has a six-hour timeout (355 minutes for the tool, leaving five minutes
for it to exit). Existing 320-minute submitter limits and Helix work-item timeouts are
unchanged. These limits start when the respective job runs; they are not a whole-run
wall-clock deadline that includes time waiting for agents.

Internal runs, including internal PR runs, import `DotNet-HelixApi-Access`. The
always-present token parameter uses a compile-time expression to select its token
macro for the internal project and an empty string otherwise. Public runs, including
public PR runs, therefore use anonymous Helix access, not an unresolved private-token
Comment thread
Copilot marked this conversation as resolved.
Outdated
variable. Azure DevOps timeline access and result reporting still use the job's
`System.AccessToken`. The tool is restored from
`.config/dotnet-tools.json` in its own checkout; `eng/Version.Details.xml` tracks that
pin alongside the Helix SDK.

Monitor test-run names include the matrix-expanded job display name. This keeps
different channels in the same phase and Helix queue independent while preserving a
stable identity when the same leg is retried.

Submitter build logs still use the existing `Logs_*` pipeline artifacts. Benchmark
results and diagnostics are still uploaded from the Helix work items to PerfLab and
Helix, respectively. The monitor reports test results and links to Helix consoles; it
does not download arbitrary Helix uploads into pipeline artifacts. Asynchronous sends
skip the submitter's `artifacts/helix-results` downloads, which were not published by
this pipeline. Local `--send-to-helix` runs still wait and download performance reports.

## SDK Build Throughput Scenario

**SDK Build Throughput** is a scenario test that measures the throughput of SDK build process. To be more specific, our test *implicitly calls*
Expand Down
4 changes: 4 additions & 0 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>bcd0a2de8927de44b65f3ad41bef8820ee2b3d0b</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.JobMonitor" Version="11.0.0-beta.26458.103">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>bcd0a2de8927de44b65f3ad41bef8820ee2b3d0b</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XHarness.CLI" Version="11.0.0-prerelease.26458.2">
<Uri>https://github.com/dotnet/xharness</Uri>
<Sha>1665037768fd7eec44e046d94fd07b8c6407c966</Sha>
Expand Down
Empty file modified eng/common/dotnet.sh
100644 → 100755
Empty file.
Loading