Skip to content

ci: NuGet Trusted Publishing for publish workflow - #1449

Merged
danielgerlag merged 1 commit into
masterfrom
ci/nuget-trusted-publishing
Sep 24, 2026
Merged

danielgerlag merged 1 commit into
masterfrom
ci/nuget-trusted-publishing

Conversation

@danielgerlag

Copy link
Copy Markdown
Owner

Summary

Switch .github/workflows/nuget-publish.yml from a long-lived NUGET_API_KEY to NuGet Trusted Publishing via GitHub OIDC (NuGet/login@v1).

Prerequisites (already done)

  • Trusted Publishing policy on nuget.org for danielgerlag/workflow-core + workflow file nuget-publish.yml
  • Repo secret NUGET_USER set to the nuget.org username

After merge

Run Actions → Publish NuGet Packages on master to publish 3.21.0 (GitHub release exists; NuGet still at 3.20.0).

Notes

  • Job now requests id-token: write
  • Temp API key comes from ${{ steps.login.outputs.NUGET_API_KEY }}
  • NUGET_API_KEY is no longer used by this workflow (can be removed after a successful publish)

@danielgerlag
danielgerlag merged commit bd8bea2 into master Sep 24, 2026
8 of 11 checks passed
TC-jBautista added a commit to tigertext/workflow-core that referenced this pull request Oct 20, 2026
* Comprehensive code review fixes: security hardening, async safety, and error handling (danielgerlag#1418)

* fix: resolve SQL connection leaks and injection risk in SqlServer queue provider

- Use 'using' statements for SqlConnection instead of manual Close()
- Validate queue name to prevent SQL injection via string replacement

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: harden DSL module against code injection and improve error handling

- Disable AllowNewToEvaluateAnyType in Dynamic LINQ parsing config
- Add TypeNameHandling.None to JSON deserialization settings
- Add error handling for missing constructors in reflection calls
- Wrap ParseLambda calls in try-catch with descriptive error messages
- Handle DynamicInvoke TargetInvocationException by unwrapping inner exception
- Add safe Enum.Parse with validation and error handling
- Remove bare catch block, add specific exception handling with logging
- Add type validation in TypeResolver.FindType

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: add input validation to WebAPI controllers and fix extension issues

- Add parameter validation and correct HTTP status codes in WorkflowsController
- Add parameter validation in EventsController
- Fix ServiceProvider disposal in JsonWorkflowTest
- Add filter sanitization in SearchService
- Fix race condition in InMemoryConversationStore
- Add logging for tool call ID truncation
- Add null check in ToolRegistry constructor
- Add source validation in AI DefinitionLoader

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: eliminate async void and blocking wait patterns in providers

- Convert async void RenewLeases to async Task in AzureLockManager
- Convert async void SendHeartbeat to async Task in DynamoLockProvider
- Convert async void Process to async Task in KinesisStreamConsumer
- Remove blocking .Wait() in DynamoPersistenceProvider.EnsureStoreExists
- Remove blocking .Wait() in DynamoLockProvider.Stop
- Remove blocking .Wait() in SqlServerQueueProvider.Dispose
- Fix blocking GetAwaiter().GetResult() in RabbitMQProvider.Dispose

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve async patterns, thread safety, and error handling in core services

- Replace lock-on-parameter with proper synchronization in MemoryPersistenceProvider
- Await Task.Run in SingleNodeEventHub, use thread-safe collection
- Convert async void FutureQueue to async Task with proper tracking
- Remove blocking .Wait() in WorkflowHost.Start/Stop
- Add timeout to QueueConsumer.Stop blocking wait
- Fix TOCTOU race condition in WorkflowRegistry using TryGetValue
- Implement proper Dispose in SingleNodeQueueProvider
- Replace First/Single with FirstOrDefault/SingleOrDefault in MemoryPersistenceProvider
- Fix compensation chain logic in CompensateHandler
- Fix lock release on unacquired lock in ActivityController
- Fix GreyList TTL race condition
- Use ConcurrentDictionary in IndexConsumer
- Add logging for null steps in WorkflowExecutor

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: improve error handling and thread safety in persistence providers

- Use TryGetValue and fix throw/throw ex in SqlLockProvider
- Synchronize static indexesCreated in MongoDB and RavenDB providers
- Replace FirstAsync with FirstOrDefaultAsync in EF persistence provider
- Add exception logging in MongoDB ProcessCommands
- Remove unused field in RabbitMQ provider
- Use using for RabbitMQ channel resources

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: defer ToolRegistry serviceProvider null check to point of use

Move the null guard from constructor to Register<T>() and GetTool() where
_serviceProvider is actually needed. This allows tests to construct
ToolRegistry with null when only using Register(tool) instance methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .

* pr feedback

* tests

* fix: upgrade test dependencies for modern Docker compatibility

- Update Squadron from 0.17.0 to 1.0.1 across 6 provider test projects
  (Redis, SqlServer, PostgreSQL, MySQL, MongoDB, Elasticsearch)
- Update xunit from 2.9.2 to 2.9.3 in test/Directory.Build.props
- Update StackExchange.Redis from 2.0.601 to 2.8.37 (required by Squadron.Redis 1.0.1)
- Drop net6.0 TFM from provider tests (Squadron 1.0.1 requires net8.0+)
- Fix MongoDB test: pass ILoggerFactory to updated MongoPersistenceProvider constructor
- Fix PostgreSQL tests: remove Npgsql legacy timestamp behavior that was
  incompatible with the timestamptz column migration, causing DateTime
  values to silently lose timezone offset on round-trip

All provider tests now pass:
  Redis 13/13, PostgreSQL 22/22, MySQL 21/21, SqlServer 44/44,
  MongoDB 25/25, Elasticsearch 7/7, DynamoDB 19/19

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address review findings from code audit PR

- SingleNodeEventHub: return Task.Run result instead of fire-and-forget
- MemoryPersistenceProvider: add null guard in TerminateSubscription
- SqlServerQueueProviderMigrator: apply SanitizeIdentifier to all
  bracket-delimited SQL identifiers (CreateService, CreateQueue,
  CreateContract, CreateMessageType, EnableBroker)
- SearchService: remove ineffective OData filter validation that used
  SQL injection patterns (OData has its own safety via Azure SDK)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Azure Table Storage persistence provider to WorkflowCore.Providers.Azure (danielgerlag#1393)

* Initial plan

* Add Azure Table Storage persistence provider with documentation

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add comprehensive end-to-end tests for Azure Table Storage persistence provider

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add Azure Table Storage tests to GitHub workflow

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix missing .NET 6.0.x in Oracle and Azure test workflows

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Remove .NET 6.0.x from Azure-Tests workflow to match project target framework

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix test project configuration - add IsTestProject property to enable test execution

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Address code review: fix OData injection, GetEvents direction, ETag conflicts, command deduplication, UTC times, test setup

Agent-Logs-Url: https://github.com/danielgerlag/workflow-core/sessions/1e652d54-54b0-46c1-8dc6-1e1e0090c0cd

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add ILogger to AzureTableStoragePersistenceProvider and implement logging

- Add optional ILoggerFactory parameter to constructor
- Update extension methods to pass ILoggerFactory from DI
- Implement actual exception logging in ProcessCommands instead of
  silent swallowing (resolves the //TODO: add logger)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: trigger CI

* Fix broken MongoDB-Tests CI step in workflow

The Restore dependencies step was missing its name/step separator,
causing 'run: dotnet restore' to be parsed as part of the setup-dotnet
action's 'with' block. This made the YAML invalid since a step cannot
have both 'uses' and 'run'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix DateTime.MinValue crash in Azure Table Storage UTC conversion

Replace direct .ToUniversalTime() calls with SafeToUtc() helper that
treats Unspecified-Kind DateTimes as UTC rather than local time.
This prevents crashes when DateTime.MinValue is passed (e.g. as a
'get all' query), since converting MinValue from local to UTC can
underflow depending on timezone offset.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Ensure DateTime properties are UTC when persisting to Azure Table Storage

The Azure.Data.Tables SDK requires all DateTime properties to have
DateTimeKind.Utc. Domain model objects often have Unspecified kind
(e.g. DateTime.MinValue). Add EnsureUtc() helper to each table entity
class to set the Kind before persistence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix LifeCycleEventPublisher crash during test host shutdown

- Change Execute() from async void to async Task so _dispatchTask
  properly tracks the full async execution lifecycle
- Use Task.Run(Execute) instead of new Task(Execute) to correctly
  unwrap the returned Task
- Catch ObjectDisposedException in Execute() to handle graceful
  shutdown when the BlockingCollection is disposed during enumeration
- Fix TOCTOU race in PublishNotification() by using TryAdd and
  catching ObjectDisposedException instead of checking IsAddingCompleted
- Improve Dispose() to complete adding and wait for the dispatch task
  before disposing the outbox, preventing unhandled exceptions that
  crash the test host process

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>
Co-authored-by: Daniel Gerlag <daniel@gerlag.ca>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* nuget publish

* Bump version to 3.18.0 in Directory.Build.props

* Add .NET 10 support: fix InvalidProgramException in expression compilation (danielgerlag#1429)

* Add .NET 10 support: fix InvalidProgramException in expression compilation

Pre-compile dynamic expressions outside closures/local functions in
DefinitionLoader to avoid InvalidProgramException on .NET 10's updated
expression tree compiler. The previous pattern of calling
LambdaExpression.Compile() inside closures that capture expression
objects produces invalid IL on .NET 10.

Changes:
- BuildScalarInputAction: compile expression before local function
- BuildObjectInputAction: pre-scan JObject and compile all @-prefixed
  expressions at definition load time instead of at each invocation
- AttachDirectlyOutput: pre-compile source expression before lambda
- AttachNestedOutput: pre-compile both target and source expressions
- MemberMapParameter: cache compiled source delegate in constructor
- Add net10.0 to test TFMs (Directory.Build.props, UnitTests, IntegrationTests)

Fixes danielgerlag#1428

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add regression test for scalar inputs (issue danielgerlag#1428)

Covers the reporter's exact scenario: a scalar variable-binding input
(data.MessageId) plus a scalar string-literal input ("waits-for-batching").
Loads the definition and assigns the inputs the same way
WorkflowExecutor.ExecuteStep does, asserting both values resolve.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* ci: install .NET 10 SDK in Azure-Tests job

The Azure-Tests job runs a repo-wide 'dotnet restore', which now fails
with NETSDK1045 because the test projects target net10.0 but this job
only installed the .NET 8/9 SDKs. Align it with the other jobs (6/8/9/10).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Bump version to 3.19.0 (danielgerlag#1436)

* 3.20.0 security release (danielgerlag#1437)

* Upgrade OpenTelemetry.Api to 1.17.0 (CVE-2026-40894)

* Bump version to 3.20.0

* Reconnect RedisLockProvider when the multiplexer is stale (danielgerlag#1435)

* Bump System.Diagnostics.DiagnosticSource to 10.0.0 for OpenTelemetry.Api 1.17.0

* Added null-handling when recording host startup exception to current activity (danielgerlag#1438)

Co-authored-by: Zoltán Tamási <zoltantamasi@pro-sharp.hu>

* Add UseCosmosDbPersistence overload for DI-registered CosmosClient (danielgerlag#1421)

* Add UseCosmosDbPersistence overload for DI-registered CosmosClient

Adds a new overload of UseCosmosDbPersistence that resolves CosmosClient
from the DI container instead of requiring a connection string or
TokenCredential. This allows applications that already register CosmosClient
in their service collection to wire up CosmosDB persistence without
duplicating client configuration.

* Remove unused CosmosClientOptions parameter from DI overload

* Resolve conflict with Azure Table persistence on master

Keep the Azure Table Storage methods added after this branch was cut,
and add the DI-registered CosmosClient overload.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Place DI CosmosClient overload above TokenCredential overload

Keeps the change in a region master did not touch so the Azure Table
methods added on master merge cleanly.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* 3.21.0: version bump + PostgreSQL Delay timezone fix (danielgerlag#1441)

* Bump version to 3.21.0

Ship the host-startup Activity NRE fix (danielgerlag#1438), PostgreSQL Delay
timezone fix (danielgerlag#1425 / danielgerlag#1440), and Cosmos DI client overload (danielgerlag#1439 / danielgerlag#1424).

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Fix EF DateTime timezone mismatch hanging Delay on PostgreSQL

Same change as danielgerlag#1425 / danielgerlag#1440. Included here so 3.21.0 ships the fix
even if the Copilot PR remains blocked by the coding-agent review rule.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Harden Elasticsearch tests against container startup flakes (danielgerlag#1445)

Replace Squadron's wait-for-green NEST health check with Testcontainers
HTTP readiness, pin ES 7.17.29, and give the single-node container
mmap-safe / no-geoip settings. Use a unique index per test and refresh
before search instead of a fixed sleep.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Fix NullReferenceException in WorkflowHost with .NET 8+ dependency injection (danielgerlag#1404)

* Initial plan

* Fix NullReferenceException in WorkflowHost for .NET 8+

- Changed GetService to GetRequiredService for ILifeCycleEventPublisher registration
- Added null-safety checks when iterating background tasks in StartAsync
- Added null-safety checks when iterating background tasks in StopAsync

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix additional NullReferenceException with null activity in StartAsync

When OpenTelemetry tracing is not enabled, WorkflowActivity.StartHost() returns null.
Added null-conditional operator when calling activity.AddException() to prevent NullReferenceException.

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add purge support for in-memory persistence (danielgerlag#1413)

* Initial plan

* Add memory persistence purger for terminated workflows

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Address purge tests and validation

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* fix issue danielgerlag#1029 (danielgerlag#1154)

Co-authored-by: Bruce Sun(XIAOPING) <xiaopsu@microsoft.com>

* Feat/pre middelware syncrunner (danielgerlag#1341)

* feat: add calls to pre workflow middlewares to SyncWorkflowRunner

* tests: cover call of Pre-Middlware execution

---------

Co-authored-by: Vildan Softic <vildan.softic@e1-solutions.com>

* ci: publish NuGet packages via Trusted Publishing (OIDC) (danielgerlag#1449)

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Daniel Gerlag <daniel@gerlag.ca>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>
Co-authored-by: Workflow Core Manager <wfcore-manager@agentmail.to>
Co-authored-by: Zoltán Tamási <zolitamasi@gmail.com>
Co-authored-by: Zoltán Tamási <zoltantamasi@pro-sharp.hu>
Co-authored-by: Michal Dev <57101364+mbadev62@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>
Co-authored-by: Bruce Zlata <xpingsun@msn.com>
Co-authored-by: Bruce Sun(XIAOPING) <xiaopsu@microsoft.com>
Co-authored-by: Vildan Softic <zewa666@gmail.com>
Co-authored-by: Vildan Softic <vildan.softic@e1-solutions.com>
Co-authored-by: Claude <noreply@anthropic.com>
TC-jBautista added a commit to tigertext/workflow-core that referenced this pull request Oct 20, 2026
…amoLockProvider, release workflow) (#12)

* WF-143: Wait step does not function as expected under edge cases (#1)

* Create release-nuget-package.yml (#2)

* Update release-nuget-package.yml (#3)

* Release nuget package (#4)

* Update release-nuget-package.yml (#5)

* fix: Update DynamoLockProvider.cs (#6)

* fix: Dynamo lock provider (#7)

* Update DynamoLockProvider.cs

* Update Directory.Build.props

* Sync fork with upstream master (3.21.0) (#8)

* Comprehensive code review fixes: security hardening, async safety, and error handling (danielgerlag#1418)

* fix: resolve SQL connection leaks and injection risk in SqlServer queue provider

- Use 'using' statements for SqlConnection instead of manual Close()
- Validate queue name to prevent SQL injection via string replacement

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: harden DSL module against code injection and improve error handling

- Disable AllowNewToEvaluateAnyType in Dynamic LINQ parsing config
- Add TypeNameHandling.None to JSON deserialization settings
- Add error handling for missing constructors in reflection calls
- Wrap ParseLambda calls in try-catch with descriptive error messages
- Handle DynamicInvoke TargetInvocationException by unwrapping inner exception
- Add safe Enum.Parse with validation and error handling
- Remove bare catch block, add specific exception handling with logging
- Add type validation in TypeResolver.FindType

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: add input validation to WebAPI controllers and fix extension issues

- Add parameter validation and correct HTTP status codes in WorkflowsController
- Add parameter validation in EventsController
- Fix ServiceProvider disposal in JsonWorkflowTest
- Add filter sanitization in SearchService
- Fix race condition in InMemoryConversationStore
- Add logging for tool call ID truncation
- Add null check in ToolRegistry constructor
- Add source validation in AI DefinitionLoader

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: eliminate async void and blocking wait patterns in providers

- Convert async void RenewLeases to async Task in AzureLockManager
- Convert async void SendHeartbeat to async Task in DynamoLockProvider
- Convert async void Process to async Task in KinesisStreamConsumer
- Remove blocking .Wait() in DynamoPersistenceProvider.EnsureStoreExists
- Remove blocking .Wait() in DynamoLockProvider.Stop
- Remove blocking .Wait() in SqlServerQueueProvider.Dispose
- Fix blocking GetAwaiter().GetResult() in RabbitMQProvider.Dispose

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve async patterns, thread safety, and error handling in core services

- Replace lock-on-parameter with proper synchronization in MemoryPersistenceProvider
- Await Task.Run in SingleNodeEventHub, use thread-safe collection
- Convert async void FutureQueue to async Task with proper tracking
- Remove blocking .Wait() in WorkflowHost.Start/Stop
- Add timeout to QueueConsumer.Stop blocking wait
- Fix TOCTOU race condition in WorkflowRegistry using TryGetValue
- Implement proper Dispose in SingleNodeQueueProvider
- Replace First/Single with FirstOrDefault/SingleOrDefault in MemoryPersistenceProvider
- Fix compensation chain logic in CompensateHandler
- Fix lock release on unacquired lock in ActivityController
- Fix GreyList TTL race condition
- Use ConcurrentDictionary in IndexConsumer
- Add logging for null steps in WorkflowExecutor

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: improve error handling and thread safety in persistence providers

- Use TryGetValue and fix throw/throw ex in SqlLockProvider
- Synchronize static indexesCreated in MongoDB and RavenDB providers
- Replace FirstAsync with FirstOrDefaultAsync in EF persistence provider
- Add exception logging in MongoDB ProcessCommands
- Remove unused field in RabbitMQ provider
- Use using for RabbitMQ channel resources

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: defer ToolRegistry serviceProvider null check to point of use

Move the null guard from constructor to Register<T>() and GetTool() where
_serviceProvider is actually needed. This allows tests to construct
ToolRegistry with null when only using Register(tool) instance methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .

* pr feedback

* tests

* fix: upgrade test dependencies for modern Docker compatibility

- Update Squadron from 0.17.0 to 1.0.1 across 6 provider test projects
  (Redis, SqlServer, PostgreSQL, MySQL, MongoDB, Elasticsearch)
- Update xunit from 2.9.2 to 2.9.3 in test/Directory.Build.props
- Update StackExchange.Redis from 2.0.601 to 2.8.37 (required by Squadron.Redis 1.0.1)
- Drop net6.0 TFM from provider tests (Squadron 1.0.1 requires net8.0+)
- Fix MongoDB test: pass ILoggerFactory to updated MongoPersistenceProvider constructor
- Fix PostgreSQL tests: remove Npgsql legacy timestamp behavior that was
  incompatible with the timestamptz column migration, causing DateTime
  values to silently lose timezone offset on round-trip

All provider tests now pass:
  Redis 13/13, PostgreSQL 22/22, MySQL 21/21, SqlServer 44/44,
  MongoDB 25/25, Elasticsearch 7/7, DynamoDB 19/19

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address review findings from code audit PR

- SingleNodeEventHub: return Task.Run result instead of fire-and-forget
- MemoryPersistenceProvider: add null guard in TerminateSubscription
- SqlServerQueueProviderMigrator: apply SanitizeIdentifier to all
  bracket-delimited SQL identifiers (CreateService, CreateQueue,
  CreateContract, CreateMessageType, EnableBroker)
- SearchService: remove ineffective OData filter validation that used
  SQL injection patterns (OData has its own safety via Azure SDK)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Azure Table Storage persistence provider to WorkflowCore.Providers.Azure (danielgerlag#1393)

* Initial plan

* Add Azure Table Storage persistence provider with documentation

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add comprehensive end-to-end tests for Azure Table Storage persistence provider

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add Azure Table Storage tests to GitHub workflow

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix missing .NET 6.0.x in Oracle and Azure test workflows

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Remove .NET 6.0.x from Azure-Tests workflow to match project target framework

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix test project configuration - add IsTestProject property to enable test execution

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Address code review: fix OData injection, GetEvents direction, ETag conflicts, command deduplication, UTC times, test setup

Agent-Logs-Url: https://github.com/danielgerlag/workflow-core/sessions/1e652d54-54b0-46c1-8dc6-1e1e0090c0cd

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add ILogger to AzureTableStoragePersistenceProvider and implement logging

- Add optional ILoggerFactory parameter to constructor
- Update extension methods to pass ILoggerFactory from DI
- Implement actual exception logging in ProcessCommands instead of
  silent swallowing (resolves the //TODO: add logger)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: trigger CI

* Fix broken MongoDB-Tests CI step in workflow

The Restore dependencies step was missing its name/step separator,
causing 'run: dotnet restore' to be parsed as part of the setup-dotnet
action's 'with' block. This made the YAML invalid since a step cannot
have both 'uses' and 'run'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix DateTime.MinValue crash in Azure Table Storage UTC conversion

Replace direct .ToUniversalTime() calls with SafeToUtc() helper that
treats Unspecified-Kind DateTimes as UTC rather than local time.
This prevents crashes when DateTime.MinValue is passed (e.g. as a
'get all' query), since converting MinValue from local to UTC can
underflow depending on timezone offset.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Ensure DateTime properties are UTC when persisting to Azure Table Storage

The Azure.Data.Tables SDK requires all DateTime properties to have
DateTimeKind.Utc. Domain model objects often have Unspecified kind
(e.g. DateTime.MinValue). Add EnsureUtc() helper to each table entity
class to set the Kind before persistence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix LifeCycleEventPublisher crash during test host shutdown

- Change Execute() from async void to async Task so _dispatchTask
  properly tracks the full async execution lifecycle
- Use Task.Run(Execute) instead of new Task(Execute) to correctly
  unwrap the returned Task
- Catch ObjectDisposedException in Execute() to handle graceful
  shutdown when the BlockingCollection is disposed during enumeration
- Fix TOCTOU race in PublishNotification() by using TryAdd and
  catching ObjectDisposedException instead of checking IsAddingCompleted
- Improve Dispose() to complete adding and wait for the dispatch task
  before disposing the outbox, preventing unhandled exceptions that
  crash the test host process

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>
Co-authored-by: Daniel Gerlag <daniel@gerlag.ca>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* nuget publish

* Bump version to 3.18.0 in Directory.Build.props

* Add .NET 10 support: fix InvalidProgramException in expression compilation (danielgerlag#1429)

* Add .NET 10 support: fix InvalidProgramException in expression compilation

Pre-compile dynamic expressions outside closures/local functions in
DefinitionLoader to avoid InvalidProgramException on .NET 10's updated
expression tree compiler. The previous pattern of calling
LambdaExpression.Compile() inside closures that capture expression
objects produces invalid IL on .NET 10.

Changes:
- BuildScalarInputAction: compile expression before local function
- BuildObjectInputAction: pre-scan JObject and compile all @-prefixed
  expressions at definition load time instead of at each invocation
- AttachDirectlyOutput: pre-compile source expression before lambda
- AttachNestedOutput: pre-compile both target and source expressions
- MemberMapParameter: cache compiled source delegate in constructor
- Add net10.0 to test TFMs (Directory.Build.props, UnitTests, IntegrationTests)

Fixes danielgerlag#1428

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add regression test for scalar inputs (issue danielgerlag#1428)

Covers the reporter's exact scenario: a scalar variable-binding input
(data.MessageId) plus a scalar string-literal input ("waits-for-batching").
Loads the definition and assigns the inputs the same way
WorkflowExecutor.ExecuteStep does, asserting both values resolve.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* ci: install .NET 10 SDK in Azure-Tests job

The Azure-Tests job runs a repo-wide 'dotnet restore', which now fails
with NETSDK1045 because the test projects target net10.0 but this job
only installed the .NET 8/9 SDKs. Align it with the other jobs (6/8/9/10).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Bump version to 3.19.0 (danielgerlag#1436)

* 3.20.0 security release (danielgerlag#1437)

* Upgrade OpenTelemetry.Api to 1.17.0 (CVE-2026-40894)

* Bump version to 3.20.0

* Reconnect RedisLockProvider when the multiplexer is stale (danielgerlag#1435)

* Bump System.Diagnostics.DiagnosticSource to 10.0.0 for OpenTelemetry.Api 1.17.0

* Added null-handling when recording host startup exception to current activity (danielgerlag#1438)

Co-authored-by: Zoltán Tamási <zoltantamasi@pro-sharp.hu>

* Add UseCosmosDbPersistence overload for DI-registered CosmosClient (danielgerlag#1421)

* Add UseCosmosDbPersistence overload for DI-registered CosmosClient

Adds a new overload of UseCosmosDbPersistence that resolves CosmosClient
from the DI container instead of requiring a connection string or
TokenCredential. This allows applications that already register CosmosClient
in their service collection to wire up CosmosDB persistence without
duplicating client configuration.

* Remove unused CosmosClientOptions parameter from DI overload

* Resolve conflict with Azure Table persistence on master

Keep the Azure Table Storage methods added after this branch was cut,
and add the DI-registered CosmosClient overload.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Place DI CosmosClient overload above TokenCredential overload

Keeps the change in a region master did not touch so the Azure Table
methods added on master merge cleanly.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* 3.21.0: version bump + PostgreSQL Delay timezone fix (danielgerlag#1441)

* Bump version to 3.21.0

Ship the host-startup Activity NRE fix (danielgerlag#1438), PostgreSQL Delay
timezone fix (danielgerlag#1425 / danielgerlag#1440), and Cosmos DI client overload (danielgerlag#1439 / danielgerlag#1424).

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Fix EF DateTime timezone mismatch hanging Delay on PostgreSQL

Same change as danielgerlag#1425 / danielgerlag#1440. Included here so 3.21.0 ships the fix
even if the Copilot PR remains blocked by the coding-agent review rule.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Harden Elasticsearch tests against container startup flakes (danielgerlag#1445)

Replace Squadron's wait-for-green NEST health check with Testcontainers
HTTP readiness, pin ES 7.17.29, and give the single-node container
mmap-safe / no-geoip settings. Use a unique index per test and refresh
before search instead of a fixed sleep.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

* Fix NullReferenceException in WorkflowHost with .NET 8+ dependency injection (danielgerlag#1404)

* Initial plan

* Fix NullReferenceException in WorkflowHost for .NET 8+

- Changed GetService to GetRequiredService for ILifeCycleEventPublisher registration
- Added null-safety checks when iterating background tasks in StartAsync
- Added null-safety checks when iterating background tasks in StopAsync

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Fix additional NullReferenceException with null activity in StartAsync

When OpenTelemetry tracing is not enabled, WorkflowActivity.StartHost() returns null.
Added null-conditional operator when calling activity.AddException() to prevent NullReferenceException.

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Add purge support for in-memory persistence (danielgerlag#1413)

* Initial plan

* Add memory persistence purger for terminated workflows

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* Address purge tests and validation

Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>

* fix issue danielgerlag#1029 (danielgerlag#1154)

Co-authored-by: Bruce Sun(XIAOPING) <xiaopsu@microsoft.com>

* Feat/pre middelware syncrunner (danielgerlag#1341)

* feat: add calls to pre workflow middlewares to SyncWorkflowRunner

* tests: cover call of Pre-Middlware execution

---------

Co-authored-by: Vildan Softic <vildan.softic@e1-solutions.com>

* ci: publish NuGet packages via Trusted Publishing (OIDC) (danielgerlag#1449)

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>

---------

Co-authored-by: Daniel Gerlag <daniel@gerlag.ca>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>
Co-authored-by: Workflow Core Manager <wfcore-manager@agentmail.to>
Co-authored-by: Zoltán Tamási <zolitamasi@gmail.com>
Co-authored-by: Zoltán Tamási <zoltantamasi@pro-sharp.hu>
Co-authored-by: Michal Dev <57101364+mbadev62@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>
Co-authored-by: Bruce Zlata <xpingsun@msn.com>
Co-authored-by: Bruce Sun(XIAOPING) <xiaopsu@microsoft.com>
Co-authored-by: Vildan Softic <zewa666@gmail.com>
Co-authored-by: Vildan Softic <vildan.softic@e1-solutions.com>
Co-authored-by: Claude <noreply@anthropic.com>

* Revert "Sync fork with upstream master (3.21.0) (#8)" (#11)

The squash merge dropped the upstream history, so the fork still shows as
16 commits behind. Reverting so the sync can be re-merged with a merge
commit.

This reverts commit 17fce4b.

🤖 Generated with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Daniel Gerlag <daniel@gerlag.ca>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danielgerlag <2357007+danielgerlag@users.noreply.github.com>
Co-authored-by: Workflow Core Manager <wfcore-manager@agentmail.to>
Co-authored-by: Zoltán Tamási <zolitamasi@gmail.com>
Co-authored-by: Zoltán Tamási <zoltantamasi@pro-sharp.hu>
Co-authored-by: Michal Dev <57101364+mbadev62@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>
Co-authored-by: Bruce Zlata <xpingsun@msn.com>
Co-authored-by: Bruce Sun(XIAOPING) <xiaopsu@microsoft.com>
Co-authored-by: Vildan Softic <zewa666@gmail.com>
Co-authored-by: Vildan Softic <vildan.softic@e1-solutions.com>
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.

1 participant