Repository navigation
Forward-merge 3.8 and 3.9 release fixes into main - #285
Conversation
* Fix MongoDB VariableSerializer using empty serialization type registry VariableSerializer constructed VariableMapper against SerializationTypeRegistry.CreateDefault(), an isolated empty registry. After 3.8 type-resolution hardening, storage driver type names such as WorkflowInstanceStorageDriver no longer resolve, so variables lose StorageDriverType and are not persisted on resume. Inject the DI-registered ISerializationTypeRegistry (populated from SerializationTypeOptions by Elsa features) and register VariableSerializer so MongoDB serializer setup can use it. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * Fix VariableSerializer tests resolving Options.Create against Elsa.Options Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Fix MongoDB JsonNode serializer for JsonObject/JsonArray/JsonValue. PolymorphicSerializer looks up serializers by concrete runtime type, but JsonNodeBsonConverter was registered only for the JsonNode base type. JsonObject values in workflow state then serialized via class-map fallback and failed to deserialize (no parameterless constructor). Register the converter for derived types, accept the legacy map format, and cover round-trips with unit tests. Fixes elsa-workflows/elsa-core#8048 Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * Tighten JsonNode tagged-envelope detection. Require exactly two elements and a BSON string value for JsonObject/JsonArray so a document that merely has type/value keys is deserialized as a map. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…183) DapperWorkflowInstanceStore.ApplyFilter never applied WorkflowInstanceFilter.BeforeLastUpdated. The property was accepted and then silently dropped from the generated SQL, so callers got unfiltered results with no error. RestartInterruptedWorkflowsTask relies on that property to distinguish a genuinely interrupted workflow from one that is simply executing right now. On the Dapper provider its inactivity guard was therefore a no-op: the query degenerated to IsExecuting = 1, and any workflow that happened to be mid-execution when the task ticked was restarted from the beginning. The query builder had no inequality support at all (only Is, IsNot, IsNull, In, NotIn and StartsWith), which is why the property could not be expressed. Add a LessThan clause and wire it up. (cherry picked from commit 28fcb58) Co-authored-by: Ronald Kroon <ronald.kroon@avivasolutions.nl>
* fix: allow TryMarkInterrupted to promote Finished/Cancelled Align Mongo, Dapper, and Elasticsearch TryMarkInterruptedAsync with elsa-core#8069 so drain force-cancel (Finished/Cancelled) can become Running+Interrupted with IsExecuting=false. Naturally completed Finished/Finished and Finished/Faulted remain refused (#8052). Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix: use UpdateByQuery for ES TryMarkInterrupted Replace Find+SaveAsync with a conditional UpdateByQuery so Elasticsearch matches core#8069's atomic write shape. Predicate is Status != Finished OR SubStatus == Cancelled; success sets Running+Interrupted and IsExecuting=false. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…191) Mirror elsa-core#8069 (bc04b84): TryMarkInterruptedAsync refuses every Finished row by default and only promotes Finished/Cancelled when the drain-only flag is set. Keep Mongo UpdateOne, Dapper raw WHERE, and ES UpdateByQuery atomic shapes. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Retarget central Elsa.* / Elsa.Studio.* package pins so extensions can republish against core and studio 3.8.1. Directory.Packages.props already consumes these properties. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Retarget central Elsa core and Studio package pins so extensions can republish Mongo/Dapper from the release/3.8.2 tip against published 3.8.2 packages. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Retarget central Elsa core and Studio package pins so extensions can publish against nuget.org 3.8.4 after the aligned studio/core cascade. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Preview package versions on release/3.9.0 should use the 3.9 train. Leave ElsaVersion/ElsaStudioVersion unchanged until core/studio previews exist. Do not cut a stable 3.9.0 tag. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Unblock compile after #217: replace stale 3.8.0-preview.5557 / 3.8.0 with published 3.8.4. packages.yml base_version stays 3.9.0. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
PRs targeting release/* previously skipped the generated pr workflow because OnPullRequestBranches listed only main. Add release/* and regenerate GitHubActions_pr so build/test CI runs on release trains. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Compile release/3.9.0 against core 3.9.0-preview.5708 from feedz instead of 3.8.4. Implement IWorkflowDefinitionStore.TryUpdateLatestAsync on the Mongo and Dapper stores to match the core 3.9.0 API. ElsaStudioVersion stays 3.8.4. Fixes #220 Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Replace the weaker release-branch compare-and-swap with main's Mongo conditional writes and Dapper TenantId/DefinitionId/ToolVersion guards. Add Dapper SQLite and Mongo Testcontainers tests modeled on core's MemoryWorkflowDefinitionStoreCompareAndSwapTests. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…view-a227 Pin ElsaVersion to 3.9.0-preview.5708 so release/3.9.0 compiles
Bring 3.8.4 Mongo/Dapper persistence fixes onto the 3.9 train. Conflict resolution: - Directory.Build.props: kept release/3.9.0 ElsaVersion 3.9.0-preview.5708 (and existing ElsaStudioVersion 3.8.4). The 3.8.1/3.8.2/3.8.4 version bumps must not change 3.9 package pins. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…3.9.0 chore: forward-merge release/3.8.4 into release/3.9.0
Dapper, Elasticsearch and Mongo now ignore allowFinishedCancelled and only mark a Running row Interrupted, matching core#8419/#8421. Fixes #225 Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…d-refuse-finished fix(persistence): TryMarkInterruptedAsync refuses Finished rows in Dapper/Elastic/Mongo (#225)
…izeManyAsync Route the drain update and the ordered, paged instance summary through MongoDbStore tenant filters so a tenant-B caller cannot mark or list tenant A's workflow instances. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…lds) Give the new Update(table, fields) member a default interface implementation so third-party dialects that implement ISqlDialect directly keep compiling. SqlDialectBase keeps the same public method and both call a shared helper. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…-default-impl fix(dapper): default implementation for ISqlDialect.Update(table, fields)
…ore-tenant-scope fix(mongodb): tenant-scope TryMarkInterruptedAsync and ordered SummarizeManyAsync (#228)
…tic flags Apply the store tenant read scope to both paged FindSummariesAsync overloads so Studio cannot list or count another tenant's workflow definitions. Pass filter.TenantAgnostic through the Mongo trigger paged query and BookmarkQueueStore methods, and reuse the scoped List/Count path in LabelStore.ListAsync. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
… take over rows
MongoDbStore upserts now match key/Id AND TenantId == document.TenantId AND
TenantId in {writer, *}, so a write cannot change a row's owner. A mismatch
hits the unique _id index (E11000), matching EF's PK violation. ApplyTenantId
normalises "" to null so default-tenant role/user re-saves keep working.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…psert tests Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…y category Add SaveAsync/SaveManyAsync cases where tenant B sends TenantId=tenant-a with A's Id. Those are the only path that needs the writer/* clause. Assert Mongo ServerErrorCategory.DuplicateKey / code 11000 instead of the E11000 string. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…summaries-tenant-scope fix(mongodb): tenant-scope paged definition summaries (#239)
…nt-owned-filter fix(mongodb): tenant-owned upsert filter so cross-tenant saves cannot take over rows
…tion V3_5 (20006) already adds ActivityExecutionRecords.AggregateFaultCount. V3_7 (20007) added it again, so a fresh SQLite MigrateUp failed and rolled back, leaving SerializedMetadata (and later Identity tables) missing. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Pin extensions to the core preview that added IWorkflowInstanceStore.TryMarkInterruptedAsync so Dapper/Mongo/Elastic stores compile as interface implementations. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…t test The predicate overload only sees DatabaseType, so AddSqlServer() (SqlServer2016), AddMySql() (MySql8) and AddOracleManaged() no longer matched. Switch back to IfDatabase(params string[]) with a shared DateTimeOffsetProviders list: SqlServer, Oracle, MySql, Postgres, PostgreSQL, PostgreSQL92. Assert the real processors from AddSqlServer/AddSQLite/AddPostgres/ AddMySql/AddOracleManaged take exactly one create branch. The fresh-PG Testcontainers test now asserts migrate + tables only. Quoting identifiers plus including the PK in PostgreSqlDialect.Upsert is a store-wide dialect change, not a focused migration fix. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Studio 1757 dropped Blazored.FluentValidation from Elsa.Studio.Core, so Agents/Secrets/WorkflowContexts now reference it directly (2.2.0). Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
FluentMigrator force-quotes PG table/column names. Re-implement ISqlDialect on PostgreSqlDialect so Dapper emits matching quoted identifiers, and include the primary key in ON CONFLICT upsert. Restore the fresh-PG Testcontainers test to migrate, persist, and run a WriteLine workflow to completion. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Avoid interpolated-string quote escaping so the helper stays compile-safe. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
SqliteDbConnectionProvider registers a string-only DateTimeOffset handler on SqlMapper. After persist, PG Find failed with InvalidCastException. Register a PG handler that accepts DateTime, DateTimeOffset, and string. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
IWorkflowHost SaveMany concatenates upserts. Without a trailing semicolon PostgreSQL reports 42601 at the second insert. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…review-5724-c29f chore(deps): bump ElsaVersion to 3.9.0-preview.5724 and ElsaStudioVersion to 3.9.0-preview.1757
Route every identifier ParameterizedQueryBuilderExtensions inlines through ISqlDialect.QuoteIdentifier. The default is a no-op so SQLite, SQL Server, MySQL and Oracle SQL stays byte-identical; only PostgreSqlDialect double-quotes. Snapshot tests lock the pre-hook non-PG SQL. The fresh-PG Testcontainers test now also covers list, search, OrderBy, VersionOptions and paged delete. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
VersionOptions compared boolean columns to 1/0, which PostgreSQL rejects (42883). ISqlDialect.BooleanLiteral defaults to 1/0 so non-PG SQL stays byte-identical; only PostgreSqlDialect emits true/false. The fresh-PG test now covers publish, run-by-definition, VersionOptions, Studio lists, journal and activity-execution reads, bookmark-queue paging, and paged delete. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
3.9-only BeforeLastUpdated uses LessThan, which still inlined the column name. Route it through QuoteIdentifier so PG quotes and SQLite/SQL Server SQL stays byte-identical. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
The slim Testcontainers host never called AddActivitiesFrom or IActivityRegistryPopulator, so PublishAsync NRE'd in CreateActivity when rematerializing the draft. Store SQL is unchanged. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
AndWorkflowInstanceSearchTerm historically inlined unquoted ID, which is byte-identical on SQLite/SQL Server. Quoted on PG it is 42703 against FluentMigrator's "Id". Non-PG SQL is unchanged. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
B4: AndWorkflowInstanceSearchTerm now quotes Id (same spelling as definition search). The non-PG snapshot changes one token (ID → Id); SQLite and default-collation SQL Server are case-insensitive. B5: rec-pg-1 uses ActivityStatus.Completed, and the paged delete is built in the test so inner parameters are not dropped. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
The instance-search snapshot token is accepted. It also fixes instance search on case-sensitive SQL Server collations, where the column is Id. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…s-provider-names-cdd8 fix(dapper): match PostgreSQL provider names and quote identifiers via dialect hook
…sync (#266) * fix(dapper): create KeyValues and add BookmarkQueueItems.SerializedOptions Guarded V3.9 runtime migration (20008) so a migration-built DB can persist IKeyValueStore rows and bookmark-queue Options. Existing hand-created KeyValues tables and SerializedOptions columns are left alone. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(dapper): apply KV prefix or exact key, not both, and bind StartsWith Prefix FindMany threw on every provider because ApplyFilter combined Is(Id) with StartsWith, and StartsWith emitted @SearchTermLike while binding @{field}. Down() for 20008 is now a no-op so a rollback cannot drop a hand-created KeyValues table or SerializedOptions column. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * chore(deps): pin ElsaVersion to 3.9.0-preview.5726 Final 3.9 cut pin. Core release/3.9.0 @ fa68369a includes #8539 (IKeyValueStore.TryDeleteAsync). ElsaStudioVersion stays 3.9.0-preview.1757. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(persistence): atomic TryDeleteAsync on Dapper and Mongo (#260) Override IKeyValueStore.TryDeleteAsync so legacy-pause adoption is a single count-checked delete. Dapper uses Store.DeleteAsync row count; Mongo uses DeleteOneAsync(ApplyTenantScope(...)).DeletedCount. Default-tenant reads and deletes now match NULL or '' TenantId so a legacy NULL row is visible to Tenant.Default (#245 gap for adoption). The rest of #245 stays on 3.10. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * ci: retrigger pr workflow for #260 Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * ci: touch TryDelete tests so pr.yml paths match Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(dapper): keep QuoteIdent with StartsWith binding after #258 rebase #258 quoted identifiers but still bound @{field} while emitting @SearchTermLike. Keep QuoteIdent and @{field}StartsWith together. Add PostgreSQL Testcontainers TryDelete coverage now that the infra is on the branch. Update the non-PG SQL snapshot for StartsWith. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * test(dapper): fail if StartsWith drops QuoteIdent on PostgreSQL CR recommended: pin the quoted @NameStartsWith shape so taking this PR's unquoted StartsWith side fails a test, not only a local PG harness. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…sion to 3.9.0-preview.1794 Pin core to release/3.9.0 tip 9fbbef94 and studio to bd443662 so extensions compile against the identity/access work that landed since 5726/1757. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…sion to 3.9.0-preview.1797 Retarget the 3.9 pin onto core 61aa0f7a (#8566 zero-grant claim, #8570 docs, #8573 refresh-by-sub) and studio 2842adf0 (#1105 open-redirect). Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…5744-16ea chore(deps): bump ElsaVersion to 3.9.0-preview.5753 and ElsaStudioVersion to 3.9.0-preview.1797
Pin core to 5ef65395 so extensions compile against dashboard per-section permission filtering (#8589). Studio stays at 3.9.0-preview.1797. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
…review-5757-16ea chore(deps): bump ElsaVersion to 3.9.0-preview.5757
…e-pins chore: pin Elsa / Elsa Studio 3.9.0 stable on release/3.9.0
sfmskywalker
left a comment
There was a problem hiding this comment.
Elsa 3 Code Review: APPROVE + HIGH @ b76f8fd
Independent review by a reviewer agent separate from the Extensions implementation found no actionable defects or lost release fixes. Main's 3.10 preview dependency pins and publishing guards are preserved; the Dapper and MongoDB fixes and tests are retained.
Verified PR #285 has this exact head and all checks are green. CI run https://github.com/elsa-workflows/elsa-extensions/actions/runs/37381631473 passed Compile, Test and Pack: 498 passed, two unrelated Slack/Azure Service Bus skips. Relevant suites passed 64/64 (persistence Dapper), 20/20 (Dapper), and 67/67 (MongoDB). PostgreSQL fixtures start PostgreSQL 16 and propagate startup failures.
Copilot was requested as the repository's advisory reviewer; no Copilot review was available at this checkpoint. This independent verdict applies only to the stated commit. Preserve ancestry with a merge commit and suppress the main-push publisher using the agreed [skip ci] merge message.
Extensions main is missing functional fixes shipped on the 3.8 and 3.9 release lines. This forward merge brings release/3.9.0 (
89d4eb9b) into main while preserving main's 3.10 preview dependencies and publishing configuration.The net changes carry MongoDB JSON-node and variable serialization fixes, tenant-scoped ordered workflow summaries and interruption, and Dapper's BeforeLastUpdated filter with regressions. Existing main implementations of the PostgreSQL and atomic key-value deletion fixes are retained. All stable 3.8 tags and the current 3.9.0 release tip are ancestors of this branch.
Refs elsa-workflows/elsa-core#8623, elsa-workflows/elsa-core#8194.
Validation: independent source-merge review found no actionable integration issue; diff checks pass. Focused local Dapper/MongoDB/PostgreSQL tests and hosted CI are pending. This PR is not yet qualified for merge.
Merge with a merge commit to retain release ancestry. The merge message must include
[skip ci]after current-head PR CI and review pass, because a normal main push triggers Feedz publishing; this task does not authorize publication. No package, release, or deployment is part of this change.