Skip to content

Add opt-in Helix work item batching#16913

Open
mmitche wants to merge 2 commits into
mainfrom
helix-work-item-batching
Open

Add opt-in Helix work item batching#16913
mmitche wants to merge 2 commits into
mainfrom
helix-work-item-batching

Conversation

@mmitche
Copy link
Copy Markdown
Member

@mmitche mmitche commented May 28, 2026

Summary

  • add an opt-in Helix SDK task that batches compatible PayloadDirectory work items
  • stage per-member payloads with generated batch runners, manifests, logs, and result collection
  • expose conservative MSBuild/send-to-helix knobs and document the public surface
  • add unit coverage for grouping, pass-through, max batch size, manifests, and shell runner generation

Validation

  • eng\\common\\dotnet.cmd test src\\Microsoft.DotNet.Helix\\Sdk.Tests\\Microsoft.DotNet.Helix.Sdk.Tests\\Microsoft.DotNet.Helix.Sdk.Tests.csproj --no-restore --verbosity minimal

Add a Helix SDK batching task that groups compatible PayloadDirectory work items into staged batch payloads with per-member runners, logs, result collection, and conservative opt-in MSBuild properties.

Document the public batching surface, expose send-to-helix template parameters, and cover grouping, pass-through, timeout, manifest, and shell runner behavior with unit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 28, 2026 17:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds opt-in, submission-time batching of Helix work items so repos sending many short PayloadDirectory/xUnit work items can amortize per-item Helix overhead. A new MSBuild task stages each member's payload under a parent batch directory, generates a shell/cmd runner that executes each command in its own subshell with per-member HELIX_WORKITEM_UPLOAD_ROOT, writes a JSON manifest, and replaces the original HelixWorkItem items with the batch items before CoreTest runs.

Changes:

  • New BatchHelixWorkItems MSBuild task + helix-batching/HelixBatching.targets wired into Microsoft.DotNet.Helix.Sdk.props via _HelixMonoQueueTargets, with EnableHelixWorkItemBatching and related knobs.
  • xUnit/xUnit v3 work item targets re-ordered (BeforeTargets="BatchHelixWorkItems;CoreTest") so generated items are visible to batching; new params flowed through eng/common/core-templates/steps/send-to-helix.yml.
  • Unit tests covering grouping, pass-through, max-batch size, manifests, and POSIX shell runner generation; new sections in Readme.md and SendingJobsToHelix.md.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Microsoft.DotNet.Helix/Sdk/BatchHelixWorkItems.cs New MSBuild task implementing the batching, runner, and manifest generation
src/Microsoft.DotNet.Helix/Sdk/tools/helix-batching/HelixBatching.targets Wires the task before CoreTest, swaps HelixWorkItem items
src/Microsoft.DotNet.Helix/Sdk/tools/Microsoft.DotNet.Helix.Sdk.props Declares defaults, registers BatchHelixWorkItems task, hooks targets via _HelixMonoQueueTargets
src/Microsoft.DotNet.Helix/Sdk/tools/xunit-runner/XUnitRunner.targets Adds BatchHelixWorkItems to BeforeTargets so xUnit items are batched
src/Microsoft.DotNet.Helix/Sdk/tools/xunitv3-runner/XUnitV3Runner.targets Same ordering change for xUnit v3
eng/common/core-templates/steps/send-to-helix.yml Surfaces batching parameters in the AzDO template
src/Microsoft.DotNet.Helix/Sdk.Tests/.../BatchHelixWorkItemsTests.cs Tests for grouping, pass-through, max-size, manifest, and POSIX runner
src/Microsoft.DotNet.Helix/Sdk/Readme.md Documents the new opt-in feature and HelixBatchable knob
Documentation/AzureDevOps/SendingJobsToHelix.md Documents YAML usage of the batching parameters

</ItemGroup>
```

Set `HelixBatchable=false` on a work item or xUnit project that needs machine-level isolation. The initial batching implementation only batches simple `PayloadDirectory` items; archive/URI payloads and items with per-work-item pre/post commands are preserved unchanged.
{
TimeSpan targetDuration = ParseDurationOrDefault(TargetDuration, TimeSpan.FromMinutes(10), nameof(TargetDuration));
TimeSpan timeoutPadding = ParseDurationOrDefault(TimeoutPadding, TimeSpan.FromMinutes(2), nameof(TimeoutPadding));
int maxItemsPerBatch = Math.Max(1, MaxItemsPerBatch);
}
}

private static string EscapePosix(string value) => value.Replace("'", "'\"'\"'");
Comment on lines +22 to +24
EnableHelixWorkItemBatching: false # optional -- batch compatible short Helix work items to reduce per-item overhead
HelixBatchTargetDuration: '00:10:00' # optional -- target aggregate duration per batch
HelixBatchMaxItems: 10 # optional -- maximum original work items per batch
Comment on lines +47 to +51
string batchRoot = Path.GetFullPath(Path.Combine(IntermediateOutputPath, "helix-work-item-batches"));
if (Directory.Exists(batchRoot))
{
Directory.Delete(batchRoot, recursive: true);
}
<Project>

<Target Name="BatchHelixWorkItems"
Condition="'$(EnableHelixWorkItemBatching)' == 'true' and '@(HelixWorkItem)' != ''"
- Use System.Text.Json instead of Newtonsoft.Json in batching tests
- Fix Readme to clarify HelixBatchable=false applies to generated HelixWorkItems
- Honor HelixBatchMinItems=1 instead of silently flooring at 2
- Remove misleading EscapePosix helper (inputs are always safe)
- Expose HelixBatchTimeoutPadding/HelixBatchMinItems in send-to-helix.yml
- Deterministically order BatchHelixWorkItems after all HelixWorkItem producers via AfterTargets
- Replace TargetDuration/TimeoutPadding TimeSpan parsing with integer minutes; remove ParseDurationOrDefault

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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