Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
272 commits
Select commit Hold shift + click to select a range
e936eae
ci(deps): Bump softprops/action-gh-release from 2.2.1 to 2.5.0 (#63)
dependabot[bot] Feb 3, 2026
9fd50ca
ci(deps): Bump actions/checkout from 4.2.2 to 6.0.2 (#64)
dependabot[bot] Feb 3, 2026
1dcb9d9
ci(deps): Bump github/codeql-action from 4.32.0 to 4.32.1 (#65)
dependabot[bot] Feb 3, 2026
31a0bf0
chore: Bump dotnet-sonarscanner from 11.0.0 to 11.1.0 (#66)
dependabot[bot] Feb 3, 2026
531e587
chore: Bump System.Text.Json from 10.0.1 to 10.0.2 (#68)
dependabot[bot] Feb 3, 2026
f9e1632
chore: Bump Testcontainers.Azurite from 4.9.0 to 4.10.0 (#69)
dependabot[bot] Feb 3, 2026
8811202
chore: Bump TUnit and TUnit.Assertions from 1.5.70 to 1.12.125 (#75)
philcarbone Feb 3, 2026
3358233
test: Restore 80% coverage threshold and add WorkCoordinator strategy…
philcarbone Feb 3, 2026
1fa255d
chore: Bump Testcontainers.PostgreSql from 4.9.0 to 4.10.0 (#70)
dependabot[bot] Feb 4, 2026
4bca918
chore: Bump Testcontainers.ServiceBus from 4.9.0 to 4.10.0 (#72)
dependabot[bot] Feb 4, 2026
b54e08f
chore: Bump @isaacs/brace-expansion (#77)
dependabot[bot] Feb 4, 2026
27cb711
fix: Update README badges and OSSF scorecard SHA (#79)
philcarbone Feb 5, 2026
ddeca26
feat: Unified Transport Abstraction + Migration CLI Enhancements (#78)
philcarbone Feb 5, 2026
127efb5
feat(migrate): CLI wiring and full LINQ support for JSONB (#80)
philcarbone Feb 7, 2026
41881b9
chore(release): bump version to 0.4.0-alpha.1 (#81)
philcarbone Feb 7, 2026
e615674
fix(ci): add secrets inherit and permissions for release workflow OID…
philcarbone Feb 7, 2026
a87f8d9
fix(generators): Resolve duplicate type definitions in MessageJsonCon…
philcarbone Feb 7, 2026
089e862
fix(scripts): Add primary DLL filter for accurate test discovery (#87)
philcarbone Feb 7, 2026
183a59c
chore(release): bump version to 0.4.0-alpha.4
github-actions[bot] Feb 7, 2026
aea7d9f
fix(ci): Add version existence check before release (#88)
philcarbone Feb 7, 2026
be3f289
chore(release): bump version to 0.5.0-alpha.1
github-actions[bot] Feb 7, 2026
47763b5
chore(release): bump version to 0.5.1-alpha.1
github-actions[bot] Feb 8, 2026
79223c4
Merge branch 'main' into develop
philcarbone Feb 8, 2026
0b97b6f
Feature/run tests primary dll filter (#90)
philcarbone Feb 8, 2026
29fdc9b
fix(ci): Share build artifacts and fix release workflow (#91)
philcarbone Feb 8, 2026
8751933
fix(ci): Share concurrency group between push and PR events
philcarbone Feb 8, 2026
b9348be
fix(test): Enable Microsoft.Testing.Platform support for all test pro…
philcarbone Feb 8, 2026
b0b4d36
fix(test): Remove global.json test runner enforcement
philcarbone Feb 8, 2026
583a11f
fix(ci): Remove --project flag from dotnet test commands
philcarbone Feb 8, 2026
55b2307
fix(ci): Remove unsupported coverage flags from test workflows
philcarbone Feb 8, 2026
74bca25
fix(ci): Run TUnit tests as executables instead of dotnet test
philcarbone Feb 8, 2026
8c8c1a8
fix(ci): Restore execute permissions after artifact download
philcarbone Feb 8, 2026
7536a71
fix(ci): Skip coverage steps when no coverage files exist
philcarbone Feb 8, 2026
c37b0fb
fix(ci): Restore coverage collection in test workflows
philcarbone Feb 8, 2026
f250015
fix(ci): Fix coverage file output path for TUnit executables
philcarbone Feb 8, 2026
5a540fc
fix(ci): Correct coverage file path - TUnit outputs to bin/TestResults/
philcarbone Feb 8, 2026
3b9d472
refactor(ci): Unify test execution with Run-Tests.ps1 across local an…
philcarbone Feb 8, 2026
2ad5746
fix(tests): display infrastructure errors in AI mode
philcarbone Feb 8, 2026
3796fd6
fix(tests): exclude AppHost projects from ProjectFilter
philcarbone Feb 8, 2026
32a3d9a
fix(ci): Update coverage artifact paths to find files in bin/TestResu…
philcarbone Feb 8, 2026
4a2a287
fix(coverage): Remove runsettings to match main branch coverage behavior
philcarbone Feb 8, 2026
bf92f8f
fix(coverage): Use minimal runsettings with only ExcludeAssembliesWit…
philcarbone Feb 8, 2026
465eb60
fix(coverage): Use absolute path for runsettings file
philcarbone Feb 8, 2026
1bb7c84
fix(coverage): Remove runsettings file usage
philcarbone Feb 8, 2026
0843a53
fix(coverage): Include runsettings file in build artifacts
philcarbone Feb 8, 2026
2fd0572
fix(coverage): Use default coverage settings without runsettings
philcarbone Feb 8, 2026
fc6adc4
feat(dispatcher): Add DispatchOptions overloads to all dispatch methods
philcarbone Feb 8, 2026
da40a4f
fix(ci): Revert to per-project testing for proper coverage collection
philcarbone Feb 8, 2026
4a43876
fix: Update workflows to use Run-Tests.ps1 for coverage collection
philcarbone Feb 8, 2026
92ed74f
fix: Add missing DispatchOptions interface methods to test doubles
philcarbone Feb 8, 2026
9c81924
fix: Add missing comma in Run-Tests.ps1 parameter list
philcarbone Feb 8, 2026
87a7ea0
fix: wrap Where-Object results in array to prevent null Count error
philcarbone Feb 8, 2026
9fa2154
fix: use dotnet run for coverage tests to avoid VSTest validation
philcarbone Feb 8, 2026
12a4cba
fix: remove extra path quotes and add --no-build for coverage tests
philcarbone Feb 8, 2026
5a80096
fix: set execute permission on test executables for Linux
philcarbone Feb 9, 2026
ea0c72e
fix: remove --no-build to allow sample projects to build if needed
philcarbone Feb 9, 2026
637cfe9
fix: add OutputType Exe to ECommerce sample test projects for TUnit/M…
philcarbone Feb 9, 2026
897c522
fix: remove duplicate generator DLL bundling from runtime packages (#93)
kdeenanauth Feb 9, 2026
ae80eba
ci: enable SonarCloud analysis for pull requests
philcarbone Feb 9, 2026
2cb0fe9
ci: add manual version input to Start Release workflow
philcarbone Feb 9, 2026
d7b0f7f
ci: trigger PR workflow re-run for SonarCloud
philcarbone Feb 9, 2026
0c9022f
ci: fix Start Release workflow - use gh pr create instead of action
philcarbone Feb 9, 2026
241d6d1
feat: add WhizbangTestTags for test project filtering
philcarbone Feb 9, 2026
d896ea3
fix: resolve scoped services within scope in generated Dispatcher
philcarbone Feb 9, 2026
46c7879
refactor: simplify Run-Tests.ps1 mode flags
philcarbone Feb 9, 2026
9a2b94e
fix: add Config.json for Azure Service Bus emulator in library tests
philcarbone Feb 9, 2026
b54470d
fix: resolve TaskCompletionSource deadlock in ASB integration tests
philcarbone Feb 9, 2026
128318e
feat: add TransportTestHarness for transport integration tests
philcarbone Feb 9, 2026
d4f84a8
fix: add RunContinuationsAsynchronously to RabbitMQ test TCS instances
philcarbone Feb 9, 2026
5994d19
feat: add lifecycle and transport test harnesses with TCS deadlock fixes
philcarbone Feb 9, 2026
ad083a2
refactor: Convert transport integration tests to use testing harnesses
philcarbone Feb 9, 2026
44c2378
Update docs and ServiceBus emulator fixture
philcarbone Feb 9, 2026
e7247e0
fix: resolve parallel ServiceBus test conflicts and script defaults
philcarbone Feb 9, 2026
3304758
feat(pack): add version auto-increment option to Pack-LocalPackages
philcarbone Feb 10, 2026
e52a3af
fix(generators): use qualified names for nested perspective classes
philcarbone Feb 11, 2026
a9f3c61
refactor(generators): move EF Core code to separate generator
philcarbone Feb 11, 2026
b37ab9a
fix(generators): use unique hintNames for nested perspective classes
philcarbone Feb 11, 2026
4bf0f78
fix(generators): find [StreamKey] on inherited properties in Perspect…
philcarbone Feb 11, 2026
0647404
feat(perspectives): support up to 50 event types in IPerspectiveFor
philcarbone Feb 14, 2026
c342d55
fix: recursive nested type discovery in MessageJsonContextGenerator
philcarbone Feb 14, 2026
bb27673
feat(generators): add ServiceRegistrationGenerator for auto DI regist…
philcarbone Feb 15, 2026
8890d6d
feat(routing): implement namespace-based topic routing
philcarbone Feb 16, 2026
f82514e
feat(routing): add strongly-typed namespace configuration methods
philcarbone Feb 16, 2026
32538dd
fix(routing): update tests for full namespace routing behavior
philcarbone Feb 16, 2026
50c6076
feat: add database resilience, temporal perspectives, and vector search
philcarbone Feb 16, 2026
4f2def7
fix: use pragma to suppress CA1848 in lambda
philcarbone Feb 16, 2026
85ba09c
Mark internal projects as non-packable
philcarbone Feb 16, 2026
6e16d83
feat: add WithRouting/AddTransportConsumer, fix integration tests, im…
philcarbone Feb 16, 2026
ccca63b
fix: register OrderedStreamProcessor in AddTransportConsumer()
philcarbone Feb 16, 2026
7416c0b
fix: apply IOutboxRoutingStrategy to transform destinations when publ…
philcarbone Feb 16, 2026
a81b2ee
fix: register IOutboxRoutingStrategy and use routing in transport reg…
philcarbone Feb 16, 2026
3a9ef17
feat: unify lifecycle invocation with source-generated receptor registry
philcarbone Feb 17, 2026
f44d65b
feat: generalize EventExtractor to MessageExtractor for events and co…
philcarbone Feb 17, 2026
c966742
feat: add resilient subscription system for TransportConsumerWorker
philcarbone Feb 18, 2026
d6acb27
feat: add detailed subscription logging to TransportConsumerWorker
philcarbone Feb 18, 2026
a103917
fix: exclude owned namespaces from event subscriptions
philcarbone Feb 18, 2026
c129854
feat: add EventNamespaceRegistry static holder with ModuleInitializer…
philcarbone Feb 18, 2026
b4a68f1
feat: auto-register perspective associations during database initiali…
philcarbone Feb 18, 2026
b00d33b
feat: turn-key perspective runner registration with module initializer
philcarbone Feb 19, 2026
c83334a
feat: add RPC response extraction and Route.None() for discriminated …
philcarbone Feb 19, 2026
ffaa0e5
fix: resolve integration test race conditions and double-publish issues
philcarbone Feb 19, 2026
efba3a3
feat: add raw event store query interface with scope filtering
philcarbone Feb 19, 2026
1131bae
feat: add TrackedGuid interception system for compile-time GUID tracking
philcarbone Feb 19, 2026
3d226ed
feat: add physical fields DDL generation and stream ID extraction
philcarbone Feb 20, 2026
aff46b2
feat: add automatic security context propagation to outgoing message …
philcarbone Feb 21, 2026
d26e911
feat: add explicit security context API (AsSystem/RunAs)
philcarbone Feb 21, 2026
4e6aa1c
fix: register IScopeContextAccessor as singleton
philcarbone Feb 21, 2026
5cacef6
fix: use static accessor for IScopeContextAccessor in singleton services
philcarbone Feb 21, 2026
169d056
fix: use fully qualified type name in SecurityContextRequiredExceptio…
philcarbone Feb 21, 2026
056aa55
feat: make IMessageContext DI-injectable and fix void LocalInvokeAsyn…
philcarbone Feb 21, 2026
916ce96
fix: generate List<T> factories for nullable value types in MessageJs…
philcarbone Feb 21, 2026
855661f
fix: use TransportConsumerWorker in Azure Service Bus integration tests
philcarbone Feb 21, 2026
0b180f1
feat: add TrackedGuid EF Core support and document Dictionary limitat…
philcarbone Feb 21, 2026
b9616f2
feat(analyzer): add WHIZ810 to detect Dictionary in perspective models
philcarbone Feb 21, 2026
1ad8e53
fix(analyzer): respect [NotMapped] and [JsonIgnore] attributes in WHI…
philcarbone Feb 21, 2026
c6d314c
feat(generators): auto-implement IEventTypeProvider in PerspectiveRun…
philcarbone Feb 22, 2026
bac257c
fix(workers): establish security context before lifecycle receptor in…
philcarbone Feb 22, 2026
aaf663e
fix(dispatcher): propagate UserId to cascaded receptor invocations
philcarbone Feb 22, 2026
0c69959
WIP: Consolidate [AggregateId] and [StreamKey] into [StreamId]
philcarbone Feb 22, 2026
8e66cab
feat(generators): add ICommand support to StreamIdGenerator
philcarbone Feb 22, 2026
82f24f1
fix(generators): use IServiceScopeFactory for lifecycle receptor reso…
philcarbone Feb 22, 2026
49159d8
fix(postgres): add advisory lock and VARCHAR casts for database init
philcarbone Feb 22, 2026
a1e838f
feat(sync): add perspective synchronization for read-your-writes cons…
philcarbone Feb 23, 2026
faf0b9a
feat(sync): auto-register perspective sync services in AddWhizbang()
philcarbone Feb 23, 2026
9e8286a
fix: unwrap Routed<T> in SendAsync to prevent InvalidCastException
philcarbone Feb 23, 2026
e8a90b8
fix: complete Routed<T> unwrapping for all LocalInvokeAsync paths
philcarbone Feb 23, 2026
b3b2953
fix(sync): check sync result in generated code and throw on timeout
philcarbone Feb 24, 2026
1401e10
feat(sync): complete perspective sync implementation with bug fixes
philcarbone Feb 25, 2026
73bb8a4
feat(efcore): add turnkey database initialization with EnsureWhizbang…
philcarbone Feb 25, 2026
748e86b
docs: update <docs> tags to versionless paths
philcarbone Feb 25, 2026
7f29945
feat(polymorphic): add polymorphic type support for EF Core JSON columns
philcarbone Feb 25, 2026
4b2d7f2
Add comprehensive tests for lifecycle stage isolation, serialization,…
philcarbone Feb 27, 2026
1c83b56
Merge main into develop
philcarbone Feb 27, 2026
7c0781e
fix: remove duplicate FakeDispatcher methods from merge
philcarbone Feb 27, 2026
0881bb8
fix: resolve merge-related build errors
philcarbone Feb 27, 2026
ff56422
style: fix import ordering in SchemaHashUtilitiesTests
philcarbone Feb 27, 2026
7de163a
fix(tests): update expected receptor count after merge
philcarbone Feb 27, 2026
b929300
fix: restore accidentally deleted ServiceBusReadinessCheck files
philcarbone Feb 27, 2026
1359308
fix(tests): mark DispatcherSyncTests as NotInParallel
philcarbone Feb 27, 2026
32777a8
fix(tests): handle InvalidOperationException in failure strategy test
philcarbone Feb 27, 2026
73c8c8c
fix(tests): observe task exception to prevent unobserved exception wa…
philcarbone Feb 27, 2026
085532a
fix(tests): use UnobservedTaskException handler to prevent CI failure
philcarbone Feb 27, 2026
39a45f9
fix(scripts): show failed project names in CI coverage test output
philcarbone Feb 27, 2026
8f4028b
feat(tags): wire MessageTagProcessor into event pipeline with auto-re…
philcarbone Feb 27, 2026
761d689
fix(tests): remove empty Whizbang.Hosting.RabbitMQ.Tests project
philcarbone Feb 27, 2026
9385cad
fix(tags): register MessageTagProcessor as Singleton with scoped hook…
philcarbone Feb 27, 2026
c29725e
feat(hotchocolate): add UseOrderByStripping to ensure GraphQL sort pr…
philcarbone Feb 27, 2026
894a54f
chore: bump version to 0.5.1-alpha.285
philcarbone Feb 27, 2026
94cc795
fix(tags): avoid unnecessary scope creation when no tags registered
philcarbone Feb 27, 2026
bcc385c
feat(sync): add generic overloads for ForEventTypes, AndEventTypes, O…
philcarbone Feb 27, 2026
ecfe13f
docs: add complete XML documentation to VectorSearchExtensions
philcarbone Feb 27, 2026
68e64f1
fix(tests): add connection strings for generated turnkey extensions
philcarbone Feb 27, 2026
5edc8f1
fix(scripts): apply Tag filter in coverage mode
philcarbone Feb 27, 2026
ed56e56
fix(scripts): show test output when projects fail in coverage mode
philcarbone Feb 28, 2026
f2c4054
fix(tests): remove Postgres tag overlap from ECommerce integration tests
philcarbone Feb 28, 2026
d583716
fix(tests): use NotInParallel instead of MaxParallelTests
philcarbone Feb 28, 2026
8fd6639
fix(dapper): use snake_case keys for metadata serialization
philcarbone Feb 28, 2026
4b819b6
feat(tracing): add comprehensive tracing and metrics infrastructure
philcarbone Feb 28, 2026
f9ab38e
fix(dapper): restore SecurityContext from Scope column when reading e…
philcarbone Feb 28, 2026
7d9ae37
Revert "feat(tracing): add comprehensive tracing and metrics infrastr…
philcarbone Feb 28, 2026
ff2bde6
fix(tests): increase perspective waiter timeouts for CI environment
philcarbone Feb 28, 2026
2f984e5
fix(tests): increase DistributeLifecycleTests timeouts for CI
philcarbone Feb 28, 2026
ed8507f
fix(lifecycle): resolve PrePerspective test timeouts
philcarbone Mar 1, 2026
4fea0bf
fix(core): add MessageHop.TraceParent property for InMemoryEventStore
philcarbone Mar 1, 2026
9ec02ac
fix(sonarcloud): resolve BLOCKER security and reliability issues
philcarbone Mar 1, 2026
b3082cb
Revert "fix(sonarcloud): resolve BLOCKER security and reliability iss…
philcarbone Mar 1, 2026
be332ec
fix(sonarcloud): resolve BLOCKER security and reliability issues
philcarbone Mar 1, 2026
721c6bc
test(security): add tests for ScopedMessageContext and MessageSecurit…
philcarbone Mar 1, 2026
f7f6aea
test(servicebus): skip flaky lifecycle tests in CI
philcarbone Mar 1, 2026
231c691
test: skip all Service Bus integration tests for v0.8.5-beta.1 release
philcarbone Mar 1, 2026
56b3cd5
test: skip WHIZ080 test until feature is implemented
philcarbone Mar 1, 2026
f5f0e7d
ci: allow Service Bus tests to pass when all skipped
philcarbone Mar 1, 2026
39147b9
ci: add continue-on-error to RabbitMQ workflow for skipped tests
philcarbone Mar 1, 2026
81e3e84
fix(sonar): resolve reliability issues for quality gate
philcarbone Mar 1, 2026
e33e0a9
test: add coverage tests for DebuggerAwareClock and PerspectiveSyncTi…
philcarbone Mar 1, 2026
45b1f86
test: add coverage tests for SystemCommands and EventStoreQueryScope
philcarbone Mar 1, 2026
fe7dcbc
Add trace testing infrastructure for OpenTelemetry span validation
philcarbone Mar 1, 2026
5d5680c
Fix lifecycle span correlation with parent HTTP request trace
philcarbone Mar 1, 2026
69a1a4e
Enhance MessageJsonContextGenerator with Dictionary and nested collec…
philcarbone Mar 1, 2026
cf1b556
Add Dictionary<TKey, TValue> type generation for AOT JSON serialization
philcarbone Mar 1, 2026
f57afc4
Add IReadOnlyList<T> type generation for AOT JSON serialization
philcarbone Mar 1, 2026
5614024
Fix IReadOnlyList<T> factory to use CreateIEnumerableInfo
philcarbone Mar 1, 2026
a97695f
test: add WhizbangOptions and GuidOrderingSeverity tests
philcarbone Mar 1, 2026
93ecf44
test: add tests for enums and tracing components
philcarbone Mar 1, 2026
1e59624
test: add enum tests for perspectives and tags
philcarbone Mar 1, 2026
83d8dbb
test: add tests for lenses and messaging enums
philcarbone Mar 1, 2026
303fb85
test: add comprehensive LifecycleStage enum tests
philcarbone Mar 1, 2026
98a3a43
test: add CompletionStatus enum tests
philcarbone Mar 1, 2026
82e9f34
test: add PersistenceMode enum tests
philcarbone Mar 1, 2026
26485f2
fix(ci): remove TracerOptionsIntegrationTests that breaks pack workflow
philcarbone Mar 1, 2026
4f27125
test: add tests for enums to improve coverage
philcarbone Mar 1, 2026
94d2365
feat(tracing): add unified [WhizbangTrace] attribute and configurable…
philcarbone Mar 1, 2026
8701d0f
chore(sonar): exclude infrastructure code from coverage requirements
philcarbone Mar 1, 2026
8c9c902
fix(tracing): cascade parent context when batch span is disabled
philcarbone Mar 1, 2026
cd120ec
feat(tracing): remove Lifecycle from Core components and add enableLi…
philcarbone Mar 1, 2026
6b868bb
fix(tracing): add distributed trace context to TransportConsumerWorker
philcarbone Mar 1, 2026
52d4551
fix(tracing): link perspective spans to original request trace
philcarbone Mar 1, 2026
c27a069
revert: remove infrastructure exclusions (made coverage worse)
philcarbone Mar 1, 2026
ff892fb
test: add additional coverage for LenientDateTimeOffsetConverter
philcarbone Mar 2, 2026
df0ed5d
fix: correct flaky test assertions in CI
philcarbone Mar 2, 2026
34fce93
fix(tracing): respect TraceComponents flags for Lifecycle and Perspec…
philcarbone Mar 2, 2026
81c3476
fix: Make distribute lifecycle spans respect TraceComponents.Lifecycle
philcarbone Mar 2, 2026
cfeb7c9
test(generators): add tests for GuidInterceptionInfo and StreamIdInfo…
philcarbone Mar 2, 2026
6c37964
fix: Make receptor spans extract parent context from envelope hops
philcarbone Mar 2, 2026
4e53740
chore: Bump version to 0.5.1-alpha.350
philcarbone Mar 2, 2026
4e27f37
feat: Add tracing spans to PerspectiveSyncAwaiter
philcarbone Mar 2, 2026
2fc248a
security: add timeout to Regex.IsMatch to prevent ReDoS
philcarbone Mar 2, 2026
f97fb87
chore: Bump version to 0.5.1-alpha.351
philcarbone Mar 2, 2026
ed9b00c
feat: Add per-event perspective tracing and documentation links
philcarbone Mar 2, 2026
2035485
test(tracer): add pattern matching tests for TracedHandlers and Trace…
philcarbone Mar 2, 2026
f6f4e58
wip: Add ServiceBusSubscriptionNameHelper scaffolding (TDD RED phase)
philcarbone Mar 2, 2026
692218a
test(resilience): add OnDisconnected and retry logging coverage tests
philcarbone Mar 2, 2026
3a09dca
fix(tests): remove underscores from test method names (CA1707)
philcarbone Mar 2, 2026
530c122
fix(asb): derive subscription names from metadata, not routing key
philcarbone Mar 2, 2026
c4a2160
fix(tests): replace flaky async patterns with reliable utilities
philcarbone Mar 2, 2026
b8b9fe6
fix(asb): use sys.Label instead of [Subject] in SqlFilter expressions
philcarbone Mar 2, 2026
c1beb13
fix(generators): auto-discover polymorphic JsonTypeInfo for property …
philcarbone Mar 2, 2026
5771a79
fix(tests): correct EXPECTED_RECEPTOR_COUNT from 60 to 55
philcarbone Mar 2, 2026
251368a
Add tests for ScopedLensFactory and DispatcherEventCascader
philcarbone Mar 2, 2026
30e29fa
Add tests to improve code coverage
philcarbone Mar 2, 2026
21063eb
Add additional ReceptorInvoker tests for coverage
philcarbone Mar 2, 2026
7bab4d5
Add verbose logging mode for Unit and Integration test modes
philcarbone Mar 2, 2026
4f8f64d
Add IEventCompletionAwaiter for RPC perspective sync waiting
philcarbone Mar 2, 2026
66107a3
Fix EF Core not detecting JSONB changes for polymorphic models
philcarbone Mar 2, 2026
a4a421f
Add integration tests for IsModified JSONB fix
philcarbone Mar 2, 2026
c09a15c
Fix EF Core generator for ScopedWorkCoordinatorDependencies
philcarbone Mar 2, 2026
2bc974a
Fix DbContext concurrency errors in HotChocolate parallel resolvers
philcarbone Mar 3, 2026
ce1a1a0
Improve coverage test execution with parallel unit tests
philcarbone Mar 3, 2026
468869c
Show failed test output in all modes (not just AI mode)
philcarbone Mar 3, 2026
52fca84
Add IDisposable to FactoryOwnedLensQuery for DI compatibility
philcarbone Mar 3, 2026
41fd41b
Fix flaky race condition tests in CI
philcarbone Mar 3, 2026
1276cdd
Fix race condition tests and add event store decorators
philcarbone Mar 3, 2026
b861dd8
fix: replace flaky Task.Delay with TaskCompletionSource signals in sy…
philcarbone Mar 3, 2026
9d3e610
test: add coverage tests for SyncEventTracker and PerspectiveSyncAwaiter
philcarbone Mar 3, 2026
d52ccff
test: add Dispatcher coverage tests for DispatchOptions and routing
philcarbone Mar 3, 2026
8388f42
Add -NoBuild flag to Run-Tests.ps1 to skip redundant builds in CI
philcarbone Mar 3, 2026
c8328ce
feat: add symmetric sync methods and observability callbacks
philcarbone Mar 3, 2026
f7842ca
test: update receptor count from 59 to 63
philcarbone Mar 3, 2026
5533784
fix(test): fix race condition in UserScenarioReproductionTests
philcarbone Mar 3, 2026
5d67bca
fix(ci): exclude samples/benchmarks/tools from coverage calculation
philcarbone Mar 3, 2026
58cbff6
fix(ci): fix ReportGenerator glob patterns and add empty coverage check
philcarbone Mar 3, 2026
57f2b69
fix(ci): revert filter changes and lower threshold for debugging
philcarbone Mar 3, 2026
6ed2488
fix(ci): remove -NoBuild from coverage-collecting workflows
philcarbone Mar 3, 2026
3f1b21f
fix: Skip perspective sync for non-IEvent messages (commands)
philcarbone Mar 3, 2026
a3804e6
feat(ci): implement dual-build approach for coverage optimization
philcarbone Mar 3, 2026
a6abf3b
feat(ci): implement in-job instrumentation for coverage with -NoBuild
philcarbone Mar 3, 2026
e19a4bc
fix(ci): instrument all Whizbang DLLs, not just src/
philcarbone Mar 3, 2026
0aed375
fix(generators): Extract attribute values from constructor arguments
philcarbone Mar 3, 2026
564f659
fix(ci): strip deterministic build path prefix from coverage paths
philcarbone Mar 3, 2026
17a08d6
feat(analyzers): add WHIZ090 MessageTag parameter naming analyzer
philcarbone Mar 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 5 additions & 6 deletions .claude/commands/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ pwsh scripts/Run-Tests.ps1 -Coverage
```

Options:
- `-Mode Ai` - AI-optimized output, excludes integration tests (default)
- `-Mode Ci` - Full output, excludes integration tests
- `-Mode AiFull` - AI-optimized output, includes all tests
- `-Mode Full` - Full output, includes all tests
- `-Mode AiIntegrations` - AI-optimized output, only integration tests
- `-Mode IntegrationsOnly` - Full output, only integration tests
- `-Mode Ai` - AI-optimized output, ALL tests (default)
- `-Mode AiUnit` - AI-optimized output, unit tests only
- `-Mode AiIntegrations` - AI-optimized output, integration tests only
- `-Mode Unit` - Verbose output, unit tests only
- `-Mode Integration` - Verbose output, integration tests only
- `-ProjectFilter "Core"` - Run only matching projects

This will:
Expand Down
20 changes: 15 additions & 5 deletions .claude/commands/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,25 @@ gh workflow run release.yml -f release_type=patch # 0.0.x
gh workflow run release.yml -f release_type=auto -f dry_run=true
```

### Versioning Philosophy

**All 0.x.x releases are pre-releases working toward v1.0.0.**

- Library versions: `0.5.1-alpha.177`, `0.6.0-beta.1`, etc.
- Documentation: Single `v1.0.0/` folder (no separate v0.1.0, v0.2.0 docs)
- `<docs>` tags in code: Always versionless (e.g., `<docs>core-concepts/dispatcher</docs>`)

When v1.0.0 is released, the library version will match the documentation version.

### GitFlow Branch Versioning

| Branch | Version Format | Example |
|--------|---------------|---------|
| `main` | Stable release | `0.2.0` |
| `develop` | Alpha pre-release | `0.3.0-alpha.1` |
| `release/*` | Beta pre-release | `0.2.0-beta.1` |
| `feature/*` | Feature pre-release | `0.3.0-feat-xyz.1` |
| `hotfix/*` | Hotfix pre-release | `0.2.1-hotfix.1` |
| `main` | Stable release | `1.0.0` (future) |
| `develop` | Alpha pre-release | `0.6.0-alpha.1` |
| `release/*` | Beta pre-release | `0.6.0-beta.1` |
| `feature/*` | Feature pre-release | `0.6.0-feat-xyz.1` |
| `hotfix/*` | Hotfix pre-release | `0.5.2-hotfix.1` |

### Conventional Commits for Version Bumps

Expand Down
16 changes: 8 additions & 8 deletions .github/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pwsh scripts/Run-Tests.ps1
pwsh scripts/Run-Tests.ps1 -ProjectFilter "Core"

# Run with AI-friendly output
pwsh scripts/Run-Tests.ps1 -AiMode
pwsh scripts/Run-Tests.ps1
```

### 1.3 Fix Absolute Paths
Expand Down Expand Up @@ -990,7 +990,7 @@ pwsh scripts/Run-Tests.ps1 -ProjectFilter "Core"
pwsh scripts/Run-Tests.ps1 -TestFilter "DispatcherTests"

# AI-friendly output
pwsh scripts/Run-Tests.ps1 -AiMode
pwsh scripts/Run-Tests.ps1
```

## Building
Expand Down Expand Up @@ -1752,19 +1752,19 @@ To release:
- Set `<PackageDescription>`
- Verify `<IsPackable>true</IsPackable>`

- [ ] **Whizbang.Testing** - Testing utilities
- Set `<PackageDescription>`
- Verify `<IsPackable>true</IsPackable>`

#### Data Packages
- [ ] **Whizbang.Data.Schema** - Schema management
- [ ] **Whizbang.Data.Postgres** - PostgreSQL support
- [ ] **Whizbang.Data.Dapper.Custom** - Base Dapper abstractions
- [ ] **Whizbang.Data.Dapper.Postgres** - Dapper + PostgreSQL
- [ ] **Whizbang.Data.Dapper.Sqlite** - Dapper + SQLite
- [ ] **Whizbang.Data.Dapper.Custom** - Custom Dapper implementations
- [ ] **Whizbang.Data.EFCore.Custom** - Base EF Core abstractions
- [ ] **Whizbang.Data.EFCore.Postgres** - EF Core + PostgreSQL
- [ ] **Whizbang.Data.EFCore.Postgres.Generators** - EF Core source generators
- [ ] **Whizbang.Data.EFCore.Custom** - Custom EF Core implementations

#### Internal Packages (NOT published to NuGet - IsPackable=false)
- **Whizbang.Generators.Shared** - ILMerged into generator packages
- **Whizbang.Testing** - Empty placeholder

#### Hosting & Transport Packages
- [ ] **Whizbang.Hosting.Azure.ServiceBus** - Azure Service Bus hosting
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
needs: build
uses: ./.github/workflows/reusable-test-unit.yml
with:
# Use pre-built artifacts with in-job instrumentation for coverage
artifact-name: build-${{ github.run_id }}

postgres-integration:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/nuget-pack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ jobs:
- name: Verify packages created
run: |
# List of all expected packages (with SoftwareExtravaganza prefix)
# NOTE: Internal packages excluded (IsPackable=false):
# - Whizbang.Generators.Shared (ILMerged into generator packages)
# - Whizbang.Testing (empty placeholder)
EXPECTED_PACKAGES=(
"SoftwareExtravaganza.Whizbang.Core"
"SoftwareExtravaganza.Whizbang.Generators"
"SoftwareExtravaganza.Whizbang.Generators.Shared"
"SoftwareExtravaganza.Whizbang.Data.Postgres"
"SoftwareExtravaganza.Whizbang.Data.Schema"
"SoftwareExtravaganza.Whizbang.Data.Dapper.Custom"
Expand All @@ -54,7 +56,6 @@ jobs:
"SoftwareExtravaganza.Whizbang.Transports.HotChocolate.Generators"
"SoftwareExtravaganza.Whizbang.Hosting.Azure.ServiceBus"
"SoftwareExtravaganza.Whizbang.Hosting.RabbitMQ"
"SoftwareExtravaganza.Whizbang.Testing"
"SoftwareExtravaganza.Whizbang.Migrate"
"SoftwareExtravaganza.Whizbang.CLI"
)
Expand Down
38 changes: 30 additions & 8 deletions .github/workflows/reusable-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,36 +89,49 @@ jobs:
COVERAGE_FILES="${{ steps.check-coverage.outputs.files }}"
echo "Coverage files to merge: $COVERAGE_FILES"

# File filters to exclude from coverage reports
# Only exclude source-generated files (*.g.cs, .whizbang-generated)
# Note: samples/benchmarks/tools are excluded via sonar.coverage.exclusions in SonarCloud
FILE_FILTERS="-*.g.cs;-**/.whizbang-generated/*"

# Generate merged report in SonarQube format
# Exclude source-generated files from coverage (*.g.cs, .whizbang-generated)
reportgenerator \
"-reports:${COVERAGE_FILES}" \
"-targetdir:coverage/sonarqube" \
"-reporttypes:SonarQube" \
"-filefilters:-*.g.cs;-*/.whizbang-generated/*"
"-filefilters:${FILE_FILTERS}"

# Convert absolute paths to relative paths for SonarCloud
# Remove CI runner path AND deterministic build prefix (/_/)
sed -i 's|/home/runner/work/whizbang/whizbang/||g' coverage/sonarqube/SonarQube.xml
sed -i 's|/_/||g' coverage/sonarqube/SonarQube.xml

# Debug: show first few lines to verify paths
echo "=== Merged coverage report (first 30 lines) ==="
head -30 coverage/sonarqube/SonarQube.xml

# Also generate text summary for coverage check
# Use same exclusions as SonarQube report
# Also generate text summary for coverage check (same filters)
reportgenerator \
"-reports:${COVERAGE_FILES}" \
"-targetdir:coverage/summary" \
"-reporttypes:TextSummary" \
"-filefilters:-*.g.cs;-*/.whizbang-generated/*"
"-filefilters:${FILE_FILTERS}"

- name: Check Coverage Threshold
run: |
# Parse coverage from TextSummary report
COVERAGE=$(grep "Line coverage:" coverage/summary/Summary.txt | grep -oP '\d+(\.\d+)?(?=%)' | head -1)
echo "Line coverage: ${COVERAGE}%"

# Check against threshold (80%)
# Fail if coverage could not be parsed
if [ -z "$COVERAGE" ]; then
echo "::error::Failed to parse coverage percentage from Summary.txt"
echo "Summary.txt contents:"
cat coverage/summary/Summary.txt
exit 1
fi

# Check against threshold
THRESHOLD=80
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
echo "::error::Coverage ${COVERAGE}% is below threshold ${THRESHOLD}%"
Expand All @@ -128,15 +141,24 @@ jobs:
fi

- name: SonarCloud Analysis
# Only run on main/develop pushes - PR analysis not supported by current SonarCloud plan
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
env:
GITHUB_TOKEN: ${{ github.token }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
HEAD_REF: ${{ github.head_ref }}
BASE_REF: ${{ github.base_ref }}
run: |
# Build PR-specific parameters if this is a pull request
PR_PARAMS=""
if [ "$EVENT_NAME" = "pull_request" ]; then
PR_PARAMS="/d:sonar.pullrequest.key=$PR_NUMBER /d:sonar.pullrequest.branch=$HEAD_REF /d:sonar.pullrequest.base=$BASE_REF"
fi

dotnet-sonarscanner begin /k:"whizbang-lib_whizbang" /o:"whizbang-lib" \
/d:sonar.token="${SONAR_TOKEN}" \
/d:sonar.host.url="https://sonarcloud.io" \
${PR_PARAMS} \
/d:sonar.exclusions="**/samples/**,**/benchmarks/**,**/node_modules/**,**/*Generated.cs,**/.whizbang-generated/**" \
/d:sonar.cpd.exclusions="**/tests/**,**/tools/**,**/samples/**,**/benchmarks/**,src/Whizbang.Generators/**,src/Whizbang.Generators.Shared/**,src/Whizbang.Data.EFCore.Postgres.Generators/**,src/Whizbang.Transports.HotChocolate.Generators/**,src/Whizbang.Transports.FastEndpoints.Generators/**" \
/d:sonar.coverage.exclusions="**/samples/**,**/benchmarks/**,**/tests/**,**/tools/**,src/Whizbang.Generators/**,src/Whizbang.Generators.Shared/**,src/Whizbang.Data.Schema/**,src/Whizbang.Data.EFCore.Postgres.Generators/**,src/Whizbang.Transports.HotChocolate.Generators/**,src/Whizbang.Transports.FastEndpoints.Generators/**,src/Whizbang.Hosting.Azure.ServiceBus/**,src/Whizbang.Hosting.RabbitMQ/**,src/Whizbang.Data.Dapper.Postgres/**,src/Whizbang.Transports.RabbitMQ/**,src/Whizbang.Data.EFCore.Postgres/**,src/Whizbang.Transports.AzureServiceBus/**,src/Whizbang.Data.Dapper.Sqlite/**,src/Whizbang.Data.Dapper.Custom/**,src/Whizbang.Data.EFCore.Custom/**,src/Whizbang.Data.Postgres/**,src/Whizbang.Testing/**,src/Whizbang.Observability/**,src/Whizbang.SignalR/**" \
Expand Down
63 changes: 58 additions & 5 deletions .github/workflows/reusable-test-inmemory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_call:
inputs:
artifact-name:
description: 'Build artifact to download (skips build if provided)'
description: 'Build artifact to download (enables -NoBuild with coverage)'
type: string
required: false

Expand Down Expand Up @@ -46,13 +46,66 @@ jobs:
if: inputs.artifact-name == ''
run: dotnet build --no-restore --configuration Release -maxcpucount:1

- name: Run InMemory Integration Tests
run: pwsh scripts/Run-Tests.ps1 -Mode Full -Coverage -Configuration Release -ProjectFilter "InMemory.Integration"
- name: Install dotnet-coverage
if: inputs.artifact-name != ''
run: dotnet tool install --global dotnet-coverage

# Instrument Whizbang DLLs in test output dirs (where tests load from)
- name: Instrument Whizbang Assemblies for Coverage
if: inputs.artifact-name != ''
run: |
SESSION_ID="coverage-${{ github.run_id }}-inmemory"
echo "SESSION_ID=$SESSION_ID" >> "$GITHUB_ENV"
echo "=== Instrumenting Whizbang assemblies for coverage ==="

find . -path "*/bin/Release/net10.0/Whizbang.*.dll" -type f | while read dll; do
if [[ "$dll" == *".resources.dll" ]] || [[ "$dll" == */ref/* ]] || [[ "$dll" == *".g.dll" ]]; then
continue
fi
echo "Instrumenting: $dll"
dotnet-coverage instrument "$dll" --session-id "$SESSION_ID" || echo "Warning: Could not instrument $dll"
done

echo "=== Instrumentation complete ==="

- name: Start Coverage Collection Server
if: inputs.artifact-name != ''
run: |
echo "Starting coverage collection server with session: $SESSION_ID"
mkdir -p TestResults
dotnet-coverage collect --session-id "$SESSION_ID" --server-mode --background \
-f cobertura -o TestResults/inmemory.cobertura.xml

- name: Run InMemory Integration Tests (with pre-built coverage)
if: inputs.artifact-name != ''
run: pwsh scripts/Run-Tests.ps1 -Mode Integration -Configuration Release -Tag InMemory -NoBuild
env:
TESTCONTAINERS_RYUK_DISABLED: 'false'

- name: Run InMemory Integration Tests (with dynamic coverage)
if: inputs.artifact-name == ''
run: pwsh scripts/Run-Tests.ps1 -Mode Integration -Coverage -Configuration Release -Tag InMemory
env:
TESTCONTAINERS_RYUK_DISABLED: 'false'

- name: Upload Coverage
if: success()
- name: Shutdown Coverage Collection
if: inputs.artifact-name != ''
run: |
echo "Shutting down coverage collection session: $SESSION_ID"
dotnet-coverage shutdown "$SESSION_ID" || true
echo "=== Coverage file contents ==="
ls -la TestResults/ || true

- name: Upload Coverage (pre-built)
if: success() && inputs.artifact-name != ''
uses: actions/upload-artifact@v6
with:
name: coverage-inmemory
path: TestResults/*.cobertura.xml
retention-days: 1

- name: Upload Coverage (dynamic)
if: success() && inputs.artifact-name == ''
uses: actions/upload-artifact@v6
with:
name: coverage-inmemory
Expand Down
63 changes: 58 additions & 5 deletions .github/workflows/reusable-test-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_call:
inputs:
artifact-name:
description: 'Build artifact to download (skips build if provided)'
description: 'Build artifact to download (enables -NoBuild with coverage)'
type: string
required: false

Expand Down Expand Up @@ -46,13 +46,66 @@ jobs:
if: inputs.artifact-name == ''
run: dotnet build --no-restore --configuration Release -maxcpucount:1

- name: Run PostgreSQL Integration Tests
run: pwsh scripts/Run-Tests.ps1 -Mode Full -Coverage -Configuration Release -ProjectFilter "Postgres"
- name: Install dotnet-coverage
if: inputs.artifact-name != ''
run: dotnet tool install --global dotnet-coverage

# Instrument Whizbang DLLs in test output dirs (where tests load from)
- name: Instrument Whizbang Assemblies for Coverage
if: inputs.artifact-name != ''
run: |
SESSION_ID="coverage-${{ github.run_id }}-postgres"
echo "SESSION_ID=$SESSION_ID" >> "$GITHUB_ENV"
echo "=== Instrumenting Whizbang assemblies for coverage ==="

find . -path "*/bin/Release/net10.0/Whizbang.*.dll" -type f | while read dll; do
if [[ "$dll" == *".resources.dll" ]] || [[ "$dll" == */ref/* ]] || [[ "$dll" == *".g.dll" ]]; then
continue
fi
echo "Instrumenting: $dll"
dotnet-coverage instrument "$dll" --session-id "$SESSION_ID" || echo "Warning: Could not instrument $dll"
done

echo "=== Instrumentation complete ==="

- name: Start Coverage Collection Server
if: inputs.artifact-name != ''
run: |
echo "Starting coverage collection server with session: $SESSION_ID"
mkdir -p TestResults
dotnet-coverage collect --session-id "$SESSION_ID" --server-mode --background \
-f cobertura -o TestResults/postgres.cobertura.xml

- name: Run PostgreSQL Integration Tests (with pre-built coverage)
if: inputs.artifact-name != ''
run: pwsh scripts/Run-Tests.ps1 -Mode Integration -Configuration Release -Tag Postgres -NoBuild
env:
TESTCONTAINERS_RYUK_DISABLED: 'false'

- name: Run PostgreSQL Integration Tests (with dynamic coverage)
if: inputs.artifact-name == ''
run: pwsh scripts/Run-Tests.ps1 -Mode Integration -Coverage -Configuration Release -Tag Postgres
env:
TESTCONTAINERS_RYUK_DISABLED: 'false'

- name: Upload Coverage
if: success()
- name: Shutdown Coverage Collection
if: inputs.artifact-name != ''
run: |
echo "Shutting down coverage collection session: $SESSION_ID"
dotnet-coverage shutdown "$SESSION_ID" || true
echo "=== Coverage file contents ==="
ls -la TestResults/ || true

- name: Upload Coverage (pre-built)
if: success() && inputs.artifact-name != ''
uses: actions/upload-artifact@v6
with:
name: coverage-postgres
path: TestResults/*.cobertura.xml
retention-days: 1

- name: Upload Coverage (dynamic)
if: success() && inputs.artifact-name == ''
uses: actions/upload-artifact@v6
with:
name: coverage-postgres
Expand Down
Loading
Loading