Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
86dba83
🐛 match dependency exclusions to exact assembly names
aicia-bot Nov 3, 2026
13b2335
📝 document exact dependency exclusion behavior
aicia-bot Nov 3, 2026
7fc6b11
🐛 fix exclusion filters to target exact assemblies from deps.json
gimlichael Nov 3, 2026
c65e2d3
🐛 preserve project outputs listed in reference entries
aicia-bot Nov 3, 2026
6872fd2
📝 add coverage advisory for the dependency exclusion regression
aicia-bot Nov 3, 2026
2b27d5d
📝 add upstream provenance ledger
aicia-bot Nov 3, 2026
3ae099e
📝 link coverage advisory from readme and integration guide
aicia-bot Nov 3, 2026
79d753e
💬 update changelog for the 10.1.2 coverage advisory
aicia-bot Nov 3, 2026
62c7913
🐛 bind netstandard facade to the owning assembly resolver
aicia-bot Nov 3, 2026
9cc91aa
📝 document the resolver correction in the coverage advisory
aicia-bot Nov 3, 2026
49e516c
📝 record resolver correction in upstream ledger
aicia-bot Nov 3, 2026
a243834
📝 correct advisory status in readme and integration guide
aicia-bot Nov 3, 2026
a06eac4
💬 update changelog for the resolver correction
aicia-bot Nov 3, 2026
9cd37b4
👷 enable CI for the 10.x maintenance branch
aicia-bot Nov 3, 2026
74da138
💬 document the 10.x maintenance release workflow
aicia-bot Nov 3, 2026
61f97ed
📝 record maintenance branch setup and CI results
aicia-bot Nov 3, 2026
a5acac0
👷 make macOS CI opt-in for manual runs
aicia-bot Nov 3, 2026
8a5debe
💬 document optional macOS validation
aicia-bot Nov 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ name: Codebelt Coverlet MTP CI

on:
pull_request:
branches: [master]
branches: [master, releases/v10]
workflow_dispatch:
inputs:
run_mac_tests:
type: boolean
description: Include macOS tests and package validation despite hosted-runner capacity constraints.
default: false

permissions:
contents: read
Expand Down Expand Up @@ -49,7 +54,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-26.04, windows-2025, macos-26]
os: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.run_mac_tests && '["ubuntu-26.04","windows-2025","macos-26"]' || '["ubuntu-26.04","windows-2025"]') }}
project_name: [core, core-coverage, mtp]
include:
- project_name: core
Expand Down Expand Up @@ -88,7 +93,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-26.04, windows-2025, macos-26]
os: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.run_mac_tests && '["ubuntu-26.04","windows-2025","macos-26"]' || '["ubuntu-26.04","windows-2025"]') }}
framework: [net9.0, net10.0]
permissions:
contents: read
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [10.1.2] - 2026-11-03

This is a patch release that restores coverage for project assemblies accidentally matched by generated dependency exclusions and fixes a separate framework assembly-resolution failure reproduced with Cuemon on .NET Framework 4.8. The dependency-filter defect was first included in Codebelt 10.0.1; the facade-resolution defect has a separate, older upstream origin. Package identity, public APIs, dependency versions, and supported target frameworks are unchanged. Restored modules can change coverage totals and quality-gate outcomes.

> [!WARNING]
> Versions 10.0.1 through 10.1.1 can produce incomplete coverage while tests and CI pass. BenchmarkDotNet's historical 92.3% report measured only its tooling runner; the library modules were missing. Review expected modules and source files when regenerating coverage. See the [full advisory](Documentation/DependencyExclusionRegression.md) for affected configurations, upstream [PR #1946](https://github.com/coverlet-coverage/coverlet/pull/1946) and commit [`c502253`](https://github.com/coverlet-coverage/coverlet/commit/c5022539cfdf3c6246c2e49b7789d7e8e529ef47), historical CI evidence, and the separately traced .NET Framework instrumentation fix validated with Cuemon.

### Changed

- Document exact dependency discovery and retained xUnit build exclusions, with prominent coverage alerts, upstream provenance, affected-version analysis, and verified results for the seven reported consumer repositories and Cuemon on .NET Framework 4.8.

### Fixed

- Generate exclusion filters from the managed runtime assets, including RID-specific assemblies, declared by non-project libraries in `deps.json` instead of from package IDs, so dependencies no longer exclude project assemblies that merely share a name prefix; preserve project outputs also listed in SDK reference entries,
- Accept hyphenated assembly names such as `[xunit.v3.mtp-v2]*` as valid exclude filters, and exclude the `xunit.abstractions`, `xunit.runner.visualstudio.testadapter`, `xunit.v3.runner.utility.netcore`, and `xunit.v3.runner.utility.netfx` build assets that the xUnit runner and VSTest adapter copy without `deps.json` runtime entries,
- Keep the runtime `netstandard.dll` facade bound to its owning assembly resolver so forwarded enum types retain configured framework fallbacks during instrumentation; restore coverage for `Cuemon.Core`, `Cuemon.Kernel`, and `Cuemon.Extensions.Core` on .NET Framework 4.8, with regression coverage for optional enum metadata.

## [10.1.1] - 2026-10-20

This is a patch release that fixes module unload mutex collisions between unrelated coverage sessions and updates the Microsoft runtime pins and the `System.Security.Cryptography.Pkcs` override used by coverlet.core, with no new capabilities.
Expand Down Expand Up @@ -97,6 +114,7 @@ This is a minor release focused on the Codebelt.Coverlet.MTP fork with narrowed
- .vscode/settings.json configuration,
- .devcontainer legacy configuration.

[10.1.2]: https://github.com/codebeltnet/coverlet/compare/v10.1.1...v10.1.2
[10.1.1]: https://github.com/codebeltnet/coverlet/compare/v10.1.0...v10.1.1
[10.1.0]: https://github.com/codebeltnet/coverlet/compare/v10.0.1...v10.1.0
[10.0.1]: https://github.com/codebeltnet/coverlet/compare/v10.0.0...v10.0.1
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Contributions are welcome. This repository is a deliberately narrow Codebelt-mai

Use the .NET SDK pinned by `global.json`. The retained production matrix is `netstandard2.0`, `net9.0`, and `net10.0`; tests execute on `net9.0` and `net10.0`.

## Release branches

Target `releases/v10` for changes to the 10.x maintenance line, following the maintenance-branch naming in the [GitHub Actions versioning example](https://github.com/actions/toolkit/blob/main/docs/action-versioning.md#sample-workflow). Its starting point is the `v10.1.1` release commit, and the 10.1.2 patch retains that release's SDK, dependency versions, and `netstandard2.0;net9.0;net10.0` package targets. CI accepts pull requests targeting either `releases/v10` or `master`.

`master` continues development toward 11.0.0, including its .NET 11 changes and recorded upstream integrations. Keep changes for that release on `master` and the existing 11.0.0 branches. Forward-port maintenance fixes separately and validate them against the destination branch's framework matrix. Merging `master` into a maintenance hotfix would also bring its later product and framework changes into the patch release.

After integrating a maintenance pull request and completing its checks, create the fixed full-version tag, such as `v10.1.2`, on the exact commit to release before starting the manual CI/release workflow. MinVer otherwise calculates a prerelease version above the latest release tag. Select `releases/v10` in the workflow's branch dropdown while that tagged commit is still its tip, or use `gh workflow run ci-pipeline.yml --ref v10.1.2` to select the tagged commit explicitly. The existing workflow builds, tests, packs, and validates that source before requesting approval in the `Production` environment for NuGet publication. The environment currently permits this maintenance branch and retains its required reviewer. The Actions guide's moving major-version tags are separate from this maintenance branch; NuGet releases retain fixed full-version tags. Do not move existing release tags.

CI requires Windows and Ubuntu tests and package validation. macOS is optional because hosted-runner capacity can prevent jobs from starting. To include it, enable `run_mac_tests` in the manual workflow form, or add `-f run_mac_tests=true` to the workflow command. The option includes macOS in both matrices; every selected job must pass before publication. A default run does not establish macOS compatibility. This follows the opt-in behavior in [Codebelt xUnit's workflow](https://github.com/codebeltnet/xunit/blob/main/.github/workflows/ci-pipeline.yml).

## Building, testing, and packing

Clone this repository:
Expand Down
18 changes: 11 additions & 7 deletions Documentation/Coverlet.MTP.Integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ More information is available here:

`Codebelt.Coverlet.MTP` packages Coverlet's Microsoft Testing Platform integration while preserving the implementation assembly name `coverlet.MTP.dll` for extension discovery.

> [!WARNING]
> Versions 10.0.1 through 10.1.1 can omit project assemblies under default dependency exclusions when their assembly names share a generated prefix. The [10.1.2 coverage advisory](DependencyExclusionRegression.md) explains the correction, upstream origins, consumer validation, and the separate .NET Framework instrumentation fix validated with Cuemon. Existing high percentages or successful test runs do not establish that all expected modules were included.

## Supported Runtime Versions

This package provides explicit dependency groups for:
Expand Down Expand Up @@ -81,7 +84,7 @@ dotnet exec <test-assembly.dll> --help
| `--coverlet-file-prefix <prefix>` | Prefix for coverage report filenames to prevent overwrites when multiple test projects write to the same directory. When specified, files are named `<prefix>.coverage.<extension>` instead of `coverage.<extension>`. (default: `none`) |
| `--coverlet-include <filter>` | Include assemblies matching filters (e.g., `[Assembly]Type`). Can be specified multiple times. (default: `none`) |
| `--coverlet-include-directory <path>` | Include additional directories for sources. Can be specified multiple times. (default: `none`) |
| `--coverlet-exclude <filter>` | Exclude assemblies matching filters (e.g., `[Assembly]Type`). Can be specified multiple times. User-specified filters are merged with defaults. (defaults: see "Default Exclusions Behavior" below) |
| `--coverlet-exclude <filter>` | Exclude assemblies matching filters (e.g., `[Assembly]Type`). Can be specified multiple times. User-specified filters are merged with the permanent baseline; dynamic exclusions are skipped. (defaults: see "Default Exclusions Behavior" below) |
| `--coverlet-exclude-by-file <pattern>` | Exclude source files matching glob patterns. Can be specified multiple times. (default: `none`) |
| `--coverlet-exclude-by-attribute <attribute>` | Exclude methods/classes decorated with attributes. Can be specified multiple times. User-specified attributes are merged with defaults. (defaults: see "Default Exclusions Behavior" below) |
| `--coverlet-include-test-assembly` | Include test assembly in coverage. (default: `false`) |
Expand All @@ -105,17 +108,18 @@ Coverlet.MTP applies sensible default exclusions to reduce noise in coverage rep

**Command Line Defaults:**

When using command line options **without** a configuration file, the following defaults are **automatically merged** with user-specified exclusions:
When using command line options **without** a configuration file, the following baseline exclusions are **automatically merged** with user-specified exclusions:

- **Default Exclude Filters:** `[coverlet.*]*`, `[Microsoft.VisualStudio.TestPlatform.*]*`, `[testhost*]*`
- **Default Exclude Filters:** `[coverlet.*]*`, `[Microsoft.VisualStudio.TestPlatform.*]*`, `[testhost*]*`, `[ReportGenerator.*]*`
- **Default Exclude by Attributes:** `ExcludeFromCodeCoverage`, `ExcludeFromCodeCoverageAttribute`, `GeneratedCodeAttribute`, `CompilerGeneratedAttribute`

**Dynamic Exclude Filters (Assembly Naming Convention):**
**Dynamic Exclude Filters (Dependency Discovery):**

Coverlet.MTP also applies **dynamic exclusions** derived from the test assembly name and its namespace conventions at runtime. These are intended to automatically exclude common test infrastructure assemblies that follow standard naming patterns.
When neither `--coverlet-exclude` nor a configuration file supplies exclusions, Coverlet.MTP also discovers managed runtime assemblies from non-project libraries in the `*.deps.json` files next to the test module, including RID-specific runtime assets. Assemblies already loaded in the controller process are also excluded, except for the test assembly itself.

> [!WARNING]
> **Assembly Naming Limitation:** Dynamic exclusions rely on the assembly name following conventional naming schemas (e.g., `MyApp.Tests`, `MyApp.UnitTests`, `MyApp.IntegrationTests`). Assemblies that **do not follow these naming conventions** will **not** be automatically excluded by the dynamic filter. In such cases, you must add explicit `--coverlet-exclude` filters manually.
Generated filters match exact assembly names, such as `[Example.Testing.Infrastructure]*`. Package IDs are resolved to their runtime assembly filenames instead of being generalized into namespace wildcards. A project assembly sharing a dependency's name prefix remains eligible for coverage. User-specified wildcard filters retain their normal matching behavior.

Default discovery also excludes the exact xUnit build asset names `xunit.abstractions`, `xunit.runner.visualstudio.testadapter`, `xunit.v3.runner.utility.netcore`, and `xunit.v3.runner.utility.netfx`. The xUnit runner and VSTest adapter copy these assets without declaring runtime entries in `deps.json`. These defaults are skipped with explicit exclusion filters or a configuration file.

**Configuration File Behavior (Authoritative Mode):**

Expand Down
Loading