diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aa74aa89..f079195bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,20 @@ 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). +## [vNext] - 2026-10-30 + +This is a patch release that makes the MTP package-validation tests prepare their own Codebelt.Coverlet.MTP package during local builds, including Visual Studio Test Explorer runs, with no runtime or package behavior changes. + +### Added + +- Add automatic preparation of the Codebelt.Coverlet.MTP package for the MTP package-validation tests during local builds, skipped for IDE design-time builds, with isolated output under `artifacts/validation` per configuration and framework. + +### Changed + +- Change the validation tests to read the package folder from MSBuild metadata instead of a hard-coded `artifacts/package/` path, with missing-package guidance that points to `-p:PrepareValidationPackage=true` or an existing package, +- Disable automatic package preparation in GitHub Actions so validation consumes the downloaded release package, while allowing opt-out outside GitHub Actions with `-p:PrepareValidationPackage=false`, +- Document the automatic packing behavior and opt-out in `CONTRIBUTING.md`, replacing the manual `dotnet pack` step. + ## [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. @@ -97,6 +111,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...vNext [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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 630f27014..25a43ee1f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,9 @@ dotnet pack src/coverlet.MTP/coverlet.MTP.csproj -c Release --no-build dotnet test -c Release --no-build ``` -The MTP package-validation tests consume the locally packed `Codebelt.Coverlet.MTP` package from `artifacts/package/release`, so pack before running `test/coverlet.MTP.validation.tests` directly. +The MTP package-validation project automatically packs `Codebelt.Coverlet.MTP` when built locally, including builds started by Visual Studio Test Explorer. No manual packing or package-folder cleanup is required. Each configuration and test framework uses an isolated directory under `artifacts/validation`, so older packages in `artifacts/package` do not affect local validation. The first build takes longer because it builds the package for all supported frameworks; subsequent package builds reuse their build outputs. + +In GitHub Actions, automatic packing is disabled so validation consumes the downloaded release package from `artifacts/package/release`. Outside GitHub Actions, use `-p:PrepareValidationPackage=false` to validate an existing package from `artifacts/package/` instead. That directory must contain exactly one `Codebelt.Coverlet.MTP.*.nupkg`. As usual, `dotnet test --no-build` reuses the package prepared by the previous build. ## Focused test runs diff --git a/test/coverlet.MTP.validation.tests/Directory.Build.targets b/test/coverlet.MTP.validation.tests/Directory.Build.targets index 8a7f9cd7b..a1e6a685f 100644 --- a/test/coverlet.MTP.validation.tests/Directory.Build.targets +++ b/test/coverlet.MTP.validation.tests/Directory.Build.targets @@ -11,4 +11,17 @@ + + + + <_PreviousValidationPackages Include="$(ValidationPackagePath)/Codebelt.Coverlet.MTP.*.nupkg;$(ValidationPackagePath)/Codebelt.Coverlet.MTP.*.snupkg" /> + + + + + + diff --git a/test/coverlet.MTP.validation.tests/HelpCommandTests.cs b/test/coverlet.MTP.validation.tests/HelpCommandTests.cs index 0be05d10a..7cdc514d5 100644 --- a/test/coverlet.MTP.validation.tests/HelpCommandTests.cs +++ b/test/coverlet.MTP.validation.tests/HelpCommandTests.cs @@ -45,7 +45,7 @@ public HelpCommandTests() // Get repository root _repoRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..")); - _localPackagesPath = Path.Combine(_repoRoot, "artifacts", "package", _buildConfiguration.ToLowerInvariant()); + _localPackagesPath = ValidationPackage.DirectoryPath; _projectOutputPath = Path.Combine(_repoRoot, "artifacts", "bin", s_projectName, _buildConfiguration.ToLowerInvariant()); @@ -58,21 +58,21 @@ public HelpCommandTests() private protected static string GetPackageVersion(string filter) { - string packagesPath = TestUtils.GetPackagePath(TestUtils.GetAssemblyBuildConfiguration().ToString().ToLowerInvariant()); + string packagesPath = ValidationPackage.DirectoryPath; if (!Directory.Exists(packagesPath)) { - throw new DirectoryNotFoundException($"Package directory '{packagesPath}' not found, run 'dotnet pack' on repository root"); + throw new DirectoryNotFoundException($"Package directory '{packagesPath}' not found. Supply the existing Codebelt.Coverlet.MTP package in this directory, or rebuild the validation test project locally with -p:PrepareValidationPackage=true to prepare it automatically."); } List files = Directory.GetFiles(packagesPath, filter).ToList(); if (files.Count == 0) { - throw new InvalidOperationException($"Could not find any package using filter '{filter}' in folder '{Path.GetFullPath(packagesPath)}'. Make sure 'dotnet pack' was called."); + throw new InvalidOperationException($"Could not find any package using filter '{filter}' in folder '{Path.GetFullPath(packagesPath)}'. Supply the existing Codebelt.Coverlet.MTP package in this directory, or rebuild the validation test project locally with -p:PrepareValidationPackage=true to prepare it automatically."); } else if (files.Count > 1) { - throw new InvalidOperationException($"Found more than one package using filter '{filter}' in folder '{Path.GetFullPath(packagesPath)}'. Make sure 'dotnet pack' was only called once."); + throw new InvalidOperationException($"Found more than one package using filter '{filter}' in folder '{Path.GetFullPath(packagesPath)}'. Expected exactly one."); } else { @@ -442,8 +442,7 @@ private async Task EnsureTestProjectBuilt() private void EnsurePackagesBuilt() { - string packagesPath = TestUtils.GetPackagePath( - TestUtils.GetAssemblyBuildConfiguration().ToString().ToLowerInvariant()); + string packagesPath = ValidationPackage.DirectoryPath; // Check for Codebelt.Coverlet.MTP string[] mtpPackages = Directory.GetFiles(packagesPath, "Codebelt.Coverlet.MTP.*.nupkg"); @@ -451,7 +450,7 @@ private void EnsurePackagesBuilt() { throw new InvalidOperationException( $"Codebelt.Coverlet.MTP package not found in '{packagesPath}'.\n" + - $"Run: dotnet pack src/coverlet.MTP -c {_buildConfiguration}"); + "Supply the existing Codebelt.Coverlet.MTP package in this directory, or rebuild the validation test project locally with -p:PrepareValidationPackage=true to prepare it automatically."); } } diff --git a/test/coverlet.MTP.validation.tests/TestInfrastructure/MtpValidationTestBase.cs b/test/coverlet.MTP.validation.tests/TestInfrastructure/MtpValidationTestBase.cs index 2344bcd27..852f3454f 100644 --- a/test/coverlet.MTP.validation.tests/TestInfrastructure/MtpValidationTestBase.cs +++ b/test/coverlet.MTP.validation.tests/TestInfrastructure/MtpValidationTestBase.cs @@ -30,8 +30,7 @@ protected MtpValidationTestBase() #endif RepoRoot = Path.GetFullPath( Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..")); - LocalPackagesPath = Path.Combine( - RepoRoot, "artifacts", "package", BuildConfiguration.ToLowerInvariant()); + LocalPackagesPath = ValidationPackage.DirectoryPath; } // ── Package version ────────────────────────────────────────────────────── @@ -45,14 +44,14 @@ protected string GetCoverletMtpPackageVersion() if (!Directory.Exists(LocalPackagesPath)) { throw new DirectoryNotFoundException( - $"Local packages path '{LocalPackagesPath}' not found. Run 'dotnet pack' first."); + $"Local packages path '{LocalPackagesPath}' not found. Supply the existing Codebelt.Coverlet.MTP package in this directory, or rebuild the validation test project locally with -p:PrepareValidationPackage=true to prepare it automatically."); } string[] packages = Directory.GetFiles(LocalPackagesPath, "Codebelt.Coverlet.MTP.*.nupkg"); if (packages.Length == 0) { throw new InvalidOperationException( - $"Could not find Codebelt.Coverlet.MTP package in '{LocalPackagesPath}'. Run 'dotnet pack' first."); + $"Could not find Codebelt.Coverlet.MTP package in '{LocalPackagesPath}'. Supply the existing Codebelt.Coverlet.MTP package in this directory, or rebuild the validation test project locally with -p:PrepareValidationPackage=true to prepare it automatically."); } if (packages.Length > 1) diff --git a/test/coverlet.MTP.validation.tests/TestInfrastructure/ValidationPackage.cs b/test/coverlet.MTP.validation.tests/TestInfrastructure/ValidationPackage.cs new file mode 100644 index 000000000..2e1c2b909 --- /dev/null +++ b/test/coverlet.MTP.validation.tests/TestInfrastructure/ValidationPackage.cs @@ -0,0 +1,15 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; + +namespace Coverlet.MTP.validation.tests; + +internal static class ValidationPackage +{ + // MSBuild selects an isolated local package or the downloaded CI release artifact. + internal static string DirectoryPath { get; } = typeof(ValidationPackage).Assembly + .GetCustomAttributes() + .Single(attribute => attribute.Key == "ValidationPackagePath").Value + ?? throw new InvalidOperationException("Validation package path is missing. Rebuild the validation test project."); +} diff --git a/test/coverlet.MTP.validation.tests/coverlet.MTP.validation.tests.csproj b/test/coverlet.MTP.validation.tests/coverlet.MTP.validation.tests.csproj index c0b6cec7e..f1e21ca86 100644 --- a/test/coverlet.MTP.validation.tests/coverlet.MTP.validation.tests.csproj +++ b/test/coverlet.MTP.validation.tests/coverlet.MTP.validation.tests.csproj @@ -10,6 +10,14 @@ true false false + + true + false + true + + $(RepoRoot)artifacts/validation/$(Configuration)/$(TargetFramework) + $(ValidationArtifactsPath)/packages + $(RepoRoot)artifacts/package/$(Configuration.ToLowerInvariant()) true true @@ -26,6 +34,7 @@ +