This release focuses on Flowchart execution improvements, stronger runtime correctness, major test coverage expansion, reliability fixes for scheduling/triggers and HTTP content handling, and a platform upgrade to .NET 10 while retaining support for .NET 8 and .NET 9.
Highlights
- Token-centric Flowchart execution model with configurable MergeMode, plus multiple refinements and DI-based configuration (opt-in). See Flowchart: token-based execution + per-activity
MergeMode. (PRs: #6632, #6937, #6993, #7141) - Upgrade to .NET 10 across the solution (with conditional compatibility dependencies where needed). (PR: #7062)
- New Activity Testing API and a major expansion of unit/integration/component test coverage across core activities, scheduling, HTTP endpoints, JavaScript, and flowchart execution. (PR: #6719 and many follow-ups)
- Improved runtime observability & execution record serialization, including snapshots and a new
ActivityCompletednotification. (PRs: #6675, #6800, #6807) - Reliability fixes across triggers/scheduling and HTTP content handling (cron delay edge cases, multi-engine trigger registration, Content-Length / charset issues). (PRs: #7047, #7131, #6676, #7027)
Flowchart: token-based execution + per-activity MergeMode (opt-in)
Elsa 3.6.0 introduces an optional token-based execution algorithm for the Flowchart activity. Instead of relying on the previous counter-based scheduling model, the Flowchart can now track progress using tokens that represent a taken connection (from a source activity outcome to a target activity).
When an activity completes, the flowchart:
- Emits tokens for each taken outbound connection (based on the activity’s outcome names).
- Consumes inbound tokens that were waiting for the completed activity.
- Schedules downstream activities based on each target activity’s
MergeMode.
New: MergeMode (configurable per activity)
With token-based execution enabled, Flowchart supports a new MergeMode concept that determines how a node behaves when it has multiple inbound connections. You can now specify a merge mode per activity, allowing different “join” semantics within the same flowchart.
In broad terms, merge modes enable behaviors like:
- Stream-like behavior: proceeds without strict joining, helping avoid dead-path waiting.
- Forward-join behavior (
Merge): waits for tokens from all forward inbound connections (loop/back edges don’t block). - Strict join behavior (
Converge): waits for tokens from all inbound connections, including loop/back edges. - First-arrival behavior (
Cascade/Race): schedules on the first arriving inbound token; inRacemode, other inbound ancestors are canceled so only the “winning” path continues.
This improves predictability for joins, forks, and cyclic graphs, while giving you fine-grained control over how each activity merges incoming paths.
How to opt in (Program.cs)
Token-based Flowchart execution is opt-in. Enable it via the Flowchart feature configuration:
elsa.UseFlowchart(flowchart => flowchart.UseTokenBasedExecution())Breaking / Upgrading Notes
These are the changes most likely to affect upgrades from 3.5.x.
1) Multi-targeting: .NET 8, .NET 9, and .NET 10
Elsa 3.6.0 multi-targets .NET 8, .NET 9, and .NET 10.
- Most consumers can continue targeting .NET 8 or .NET 9.
- If you build Elsa from source (or run CI against the full repo), ensure your build agents have a .NET 10 SDK available. (PR: #7062)
2) Package / project renames
Some projects / packages have been renamed. Make sure to update your package references accordingly.
In most cases, this also impacted the root namespace of these packages, so update using statements and fully-qualified type names as needed.
Migration tips
- Start by updating NuGet references (e.g., in
.csproj,Directory.Packages.props,Directory.Build.props). - Then update namespaces/usages:
- A simple approach is a solution-wide search/replace for the old root namespaces (e.g.
Elsa.EntityFrameworkCore→Elsa.Persistence.EFCore). - If you have global usings, update those too.
- A simple approach is a solution-wide search/replace for the old root namespaces (e.g.
- If you use central package management, ensure only the new package IDs remain (to avoid restore conflicts).
Optional commands (adjust paths as needed):
# If you want a quick way to find old package IDs/usings in your codebase:
rg "Elsa\\.(EntityFrameworkCore|Dapper|MongoDb|Elasticsearch|Webhooks|CSharp|Dsl|JavaScript|Liquid|Python|Kafka|MassTransit|FileStorage|Hangfire|Quartz)" -S
# Restore/build after updates:
dotnet restore --ignore-failed-sources
DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet build| Old | New | Repo | Notes |
|---|---|---|---|
Elsa.EntityFrameworkCore.*
| Elsa.Persistence.EFCore.*
| elsa-core | |
Elsa.Dapper
| Elsa.Persistence.Dapper
| elsa-extensions | |
Elsa.MongoDb
| Elsa.Persistence.MongoDb
| elsa-extensions | |
Elsa.Elasticsearch
| Elsa.Persistence.Elasticsearch
| elsa-extensions | |
Elsa.Webhooks
| Elsa.Http.Webhooks
| elsa-extensions | |
Elsa.CSharp
| Elsa.Expressions.CSharp
| elsa-core | |
Elsa.Dsl
| Elsa.Dsl.ElsaScript
| elsa-core | Complete replacement |
Elsa.JavaScript
| Elsa.Expressions.JavaScript
| elsa-core | |
Elsa.JavaScript.Libraries
| Elsa.Expressions.JavaScript.Libraries
| elsa-core | |
Elsa.Liquid
| Elsa.Expressions.Liquid
| elsa-core | |
Elsa.Python
| Elsa.Expressions.Python
| elsa-core | |
Elsa.Kafka
| Elsa.ServiceBus.Kafka
| elsa-extensions | |
Elsa.MassTransit.*
| Elsa.ServiceBus.MassTransit.*
| elsa-extensions | |
Elsa.FileStorage
| Elsa.Storage.FileStorage
| elsa-extensions | |
Elsa.Hangfire
| Elsa.Scheduling.Hangfire
| elsa-extensions | |
Elsa.Quartz.*
| Elsa.Scheduling.Quartz.*
| elsa-extensions |
3) Modules moved out of Core
- SQL activities removed from Core. If you used SQL activities, reference the appropriate extension package(s) instead of relying on core-only dependencies. (PR: #6625)
- IO module moved to Extensions. If you depended on IO activities/types from core, update references to the new extension location. (PR: #6835)
- Persistence and integration packages renamed. If you referenced these packages previously, update your package references accordingly:
Elsa.Dapper→Elsa.Persistence.DapperElsa.MongoDb→Elsa.Persistence.MongoDbElsa.Elasticsearch→Elsa.Persistence.ElasticsearchElsa.Webhooks→Elsa.Http.WebhooksElsa.Kafka→Elsa.ServiceBus.KafkaElsa.MassTransit.*→Elsa.ServiceBus.MassTransit.*Elsa.FileStorage→Elsa.Storage.FileStorageElsa.Hangfire→Elsa.Scheduling.HangfireElsa.Quartz.*→Elsa.Scheduling.Quartz.*
4) Persistence & database migrations
- Database extensions were refactored and migration support for v3.6 was added. Review persistence configuration and apply migrations where applicable. (PRs: #6788, #6931)
5) Flowchart execution semantics
- The token-centric Flowchart model and merge-mode changes can affect execution semantics in complex graphs (especially joins/loops/cycles). Re-test those workflows after upgrading. See Flowchart: token-based execution + per-activity
MergeMode. (PRs: #6632, #6937, #6993, #7141)
Recommended verification checklist
After upgrading, we recommend validating the following areas:
- Flowcharts using joins, loops, and cyclic graphs (FlowJoin/WaitAny, merge modes). (#6592, #6632, #6937, #7151)
- Scheduling & cron triggers, especially fast schedules / edge cases. (#6641, #7047, #7045)
- Multi-engine environments for trigger registration correctness (no duplicates). (#7131)
- HTTP activities: Content-Type/charset handling and Content-Length correctness; file upload/download scenarios. (#6676, #7027, #7094, #7125)
- Persistence: migration path and EF Core provider configuration in your target environment. (#6788, #6931)
What’s Changed
Flowchart & core execution
- Fix unexpected FlowJoin(WaitAny) behavior in cyclic flow. (PR: #6592)
- Introduce token-centric Flowchart execution model with configurable MergeMode. (PR: #6632)
- Refactor flowchart token handling and enhance merge mode behavior. (PR: #6937)
- Refactors and clarifies Flowchart merge modes. (PR: #6993)
- Configures Flowchart Execution via DI. (PR: #7141)
- Fix
Switchactivity behavior and improve testing utilities. (PR: #7151) - Improves Fork activity and break signal handling. (PR: #7104)
- Add missing
Pendingstate toActivityStatusenum. (PR: #6856)
Workflow composition, scripting & developer hooks
- Add optional workflow output flag. (PR: #6659)
- Add
ActivityCompletednotification for workflow activity completion. (PR: #6675) - Fix Liquid expressions not working in sub-workflows (workflow-as-activity). (PR: #6678)
- Allow C# Script to use dot notation with
ExpandoObject(JSON variables). (PR: #6689) - Search for workflow-as-activities based on DefinitionId (not only VersionId). (PR: #7149)
- Add Elsa Script DSL. (PR: #7076)
- Add bus configurator hook to
MassTransitFeature. (PR: #6658) - Workflow input as activity input. (PR: #6910)
HTTP, endpoints & content handling
- Fix Content-Type header charset auto-appending in HTTP requests. (PR: #6676)
- Fix Content-Length mismatch by reworking
RawStringContent. (PR: #7027) - Update
RawStringContentencoding inJsonContentFactory. (PR: #6786) - Fix wrong strategy selection for some string content. (PR: #6777)
- Expose the first uploaded file. (PR: #7010)
- Better base64 evaluation + appropriate zip entry naming. (PR: #6783)
- Fix wrong naming in resulting entries when file is input from HTTP. (PR: #6806)
- Unit & integration tests for
DownloadHttpFile. (PR: #7094) - HTTP endpoint unit, integration and component tests. (PR: #7125)
Triggers, scheduling & concurrency
- Trigger payload validation; refactor HttpEndpoint validator; add Cron validator. (PR: #6641)
- Fix cron triggers silently stopping when delay calculation returns zero. (PR: #7047)
- Fix semaphore release logic in scheduled task execution. (PR: #7045)
- Fix race condition causing duplicate trigger registration in multi-engine environments + add concurrency regression tests. (PR: #7131)
- Extensive unit and component tests for scheduling activities. (PR: #7036)
Persistence, database & migrations
- Refactor database extensions and support migrations for v3.6. (PR: #6788)
Serialization, conversion & correctness
- Add
FuncExpressionValueConverterfor JSON serialization. (PR: #6607) - Introduce activity execution record capturing and serialization improvements. (PR: #6800)
- Refactor activity execution record serialization with snapshots. (PR: #6807)
- Add
IEnumerableTypeConverter. (PR: #7020) - Add
IAsyncEnumerablecheck toGetItemSource. (PR: #6897) - Parse
VariableTestValuesmore robustly (ExpandoObject + type conversion). (PR: #6883) - Use
FullNameinWorkflowDictionary. (PR: #6923) - Add
ILoggerFactorysupport to converters. (PR: #7153) - Fix missing
DefaultValueforOuterBoundInclusiveinForactivity. (PR: #6680)
Platform / dependencies / repo organization
- Upgrade projects to target .NET 10; update project files for consistency; add conditional compatibility dependencies. (PR: #7062)
- Update Jint to 4.3.0. (PR: #6794)
- Enhanced
SasTokensFeatureto support sharing protected keys via shared drive, Redis cache, and other mechanisms. (PR: #6665) - Realign Core and Extension repos. (PR: #6664)
- Add back SasToken project. (PR: #6673)
- Remove SQL activities from Core. (PR: #6625)
- Remove IO module from Core (moved to Extensions). (PR: #6835)
- Enhance thread safety with
ConcurrentDictionaryusage. (PR: #6760) - Downgrade
JetBrains.Annotationsto fix package builds. (PR: #6848)
Runtime stability / cleanup
- Fix
FileSystemWatchercleanup. (PR: #6657) - Fix ASP.NET integration test crashes by adding proper Elsa background task shutdown. (PR: #6686)
- Fix
EventBasechild activity not executingOnEventReceived. (PR: #6687) - Fix
ParentWorkflowInstanceIdnot being set. (PR: #7029)
UI / Studio / Designer
- View suspended workflow in studio fix. (PR: #6646)
- New UI hint:
RadioList(API models + UI components + related refactors). (PRs: #6711, #6712, #6713, #6714) - Generic activity name fix. (PR: #6698)
- Refactor
ActivityRegistryto populate all activities in workflow edit. (PR: #6605) - Fix: allow loading all descriptors in the UI. (PR: #6648)
Testing (major coverage expansion)
This release includes a large number of new tests across most core activities. Some representative additions:
- Implement Activity Testing API. (PR: #6719)
- Coverage enforcement for test projects. (PR: #6950)
- Code coverage configuration and test project adjustments. (PR: #7049)
- Integration tests for Flowchart. (PR: #6991)
- Integration tests for RunJavaScript + introduce
WorkflowTestFixture. (PR: #7002) - Integration tests for
WorkflowDefinitionActivityscenarios. (PR: #6999) - ExecuteWorkflow activity tests. (PR: #7003)
- BulkDispatchWorkflows tests and improved activity coverage. (PR: #7026)
- DispatchWorkflow tests with new workflow definitions. (PR: #7035)
- Integration tests for core activities. (PR: #7100)
- Many more unit & integration tests across core activities such as Container, Sequence, Start/End/Complete/Finish/Fault, ParallelForEach, Correlate, EventBase, Publish Event, and multiple flow activities. (Multiple PRs including: #6989, #6995–#6997, #7001, #7004, #7005, #7007, #7008, #7016, #7031, #7090, #7093, #7102, #7103, #7108–#7117, #7119–#7120, #7112)
Misc / docs / polish
- Update
CommonTypesDefinitionProvider.cs. (PR: #6615) - Fix typo in README section title. (PR: #6629)
- Fix spelling in hosted service LogError messages. (PR: #6654)
- Fix duplicate words in XML comments. (PR: #6655)
New Contributors
Thanks to our new contributors:
- @Nordran (PR: #6592)
- @mhichb (PR: #6615)
- @MaxBrooks114 (PR: #6607)
- @LaamiriOuail (PR: #6629)
- @zengande (PR: #6761)
- @FuJa0815 (PR: #6897)
- @mberthillot-flowwa (PR: #6910)
- @crashkonijn (PR: #7029)
- @j03y-nxxbz (PR: #7149)
- @Jelger-Quadira (PR: #7146)
Full Changelog
- Compare view: 3.5.2...3.6.0-rc1