Release v0.1.0: ship Wolfgang.Extensions.Logging.InMemoryLogger#32
Merged
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Setup-BranchRuleset.ps1, Setup-Labels.ps1, Setup-GitHubPages.ps1, and format.ps1 scripts. These must be run manually after merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace feature_request.md with feature_request.yaml for structured issue forms with validation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…yaml - Add Fix-BranchRuleset.ps1: inspects, disables, and renames existing rulesets so Setup-BranchRuleset.ps1 can recreate them cleanly - Update Setup-BranchRuleset.ps1 to match current repo-template with correct repository name and status check names - Switch pr.yaml to pull_request_target for secure workflow execution - Add explicit ref and persist-credentials: false to all checkout steps Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uccess Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Exclude Claude Code local settings from version control. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…scripts Add Fix-BranchRuleset.ps1 and update Setup-BranchRuleset.ps1
Add SECURITY.md
…-request-template Update Repo - 007 - Upgrade feature request to GitHub Forms
Update Repo - Add Setup-Labels.ps1 script
Add .claude/ to .gitignore
PR #9 already merged a newer version of this script to develop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add .gitattributes, .globalconfig, Directory.Build.props, and BannedSymbols.txt from repo-template to standardize line endings, analyzer configuration, and banned API enforcement. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add missing documentation infrastructure files for DocFX site generation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add weekly CodeQL scanning from repo-template. Runs on pushes to main, PRs targeting main, and weekly Sunday schedule. Gracefully skips when no C# source code is present. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ning' into develop # Conflicts: # .github/workflows/pr.yaml
Source project: - Fix PackageProjectUrl pointing to wrong repo - Single-line TargetFrameworks (CI grep compat) - Add missing TFMs: netstandard2.1 and net10.0 - Clean up ImplicitUsings condition (remove embedded CRLF escapes) - Add SuppressTfmSupportBuildWarnings for older TFMs - Fix FullName null safety (fallback to Name) - Add thread safety via lock on log entry collection - Fix BeginScope to return no-op disposable instead of null! - Remove stale NotImplementedException XML doc from IsEnabled - Fix ambiguous LogLevel cref in XML doc - Add explicit null-forgiving operators on state boxing - Change LogEntries to IReadOnlyList with snapshot copy - Add InternalsVisibleTo for test project Test project: - Update xunit to 2.9.3, xunit.runner.visualstudio to 2.8.2 - Update coverlet.collector to 6.0.4, Microsoft.NET.Test.Sdk to 17.12.0 - Add multi-TFM: net462 through net481, net5.0 through net10.0 - Suppress NU1701 for xunit runner TFM compat - Fix test naming to MethodUnderTest_when_condition_result pattern - Remove dead commented-out test code - Add BeginScope test Solution/docs: - Delete duplicate Solution.slnx (template leftover) - Update .slnx references (fix feature_request.md -> .yaml, add new files) - Replace template README with project-specific content Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- IsEnabled: return false when logLevel is LogLevel.None - Capacity: acquire lock for thread safety - PackageReadmeFile: include root README.md via None item for NuGet pack - Add IsEnabled_when_logLevel_is_None_returns_false test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Source project: - Fix PackageProjectUrl pointing to wrong repo - Single-line TargetFrameworks (CI grep compat) - Add missing TFMs: netstandard2.1 and net10.0 - Clean up ImplicitUsings condition (remove embedded CRLF escapes) - Add SuppressTfmSupportBuildWarnings for older TFMs - Fix FullName null safety (fallback to Name) - Add thread safety via lock on log entry collection - Fix BeginScope to return no-op disposable instead of null! - Remove stale NotImplementedException XML doc from IsEnabled - Fix ambiguous LogLevel cref in XML doc - Add explicit null-forgiving operators on state boxing - Change LogEntries to IReadOnlyList with snapshot copy - Add InternalsVisibleTo for test project Test project: - Update xunit to 2.9.3, xunit.runner.visualstudio to 2.8.2 - Update coverlet.collector to 6.0.4, Microsoft.NET.Test.Sdk to 17.12.0 - Add multi-TFM: net462 through net481, net5.0 through net10.0 - Suppress NU1701 for xunit runner TFM compat - Fix test naming to MethodUnderTest_when_condition_result pattern - Remove dead commented-out test code - Add BeginScope test Solution/docs: - Delete duplicate Solution.slnx (template leftover) - Update .slnx references (fix feature_request.md -> .yaml, add new files) - Replace template README with project-specific content Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- IsEnabled: return false when logLevel is LogLevel.None - Capacity: acquire lock for thread safety - PackageReadmeFile: include root README.md via None item for NuGet pack - Add IsEnabled_when_logLevel_is_None_returns_false test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Feature 1: Non-generic InMemoryLogger - Takes a category string instead of type parameter - Same thread-safe implementation as InMemoryLogger<T> - InMemoryLogger<T> now delegates to InMemoryLogger internally Feature 2: InMemoryLoggerProvider - Implements ILoggerProvider for DI integration - Creates and caches InMemoryLogger instances per category - Exposes LogEntries (all entries across all loggers) and Loggers dictionary Feature 3: AddInMemoryLogger extension method - ILoggingBuilder.AddInMemoryLogger(provider) for DI registration - Adds Microsoft.Extensions.Logging package reference Feature 4: Scope tracking - BeginScope pushes state onto AsyncLocal<ScopeStack> - Dispose pops the scope (thread-safe via Interlocked) - Scopes property returns active scopes outermost to innermost 52 tests pass on net462 and net10.0. 0 build warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-infrastructure # Conflicts: # src/Wolfgang.Extensions.Logging.InMemoryLogger/InMemoryLogger.cs # src/Wolfgang.Extensions.Logging.InMemoryLogger/Wolfgang.Extensions.Logging.InMemoryLogger.csproj # tests/Wolfgang.Extensions.Logging.InMemoryLogger.Tests.Unit/InMemoryLoggerOfTTests.cs # tests/Wolfgang.Extensions.Logging.InMemoryLogger.Tests.Unit/Wolfgang.Extensions.Logging.InMemoryLogger.Tests.Unit.csproj
…emblies - CreateLogger: add null check for categoryName - ScopeDisposable.Dispose: guard against out-of-order disposal - LogEntries: fix doc to note ordering is not guaranteed across categories - Add Microsoft.NETFramework.ReferenceAssemblies for net462 CI builds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ructure Add non-generic logger, provider, DI extension, and scope tracking
Brings in: CI workflow upgrades (pr.yaml v3 gated, expanded release.yaml, DocFX deploy), MIT LICENSE, REPO-INSTRUCTIONS.md, refreshed scripts, docfx_project structure refresh, and placeholder fills. Conflict resolution: - workflows, scripts, BannedSymbols.txt: take main (latest CI infra) - README.md: keep develop (project-specific content, not scaffolding) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merge main into develop (template-sync catch-up)
Release builds now run 'dotnet build -c Release' with TreatWarningsAsErrors,
which surfaced existing analyzer findings that Debug builds didn't enforce.
src:
- InMemoryLoggerBuilderExtensions.AddInMemoryLogger: add <exception> XML doc
for ArgumentNullException (RCS1140)
- InMemoryLoggerProvider.CreateLogger: add <exception> XML doc for
ArgumentNullException (RCS1140)
- InMemoryLoggerProvider: mark sealed (CA1063, S3881). The class has no
overridable members and the existing no-op Dispose doesn't justify the
full Dispose(bool) pattern.
tests:
- InMemoryLogger{,OfT}Tests.Log_when_called_adds_entry_to_LogEntries:
- Name the 'exception' parameter explicitly (MA0003)
- Discard unused 'exception' parameter in the formatter delegate
(RCS1163, S3257)
- Use indexer on IReadOnlyList instead of First() (CA1826)
Verified locally: Release build 0/0, 52 tests pass on all TFMs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-errors Fix Release-build analyzer errors blocking develop -> main release
Brings the Dependabot exemption for the protected-configuration-files guard in pr.yaml from main onto develop. No source code changes, no conflicts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lop-pr29 Merge main into develop (PR #29 Dependabot exemption catch-up)
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
CI's pr.yaml fetches .editorconfig from main before building (the 'protected configuration files' guard). Locally, our .editorconfig sets several rules to 'suggestion' so they don't fail the build, but on CI the file appears to be ignored (the fetch step writes UTF-8 with BOM, which can prevent the analyzer from picking it up). Either way, the findings are real, so fix them at the source rather than leaning on .editorconfig overrides. src: - InMemoryLogger / InMemoryLogger<T>: suppress MA0049 (type name matches containing namespace) on each class with a SuppressMessage attribute and justification - the package, namespace, and primary type intentionally share a name. - InMemoryLogger: use System.Threading.Lock on net9+ (MA0158) via conditional compilation; keep object-based lock on older TFMs. - InMemoryLogger.ScopeDisposable.Dispose: merge nested ifs (S1066). - InMemoryLoggerProvider.LogEntries / Loggers: suppress S2365 (properties copying collections) - this is a deliberate test-helper API; cost is documented in <remarks>. - InMemoryLoggerProvider.Loggers: pass StringComparer.Ordinal to the Dictionary copy constructor (MA0002), matching the inner ConcurrentDictionary. tests: - InMemoryLoggerOfTTests.Ctor_when_default_parameters_creates_instance: Assert.NotNull(sut) instead of relying on a ReSharper comment to silence S1481/S2699. - InMemoryLoggerProviderTests.Dispose_does_not_throw: capture and assert on Record.Exception so the test has a real assertion (S2699). Verified locally: build clean both with and without .editorconfig present (simulating CI), 52/52 tests pass on net462, net47, net471, net472, net48, net481, net6.0, net7.0, net8.0, net9.0, net10.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
…zer-errors Fix CI Release-build analyzer errors
- actions/download-artifact: v4 -> v8.0.1 - softprops/action-gh-release: v2.5.0 -> v3.0.0 (SHA b4309332) - Add 3.1.x to dotnet-version in all 3 setup-dotnet blocks Bundles two related release-workflow fixes (Node 24 mirrors ETL-Test-Kit#54; 3.1 mirrors ETL-Json#54). Test projects target netcoreapp3.1 and need the 3.1 SDK to restore/test in release.yaml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…add-netcore31 Upgrade release workflow actions to Node 24 and add .NET Core 3.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First release of the library. Brings 45 commits of feature work from
developontomain. After this lands, publishing av0.1.0tag/release will triggerrelease.yamlto build, validate, pack, smoke-test, and push the NuGet package.What's shipping (v0.1.0)
Public API
InMemoryLogger— non-genericILoggerthat captures entries in a thread-safe in-memory listInMemoryLogger<T>— thin generic wrapper aroundInMemoryLoggerInMemoryLoggerProvider—ILoggerProviderthat creates and cachesInMemoryLoggerinstances per category (ConcurrentDictionary)InMemoryLoggerBuilderExtensions.AddInMemoryLogger(this ILoggingBuilder, InMemoryLoggerProvider)— DI registrationFeatures
LogLevel.Nonecorrectly disables all)BeginScopewithAsyncLocal-tracked active scopes and idempotentDispose(Interlocked.CompareExchange)IReadOnlyList<LogEntry<object>>for easy assertionTarget frameworks
net462;netstandard2.0;netstandard2.1;net8.0;net10.0Verified
net462,net47,net471,net472,net48,net481,net6.0,net7.0,net8.0,net9.0,net10.0)Test plan
validate-releasejob passes on Release configpack-and-validatejob produces a NuGet packagev0.1.0and publish a GitHub Release to trigger NuGet push🤖 Generated with Claude Code