Skip to content

Modernize async library and test fixes#126

Merged
ChrisPulman merged 10 commits intomainfrom
CP_UpdatePackages
Feb 28, 2026
Merged

Modernize async library and test fixes#126
ChrisPulman merged 10 commits intomainfrom
CP_UpdatePackages

Conversation

@ChrisPulman
Copy link
Member

What kind of change does this PR introduce?

Update

What is the new behavior?

Apply modern C# updates and various test fixes across the async library. Highlights:

  • Update .github documentation target frameworks and add RCS1047 to NoWarn in Directory.Build.props.
  • Bump copyright years from 2019-2025 to 2019-2026 in many source files.
  • Add conditional ArgumentNullException.ThrowIfNull / ThrowIfLessThan checks for .NET 8+ and use Lock on newer frameworks where appropriate to improve null-safety and reliability.
  • Expand ConcurrentObserverCallsException into a full exception class with standard constructors.
  • Minor API/implementation cleanups: suppress CA2000 where needed, simplify nullable/collection initializations, expression-bodied test methods, additional disposals in tests, and other small refactors to reduce analyzer warnings and improve robustness.

Please check if the PR fulfills these requirements

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

Other information:

Update package versions in Directory.Packages.props (Polyfill -> 9.12.0, Microsoft.NET.Test.Sdk -> 18.3.0, TUnit -> 1.17.54, Verify.TUnit -> 31.13.2, Microsoft.Testing.Extensions.CodeCoverage -> 18.5.1, etc.) and remove some older test package entries.

Refactor ReactiveExtensionsTests to reliably track and await async subscription handlers: replace inline async Subscribe callbacks with a tasks list and a local HandleAsync wrapper that disposes the sync token in a finally block, then await Task.WhenAll(tasks) to avoid race conditions and flakiness in the tests.
Change SyncTimer to key timers by both TimeSpan and IScheduler, add an overload SyncTimer(TimeSpan, IScheduler) and keep a fallback to Scheduler.Default. Validate scheduler is non-null and create the underlying Observable.Timer with the provided scheduler so timers can be shared per scheduler. Update tests to use TestScheduler (pass it into SyncTimer and OnErrorRetry), and replace async wait helpers with scheduler.AdvanceBy to make timing deterministic.
Apply modern C# updates and various test fixes across the async library. Highlights:
- Update .github documentation target frameworks and add RCS1047 to NoWarn in Directory.Build.props.
- Bump copyright years from 2019-2025 to 2019-2026 in many source files.
- Add conditional ArgumentNullException.ThrowIfNull / ThrowIfLessThan checks for .NET 8+ and use Lock on newer frameworks where appropriate to improve null-safety and reliability.
- Expand ConcurrentObserverCallsException into a full exception class with standard constructors.
- Minor API/implementation cleanups: suppress CA2000 where needed, simplify nullable/collection initializations, expression-bodied test methods, additional disposals in tests, and other small refactors to reduce analyzer warnings and improve robustness.
@ChrisPulman ChrisPulman changed the title Cp update packages Modernize async library and test fixes Feb 28, 2026
@glennawatson
Copy link
Contributor

Just turn off RCS1047 in the editorconfig if you want to disable it everywhere rather than NoWarn

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Modernizes ReactiveUI.Extensions (including the async observable/subject/operator layer) by adopting newer C#/.NET patterns (NET8+ argument guards, NET9 Lock usage), updating analyzer configuration/docs, and adjusting tests for improved reliability.

Changes:

  • Add conditional NET8+ argument/range guards (ThrowIfNull / ThrowIfLessThan*) and adopt NET9 Lock in several synchronization gates.
  • Expand ConcurrentObserverCallsException into a fuller exception type with standard constructors.
  • Update copyrights/analyzer configuration and refine tests (timing, disposal, small refactors).

Reviewed changes

Copilot reviewed 151 out of 151 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/stylecop.json Updates copyright year template.
src/ReactiveUI.Extensions/Usings.cs Adjusts global usings to support moved/modernized references.
src/ReactiveUI.Extensions/ReactiveExtensions.cs Adds NET8+ argument guards; uses NET9 Lock gates in several operators; minor doc/comment change.
src/ReactiveUI.Extensions/Internal/Stale.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/IEnumerableIList{T}.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/Heartbeat.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/EnumeratorIList.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/EnumerableIList{T}.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/EnumerableIList.cs Copyright year bump.
src/ReactiveUI.Extensions/Internal/ConcurrencyLimiter.cs Uses NET9 Lock for synchronization gate; rename _locker_gate.
src/ReactiveUI.Extensions/IStale.cs Copyright year bump.
src/ReactiveUI.Extensions/IHeartbeat.cs Copyright year bump.
src/ReactiveUI.Extensions/Continuation.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/UnhandledExceptionHandler.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/SubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/SerialSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/SerialStatelessSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/SerialStatelessReplayLastSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/SerialReplayLatestSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Options/SubjectCreationOptions.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Options/ReplayLatestSubjectCreationOptions.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Options/PublishingOption.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Options/BehaviorSubjectCreationOptions.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/ISubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/ConcurrentSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/ConcurrentStatelessSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/ConcurrentStatelessReplayLatestSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/ConcurrentReplayLatestSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Base/Concurrent.cs Adds NET8+ null checks for observer lists.
src/ReactiveUI.Extensions/Async/Subjects/Base/BaseSubjectAsync.cs Uses NET9 Lock gate; adds NET8+ null guard in subscribe core.
src/ReactiveUI.Extensions/Async/Subjects/Base/BaseStatelessSubjectAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Subjects/Base/BaseStatelessReplayLastSubjectAsync.cs Adds NET8+ null guard in subscribe core.
src/ReactiveUI.Extensions/Async/Subjects/Base/BaseReplayLatestSubjectAsync.cs Adds NET8+ null guard in subscribe core.
src/ReactiveUI.Extensions/Async/Operators/Zip.cs Adds NET8+ null guards; uses NET9 Lock inside Zip state.
src/ReactiveUI.Extensions/Async/Operators/Yield.cs Adds NET8+ null guard.
src/ReactiveUI.Extensions/Async/Operators/Wrap.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Where.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/WaitCompletionAsync.cs Adds NET8+ null guard.
src/ReactiveUI.Extensions/Async/Operators/Using.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ToListAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ToDictionaryAsync.cs Adds NET8+ null guards for selectors.
src/ReactiveUI.Extensions/Async/Operators/ToAsyncEnumerable.cs Adds NET8+ null guards for source/factory.
src/ReactiveUI.Extensions/Async/Operators/Timeout.cs Adds NET8+ range/null guards; uses NET9 Lock gate in observer.
src/ReactiveUI.Extensions/Async/Operators/Throttle.cs Adds NET8+ range guard.
src/ReactiveUI.Extensions/Async/Operators/TakeWhile.cs Adds NET8+ null guards for predicates.
src/ReactiveUI.Extensions/Async/Operators/TakeUntilOptions.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/TakeUntil.cs Adds NET8+ null guards; minor expression-bodied refactor.
src/ReactiveUI.Extensions/Async/Operators/Take.cs Adds NET8+ range guard.
src/ReactiveUI.Extensions/Async/Operators/SwitchObservable.cs Uses NET9 Lock gate in subscription.
src/ReactiveUI.Extensions/Async/Operators/Switch.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/SubscribeAsync.cs Adds NET8+ null guards for source/delegates.
src/ReactiveUI.Extensions/Async/Operators/StartWith.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/SkipWhile.cs Adds NET8+ null guards for predicates.
src/ReactiveUI.Extensions/Async/Operators/Skip.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/SingleOrDefaultAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/SingleAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/SelectMany.cs Adds NET8+ null guards for selectors.
src/ReactiveUI.Extensions/Async/Operators/Select.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Scan.cs Adds NET8+ null guards for accumulator.
src/ReactiveUI.Extensions/Async/Operators/Retry.cs Adds NET8+ range guard.
src/ReactiveUI.Extensions/Async/Operators/RefCount.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Prepend.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/OnErrorResumeAsFailure.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/OnDispose.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/OfType.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ObserveOnAsyncObservable.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ObserveOn.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Multicast.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Merge.cs Minor expression-bodied refactor in nested observer disposal.
src/ReactiveUI.Extensions/Async/Operators/LongCountAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/LastOrDefaultAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/LastAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/GroupedAsyncObservable.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/GroupBy.cs Adds NET8+ null guards for source/selector.
src/ReactiveUI.Extensions/Async/Operators/ForEachAsync.cs Adds NET8+ null guard for action.
src/ReactiveUI.Extensions/Async/Operators/FirstOrDefaultAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/FirstAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Do.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/DistinctUntilChanged.cs Adds NET8+ null guards for comparer/selectors.
src/ReactiveUI.Extensions/Async/Operators/Distinct.cs Adds NET8+ null guards for selector/comparer.
src/ReactiveUI.Extensions/Async/Operators/Delay.cs Adds NET8+ range guard.
src/ReactiveUI.Extensions/Async/Operators/CountAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ContainsAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ConcatObservablesObservable{T}.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/ConcatEnumerableObservable{T}.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Concat.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/CompletionObservableDelegate.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/CombineLatest.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/Catch.cs Adds NET8+ null guards for source/handler.
src/ReactiveUI.Extensions/Async/Operators/Cast.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Operators/AnyAllAsync.cs Adds NET8+ null guard for predicate.
src/ReactiveUI.Extensions/Async/Operators/AggregateAsync.cs Adds NET8+ null guards; minor parameter naming cleanup.
src/ReactiveUI.Extensions/Async/ObserverAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/ToAsyncObservable.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Timer.cs Adds NET8+ range guards for dueTime/period.
src/ReactiveUI.Extensions/Async/Observables/Throw.cs Adds NET8+ null guard for error.
src/ReactiveUI.Extensions/Async/Observables/Return.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Range.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Never.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Interval.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/FromAsync.cs Adds NET8+ null guard for factory.
src/ReactiveUI.Extensions/Async/Observables/Empty.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Defer.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Observables/Create.cs Adds NET8+ null guard; minor refactor in background scheduling lambda.
src/ReactiveUI.Extensions/Async/ObservableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Mixins/SubjectMixins.cs Adds NET8+ null guards for subject/mapper.
src/ReactiveUI.Extensions/Async/Mixins/OptionalMixins.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Mixins/DisposableAsyncMixins.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Mixins/AsyncContextMixins.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/WrappedObserverAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/TaskObserverAsyncBase.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/Result.cs Adds NET8+ null guard for exception.
src/ReactiveUI.Extensions/Async/Internals/Optional.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/MulticastObservableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/CancelableTaskSubscription{T}.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/CancelableTaskSubscription.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/AsyncGate.cs Uses NET9 Lock for internal gate.
src/ReactiveUI.Extensions/Async/Internals/AnonymousObserverAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Internals/AnonymousObservableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/IObserverAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/IObservableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Disposables/SingleAssignmentDisposableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Disposables/SerialDisposableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Disposables/DisposableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/Disposables/CompositeDisposableAsync.cs Uses NET9 Lock; adds NET8+ guards; minor list initialization refactor.
src/ReactiveUI.Extensions/Async/ConnectableObservableAsync.cs Copyright year bump.
src/ReactiveUI.Extensions/Async/ConcurrentObserverCallsException.cs Expands exception type with additional constructors.
src/ReactiveUI.Extensions/Async/Bridge/ObservableBridgeExtensions.cs Adds NET8+ guards; adds CA2000 suppression; uses NET9 Lock; minor disposal/refactor.
src/ReactiveUI.Extensions/Async/AsyncContext.cs Adds NET8+ null guards for factory methods/continuation.
src/ReactiveUI.Extensions.Tests/ReactiveExtensionsTests.cs Improves async test timing robustness by separating wait conditions.
src/ReactiveUI.Extensions.Tests/DisposableExtensionsTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/TransformationOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/TimeBasedOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/TerminalOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/TakeUntilOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/SubjectTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/ResultAndInfrastructureTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/OperatorEdgeCaseTests.cs Adds extra disposals; converts some tests to expression-bodied; minor refactors.
src/ReactiveUI.Extensions.Tests/Async/FilteringOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/FactoryObservableTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/ErrorHandlingOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/DisposableTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/DeepCoverageTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/CoverageBoostTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/CombiningOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/CombineLatestOperatorTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/BridgeTests.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/AsyncTestHelpers.cs Copyright year bump.
src/ReactiveUI.Extensions.Tests/Async/AdditionalOperatorTests.cs Copyright year bump.
src/Directory.Build.props Adds RCS1047 to NoWarn; defines TFMs; confirms analyzers/lang version settings.
.github/copilot-instructions.md Updates documented target frameworks list.
Comments suppressed due to low confidence (1)

src/ReactiveUI.Extensions/ReactiveExtensions.cs:1322

  • The XML doc comment contains a malformed apostrophe character ("hasn�t"), which can render incorrectly in generated docs and is likely an encoding artifact. Replace it with a standard ASCII apostrophe ("hasn't").

Copy link
Contributor

Copilot AI commented Feb 28, 2026

@ChrisPulman I've opened a new pull request, #127, to work on those changes. Once the pull request is ready, I'll request review from you.

ChrisPulman and others added 3 commits February 28, 2026 13:16
Introduce Internal/ArgumentExceptionHelper with ThrowIfNull and ThrowIfNullOrEmpty helpers and replace scattered NET8/legacy null-check conditionals across the Async and Reactive extensions with calls to ArgumentExceptionHelper.ThrowIfNull. This centralizes argument validation (removing many #if NET8_0_OR_GREATER blocks), streamlines a few checks (e.g. Timeout and WaitForCondition), and reduces duplication across numerous operator/subject/observable implementations.
…rCallsException (#127)

* Initial plan

* Add [Serializable] attribute and serialization constructor to ConcurrentObserverCallsException

Co-authored-by: ChrisPulman <4910015+ChrisPulman@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChrisPulman <4910015+ChrisPulman@users.noreply.github.com>
@codecov
Copy link

codecov bot commented Feb 28, 2026

Codecov Report

❌ Patch coverage is 87.31343% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.22%. Comparing base (a9b59e7) to head (f799074).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...tensions/Async/ConcurrentObserverCallsException.cs 33.33% 4 Missing ⚠️
src/ReactiveUI.Extensions/ReactiveExtensions.cs 84.61% 4 Missing ⚠️
...iveUI.Extensions/Async/Operators/SubscribeAsync.cs 57.14% 3 Missing ⚠️
.../ReactiveUI.Extensions/Async/Observables/Create.cs 33.33% 2 Missing ⚠️
src/ReactiveUI.Extensions/Async/AsyncContext.cs 75.00% 1 Missing ⚠️
...ensions/Async/Bridge/ObservableBridgeExtensions.cs 83.33% 1 Missing ⚠️
...iveUI.Extensions/Async/Operators/AggregateAsync.cs 83.33% 1 Missing ⚠️
...iveUI.Extensions/Async/Subjects/Base/Concurrent.cs 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #126      +/-   ##
==========================================
+ Coverage   76.48%   78.22%   +1.74%     
==========================================
  Files         117      117              
  Lines        4796     4757      -39     
  Branches      723      636      -87     
==========================================
+ Hits         3668     3721      +53     
+ Misses        809      761      -48     
+ Partials      319      275      -44     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI commented Feb 28, 2026

@ChrisPulman I've opened a new pull request, #128, to work on those changes. Once the pull request is ready, I'll request review from you.

ChrisPulman and others added 3 commits February 28, 2026 13:24
Set dotnet_diagnostic.RCS1047.severity = none in .editorconfig and remove RCS1047 from the NoWarn list in src/Directory.Build.props. This centralizes the analyzer configuration in .editorconfig and avoids duplicate suppression in MSBuild.
…ert callback invocation (#128)

* Initial plan

* Add disposeCallbackInvoked flag assertion in WhenOnDisposeAsyncSourceFails_ThenCallbackInvoked test

Co-authored-by: ChrisPulman <4910015+ChrisPulman@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ChrisPulman <4910015+ChrisPulman@users.noreply.github.com>
@ChrisPulman ChrisPulman merged commit bedbc58 into main Feb 28, 2026
6 checks passed
@ChrisPulman ChrisPulman deleted the CP_UpdatePackages branch February 28, 2026 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants