Skip to content

fix: missing vstest outcomes, TestProjectDirectory heuristic, xmlns fallback#47

Merged
BenjaminMichaelis merged 20 commits into
mainfrom
benjaminmichaelis/trex-trxlib-bug-analysis
May 17, 2026
Merged

fix: missing vstest outcomes, TestProjectDirectory heuristic, xmlns fallback#47
BenjaminMichaelis merged 20 commits into
mainfrom
benjaminmichaelis/trex-trxlib-bug-analysis

Conversation

@BenjaminMichaelis
Copy link
Copy Markdown
Owner

@BenjaminMichaelis BenjaminMichaelis commented May 17, 2026

Summary

Bug A — Unknown vstest outcomes silently mapped to NotExecuted

Root cause: The outcome switch in TrxParser had _ => TestOutcome.NotExecuted as its default, so real vstest outcomes like Aborted, Disconnected, Warning, Error, NotRunnable, PassedButRunAborted, and InProgress were all silently lost.

Fix:

  • Added 7 new values to TestOutcome enum with XML docs
  • Wired all of them in the parser switch

Aborted is semantically distinct from NotExecuted — a test that was running and stopped mid-run is not the same as one that was deliberately skipped.

Bug C — Hardcoded 3-level parent walk for TestProjectDirectory

Root cause: The parser walked exactly 3 levels up from the DLL path to derive TestProjectDirectory, hard-coding the assumption of a bin\Debug\<TFM>\ layout. Any other layout (e.g. publish\, custom OutputPath, Azure DevOps drop directories) overshoots or undershoots.

Fix: Replaced the loop with FindProjectDirectory, which walks upward from the DLL directory skipping segments whose names match known build-output patterns:

  • Named dirs: bin, obj, debug, release, publish, x86, x64, arm, arm64, anycpu
  • .NET TFM patterns: names starting with net or mono that contain a digit (e.g. net10.0, netcoreapp3.1, net48)

Stops at the first segment that doesn't match — that's the project root.

codeBase Before After
…\bin\Debug\net10.0\Foo.dll …\Foo\ …\Foo\
…\publish\Foo.dll C:\ …\project\

Bug D — No xmlns fallback causes zero results for namespace-free TRX files

Root cause: All child-element lookups used TrxNs + "ElementName". If a TRX file omits xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" on the root, XDocument treats every element as having no namespace, so no lookups match and the parser returns 0 results.

Fix: Detect the effective namespace once at parse time:

var ns = root.Name.Namespace == XNamespace.None ? XNamespace.None : TrxNs;

All child-element lookups now use ns instead of TrxNs. Root attributes (name, id, runUser) were already correct since attributes don't inherit namespace.

Tests

Three regression tests were added to prove each bug before fixing it:

Test Bug Sample TRX
Parse_AbortedOutcomeTrx_AbortedIsNotSilentlyMappedToNotExecuted A aborted-outcome.trx
Parse_PublishedCodeBaseTrx_TestProjectDirectoryIsProjectRoot C published-codebase.trx
Parse_NoNamespaceTrx_ParsesResultsWithoutNamespace D no-namespace.trx

All 55 tests pass.

BenjaminMichaelis and others added 5 commits May 16, 2026 22:07
…net10.0) (#41)

## Summary

Makes TrxLib fully AOT-compatible by replacing `XmlSerializer` with
`XDocument`/`XElement` manual parsing, adding multi-targeting, and
validating with a native AOT smoke-test project in CI.

## Changes

### Library (`TrxLib`)
- **Multi-target**: `netstandard2.1;net8.0;net10.0` — keeps backward
compatibility while enabling `IsAotCompatible=true` on net8.0+
- **Parser rewrite**: `XmlSerializer` → `XDocument.Load()` + `XElement`
navigation (fully AOT-safe, available on all targets, no `#if`
branching)
- **New model classes**: `Execution`, `Counters`, `ResultSummary`,
`TestList`, `TestLists`, `TestEntry`, `TestEntries`
- **Complete parsing**: all previously-unset fields now populated —
`RunUser`, `ResultSummary`/`Counters`, `TestLists`, `TestEntries`,
`UnitTest.Storage`/`Execution`,
`UnitTestResult.ExecutionId`/`TestListId`/`TestType`/`RelativeResultsDirectory`
- **`TestResultSet` properties**: `TestRunId`, `DeploymentRoot`,
`TestSettingsName` now populated from parsed data
- **Theory/parameterized test names**: FQTN now correctly appends
parameter suffixes (e.g. `MethodName(arg: "value")`)
- **Exception handling**: `catch (Exception)` narrowed to `catch
(XmlException)` in the XML loading path
- **Cleanup**: removed inert `[XmlRoot]`/`[XmlElement]`/`[XmlAttribute]`
attributes and `using System.Xml.Serialization` from all model classes

### AOT Smoke Test (`TrxLib.AotSample`)
- New `net10.0` console app with `PublishAot=true` that references
TrxLib
- Writes a minimal TRX to a temp file, parses it with `TrxParser.Parse`,
and asserts the result — exercising the full `XDocument` parse path in
the native binary

### CI (`.github/workflows/build-and-test.yml`)
- Added `AOT Publish Validation` step to the existing matrix job (ubuntu
+ windows)
- Runs `dotnet publish -r <rid> --self-contained` then **executes the
native binary** to catch both link-time and runtime AOT regressions

## Verification
- ✅ 38/38 tests pass
- ✅ `dotnet build` — 0 AOT analyzer warnings on net8.0/net10.0
- ✅ `dotnet publish -r win-x64` — 0 ILLink/AOT warnings
- ✅ Native binary runs and prints `TrxLib AOT validation passed.`
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 6 to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>v7 What's new</h2>
<h3>Direct Uploads</h3>
<p>Adds support for uploading single files directly (unzipped). Callers
can set the new <code>archive</code> parameter to <code>false</code> to
skip zipping the file during upload. Right now, we only support single
files. The action will fail if the glob passed resolves to multiple
files. The <code>name</code> parameter is also ignored with this
setting. Instead, the name of the artifact will be the name of the
uploaded file.</p>
<h3>ESM</h3>
<p>To support new versions of the <code>@actions/*</code> packages,
we've upgraded the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Add proxy integration test by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
<li>Upgrade the module to ESM and bump dependencies by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/762">actions/upload-artifact#762</a></li>
<li>Support direct file uploads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/764">actions/upload-artifact#764</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Link"><code>@​Link</code></a>- made
their first contribution in <a
href="https://github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v6...v7.0.0">https://github.com/actions/upload-artifact/compare/v6...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f"><code>bbbca2d</code></a>
Support direct file uploads (<a
href="https://github.com/actions/upload-artifact/issues/764">#764</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/589182c5a4cec8920b8c1bce3e2fab1c97a02296"><code>589182c</code></a>
Upgrade the module to ESM and bump dependencies (<a
href="https://github.com/actions/upload-artifact/issues/762">#762</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/47309c993abb98030a35d55ef7ff34b7fa1074b5"><code>47309c9</code></a>
Merge pull request <a
href="https://github.com/actions/upload-artifact/issues/754">#754</a>
from actions/Link-/add-proxy-integration-tests</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/02a8460834e70dab0ce194c64360c59dc1475ef0"><code>02a8460</code></a>
Add proxy integration test</li>
<li>See full diff in <a
href="https://github.com/actions/upload-artifact/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Potential fix for
[https://github.com/BenjaminMichaelis/TrxLib/security/code-scanning/3](https://github.com/BenjaminMichaelis/TrxLib/security/code-scanning/3)

Add an explicit `permissions` block for the `build-and-test` job in
`.github/workflows/build-and-test.yml`, with the minimum required scope:
- `contents: read`

This is the best fix because it preserves existing behavior
(checkout/build/test still work) while ensuring `GITHUB_TOKEN` cannot
get unintended write privileges from repo/org defaults.
Edit only the `build-and-test` job section, directly under `runs-on`.


_Suggested fixes powered by Copilot Autofix. Review carefully before
merging._

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Bug A: Aborted and other real vstest outcomes are silently mapped to
NotExecuted by the switch default. The test asserts Aborted must NOT
become NotExecuted.

Bug C: Parser hardcodes a 3-level parent walk from the DLL path to
derive TestProjectDirectory. This assumes bin\Debug\<TFM>\ layout
and gives the wrong directory for publish\ or other non-standard
output paths. The test uses a codeBase one level deep (publish\)
and asserts the project root is 1 level up, not 3.

Bug D: All child-element lookups use the xmlns-qualified XName
(TrxNs + element). A TRX that omits the xmlns declaration produces
zero results even though the structure is otherwise valid. The test
asserts 3 results from a namespace-free TRX.

Adds three PII-free sample TRX files to drive the tests:
- aborted-outcome.trx (single result, outcome=Aborted)
- published-codebase.trx (single result, codeBase in publish\)
- no-namespace.trx (3 results, no xmlns on root element)
Bug A: Map all vstest outcome strings to dedicated TestOutcome enum values
instead of silently collapsing unknown outcomes to NotExecuted.
Adds Aborted, Disconnected, Warning, Error, NotRunnable,
PassedButRunAborted, and InProgress to TestOutcome.

Bug C: Replace the hardcoded 3-level parent walk with a
FindProjectDirectory heuristic that walks up from the DLL directory,
skipping known build-output segments (bin, obj, debug, release, publish,
platform names, and .NET TFM patterns) until it reaches the project root.
This correctly handles publish\, custom OutputPath, and other non-standard
build layouts without breaking the standard bin\Debug\<TFM>\ case.

Bug D: Detect whether the TRX document uses the standard xmlns at parse
time (var ns = root.Name.Namespace == XNamespace.None ? XNamespace.None : TrxNs)
and use the detected namespace for all child-element lookups. TRX files
that omit the xmlns declaration now parse correctly instead of returning
zero results.
Copilot AI review requested due to automatic review settings May 17, 2026 06:01
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

This PR fixes multiple TRX parsing mismatches vs. the reference implementation by expanding supported vstest outcomes, making TestProjectDirectory derivation resilient to non-bin/Debug/<TFM> layouts, and adding a namespace-free (xmlns missing) parsing fallback. It also removes the XmlSerializer-based approach (improving Native AOT compatibility), adds regression tests + sample TRX files, and introduces an AOT publish validation sample that runs in CI.

Changes:

  • Replace XmlSerializer deserialization with an XDocument-based TRX reader that supports namespace-free TRX files.
  • Add missing vstest outcome mappings (Aborted, Disconnected, etc.) and improve theory/parameterized test FQTN handling.
  • Improve TestProjectDirectory detection via an upward-walk heuristic; add AOT sample project + CI publish/run validation.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
TrxLib/TrxParser.cs Switch to LINQ-to-XML deserialization, add outcome mappings, FQTN suffix logic, and project-dir heuristic.
TrxLib/TestOutcome.cs Add additional vstest outcomes with XML docs.
TrxLib/TrxLib.csproj Multi-target the library and mark AOT-compatible for net8+ TFMs.
TrxLib/TestRun.cs Remove XmlSerializer attributes; minor doc clarification.
TrxLib/Times.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/TestSettings.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/Results.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/UnitTestResult.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/UnitTest.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/TestMethod.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/TestDefinitions.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/Execution.cs Remove XmlSerializer attributes; tighten docs.
TrxLib/Output.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/ErrorInfo.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/Deployment.cs Remove XmlSerializer attributes (model now populated manually).
TrxLib/ResultSummary.cs Remove XmlSerializer attributes; doc tweaks.
TrxLib/Counters.cs Remove XmlSerializer attributes; doc tweaks.
TrxLib/TestLists.cs Remove XmlSerializer attributes; doc tweaks.
TrxLib/TestList.cs Remove XmlSerializer attributes; doc tweaks.
TrxLib/TestEntries.cs Remove XmlSerializer attributes; doc tweaks.
TrxLib/TestEntry.cs Remove XmlSerializer attributes; doc tweak for TestListId.
TrxLib.Tests/TrxParserTests.cs Add regression tests for new behaviors/outcomes, namespace-free parsing, and directory heuristic.
TrxLib.Tests/SampleTrxFiles/theory-tests.trx Add sample TRX for parameterized/theory test name parsing.
TrxLib.Tests/SampleTrxFiles/aborted-outcome.trx Add sample TRX for Aborted outcome regression.
TrxLib.Tests/SampleTrxFiles/published-codebase.trx Add sample TRX for publish-layout codeBase directory regression.
TrxLib.Tests/SampleTrxFiles/no-namespace.trx Add sample TRX missing xmlns for namespace fallback regression.
TrxLib.slnx Add the AOT validation sample project to the solution.
TrxLib.AotSample/TrxLib.AotSample.csproj New AOT publishable console app to validate TrxLib under Native AOT.
TrxLib.AotSample/Program.cs Parse all sample TRX files at runtime to ensure AOT-safe code paths.
.github/workflows/build-and-test.yml Add job permissions and an AOT publish+run validation step.
.github/workflows/deploy.yml Bump upload-artifact action version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread TrxLib/TrxParser.cs Outdated
return dir;
dir = dir.Parent;
}
return dllDirectory;
Comment thread TrxLib/TrxParser.cs Outdated
Comment on lines +221 to +222
// Support TRX files that omit the xmlns declaration: fall back to no-namespace lookups.
var ns = root.Name.Namespace == XNamespace.None ? XNamespace.None : TrxNs;
Comment thread TrxLib.Tests/TrxParserTests.cs Outdated
results.Count.Should().Be(recombinedCount);
}

// ── Bug regression tests (currently FAILING — prove known bugs) ──────────────
Comment thread TrxLib.Tests/TrxParserTests.cs Outdated
Comment on lines +335 to +339
// NotExecuted (which means "deliberately skipped"). It should NOT become NotExecuted.
var results = TrxParser.Parse(new FileInfo(GetSampleFilePath("aborted-outcome.trx")));
results.Should().HaveCount(1);
results.Single().Outcome.Should().NotBe(TestOutcome.NotExecuted,
"\"Aborted\" is a distinct vstest outcome and must not be silently mapped to NotExecuted");
- Drop stale '(currently FAILING - prove known bugs)' section header
- Remove 'Bug A/C/D:' labels and descriptions of old broken behavior
- Trim verbose path diagram in the publish-layout test
- Assertions and test names already capture the intent
Switch published-codebase.trx from a Windows-specific C:\ path to a
forward-slash path (/home/user/acme-project/publish/Acme.Tests.dll).
.NET normalises forward slashes on all platforms, so FileInfo and
DirectoryInfo behave correctly on both Windows and Linux/macOS.

Assert TestProjectDirectory.Name instead of FullName so the test
checks the semantic invariant (resolved directory is the project root)
without depending on the absolute path of the current drive.

Drop the Windows-only platform guard entirely.
Conflicts resolved:
- TrxLib/TestOutcome.cs: both sides added enum values; merged to union,
  keeping main's VSTest-aligned ordering and docs. Added 'Completed' from
  main; removed duplicate entries produced by faulty auto-merge.
- TrxLib/TrxParser.cs: kept our Bug C (FindProjectDirectory helpers) and
  Bug D (xmlns-fallback 'ns' variable) fixes over main's original.
  Added 'completed' => TestOutcome.Completed to the outcome switch.
- TrxLib.Tests/SampleTrxFiles/theory-tests.trx: took main's sanitized
  version (sample@MACHINE) over our local PII-containing version.
@BenjaminMichaelis BenjaminMichaelis changed the title Fix bugs A, C, D: missing vstest outcomes, TestProjectDirectory heuristic, xmlns fallback fix: missing vstest outcomes, TestProjectDirectory heuristic, xmlns fallback May 17, 2026
- Use root element namespace directly for XML lookups (supports non-2010 namespaces and no-namespace files)
- Return filesystem root when project-directory heuristic never exits build-output segments
- Strengthen aborted outcome regression test to assert exact mapping
Resolved TrxParser.cs conflicts by preserving namespace-agnostic parsing and
combining directory resolution behavior:
- anchor on nearest 'bin' for SDK output layouts (including RID/publish)
- fallback heuristic for non-bin layouts (e.g., published artifact paths)
- preserve null outcome mapping to TestOutcome.Error
Reintroduced the explanatory note for null outcome attribute mapping to
TestOutcome.Error, matching the upstream vstest serialization behavior
captured in origin/main.
- Remove explanatory outcome comment per feedback
- Format outcome switch with aligned pattern arms
- Prefer pattern matching style (is not null) for element checks
- Keep existing merge behavior (namespace-aware parsing + directory heuristic)
Generated a real TRX from a temporary test run that was aborted via
vstest hang-blame collection, copied it into SampleTrxFiles, and scrubbed
high-level PII (user/machine/workspace paths).

Updated the regression test to assert against the real captured fixture
shape (passed unit result with aborted run summary).
Document the required workflow for TRX test fixtures:
- generate from temporary tests via dotnet test TRX output
- copy into sample fixtures
- scrub high-level PII
- avoid hand-authored synthetic TRX when real capture is possible
@BenjaminMichaelis
Copy link
Copy Markdown
Owner Author

@copilot I think the instruction we added would be better as a skill file. change it. research skill files if needed.

Agent-Logs-Url: https://github.com/BenjaminMichaelis/TrxLib/sessions/8b8f74ee-ab61-4860-b945-52640f04bb44

Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 17, 2026

@copilot I think the instruction we added would be better as a skill file. change it. research skill files if needed.

Done in ff90059. Moved the content from .github/instructions/test-writing.instructions.md to .github/skills/trx-fixture-policy/SKILL.md — a skill file with YAML frontmatter (name/description) followed by the same markdown instructions. The old instruction file and now-empty instructions/ directory have been removed.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • agentskills.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • blog.codeinside.eu
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • code.visualstudio.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • learn.microsoft.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • smartscope.blog
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • stefanstranger.github.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Updated skill name and description for clarity.
…d-codebase.trx

no-namespace.trx is now a verbatim copy of a real NUnit TRX captured by
joaoopereira without an xmlns attribute on the root element, confirming
this is a genuine real-world format variant the parser must handle.
Source: https://github.com/joaoopereira/dotnet-test-rerun/blob/main/test/dotnet-test-rerun.UnitTests/Fixtures/RerunCommand/NUnitTrxFileWithOneFailedTest.trx

published-codebase.trx had no real-world equivalent found on GitHub. A
publish-path codeBase outside any bin\ ancestor does not appear in public
repos, so there is no proven bug to test for here. The synthetic fixture
and its test are removed.
…g-analysis' into benjaminmichaelis/trex-trxlib-bug-analysis
The fallback heuristic (KnownBuildOutputDirs, IsDotNetTfm, second walk)
was added to handle codeBase paths under a publish\ directory with no
bin\ ancestor. No real-world TRX file with that layout was found on
GitHub, so there is no proven bug to solve. Removing the dead code keeps
FindProjectDirectory simple and only as capable as the evidence supports.
@BenjaminMichaelis BenjaminMichaelis merged commit 9792a31 into main May 17, 2026
6 checks passed
@BenjaminMichaelis BenjaminMichaelis deleted the benjaminmichaelis/trex-trxlib-bug-analysis branch May 17, 2026 08:12
github-actions Bot pushed a commit to BenjaminMichaelis/VS.TestPlaylistTools that referenced this pull request May 19, 2026
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Updated [TrxLib](https://github.com/BenjaminMichaelis/TrxLib) from 0.0.3
to 1.0.0.

<details>
<summary>Release notes</summary>

_Sourced from [TrxLib's
releases](https://github.com/BenjaminMichaelis/TrxLib/releases)._

## 1.0.0

## Features
- Cleaned up some TRX file bugs
- Now AOT compliant!
- Cleaned up a lot of misc tech debt

## What's Changed
* Bump actions/checkout from 5 to 6 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#20
* Bump actions/upload-artifact from 5 to 6 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#22
* Bump Microsoft.SourceLink.GitHub from 8.0.0 to 10.0.102 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#23
* Bump coverlet.collector from 6.0.4 to 8.0.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#24
* Bump Microsoft.SourceLink.GitHub from 10.0.102 to 10.0.103 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#25
* Bump AwesomeAssertions from 9.3.0 to 9.4.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#26
* Bump actions/download-artifact from 6 to 8 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#28
* Bump IntelliTect.Multitool from 1.5.3 to 2.0.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#29
* Bump Microsoft.NET.Test.Sdk from 18.0.1 to 18.3.0 by @​dependabot[bot]
in BenjaminMichaelis/TrxLib#30
* Bump Microsoft.SourceLink.GitHub from 10.0.103 to 10.0.201 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#31
* Bump coverlet.collector from 8.0.0 to 8.0.1 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#32
* Bump fastify/github-action-merge-dependabot from 3.11.2 to 3.12.0 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#33
* Bump Microsoft.NET.Test.Sdk from 18.3.0 to 18.4.0 by @​dependabot[bot]
in BenjaminMichaelis/TrxLib#34
* Bump Microsoft.SourceLink.GitHub from 10.0.201 to 10.0.202 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#36
* Bump coverlet.collector from 8.0.1 to 10.0.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#35
* Bump Microsoft.SourceLink.GitHub from 10.0.202 to 10.0.203 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#37
* Bump Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1 by @​dependabot[bot]
in BenjaminMichaelis/TrxLib#38
* feat: Migrate NuGet publish to trusted publishing (OIDC) by
@​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#39
* Migrate to slnx solution file format by @​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#40
* fix: TRX parser data-loss bugs and FQTN derivation spec compliance by
@​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#42
* fix: Refactor TestOutcome enum with updated summaries by
@​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#43
* fix: add missing vstest outcomes and fix directory heuristic for RID
paths by @​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#46
* fix: missing vstest outcomes, TestProjectDirectory heuristic, xmlns
fallback by @​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#47
* Migrate from xUnit to TUnit and adopt Microsoft.Testing.Platform v2 by
@​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#48
* Remove AwesomeAssertions, use TUnit built-in assertions by
@​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#49
* Bump IntelliTect.Multitool from 2.0.0 to 2.1.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#50
* Bump TUnit from 1.44.39 to 1.45.0 by @​dependabot[bot] in
BenjaminMichaelis/TrxLib#52
* Bump Microsoft.SourceLink.GitHub from 10.0.203 to 10.0.300 by
@​dependabot[bot] in BenjaminMichaelis/TrxLib#51
* chore: align project configuration with NuGet library template best
practices by @​BenjaminMichaelis in
BenjaminMichaelis/TrxLib#53


**Full Changelog**:
BenjaminMichaelis/TrxLib@v0.0.3...v1.0.0

Commits viewable in [compare
view](BenjaminMichaelis/TrxLib@v0.0.3...v1.0.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=TrxLib&package-manager=nuget&previous-version=0.0.3&new-version=1.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@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.

3 participants