From e50d4a539d18f637b84bf03cc6f65f30ab7977bc Mon Sep 17 00:00:00 2001 From: Monsieur Le Berre Date: Fri, 10 Jul 2026 10:49:13 +0200 Subject: [PATCH 1/2] fix(csharp-ci): match CodeCoverage 18.9.0 relocated cobertura output Microsoft.Testing.Extensions.CodeCoverage 18.9.0 together with .NET SDK 10.0.3xx solution-level 'dotnet test' resolves the relative --coverage-output against the run-level /TestResults/ instead of each project's bin/Release//TestResults/, so the default tests-glob matched nothing and failed the coverage shard for consumers that bumped the package. Broaden the default with a second glob (the merge step word-splits the input) and update the caller-prerequisites docs, including the stale 18.0.x CodeCoverage ceiling. Validated caller-side in daml-codegen-csharp-internal#585. --- .github/workflows/csharp-ci.yaml | 25 ++++++++++++++++--------- README.md | 29 +++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/.github/workflows/csharp-ci.yaml b/.github/workflows/csharp-ci.yaml index 029894a..701f475 100644 --- a/.github/workflows/csharp-ci.yaml +++ b/.github/workflows/csharp-ci.yaml @@ -142,18 +142,25 @@ on: default: 'C# coverage' tests-glob: description: >- - Glob (relative to working-directory) used to locate the per-project - `*.cobertura.xml` files emitted by MTP's coverage extension. The - matching files are union-merged into a single report - (`coverage/merged.cobertura.xml`) by `dotnet-coverage merge` - before irongut/CodeCoverageSummary summarizes it. The default - narrows to `bin/Release/net*/` so that stale cobertura files + Glob(s) (relative to working-directory) used to locate the + per-project `*.cobertura.xml` files emitted by MTP's coverage + extension. The value is word-split into multiple space-separated + globs, and the matching files are union-merged into a single + report (`coverage/merged.cobertura.xml`) by `dotnet-coverage merge` + before irongut/CodeCoverageSummary summarizes it. The first default + glob narrows to `bin/Release/net*/` so that stale cobertura files left over in source-controlled or scratch directories do not get - merged. Adjust if your tests live outside a top-level `tests/` - directory or target a non-Release configuration. + merged. The second default glob covers the relocated layout: + CodeCoverage 18.9.0 together with .NET SDK 10.0.3xx solution-level + `dotnet test` resolves the relative `--coverage-output` against the + run-level `/TestResults/`; with an older package + line or an older SDK feature band (e.g. 10.0.1xx) the per-project + `bin/Release//TestResults/` location still applies. Adjust if + your tests live outside a top-level `tests/` directory or target a + non-Release configuration. required: false type: string - default: 'tests/**/bin/Release/net*/**/*.cobertura.xml' + default: 'tests/**/bin/Release/net*/**/*.cobertura.xml TestResults/**/*.cobertura.xml' pack: description: >- Whether to run `dotnet pack` and upload the resulting .nupkg as a diff --git a/README.md b/README.md index 2883ab3..a5b73d3 100644 --- a/README.md +++ b/README.md @@ -187,9 +187,11 @@ stay on a previous SHA / tag until you've migrated the items below. across files fails the coverage shard loud — like a missing `global.json`. The version must be a literal (e.g. `18.8.0`). See [`canton-ledger-api-csharp#79`](https://github.com/peacefulstudio/canton-ledger-api-csharp/pull/79) - for the MTP 1.x / 2.x compatibility rationale: do not bump - `CodeCoverage` past 18.0.x until `xunit.v3` ships an MTP 2.x build — - newer 19.x lines have produced empty Cobertura output in this pipeline. + for the MTP 1.x / 2.x compatibility rationale: the 18.0.x ceiling + applied until `xunit.v3` shipped its MTP 2.x package. With + `xunit.v3.mtp-v2` in place, 18.x lines through 18.9.x are supported — + but newer 19.x lines have produced empty Cobertura output in this + pipeline. - **`tests/Directory.Build.props`** (or equivalent) must enable MTP: @@ -200,16 +202,27 @@ stay on a previous SHA / tag until you've migrated the items below. ``` The exact arguments live in the caller — what matters is that MTP runs - in-process and emits `*.cobertura.xml` files somewhere under `tests/`. - -- **Multi-TFM test projects** must set a per-TFM Cobertura filename to - avoid silent overwrites between target frameworks: + in-process and emits `*.cobertura.xml` files. Their location depends on + the toolchain combination: CodeCoverage 18.9.0 together with .NET SDK + 10.0.3xx relocates the relative `--coverage-output` file to + `/TestResults/` (the run-level results directory), + whereas with an older package line or SDK 10.0.1xx they land under each + test project's `tests/**/bin/Release//TestResults/`. The default + `tests-glob` matches both layouts. + +- **Multi-TFM test projects** must set a Cobertura filename that is unique + per project *and* per TFM to avoid silent overwrites — under the relocated + layout (CodeCoverage 18.9.0 + SDK 10.0.3xx) every project writes into the + shared `/TestResults/`, so a project-name prefix is + what keeps two projects from clobbering each other's files: ```xml ... --coverage-output $(MSBuildProjectName)_$(TargetFramework).cobertura.xml ``` - Single-TFM projects can omit this. + The `$(MSBuildProjectName)` prefix satisfies both. Single-TFM projects in + the per-project layout can omit this, but the project-name prefix is + still required to stay collision-free in the shared directory. - **`coverage.settings.xml`** at the repo root (or wherever `TestingPlatformCommandLineArguments` points), tuning the coverage From 0e33b939432ffec1e354999f456f21b81839e33e Mon Sep 17 00:00:00 2001 From: Monsieur Le Berre Date: Fri, 10 Jul 2026 11:02:12 +0200 Subject: [PATCH 2/2] docs(csharp-ci): trim tests-glob description to timeless facts --- .github/workflows/csharp-ci.yaml | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/csharp-ci.yaml b/.github/workflows/csharp-ci.yaml index 701f475..2b17680 100644 --- a/.github/workflows/csharp-ci.yaml +++ b/.github/workflows/csharp-ci.yaml @@ -142,21 +142,16 @@ on: default: 'C# coverage' tests-glob: description: >- - Glob(s) (relative to working-directory) used to locate the - per-project `*.cobertura.xml` files emitted by MTP's coverage - extension. The value is word-split into multiple space-separated - globs, and the matching files are union-merged into a single - report (`coverage/merged.cobertura.xml`) by `dotnet-coverage merge` - before irongut/CodeCoverageSummary summarizes it. The first default - glob narrows to `bin/Release/net*/` so that stale cobertura files - left over in source-controlled or scratch directories do not get - merged. The second default glob covers the relocated layout: - CodeCoverage 18.9.0 together with .NET SDK 10.0.3xx solution-level - `dotnet test` resolves the relative `--coverage-output` against the - run-level `/TestResults/`; with an older package - line or an older SDK feature band (e.g. 10.0.1xx) the per-project - `bin/Release//TestResults/` location still applies. Adjust if - your tests live outside a top-level `tests/` directory or target a + Space-separated glob(s), relative to working-directory, used to + locate the `*.cobertura.xml` files emitted by MTP's coverage + extension. All matching files are union-merged into + `coverage/merged.cobertura.xml` by `dotnet-coverage merge` before + irongut/CodeCoverageSummary summarizes it. The defaults cover the + two places the toolchain writes coverage output — each test + project's `bin/Release/` tree and the run-level `TestResults/` + directory — while staying narrow enough to skip stale files in + source-controlled or scratch directories. Adjust if your tests + live outside a top-level `tests/` directory or target a non-Release configuration. required: false type: string