Skip to content

Port parallel per assembly test running from ServiceControl - #16

Open
rbev wants to merge 2 commits into
mainfrom
run-projects-parallel
Open

Port parallel per assembly test running from ServiceControl#16
rbev wants to merge 2 commits into
mainfrom
run-projects-parallel

Conversation

@rbev

@rbev rbev commented Sep 7, 2026

Copy link
Copy Markdown

Follow up from: Particular/ServiceControl#5783 (comment)

This pull request introduces significant enhancements to the run-tests GitHub Action, most notably adding support for running a subset of projects and enabling parallel execution of test runs. These changes improve flexibility and performance, especially for repositories with large or categorized test suites. Documentation and input parameters have been updated accordingly to reflect the new features and their usage.

Enhancements to test execution:

  • Added support for running an explicit list of projects via the new projects input, allowing users to bypass auto-discovery and specify which test projects to run. This is particularly useful for test suites subdivided by category. (README.md, action.yml, run-tests.ps1) [1] [2] [3]
  • Introduced the max-parallel input to enable concurrent execution of test assemblies (1–16 in parallel), with per-run output buffering and replay for readability. When parallel execution is enabled, reset-script is ignored and a warning is emitted. (README.md, action.yml, run-tests.ps1) [1] [2] [3]

Environment and resource management:

  • Each test run now receives a unique PARTICULAR_RUN_TESTS_ACTION_PARALLEL_INDEX environment variable, allowing consumers to allocate unique resources (e.g., ports or temp directories) per run. (README.md, run-tests.ps1) [1] [2] [3]

Documentation and input updates:

  • Updated the README.md with detailed usage instructions and examples for the new projects and max-parallel features, including guidance on parallel index usage and reset script behavior.
  • Added and documented the new projects and max-parallel inputs in action.yml, and clarified the behavior of reset-script in parallel mode. [1] [2]

Internal refactoring:

  • Refactored run-tests.ps1 to support both sequential (historic) and parallel execution modes, including logic for project selection, framework targeting, and process management. [1] [2] [3]

These changes collectively make the action more powerful and adaptable to complex CI scenarios.

Comment thread run-tests.ps1

$testSdkNodes = Select-Xml -Path $project -XPath "/Project/ItemGroup/PackageReference[@Include='Microsoft.NET.Test.Sdk']"
if ($hasExplicitProjects) {
$projectPaths = $explicitProjectsRaw -Split "`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ }

@danielmarbach danielmarbach Sep 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Out of curiosity, why did you choose newline instead of space? I'm asking because when using command line arguments on CLIs, they are usually space-separated, comma-separated, or a repeated argument, but a new line sounds error-prone across operating systems

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It was a faithful porting of the script in ServiceControl

It should probably be ; like the platforms list

Comment thread action.yml
inputs:
reset-script:
description: 'pwsh expression to be run between test runs to reset infrastructure, if required'
description: 'pwsh expression to be run between test runs to reset infrastructure, if required. Only used when max-parallel is 1; ignored (with a warning) when max-parallel > 1.'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think that is a fair tradeoff

Comment thread run-tests.ps1
$pending = [Collections.Generic.Queue[object]]::new($runs)
$active = [Collections.Generic.List[object]]::new()

while ($pending.Count -gt 0 -or $active.Count -gt 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In the old RavenDB actions I used the foreach with the parallel option but I can't remember what the tradeoffs were.

https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This seems much better than managing a custom loop and some of the drawbacks about how it handles output seem to be overblown as long as you write everything using pipelines.

I'll swap it over tomorrow.

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