From 2c90a4199b3c6aaec33ac2ba3b948b327dc4ddd4 Mon Sep 17 00:00:00 2001 From: JerrettDavis Date: Wed, 27 May 2026 21:47:18 -0500 Subject: [PATCH] build: baseline recommended analyzers --- .editorconfig | 55 +++++++++++++++++++ .github/workflows/ci.yml | 52 ++++++++++++------ Directory.Build.props | 9 +++ .../PatternKit.Benchmarks.csproj | 3 +- docs/guides/quality-gates.md | 37 +++++++++---- 5 files changed, 129 insertions(+), 27 deletions(-) diff --git a/.editorconfig b/.editorconfig index 94c5eae8..261c615c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -49,6 +49,61 @@ dotnet_style_prefer_auto_properties = true:suggestion dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion dotnet_style_prefer_conditional_expression_over_return = true:suggestion +# Recommended .NET analyzers are enabled for production package projects. +# These path-scoped suppressions are the current production API baseline; tighten +# them by rule family as tracked cleanup work resolves each category. +[src/PatternKit.Core/**/*.cs] +dotnet_diagnostic.CA1000.severity = none +dotnet_diagnostic.CA1001.severity = none +dotnet_diagnostic.CA1018.severity = none +dotnet_diagnostic.CA1068.severity = none +dotnet_diagnostic.CA1305.severity = none +dotnet_diagnostic.CA1510.severity = none +dotnet_diagnostic.CA1512.severity = none +dotnet_diagnostic.CA1513.severity = none +dotnet_diagnostic.CA1710.severity = none +dotnet_diagnostic.CA1711.severity = none +dotnet_diagnostic.CA1716.severity = none +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA1822.severity = none +dotnet_diagnostic.CA1859.severity = none +dotnet_diagnostic.CA1860.severity = none +dotnet_diagnostic.CA2012.severity = none +dotnet_diagnostic.CA2016.severity = none +dotnet_diagnostic.CA2208.severity = none + +[src/PatternKit.Generators/**/*.cs] +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA1725.severity = none +dotnet_diagnostic.CA1805.severity = none +dotnet_diagnostic.CA1822.severity = none +dotnet_diagnostic.CA1834.severity = none +dotnet_diagnostic.CA1852.severity = none +dotnet_diagnostic.CA1859.severity = none +dotnet_diagnostic.CA1860.severity = none + +[src/PatternKit.Generators/*.cs] +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA1725.severity = none +dotnet_diagnostic.CA1805.severity = none +dotnet_diagnostic.CA1822.severity = none +dotnet_diagnostic.CA1834.severity = none +dotnet_diagnostic.CA1852.severity = none +dotnet_diagnostic.CA1859.severity = none +dotnet_diagnostic.CA1860.severity = none + +[src/PatternKit.Generators.Abstractions/**/*.cs] +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA1805.severity = none + +[src/PatternKit.Generators.Abstractions/*.cs] +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA1805.severity = none + +[src/PatternKit.Hosting.Extensions/**/*.cs] +dotnet_diagnostic.CA1510.severity = none +dotnet_diagnostic.CA2263.severity = none + [*.{json,yml,yaml,md}] indent_style = space indent_size = 2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d635ed0f..06fb1d83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,15 +54,25 @@ jobs: - name: Test with coverage timeout-minutes: 30 + shell: bash run: | - dotnet test PatternKit.slnx \ - --configuration Release \ - -p:TestTfmsInParallel=false \ - --collect:"XPlat Code Coverage" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ - -- RunConfiguration.TestSessionTimeout=1800000 + set -euo pipefail + for project in \ + test/PatternKit.Tests/PatternKit.Tests.csproj \ + test/PatternKit.Generators.Tests/PatternKit.Generators.Tests.csproj \ + test/PatternKit.Examples.Tests/PatternKit.Examples.Tests.csproj \ + test/PatternKit.Hosting.Extensions.Tests/PatternKit.Hosting.Extensions.Tests.csproj + do + dotnet test "$project" \ + --configuration Release \ + --no-build \ + -p:TestTfmsInParallel=false \ + --collect:"XPlat Code Coverage" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ + -- RunConfiguration.TestSessionTimeout=1800000 + done - name: Install ReportGenerator run: dotnet tool update -g dotnet-reportgenerator-globaltool @@ -171,15 +181,25 @@ jobs: - name: Test with coverage (Release) timeout-minutes: 30 + shell: bash run: | - dotnet test PatternKit.slnx \ - --configuration Release \ - -p:TestTfmsInParallel=false \ - --collect:"XPlat Code Coverage" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ - -- RunConfiguration.TestSessionTimeout=1800000 + set -euo pipefail + for project in \ + test/PatternKit.Tests/PatternKit.Tests.csproj \ + test/PatternKit.Generators.Tests/PatternKit.Generators.Tests.csproj \ + test/PatternKit.Examples.Tests/PatternKit.Examples.Tests.csproj \ + test/PatternKit.Hosting.Extensions.Tests/PatternKit.Hosting.Extensions.Tests.csproj + do + dotnet test "$project" \ + --configuration Release \ + --no-build \ + -p:TestTfmsInParallel=false \ + --collect:"XPlat Code Coverage" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ + -- RunConfiguration.TestSessionTimeout=1800000 + done - name: Pack (all packable projects) diff --git a/Directory.Build.props b/Directory.Build.props index f2b15ae7..2d75f2a0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,6 +11,15 @@ $(NoWarn);1591 + + true + latest + Recommended + + Jerrett Davis and contributors JDH Productions LLC. diff --git a/benchmarks/PatternKit.Benchmarks/PatternKit.Benchmarks.csproj b/benchmarks/PatternKit.Benchmarks/PatternKit.Benchmarks.csproj index 4e64b477..50eda038 100644 --- a/benchmarks/PatternKit.Benchmarks/PatternKit.Benchmarks.csproj +++ b/benchmarks/PatternKit.Benchmarks/PatternKit.Benchmarks.csproj @@ -17,6 +17,7 @@ + ReferenceOutputAssembly="false" + AdditionalProperties="TargetFramework=netstandard2.0" /> diff --git a/docs/guides/quality-gates.md b/docs/guides/quality-gates.md index 6c7924ce..90a9b91f 100644 --- a/docs/guides/quality-gates.md +++ b/docs/guides/quality-gates.md @@ -12,17 +12,25 @@ dotnet format PatternKit.slnx --verify-no-changes --verbosity minimal dotnet build PatternKit.slnx --configuration Release --no-restore -m:1 ``` -Run the focused test suite for the area being changed. For broad changes, run the solution test command used by CI: +Run the focused test suite for the area being changed. For broad changes, run the same project-by-project coverage shape used by CI: ```bash -dotnet test PatternKit.slnx \ - --configuration Release \ - -p:TestTfmsInParallel=false \ - --collect:"XPlat Code Coverage" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ - -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ - -- RunConfiguration.TestSessionTimeout=1800000 +for project in \ + test/PatternKit.Tests/PatternKit.Tests.csproj \ + test/PatternKit.Generators.Tests/PatternKit.Generators.Tests.csproj \ + test/PatternKit.Examples.Tests/PatternKit.Examples.Tests.csproj \ + test/PatternKit.Hosting.Extensions.Tests/PatternKit.Hosting.Extensions.Tests.csproj +do + dotnet test "$project" \ + --configuration Release \ + --no-build \ + -p:TestTfmsInParallel=false \ + --collect:"XPlat Code Coverage" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PatternKit*]*" \ + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[*Tests]*" \ + -- RunConfiguration.TestSessionTimeout=1800000 +done ``` Build documentation with warnings treated as failures: @@ -71,4 +79,13 @@ Every production pattern should have: The repository includes a root `.editorconfig` so editors, `dotnet format`, and CI agree on basic C# layout and style. Run `dotnet format PatternKit.slnx --verify-no-changes --verbosity minimal` before opening a PR; CI enforces the same gate for pull requests and `main` releases. -Built-in .NET analyzers can be audited with `/p:EnableNETAnalyzers=true /p:AnalysisLevel=latest /p:AnalysisMode=Recommended /p:EnforceCodeStyleInBuild=true`. That audit currently surfaces project-specific baselines, including source-generator workspace gaps in examples and benchmarks, fluent API shape warnings in production code, benchmark naming warnings, and culture-sensitive string assertions in generator tests. Enable stricter analyzer families by project with explicit baselines rather than turning on every optional rule at once. +Built-in .NET analyzers are enabled in `Recommended` mode for the production package projects: + +- `PatternKit.Core` +- `PatternKit.Generators` +- `PatternKit.Generators.Abstractions` +- `PatternKit.Hosting.Extensions` + +The current rule-family baseline is path-scoped in `.editorconfig`. Tighten it by removing one rule family at a time, fixing or documenting the production API impact, and validating the affected package with `/t:Rebuild`. + +Do not enable `EnforceCodeStyleInBuild` at the solution level. `dotnet format` remains the repository style gate, and forcing code-style analysis through MSBuild currently prevents design-time workspace loading for examples and benchmarks that depend on PatternKit source generators. Keep source-generated consumers validated through the normal restore, format, build, test, docs, and benchmark gates instead of routing style diagnostics through generated-symbol design-time builds.