From 0fdabd67f7f9d5e5a1b093b259a54d5205199658 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 25 Sep 2026 12:12:06 +0000 Subject: [PATCH 1/2] build(deps): consolidate all pending Dependabot updates and group future ones Supersedes the individual Dependabot PRs with one validated change: - NuGet: Microsoft.SourceLink.GitHub 10.0.401, CsCheck 4.9.1, Microsoft.NET.Test.Sdk 18.10.1, xunit.runner.visualstudio 4.0.0, TngTech.ArchUnitNET.xUnit 0.13.4, BenchmarkDotNet 0.15.8, JsonSchema.Net 8.0.5 (last MIT line; 9.x is under the OSMF EULA). - Tools: docfx 2.81.0, dotnet-stryker 5.0.0. - Actions (SHA-pinned): checkout v7.0.1, setup-dotnet v6.0.0, upload-artifact v7.0.1, upload-pages-artifact v5.0.0, deploy-pages v5.0.1, attest-build-provenance v4.2.2. JsonSchema.Net 8 evaluates JsonElement and registers schemas globally by $id, so the published CLI schemas are now built once and JsonNode instances are bridged through a small Evaluate extension. Dependabot now runs monthly with grouped PRs (minor/patch, major, security, actions) and ignores JsonSchema.Net >= 9. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015aAHNotbe7KMXnnyfZwMG9 --- .config/dotnet-tools.json | 4 +- .github/dependabot.yml | 40 ++++++++++++++++--- .github/workflows/aot.yml | 4 +- .github/workflows/ci.yml | 8 ++-- .github/workflows/comparison.yml | 10 ++--- .github/workflows/dependency-audit.yml | 6 +-- .github/workflows/docs.yml | 8 ++-- .github/workflows/exhaustive.yml | 6 +-- .github/workflows/perf.yml | 6 +-- .github/workflows/release.yml | 14 +++---- .github/workflows/sat-benchmarks.yml | 8 ++-- CHANGELOG.md | 13 +++++- .../LogicalOptimizer.Bdd.csproj | 2 +- .../LogicalOptimizer.Benchmarks.csproj | 2 +- .../LogicalOptimizer.Core.csproj | 2 +- .../LogicalOptimizer.Dnnf.csproj | 2 +- .../LogicalOptimizer.Formats.csproj | 2 +- .../LogicalOptimizer.Minimization.csproj | 2 +- .../LogicalOptimizer.Sat.csproj | 2 +- .../Cli/PublishedCliSchema.cs | 22 ++++++++-- .../LogicalOptimizer.Tests.csproj | 10 ++--- LogicalOptimizer/LogicalOptimizer.csproj | 2 +- 22 files changed, 115 insertions(+), 60 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9a373fa..9285e85 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,14 +3,14 @@ "isRoot": true, "tools": { "dotnet-stryker": { - "version": "4.14.2", + "version": "5.0.0", "commands": [ "dotnet-stryker" ], "rollForward": false }, "docfx": { - "version": "2.78.5", + "version": "2.81.0", "commands": [ "docfx" ], diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d8702c1..1830c40 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,19 +1,49 @@ # Automated dependency update PRs. Complements .github/workflows/dependency-audit.yml # (the scheduled vulnerability scan): Dependabot proposes upgrades, the audit fails loudly # when a currently-referenced package acquires a known advisory. +# +# Updates are GROUPED so a normal month produces a couple of PRs, not one per package: +# every bump still lands as an exact pinned version and still has to pass the full CI +# matrix, but related bumps are reviewed (and fixed up, when a major breaks the build) together. +# Security updates are not delayed by the schedule — Dependabot raises them as soon as an +# advisory is published, in their own group. version: 2 updates: - package-ecosystem: nuget directory: / schedule: - interval: weekly - # One PR per dependency; the repo pins exact versions, so every bump is reviewed. - open-pull-requests-limit: 10 + interval: monthly + open-pull-requests-limit: 5 + groups: + # SourceLink and the test/benchmark stack: minor and patch bumps travel together. + nuget-minor-and-patch: + applies-to: version-updates + update-types: + - minor + - patch + # Majors get their own grouped PR: they are the ones that can need code changes. + nuget-major: + applies-to: version-updates + update-types: + - major + nuget-security: + applies-to: security-updates + patterns: + - "*" + ignore: + # 9.x moved from MIT to the Open Source Maintenance Fee EULA; 8.x is the last + # MIT-licensed line. Test-only dependency, pinned there on purpose. + - dependency-name: JsonSchema.Net + versions: [">= 9.0.0"] # Keeps the SHA-pinned actions current: Dependabot updates the pinned commit and the # human-readable version comment together, which is the only sane way to maintain - # SHA pinning by hand-edited workflows. + # SHA pinning by hand-edited workflows. All action bumps arrive as one PR. - package-ecosystem: github-actions directory: / schedule: - interval: weekly + interval: monthly + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/aot.yml b/.github/workflows/aot.yml index afc8cfa..1e1e5df 100644 --- a/.github/workflows/aot.yml +++ b/.github/workflows/aot.yml @@ -26,10 +26,10 @@ jobs: binary: LogicalOptimizer.AotSmoke.exe steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c176e3..31c50be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,10 +18,10 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -63,7 +63,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-results-${{ matrix.os }} path: TestResults/** @@ -119,7 +119,7 @@ jobs: - name: Upload package contract report if: always() && runner.os == 'Linux' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: package-contract-report path: package-contract-report.json diff --git a/.github/workflows/comparison.yml b/.github/workflows/comparison.yml index 1d0d3d3..7f698d3 100644 --- a/.github/workflows/comparison.yml +++ b/.github/workflows/comparison.yml @@ -16,10 +16,10 @@ jobs: timeout-minutes: 20 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -56,7 +56,7 @@ jobs: - name: Upload comparison artifacts if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: cross-library-comparison path: | @@ -82,7 +82,7 @@ jobs: timeout-minutes: 90 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Keep what is committed, so the fresh run can be diffed against it for determinism. - name: Set aside the committed results @@ -112,7 +112,7 @@ jobs: - name: Upload the reproduced report if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: comparison-reproduced-from-scratch path: | diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml index e403866..9a3be61 100644 --- a/.github/workflows/dependency-audit.yml +++ b/.github/workflows/dependency-audit.yml @@ -18,10 +18,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -43,7 +43,7 @@ jobs: - name: Upload audit log if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: dependency-audit path: audit.txt diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 56cf027..be972f1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -44,10 +44,10 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -75,7 +75,7 @@ jobs: run: dotnet docfx docs-site/docfx.json - name: Upload Pages artifact - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: docs-site/_site @@ -88,4 +88,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.github/workflows/exhaustive.yml b/.github/workflows/exhaustive.yml index 8e0edd2..ec6579b 100644 --- a/.github/workflows/exhaustive.yml +++ b/.github/workflows/exhaustive.yml @@ -25,10 +25,10 @@ jobs: timeout-minutes: 120 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -48,7 +48,7 @@ jobs: - name: Upload results if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: exhaustive-results path: TestResults/** diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 2ccc494..f7abe01 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -27,10 +27,10 @@ jobs: timeout-minutes: 40 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -67,7 +67,7 @@ jobs: - name: Upload BenchmarkDotNet artifacts if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: perf-benchmarkdotnet path: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5d15ab..6d77dd4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,10 +27,10 @@ jobs: contents: write # checkout + attach the evidence bundle to this tag's release attestations: write # build provenance attestations for the published packages steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -94,7 +94,7 @@ jobs: # the bundle is never built — upload them directly so a refused release is diagnosable. - name: Upload test results if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: release-test-results path: TestResults/** @@ -170,7 +170,7 @@ jobs: # for real (including the Linux Native AOT smoke of the packed bytes), nothing below does. - name: Upload pre-publish evidence (dry run) if: env.PUBLISH != 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: dry-run-evidence-${{ env.VERSION }} path: | @@ -183,13 +183,13 @@ jobs: # and a dry run releases nothing. - name: Attest build provenance if: env.PUBLISH == 'true' - uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0 + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 with: subject-path: 'artifacts/*.nupkg' - name: Upload packages as run artifacts if: env.PUBLISH == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: nupkg-${{ env.VERSION }} path: | @@ -242,7 +242,7 @@ jobs: - name: Upload evidence bundle as a run artifact if: env.PUBLISH == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: release-evidence-${{ env.VERSION }} path: evidence/** diff --git a/.github/workflows/sat-benchmarks.yml b/.github/workflows/sat-benchmarks.yml index 0884602..0807d6b 100644 --- a/.github/workflows/sat-benchmarks.yml +++ b/.github/workflows/sat-benchmarks.yml @@ -20,10 +20,10 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: dotnet-version: 10.0.x @@ -45,7 +45,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: sat-corpus-trx path: '**/TestResults/*.trx' @@ -60,7 +60,7 @@ jobs: - name: Upload BenchmarkDotNet artifacts if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_benchmarkdotnet }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: sat-benchmarkdotnet path: BenchmarkDotNet.Artifacts/** diff --git a/CHANGELOG.md b/CHANGELOG.md index 0394134..e8990c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Fixed +### Changed + +- **Dependencies brought current.** SourceLink 10.0.401 (build-only, `PrivateAssets="All"`), and + in the non-shipping projects CsCheck 4.9.1, Microsoft.NET.Test.Sdk 18.10.1, + xunit.runner.visualstudio 4.0.0, TngTech.ArchUnitNET.xUnit 0.13.4, BenchmarkDotNet 0.15.8; + tool manifest docfx 2.81.0 and dotnet-stryker 5.0.0; workflow actions checkout v7.0.1, + setup-dotnet v6.0.0, upload-artifact v7.0.1, upload-pages-artifact v5.0.0, deploy-pages v5.0.1 + and attest-build-provenance v4.2.2 (still SHA-pinned). JsonSchema.Net moves to 8.0.5, the last + MIT-licensed line: 9.x ships under the Open Source Maintenance Fee EULA, so Dependabot ignores + it. The library's own dependency graph is unchanged. +- **Dependabot groups its PRs.** Monthly, with minor/patch bumps, majors, security fixes and + GitHub Actions each arriving as one grouped PR instead of one PR per package. - **The release workflow no longer finishes green without a GitHub release.** Its last step attached the evidence bundle and the attested `.nupkg`/`.snupkg`/`SHA256SUMS.txt` only when a diff --git a/LogicalOptimizer.Bdd/LogicalOptimizer.Bdd.csproj b/LogicalOptimizer.Bdd/LogicalOptimizer.Bdd.csproj index c2de8e4..9498e8e 100644 --- a/LogicalOptimizer.Bdd/LogicalOptimizer.Bdd.csproj +++ b/LogicalOptimizer.Bdd/LogicalOptimizer.Bdd.csproj @@ -36,7 +36,7 @@ - + diff --git a/LogicalOptimizer.Benchmarks/LogicalOptimizer.Benchmarks.csproj b/LogicalOptimizer.Benchmarks/LogicalOptimizer.Benchmarks.csproj index c0f330f..5c0a45a 100644 --- a/LogicalOptimizer.Benchmarks/LogicalOptimizer.Benchmarks.csproj +++ b/LogicalOptimizer.Benchmarks/LogicalOptimizer.Benchmarks.csproj @@ -10,7 +10,7 @@ - + diff --git a/LogicalOptimizer.Core/LogicalOptimizer.Core.csproj b/LogicalOptimizer.Core/LogicalOptimizer.Core.csproj index 6cdfab0..ce5e9a0 100644 --- a/LogicalOptimizer.Core/LogicalOptimizer.Core.csproj +++ b/LogicalOptimizer.Core/LogicalOptimizer.Core.csproj @@ -42,7 +42,7 @@ - + diff --git a/LogicalOptimizer.Dnnf/LogicalOptimizer.Dnnf.csproj b/LogicalOptimizer.Dnnf/LogicalOptimizer.Dnnf.csproj index c6ad41e..ce28b5d 100644 --- a/LogicalOptimizer.Dnnf/LogicalOptimizer.Dnnf.csproj +++ b/LogicalOptimizer.Dnnf/LogicalOptimizer.Dnnf.csproj @@ -34,7 +34,7 @@ - + diff --git a/LogicalOptimizer.Formats/LogicalOptimizer.Formats.csproj b/LogicalOptimizer.Formats/LogicalOptimizer.Formats.csproj index 46ccb17..544f553 100644 --- a/LogicalOptimizer.Formats/LogicalOptimizer.Formats.csproj +++ b/LogicalOptimizer.Formats/LogicalOptimizer.Formats.csproj @@ -34,7 +34,7 @@ - + diff --git a/LogicalOptimizer.Minimization/LogicalOptimizer.Minimization.csproj b/LogicalOptimizer.Minimization/LogicalOptimizer.Minimization.csproj index 33ea340..b00c6c6 100644 --- a/LogicalOptimizer.Minimization/LogicalOptimizer.Minimization.csproj +++ b/LogicalOptimizer.Minimization/LogicalOptimizer.Minimization.csproj @@ -36,7 +36,7 @@ - + diff --git a/LogicalOptimizer.Sat/LogicalOptimizer.Sat.csproj b/LogicalOptimizer.Sat/LogicalOptimizer.Sat.csproj index a372337..71f87d0 100644 --- a/LogicalOptimizer.Sat/LogicalOptimizer.Sat.csproj +++ b/LogicalOptimizer.Sat/LogicalOptimizer.Sat.csproj @@ -38,7 +38,7 @@ - + diff --git a/LogicalOptimizer.Tests/Cli/PublishedCliSchema.cs b/LogicalOptimizer.Tests/Cli/PublishedCliSchema.cs index 979e200..b5fecf8 100644 --- a/LogicalOptimizer.Tests/Cli/PublishedCliSchema.cs +++ b/LogicalOptimizer.Tests/Cli/PublishedCliSchema.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Text.Json; using System.Text.Json.Nodes; using Json.Schema; using Xunit; @@ -18,9 +19,15 @@ internal static class PublishedCliSchema { public static string Directory => Path.Combine(AppContext.BaseDirectory, "Schema"); - public static JsonSchema Schema => Load("cli-report-v1.schema.json"); + // Built once per test run: JsonSchema.Net registers every built schema under its `$id` in the + // process-wide SchemaRegistry and refuses to register the same `$id` twice. + private static readonly Lazy ReportSchema = new(() => Load("cli-report-v1.schema.json")); - public static JsonSchema CheckSchema => Load("cli-check-report-v1.schema.json"); + private static readonly Lazy CheckReportSchema = new(() => Load("cli-check-report-v1.schema.json")); + + public static JsonSchema Schema => ReportSchema.Value; + + public static JsonSchema CheckSchema => CheckReportSchema.Value; private static JsonSchema Load(string fileName) { @@ -55,14 +62,21 @@ private static void AssertValid(JsonSchema schema, string schemaName, string jso var evaluation = schema.Evaluate(instance, StrictEvaluation); if (evaluation.IsValid) return; - var errors = evaluation.Details - .Where(d => d.HasErrors) + var errors = (evaluation.Details ?? [evaluation]) + .Where(d => d.Errors is { Count: > 0 }) .SelectMany(d => d.Errors!.Select(e => $" {d.InstanceLocation}: {e.Key} -> {e.Value}")) .ToArray(); Assert.Fail($"{what} does not satisfy schema/{schemaName}:\n" + string.Join("\n", errors) + "\n\nDocument was:\n" + json); } + /// + /// JsonSchema.Net 8 evaluates instances only; the suites build and + /// mutate their documents as , so this bridges the two at the call site. + /// + public static EvaluationResults Evaluate(this JsonSchema schema, JsonNode? instance, EvaluationOptions options) => + schema.Evaluate(JsonSerializer.SerializeToElement(instance), options); + public static string RepositoryRoot() { var directory = new DirectoryInfo(AppContext.BaseDirectory); diff --git a/LogicalOptimizer.Tests/LogicalOptimizer.Tests.csproj b/LogicalOptimizer.Tests/LogicalOptimizer.Tests.csproj index af1ebd5..b82cef4 100644 --- a/LogicalOptimizer.Tests/LogicalOptimizer.Tests.csproj +++ b/LogicalOptimizer.Tests/LogicalOptimizer.Tests.csproj @@ -10,18 +10,18 @@ - + - - + + - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/LogicalOptimizer/LogicalOptimizer.csproj b/LogicalOptimizer/LogicalOptimizer.csproj index 93fe911..2f410b4 100644 --- a/LogicalOptimizer/LogicalOptimizer.csproj +++ b/LogicalOptimizer/LogicalOptimizer.csproj @@ -43,7 +43,7 @@ - + From e4c61c08e8b078102a781dcb7d50ac6531fbd78f Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 25 Sep 2026 12:46:43 +0000 Subject: [PATCH 2/2] chore(release): prepare 4.0.1 Bump to 4.0.1 and date the CHANGELOG section so the release workflow's changelog gate accepts the v4.0.1 tag. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015aAHNotbe7KMXnnyfZwMG9 --- CHANGELOG.md | 2 ++ Directory.Build.props | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8990c6..2846de7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.0.1] - 2026-09-25 + ### Changed - **Dependencies brought current.** SourceLink 10.0.401 (build-only, `PrivateAssets="All"`), and diff --git a/Directory.Build.props b/Directory.Build.props index 0d802a5..8e0bc26 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -10,7 +10,7 @@ TreatWarningsAsErrors. --> - 4.0.0 + 4.0.1 Oleksandr Panasenko Apache-2.0 https://AlexanderV.github.io/LogicalOptimizer/