Skip to content

Quote --ignore-exit-code values so the quarantine pipeline does not shell-split on Unix#13918

Merged
ViktorHofer merged 2 commits into
mainfrom
fix-quarantine-ignore-exit-code-quoting
Jun 2, 2026
Merged

Quote --ignore-exit-code values so the quarantine pipeline does not shell-split on Unix#13918
ViktorHofer merged 2 commits into
mainfrom
fix-quarantine-ignore-exit-code-quoting

Conversation

@ViktorHofer

Copy link
Copy Markdown
Member

Problem

The scheduled quarantine pipeline (azure-pipelines/quarantine.yml, definition 344) failed on its first real run — build 1445333 — on the Linux and macOS legs with:

error MSB3073: The command "echo ... --ignore-exit-code 8;2 --results-directory ..." exited with code 127.

Root cause

RunQuarantinedTests=true adds --ignore-exit-code 8;2 to the xUnit v3 test command (so a quarantined-only run treats exit code 8 = zero tests ran and 2 = test failures as success — the per-test signal is the published TRX, not the exit code).

Arcade's XUnitV3.Runner.targets assembles the command and runs it via <Exec>, which on non-Windows executes through /bin/sh. The unquoted ; was interpreted by the shell as a command separator, splitting the line into:

  1. <runner> ... --ignore-exit-code 8
  2. 2 --results-directory ...

The second fragment starts with the token 2, which is not a command, so the step failed with exit code 127 (command not found).

Fix

Quote the value: --ignore-exit-code "8;2". This keeps 8;2 as a single argument on both /bin/sh and cmd. 8;2 is the correct semicolon-separated multi-code syntax for Microsoft.Testing.Platform; only the shell-level quoting was missing.

Verified the parse through /bin/sh:

  • unquoted -> 2: command not found
  • quoted -> --ignore-exit-code receives a single arg 8;2

Windows was unaffected (cmd does not treat ; as a command separator), but the quoted form is correct on both.

Follow-up to #13915.

…ll-split on Unix

The scheduled quarantine pipeline (azure-pipelines/quarantine.yml, definition 344)
sets RunQuarantinedTests=true, which adds '--ignore-exit-code 8;2' to the xUnit v3
test command so a quarantined-only run treats exit code 8 (zero tests ran) and 2
(test failures) as success.

Arcade's XUnitV3.Runner.targets runs the assembled command via <Exec>, which on
non-Windows executes through /bin/sh. The unquoted ';' was interpreted as a shell
command separator, splitting the line into '<runner> ... --ignore-exit-code 8' and a
second fragment '2 --results-directory ...'. The latter starts with the token '2',
which is not a command, so the step failed with exit code 127 (MSB3073) on the Linux
and macOS legs (first observed in build 1445333).

Quoting the value keeps '8;2' as a single argument to --ignore-exit-code on both sh
and cmd. Verified the parsing through /bin/sh.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 2, 2026 11:07

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

Updates unit test runner arguments used by the quarantine pipeline to ensure Unix shells don’t split the --ignore-exit-code value on ;, keeping Linux/macOS quarantine legs from failing when invoked via Arcade’s <Exec>.

Changes:

  • Quote the --ignore-exit-code multi-exit-code value as "8;2" when RunQuarantinedTests=true.
  • Expand the inline comment explaining why the quoting is required for /bin/sh execution.
Show a summary per file
File Description
src/Directory.Build.targets Quotes the --ignore-exit-code value for quarantined test runs and documents the shell-splitting rationale.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread src/Directory.Build.targets Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@ViktorHofer ViktorHofer enabled auto-merge (squash) June 2, 2026 11:10

@github-actions github-actions Bot 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.

24/24 dimensions clean — no findings.

Reviewed against all 24 dimensions (backwards compatibility, ChangeWave discipline, performance, test coverage, error messages, logging, string comparison, API surface, target authoring, design, cross-platform correctness, code simplification, concurrency, naming, SDK integration, idiomatic C#, file I/O, documentation, build infrastructure, scope/PR discipline, evaluation model integrity, correctness/edge cases, dependency management, security).

Summary: This is a correct, minimal fix for a real Unix shell-splitting bug in an opt-in CI scenario. The semicolon in 8;2 is a literal character in MSBuild property values and the double quotes are preserved through property expansion into the Exec command string. The added comment is excellent — it documents the "why" and prevents future regressions from well-intentioned quote removal.

Generated by Expert Code Review (on open) for issue #13918 · ● 1.3M

@ViktorHofer ViktorHofer merged commit f6064e2 into main Jun 2, 2026
10 checks passed
@ViktorHofer ViktorHofer deleted the fix-quarantine-ignore-exit-code-quoting branch June 2, 2026 12:16
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.

3 participants