From 2494826eedbe57a8087159055945f843a118a792 Mon Sep 17 00:00:00 2001 From: Stuart Meeks Date: Wed, 19 Aug 2026 15:30:33 +0000 Subject: [PATCH] chore: migrate tests to xUnit.net v3, cover both shipped TFMs, repo maintenance Test framework - xunit 2.9.3 -> xunit.v3 4.0.0 (there is no `xunit` 4.0.0; v3 ships as `xunit.v3`). v3 test projects are self-executing console apps, so the test project is now OutputType=Exe. - v3 4.0.0 runs on Microsoft.Testing.Platform, and MTP dropped VSTest-bridge support on the .NET 10 SDK, so `dotnet test` opts into the MTP runner via a root global.json. `TestingPlatformDotnetTestSupport` is the old path and now hard-errors. - Dropped Microsoft.NET.Test.Sdk and xunit.runner.visualstudio: both are VSTest-only. (xunit.runner.visualstudio 4.0.0 is still the *v2* adapter, not a v3 upgrade path.) - Fixed xUnit2033 in GradientTests, surfaced by v3's analyzers and promoted to an error by TreatWarningsAsErrors. Test coverage - Test project multi-targets net8.0;net10.0, mirroring the library. lib/net8.0 was previously compiled but never executed; the suite now runs once per TFM against its own dependency graph (80 executions). - CI build job installs the 8.0.x runtime alongside 10.0.x. Building an older TFM needs only reference assemblies, but running it needs that runtime, so the previous 10.0.x-only setup would fail the net8.0 leg outright. The build still uses the newest SDK, as global.json carries no `sdk` pin. The publish job stays on 10.0.x since it executes no test code. Fixes - PackageOutputPath is guarded to Windows. With GeneratePackageOnBuild=true the hardcoded C:\nuget-local\ made every non-Windows build create a literal `C:\nuget-local\` directory under src/. - Publish job gains `contents: read`. An explicit `permissions` block sets every unlisted scope to `none`, leaving actions/checkout unable to clone. Cleanup - Removed Microsoft.SourceLink.GitHub; the .NET SDK has bundled SourceLink since .NET 8. Verified pack output is unchanged either way: identical .nuspec repository metadata and .snupkg PDBs still carrying source URLs. - Bumped actions/checkout v6->v7, setup-dotnet v5->v6, upload-artifact v6->v7, download-artifact v7->v8 (all routine dependency/runtime updates; no input changes affecting this workflow) and dropped the now-obsolete FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 transitional flag. - Deduped Nullable/Authors already set by Directory.Build.props. No library code, public API, or shipped package contents changed. Verified: restore/build/test/pack in Release matching CI - 0 warnings, 0 errors, 80/80 tests passing across net8.0 and net10.0, both lib/ assets packed with repository metadata intact. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 27 +++++++------ CHANGELOG.md | 38 +++++++++++++++++++ Directory.Packages.props | 5 +-- global.json | 5 +++ ...NextIteration.SpectreConsole.Splash.csproj | 7 ++-- .../GradientTests.cs | 8 ++-- ...eration.SpectreConsole.Splash.Tests.csproj | 11 +++--- 7 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 global.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbabcc3..e65602c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,5 @@ name: CI -env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - on: push: branches: [ main ] @@ -15,14 +12,21 @@ jobs: build: runs-on: ubuntu-latest + permissions: + contents: read + steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - - name: Setup .NET 10 - uses: actions/setup-dotnet@v5 + - name: Setup .NET + uses: actions/setup-dotnet@v6 with: - dotnet-version: '10.0.x' + # 8.0.x supplies the runtime the net8.0 test run executes on; the + # build itself uses the newest installed SDK (10.0.x). + dotnet-version: | + 8.0.x + 10.0.x - name: Restore run: dotnet restore @@ -37,7 +41,7 @@ jobs: run: dotnet pack --configuration Release --no-build --output ./artifacts - name: Upload package artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nuget-package # Capture both .nupkg and .snupkg so the publish job's @@ -51,19 +55,20 @@ jobs: if: startsWith(github.ref, 'refs/tags/v') permissions: + contents: read # actions/checkout — an explicit `permissions` block sets unlisted scopes to `none` id-token: write # required for NuGet trusted publishing (OIDC token issuance) steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Setup .NET 10 - uses: actions/setup-dotnet@v5 + uses: actions/setup-dotnet@v6 with: dotnet-version: '10.0.x' - name: Download artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: nuget-package path: ./artifacts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c63c00..e122e8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [Unreleased] + +### Changed + +- **Test suite migrated to xUnit.net v3 (`xunit.v3` 4.0.0)** from `xunit` 2.9.3. + Contributor-facing only — no library code, public API, or shipped package + contents changed. v3 test projects are self-executing console apps and run on + [Microsoft.Testing.Platform](https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro) + rather than VSTest, so a root `global.json` now opts `dotnet test` into the + MTP runner. `Microsoft.NET.Test.Sdk` and `xunit.runner.visualstudio` are no + longer needed and were dropped. + +- **Tests now run against both shipped TFMs.** The test project multi-targets + `net8.0;net10.0`, mirroring the library, so `lib/net8.0` is actually executed + against its own dependency graph instead of only being compiled. Previously + the suite ran on `net10.0` only. Running the full suite locally now requires + the .NET 8 runtime alongside the .NET 10 SDK. + +### Removed + +- **`Microsoft.SourceLink.GitHub` package reference.** The .NET SDK has bundled + SourceLink since .NET 8; the explicit reference was redundant. Verified + byte-identical `.nuspec` and `.snupkg` output either way — consumers still get + repository metadata and step-through sources. + +### Fixed + +- **`PackageOutputPath` no longer breaks non-Windows builds.** The hardcoded + `C:\nuget-local\` local dev feed is now guarded to Windows; previously every + `dotnet build` on Linux/macOS and in CI created a literal `C:\nuget-local\` + directory under `src/`. +- **CI publish job could not check out the repo.** Its `permissions` block listed + only `id-token: write`, and GitHub sets every unlisted scope to `none`, leaving + `actions/checkout` without `contents: read`. + +--- + ## [0.3.0] — 2026-07-24 ### Changed @@ -82,6 +119,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 interpolation, colour validation, tagline strategies, renderer output, and the quote pool). +[Unreleased]: https://github.com/StuartMeeks/NextIteration.SpectreConsole.Splash/compare/v0.3.0...HEAD [0.3.0]: https://github.com/StuartMeeks/NextIteration.SpectreConsole.Splash/releases/tag/v0.3.0 [0.2.0]: https://github.com/StuartMeeks/NextIteration.SpectreConsole.Splash/releases/tag/v0.2.0 [0.1.2]: https://github.com/StuartMeeks/NextIteration.SpectreConsole.Splash/releases/tag/v0.1.2 diff --git a/Directory.Packages.props b/Directory.Packages.props index 1bafd33..8d91e1b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,13 +7,10 @@ - - - - + diff --git a/global.json b/global.json new file mode 100644 index 0000000..3140116 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +} diff --git a/src/NextIteration.SpectreConsole.Splash/NextIteration.SpectreConsole.Splash.csproj b/src/NextIteration.SpectreConsole.Splash/NextIteration.SpectreConsole.Splash.csproj index b846efa..153949d 100644 --- a/src/NextIteration.SpectreConsole.Splash/NextIteration.SpectreConsole.Splash.csproj +++ b/src/NextIteration.SpectreConsole.Splash/NextIteration.SpectreConsole.Splash.csproj @@ -3,7 +3,6 @@ net8.0;net10.0 enable - enable en true latest @@ -12,10 +11,11 @@ NextIteration.SpectreConsole.Splash 0.3.0 - Stuart Meeks Configurable Figgle + Spectre.Console splash screen for .NET CLIs — gradient palette, pluggable tagline strategy, single-markup-call render path. true - C:\nuget-local\ + + C:\nuget-local\ true MIT README.md @@ -42,7 +42,6 @@ - diff --git a/tests/NextIteration.SpectreConsole.Splash.Tests/GradientTests.cs b/tests/NextIteration.SpectreConsole.Splash.Tests/GradientTests.cs index 60ea4be..c66ec06 100644 --- a/tests/NextIteration.SpectreConsole.Splash.Tests/GradientTests.cs +++ b/tests/NextIteration.SpectreConsole.Splash.Tests/GradientTests.cs @@ -78,10 +78,10 @@ public void Width_one_returns_first_stop() { var result = Gradient.Generate(["#123456", "#FFFFFF"], 1); - Assert.Single(result); - Assert.Equal(0x12, result[0].R); - Assert.Equal(0x34, result[0].G); - Assert.Equal(0x56, result[0].B); + var only = Assert.Single(result); + Assert.Equal(0x12, only.R); + Assert.Equal(0x34, only.G); + Assert.Equal(0x56, only.B); } [Fact] diff --git a/tests/NextIteration.SpectreConsole.Splash.Tests/NextIteration.SpectreConsole.Splash.Tests.csproj b/tests/NextIteration.SpectreConsole.Splash.Tests/NextIteration.SpectreConsole.Splash.Tests.csproj index e56d1fb..1447a3d 100644 --- a/tests/NextIteration.SpectreConsole.Splash.Tests/NextIteration.SpectreConsole.Splash.Tests.csproj +++ b/tests/NextIteration.SpectreConsole.Splash.Tests/NextIteration.SpectreConsole.Splash.Tests.csproj @@ -1,9 +1,12 @@ - net10.0 + + net8.0;net10.0 + + Exe enable - enable false true @@ -11,10 +14,8 @@ - - - +