From 9454ab5cc439aeba7eb9133bd34cfa5a9e27fcaf Mon Sep 17 00:00:00 2001 From: wendrul <53628737+wendrul@users.noreply.github.com> Date: Sat, 13 Sep 2025 10:43:48 +0200 Subject: [PATCH] fix: workspace forks script versioning (hashes) (#6604) * fix: use same hashes as original workspace when forking * Remove overwrite of created_by * Update SQLx metadata --------- Co-authored-by: GitHub Action --- ...96408e219d70015dd2f419fc87a440f070c64.json | 15 + ...1f7f387f5055c47f493271d26731336257384.json | 10 +- ...f87437ac0e47f59eb9d15ad07856a690319ce.json | 46 --- ...94bbb30311749431f31e488c32d21b2337544.json | 15 + ...11e11c7a05d69b4b7907f8909aec82fb1eb2.json} | 5 +- ...ae28b5ba639731cb4867ab2a8e0acdcc9c32.json} | 5 +- ...013eb133a28cd848bf8fdf9571b2ee402a3e.json} | 5 +- ...1abb820df9d6ec54a340cf8b1332e1052f666.json | 271 ------------------ ...f3bee9b93ba0387f566ad7f502cbee818296e.json | 15 + ...2adce1be8b897288b655505729c97c6e324c.json} | 5 +- ...931837dd6fb319577ba9d6103fb88b807bfca.json | 19 -- ...bbc3fad75c097ed483adba1f2f7f593481807.json | 95 ------ backend/windmill-api/src/workspaces.rs | 251 ++++------------ 13 files changed, 116 insertions(+), 641 deletions(-) create mode 100644 backend/.sqlx/query-00b9f392a5cc07bd4ed14e3b69f96408e219d70015dd2f419fc87a440f070c64.json delete mode 100644 backend/.sqlx/query-28e81c9e4a9d166f38fff7e7f1cf87437ac0e47f59eb9d15ad07856a690319ce.json create mode 100644 backend/.sqlx/query-4fcce9b5b039b73b2f19fa9d15294bbb30311749431f31e488c32d21b2337544.json rename backend/.sqlx/{query-26829b40c9cbdc466154dbb9cea3c2a6a1378d87c0e2f0b5c9cda882b52e3eb0.json => query-748b63f877498d6d279fdf23894611e11c7a05d69b4b7907f8909aec82fb1eb2.json} (67%) rename backend/.sqlx/{query-681be1486a7853c42b1a74aa523a6a1cd42a79852952115e6f30db0dc6ee4b6e.json => query-755a9c2f19d3befe68ebffca43abae28b5ba639731cb4867ab2a8e0acdcc9c32.json} (55%) rename backend/.sqlx/{query-841aaef7303e5994d97b529d256e7980b81861af63ba116630603087196ce02b.json => query-7abd579d3ec97853ac36cc8dad29013eb133a28cd848bf8fdf9571b2ee402a3e.json} (56%) delete mode 100644 backend/.sqlx/query-97547c49f4ed07e7d07ddf2ef971abb820df9d6ec54a340cf8b1332e1052f666.json create mode 100644 backend/.sqlx/query-a54e2334c365f90577f68ebefc8f3bee9b93ba0387f566ad7f502cbee818296e.json rename backend/.sqlx/{query-b7ba64475398162ba43001a9932ac9a2b9ce8295e4ac85421091ab7da17a9a7c.json => query-dbd66bee283a7b4f892673f968f92adce1be8b897288b655505729c97c6e324c.json} (68%) delete mode 100644 backend/.sqlx/query-e628e560caad2e6f37459a255cc931837dd6fb319577ba9d6103fb88b807bfca.json delete mode 100644 backend/.sqlx/query-e734447a2506c7d69e744f8ddf1bbc3fad75c097ed483adba1f2f7f593481807.json diff --git a/backend/.sqlx/query-00b9f392a5cc07bd4ed14e3b69f96408e219d70015dd2f419fc87a440f070c64.json b/backend/.sqlx/query-00b9f392a5cc07bd4ed14e3b69f96408e219d70015dd2f419fc87a440f070c64.json new file mode 100644 index 0000000000..f09f6d0d85 --- /dev/null +++ b/backend/.sqlx/query-00b9f392a5cc07bd4ed14e3b69f96408e219d70015dd2f419fc87a440f070c64.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO dependency_map (workspace_id, importer_path, importer_kind, imported_path, importer_node_id)\n SELECT $1, importer_path, importer_kind, imported_path, importer_node_id\n FROM dependency_map\n WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "00b9f392a5cc07bd4ed14e3b69f96408e219d70015dd2f419fc87a440f070c64" +} diff --git a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json index d29a18c691..e7ed0aee65 100644 --- a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json +++ b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json @@ -46,11 +46,11 @@ ] }, "nullable": [ - true, - true, - true, - true, - true, + false, + false, + false, + false, + false, true, true ] diff --git a/backend/.sqlx/query-28e81c9e4a9d166f38fff7e7f1cf87437ac0e47f59eb9d15ad07856a690319ce.json b/backend/.sqlx/query-28e81c9e4a9d166f38fff7e7f1cf87437ac0e47f59eb9d15ad07856a690319ce.json deleted file mode 100644 index a139571c83..0000000000 --- a/backend/.sqlx/query-28e81c9e4a9d166f38fff7e7f1cf87437ac0e47f59eb9d15ad07856a690319ce.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT flow_path, runnable_path, script_hash, runnable_is_flow, app_path\n FROM workspace_runnable_dependencies \n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "flow_path", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "runnable_path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "script_hash", - "type_info": "Int8" - }, - { - "ordinal": 3, - "name": "runnable_is_flow", - "type_info": "Bool" - }, - { - "ordinal": 4, - "name": "app_path", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - true, - false, - true, - false, - true - ] - }, - "hash": "28e81c9e4a9d166f38fff7e7f1cf87437ac0e47f59eb9d15ad07856a690319ce" -} diff --git a/backend/.sqlx/query-4fcce9b5b039b73b2f19fa9d15294bbb30311749431f31e488c32d21b2337544.json b/backend/.sqlx/query-4fcce9b5b039b73b2f19fa9d15294bbb30311749431f31e488c32d21b2337544.json new file mode 100644 index 0000000000..4c108cfea2 --- /dev/null +++ b/backend/.sqlx/query-4fcce9b5b039b73b2f19fa9d15294bbb30311749431f31e488c32d21b2337544.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO script (\n workspace_id, hash, path, parent_hashes, summary, description, content,\n created_by, created_at, archived, schema, deleted, is_template,\n extra_perms, lock, lock_error_logs, language, kind, tag, draft_only,\n envs, concurrent_limit, concurrency_time_window_s, cache_ttl,\n dedicated_worker, ws_error_handler_muted, priority, timeout,\n delete_after_use, restart_unless_cancelled, concurrency_key,\n visible_to_runner_only, no_main_func, codebase, has_preprocessor,\n on_behalf_of_email, assets\n )\n SELECT\n $1, hash, path, parent_hashes, summary, description, content,\n created_by, created_at, archived, schema, deleted, is_template,\n extra_perms, lock, lock_error_logs, language, kind, tag, draft_only,\n envs, concurrent_limit, concurrency_time_window_s, cache_ttl,\n dedicated_worker, ws_error_handler_muted, priority, timeout,\n delete_after_use, restart_unless_cancelled, concurrency_key,\n visible_to_runner_only, no_main_func, codebase, has_preprocessor,\n on_behalf_of_email, assets\n FROM script\n WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "4fcce9b5b039b73b2f19fa9d15294bbb30311749431f31e488c32d21b2337544" +} diff --git a/backend/.sqlx/query-26829b40c9cbdc466154dbb9cea3c2a6a1378d87c0e2f0b5c9cda882b52e3eb0.json b/backend/.sqlx/query-748b63f877498d6d279fdf23894611e11c7a05d69b4b7907f8909aec82fb1eb2.json similarity index 67% rename from backend/.sqlx/query-26829b40c9cbdc466154dbb9cea3c2a6a1378d87c0e2f0b5c9cda882b52e3eb0.json rename to backend/.sqlx/query-748b63f877498d6d279fdf23894611e11c7a05d69b4b7907f8909aec82fb1eb2.json index c2639ca086..d710d59055 100644 --- a/backend/.sqlx/query-26829b40c9cbdc466154dbb9cea3c2a6a1378d87c0e2f0b5c9cda882b52e3eb0.json +++ b/backend/.sqlx/query-748b63f877498d6d279fdf23894611e11c7a05d69b4b7907f8909aec82fb1eb2.json @@ -1,16 +1,15 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO resource (workspace_id, path, value, description, resource_type, extra_perms, edited_at, created_by)\n SELECT $2, path, value, description, resource_type, extra_perms, edited_at, $3\n FROM resource \n WHERE workspace_id = $1", + "query": "INSERT INTO resource (workspace_id, path, value, description, resource_type, extra_perms, edited_at, created_by)\n SELECT $2, path, value, description, resource_type, extra_perms, edited_at, created_by\n FROM resource\n WHERE workspace_id = $1", "describe": { "columns": [], "parameters": { "Left": [ "Text", - "Varchar", "Varchar" ] }, "nullable": [] }, - "hash": "26829b40c9cbdc466154dbb9cea3c2a6a1378d87c0e2f0b5c9cda882b52e3eb0" + "hash": "748b63f877498d6d279fdf23894611e11c7a05d69b4b7907f8909aec82fb1eb2" } diff --git a/backend/.sqlx/query-681be1486a7853c42b1a74aa523a6a1cd42a79852952115e6f30db0dc6ee4b6e.json b/backend/.sqlx/query-755a9c2f19d3befe68ebffca43abae28b5ba639731cb4867ab2a8e0acdcc9c32.json similarity index 55% rename from backend/.sqlx/query-681be1486a7853c42b1a74aa523a6a1cd42a79852952115e6f30db0dc6ee4b6e.json rename to backend/.sqlx/query-755a9c2f19d3befe68ebffca43abae28b5ba639731cb4867ab2a8e0acdcc9c32.json index 01693cc7c5..112b8fe253 100644 --- a/backend/.sqlx/query-681be1486a7853c42b1a74aa523a6a1cd42a79852952115e6f30db0dc6ee4b6e.json +++ b/backend/.sqlx/query-755a9c2f19d3befe68ebffca43abae28b5ba639731cb4867ab2a8e0acdcc9c32.json @@ -1,16 +1,15 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO flow (\n workspace_id, path, summary, description, value, edited_by, edited_at,\n archived, schema, extra_perms, dependency_job, draft_only, tag,\n ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only,\n concurrency_key, versions, on_behalf_of_email, lock_error_logs\n )\n SELECT $2, path, summary, description, value, $3, edited_at,\n archived, schema, extra_perms, NULL, draft_only, tag,\n ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only,\n concurrency_key, ARRAY[]::bigint[], on_behalf_of_email, lock_error_logs\n FROM flow \n WHERE workspace_id = $1", + "query": "INSERT INTO flow (\n workspace_id, path, summary, description, value, edited_by, edited_at,\n archived, schema, extra_perms, dependency_job, draft_only, tag,\n ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only,\n concurrency_key, versions, on_behalf_of_email, lock_error_logs\n )\n SELECT $2, path, summary, description, value, edited_by, edited_at,\n archived, schema, extra_perms, NULL, draft_only, tag,\n ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only,\n concurrency_key, ARRAY[]::bigint[], on_behalf_of_email, lock_error_logs\n FROM flow\n WHERE workspace_id = $1", "describe": { "columns": [], "parameters": { "Left": [ "Text", - "Varchar", "Varchar" ] }, "nullable": [] }, - "hash": "681be1486a7853c42b1a74aa523a6a1cd42a79852952115e6f30db0dc6ee4b6e" + "hash": "755a9c2f19d3befe68ebffca43abae28b5ba639731cb4867ab2a8e0acdcc9c32" } diff --git a/backend/.sqlx/query-841aaef7303e5994d97b529d256e7980b81861af63ba116630603087196ce02b.json b/backend/.sqlx/query-7abd579d3ec97853ac36cc8dad29013eb133a28cd848bf8fdf9571b2ee402a3e.json similarity index 56% rename from backend/.sqlx/query-841aaef7303e5994d97b529d256e7980b81861af63ba116630603087196ce02b.json rename to backend/.sqlx/query-7abd579d3ec97853ac36cc8dad29013eb133a28cd848bf8fdf9571b2ee402a3e.json index b95af1ddc8..7d45d000ab 100644 --- a/backend/.sqlx/query-841aaef7303e5994d97b529d256e7980b81861af63ba116630603087196ce02b.json +++ b/backend/.sqlx/query-7abd579d3ec97853ac36cc8dad29013eb133a28cd848bf8fdf9571b2ee402a3e.json @@ -1,16 +1,15 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO resource_type (workspace_id, name, schema, description, edited_at, created_by, format_extension)\n SELECT $2, name, schema, description, edited_at, $3, format_extension\n FROM resource_type \n WHERE workspace_id = $1", + "query": "INSERT INTO resource_type (workspace_id, name, schema, description, edited_at, created_by, format_extension)\n SELECT $2, name, schema, description, edited_at, created_by, format_extension\n FROM resource_type\n WHERE workspace_id = $1", "describe": { "columns": [], "parameters": { "Left": [ "Text", - "Varchar", "Varchar" ] }, "nullable": [] }, - "hash": "841aaef7303e5994d97b529d256e7980b81861af63ba116630603087196ce02b" + "hash": "7abd579d3ec97853ac36cc8dad29013eb133a28cd848bf8fdf9571b2ee402a3e" } diff --git a/backend/.sqlx/query-97547c49f4ed07e7d07ddf2ef971abb820df9d6ec54a340cf8b1332e1052f666.json b/backend/.sqlx/query-97547c49f4ed07e7d07ddf2ef971abb820df9d6ec54a340cf8b1332e1052f666.json deleted file mode 100644 index 0a9fd45382..0000000000 --- a/backend/.sqlx/query-97547c49f4ed07e7d07ddf2ef971abb820df9d6ec54a340cf8b1332e1052f666.json +++ /dev/null @@ -1,271 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT hash, path, summary, description, content,\n created_at, archived, schema, deleted, is_template,\n extra_perms, lock, lock_error_logs, language as \"language: ScriptLang\", \n kind as \"kind: ScriptKind\", tag, draft_only, envs, concurrent_limit, \n concurrency_time_window_s, cache_ttl, dedicated_worker, \n ws_error_handler_muted, priority, timeout, delete_after_use, \n restart_unless_cancelled, concurrency_key, visible_to_runner_only,\n no_main_func, codebase, has_preprocessor, on_behalf_of_email,\n parent_hashes, assets\n FROM script WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "hash", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "summary", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "description", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "content", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "created_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 6, - "name": "archived", - "type_info": "Bool" - }, - { - "ordinal": 7, - "name": "schema", - "type_info": "Json" - }, - { - "ordinal": 8, - "name": "deleted", - "type_info": "Bool" - }, - { - "ordinal": 9, - "name": "is_template", - "type_info": "Bool" - }, - { - "ordinal": 10, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 11, - "name": "lock", - "type_info": "Text" - }, - { - "ordinal": 12, - "name": "lock_error_logs", - "type_info": "Text" - }, - { - "ordinal": 13, - "name": "language: ScriptLang", - "type_info": { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp", - "oracledb", - "nu", - "java", - "duckdb", - "ruby" - ] - } - } - } - }, - { - "ordinal": 14, - "name": "kind: ScriptKind", - "type_info": { - "Custom": { - "name": "script_kind", - "kind": { - "Enum": [ - "script", - "trigger", - "failure", - "command", - "approval", - "preprocessor" - ] - } - } - } - }, - { - "ordinal": 15, - "name": "tag", - "type_info": "Varchar" - }, - { - "ordinal": 16, - "name": "draft_only", - "type_info": "Bool" - }, - { - "ordinal": 17, - "name": "envs", - "type_info": "VarcharArray" - }, - { - "ordinal": 18, - "name": "concurrent_limit", - "type_info": "Int4" - }, - { - "ordinal": 19, - "name": "concurrency_time_window_s", - "type_info": "Int4" - }, - { - "ordinal": 20, - "name": "cache_ttl", - "type_info": "Int4" - }, - { - "ordinal": 21, - "name": "dedicated_worker", - "type_info": "Bool" - }, - { - "ordinal": 22, - "name": "ws_error_handler_muted", - "type_info": "Bool" - }, - { - "ordinal": 23, - "name": "priority", - "type_info": "Int2" - }, - { - "ordinal": 24, - "name": "timeout", - "type_info": "Int4" - }, - { - "ordinal": 25, - "name": "delete_after_use", - "type_info": "Bool" - }, - { - "ordinal": 26, - "name": "restart_unless_cancelled", - "type_info": "Bool" - }, - { - "ordinal": 27, - "name": "concurrency_key", - "type_info": "Varchar" - }, - { - "ordinal": 28, - "name": "visible_to_runner_only", - "type_info": "Bool" - }, - { - "ordinal": 29, - "name": "no_main_func", - "type_info": "Bool" - }, - { - "ordinal": 30, - "name": "codebase", - "type_info": "Varchar" - }, - { - "ordinal": 31, - "name": "has_preprocessor", - "type_info": "Bool" - }, - { - "ordinal": 32, - "name": "on_behalf_of_email", - "type_info": "Text" - }, - { - "ordinal": 33, - "name": "parent_hashes", - "type_info": "Int8Array" - }, - { - "ordinal": 34, - "name": "assets", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - false, - true, - false, - true, - true, - false, - false, - true, - true, - true, - true, - true, - true, - true, - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "hash": "97547c49f4ed07e7d07ddf2ef971abb820df9d6ec54a340cf8b1332e1052f666" -} diff --git a/backend/.sqlx/query-a54e2334c365f90577f68ebefc8f3bee9b93ba0387f566ad7f502cbee818296e.json b/backend/.sqlx/query-a54e2334c365f90577f68ebefc8f3bee9b93ba0387f566ad7f502cbee818296e.json new file mode 100644 index 0000000000..4e3b39403f --- /dev/null +++ b/backend/.sqlx/query-a54e2334c365f90577f68ebefc8f3bee9b93ba0387f566ad7f502cbee818296e.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace_runnable_dependencies (flow_path, runnable_path, script_hash, runnable_is_flow, workspace_id, app_path)\n SELECT flow_path, runnable_path, script_hash, runnable_is_flow, $1, app_path\n FROM workspace_runnable_dependencies\n WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "a54e2334c365f90577f68ebefc8f3bee9b93ba0387f566ad7f502cbee818296e" +} diff --git a/backend/.sqlx/query-b7ba64475398162ba43001a9932ac9a2b9ce8295e4ac85421091ab7da17a9a7c.json b/backend/.sqlx/query-dbd66bee283a7b4f892673f968f92adce1be8b897288b655505729c97c6e324c.json similarity index 68% rename from backend/.sqlx/query-b7ba64475398162ba43001a9932ac9a2b9ce8295e4ac85421091ab7da17a9a7c.json rename to backend/.sqlx/query-dbd66bee283a7b4f892673f968f92adce1be8b897288b655505729c97c6e324c.json index 1ccac6145e..8049f4de1a 100644 --- a/backend/.sqlx/query-b7ba64475398162ba43001a9932ac9a2b9ce8295e4ac85421091ab7da17a9a7c.json +++ b/backend/.sqlx/query-dbd66bee283a7b4f892673f968f92adce1be8b897288b655505729c97c6e324c.json @@ -1,16 +1,15 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO folder (workspace_id, name, display_name, owners, extra_perms, summary, edited_at, created_by)\n SELECT $2, name, display_name, owners, extra_perms, summary, edited_at, $3\n FROM folder\n WHERE workspace_id = $1", + "query": "INSERT INTO folder (workspace_id, name, display_name, owners, extra_perms, summary, edited_at, created_by)\n SELECT $2, name, display_name, owners, extra_perms, summary, edited_at, created_by\n FROM folder\n WHERE workspace_id = $1", "describe": { "columns": [], "parameters": { "Left": [ "Text", - "Varchar", "Varchar" ] }, "nullable": [] }, - "hash": "b7ba64475398162ba43001a9932ac9a2b9ce8295e4ac85421091ab7da17a9a7c" + "hash": "dbd66bee283a7b4f892673f968f92adce1be8b897288b655505729c97c6e324c" } diff --git a/backend/.sqlx/query-e628e560caad2e6f37459a255cc931837dd6fb319577ba9d6103fb88b807bfca.json b/backend/.sqlx/query-e628e560caad2e6f37459a255cc931837dd6fb319577ba9d6103fb88b807bfca.json deleted file mode 100644 index b75aaa7383..0000000000 --- a/backend/.sqlx/query-e628e560caad2e6f37459a255cc931837dd6fb319577ba9d6103fb88b807bfca.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_runnable_dependencies (\n flow_path, runnable_path, script_hash, runnable_is_flow, workspace_id, app_path\n ) VALUES ($1, $2, $3, $4, $5, $6)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Varchar", - "Int8", - "Bool", - "Varchar", - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "e628e560caad2e6f37459a255cc931837dd6fb319577ba9d6103fb88b807bfca" -} diff --git a/backend/.sqlx/query-e734447a2506c7d69e744f8ddf1bbc3fad75c097ed483adba1f2f7f593481807.json b/backend/.sqlx/query-e734447a2506c7d69e744f8ddf1bbc3fad75c097ed483adba1f2f7f593481807.json deleted file mode 100644 index 3d0c982141..0000000000 --- a/backend/.sqlx/query-e734447a2506c7d69e744f8ddf1bbc3fad75c097ed483adba1f2f7f593481807.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO script (\n workspace_id, hash, path, parent_hashes, summary, description, content,\n created_by, created_at, archived, schema, deleted, is_template,\n extra_perms, lock, lock_error_logs, language, kind, tag, draft_only,\n envs, concurrent_limit, concurrency_time_window_s, cache_ttl,\n dedicated_worker, ws_error_handler_muted, priority, timeout,\n delete_after_use, restart_unless_cancelled, concurrency_key,\n visible_to_runner_only, no_main_func, codebase, has_preprocessor,\n on_behalf_of_email, assets\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13,\n $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24,\n $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35,\n $36, $37\n )", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Int8", - "Varchar", - "Int8Array", - "Text", - "Text", - "Text", - "Varchar", - "Timestamptz", - "Bool", - "Json", - "Bool", - "Bool", - "Jsonb", - "Text", - "Text", - { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp", - "oracledb", - "nu", - "java", - "duckdb", - "ruby" - ] - } - } - }, - { - "Custom": { - "name": "script_kind", - "kind": { - "Enum": [ - "script", - "trigger", - "failure", - "command", - "approval", - "preprocessor" - ] - } - } - }, - "Varchar", - "Bool", - "VarcharArray", - "Int4", - "Int4", - "Int4", - "Bool", - "Bool", - "Int2", - "Int4", - "Bool", - "Bool", - "Varchar", - "Bool", - "Bool", - "Varchar", - "Bool", - "Text", - "Jsonb" - ] - }, - "nullable": [] - }, - "hash": "e734447a2506c7d69e744f8ddf1bbc3fad75c097ed483adba1f2f7f593481807" -} diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index 8afe591dbd..0049427c63 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -2350,7 +2350,6 @@ async fn clone_workspace_data( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, db: &DB, ) -> Result<()> { // Clone workspace settings (merge with existing basic settings) @@ -2358,7 +2357,6 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2370,7 +2368,6 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2382,7 +2379,6 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2391,7 +2387,6 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2399,11 +2394,10 @@ async fn clone_workspace_data( clone_variables(tx, source_workspace_id, target_workspace_id, db).await?; // Clone scripts with new hashes - let script_hash_mapping = clone_scripts( + clone_scripts( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2412,7 +2406,6 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; @@ -2424,19 +2417,17 @@ async fn clone_workspace_data( tx, source_workspace_id, target_workspace_id, - target_username, ) .await?; // Clone raw apps clone_raw_apps(tx, source_workspace_id, target_workspace_id).await?; - // Clone workspace runnable dependencies with updated mappings + // Clone workspace runnable dependencies and dependency map clone_workspace_dependencies( tx, source_workspace_id, target_workspace_id, - &script_hash_mapping, ) .await?; @@ -2447,7 +2438,6 @@ async fn update_workspace_settings( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - _target_username: &str, ) -> Result<()> { sqlx::query!( r#" @@ -2526,16 +2516,14 @@ async fn clone_folders( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, ) -> Result<()> { sqlx::query!( "INSERT INTO folder (workspace_id, name, display_name, owners, extra_perms, summary, edited_at, created_by) - SELECT $2, name, display_name, owners, extra_perms, summary, edited_at, $3 + SELECT $2, name, display_name, owners, extra_perms, summary, edited_at, created_by FROM folder WHERE workspace_id = $1", source_workspace_id, target_workspace_id, - target_username, ) .execute(&mut **tx) .await?; @@ -2566,16 +2554,14 @@ async fn clone_resource_types( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, ) -> Result<()> { sqlx::query!( "INSERT INTO resource_type (workspace_id, name, schema, description, edited_at, created_by, format_extension) - SELECT $2, name, schema, description, edited_at, $3, format_extension - FROM resource_type + SELECT $2, name, schema, description, edited_at, created_by, format_extension + FROM resource_type WHERE workspace_id = $1", source_workspace_id, target_workspace_id, - target_username, ) .execute(&mut **tx) .await?; @@ -2587,16 +2573,14 @@ async fn clone_resources( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, ) -> Result<()> { sqlx::query!( "INSERT INTO resource (workspace_id, path, value, description, resource_type, extra_perms, edited_at, created_by) - SELECT $2, path, value, description, resource_type, extra_perms, edited_at, $3 - FROM resource + SELECT $2, path, value, description, resource_type, extra_perms, edited_at, created_by + FROM resource WHERE workspace_id = $1", source_workspace_id, target_workspace_id, - target_username, ) .execute(&mut **tx) .await?; @@ -2690,152 +2674,43 @@ async fn clone_scripts( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, -) -> Result> { - // Get all scripts from source workspace - let scripts = sqlx::query!( - r#"SELECT hash, path, summary, description, content, - created_at, archived, schema, deleted, is_template, - extra_perms, lock, lock_error_logs, language as "language: ScriptLang", - kind as "kind: ScriptKind", tag, draft_only, envs, concurrent_limit, - concurrency_time_window_s, cache_ttl, dedicated_worker, - ws_error_handler_muted, priority, timeout, delete_after_use, - restart_unless_cancelled, concurrency_key, visible_to_runner_only, - no_main_func, codebase, has_preprocessor, on_behalf_of_email, - parent_hashes, assets - FROM script WHERE workspace_id = $1"#, +) -> Result<()> { + // Clone all scripts directly with a single query + sqlx::query!( + r#"INSERT INTO script ( + workspace_id, hash, path, parent_hashes, summary, description, content, + created_by, created_at, archived, schema, deleted, is_template, + extra_perms, lock, lock_error_logs, language, kind, tag, draft_only, + envs, concurrent_limit, concurrency_time_window_s, cache_ttl, + dedicated_worker, ws_error_handler_muted, priority, timeout, + delete_after_use, restart_unless_cancelled, concurrency_key, + visible_to_runner_only, no_main_func, codebase, has_preprocessor, + on_behalf_of_email, assets + ) + SELECT + $1, hash, path, parent_hashes, summary, description, content, + created_by, created_at, archived, schema, deleted, is_template, + extra_perms, lock, lock_error_logs, language, kind, tag, draft_only, + envs, concurrent_limit, concurrency_time_window_s, cache_ttl, + dedicated_worker, ws_error_handler_muted, priority, timeout, + delete_after_use, restart_unless_cancelled, concurrency_key, + visible_to_runner_only, no_main_func, codebase, has_preprocessor, + on_behalf_of_email, assets + FROM script + WHERE workspace_id = $2"#, + target_workspace_id, source_workspace_id ) - .fetch_all(&mut **tx) + .execute(&mut **tx) .await?; - let mut script_hash_mapping: HashMap = HashMap::new(); - - // Process each script with new hash computation - for script in scripts { - // Create a duplicate of ScriptKind by matching the enum - let script_kind_for_hash = match script.kind { - ScriptKind::Script => ScriptKind::Script, - ScriptKind::Trigger => ScriptKind::Trigger, - ScriptKind::Failure => ScriptKind::Failure, - ScriptKind::Approval => ScriptKind::Approval, - ScriptKind::Preprocessor => ScriptKind::Preprocessor, - }; - let script_kind_for_db = match script.kind { - ScriptKind::Script => ScriptKind::Script, - ScriptKind::Trigger => ScriptKind::Trigger, - ScriptKind::Failure => ScriptKind::Failure, - ScriptKind::Approval => ScriptKind::Approval, - ScriptKind::Preprocessor => ScriptKind::Preprocessor, - }; - - // Create NewScript for hash computation - simplified approach - let new_script = NewScript { - path: script.path.clone(), - parent_hash: None, - summary: script.summary.clone(), - description: script.description.clone(), - content: script.content.clone(), - schema: None, // Keep it simple for hash computation - is_template: Some(script.is_template.unwrap_or(false)), - lock: script.lock.clone(), - language: script.language.clone(), - kind: Some(script_kind_for_hash), - tag: script.tag.clone(), - draft_only: script.draft_only, - envs: script.envs.clone(), - concurrent_limit: script.concurrent_limit, - concurrency_time_window_s: script.concurrency_time_window_s, - cache_ttl: script.cache_ttl, - dedicated_worker: script.dedicated_worker, - ws_error_handler_muted: Some(script.ws_error_handler_muted), - priority: script.priority, - timeout: script.timeout, - delete_after_use: script.delete_after_use, - restart_unless_cancelled: script.restart_unless_cancelled, - deployment_message: None, - concurrency_key: script.concurrency_key.clone(), - visible_to_runner_only: script.visible_to_runner_only, - no_main_func: script.no_main_func, - codebase: script.codebase.clone(), - has_preprocessor: script.has_preprocessor, - on_behalf_of_email: script.on_behalf_of_email.clone(), - assets: None, - }; - - // Generate new hash - let new_hash = hash_script(&new_script); - - // Store mapping for later reference updates - script_hash_mapping.insert(script.hash, new_hash); - - // Insert script with new hash - direct copy most fields - sqlx::query!( - r#"INSERT INTO script ( - workspace_id, hash, path, parent_hashes, summary, description, content, - created_by, created_at, archived, schema, deleted, is_template, - extra_perms, lock, lock_error_logs, language, kind, tag, draft_only, - envs, concurrent_limit, concurrency_time_window_s, cache_ttl, - dedicated_worker, ws_error_handler_muted, priority, timeout, - delete_after_use, restart_unless_cancelled, concurrency_key, - visible_to_runner_only, no_main_func, codebase, has_preprocessor, - on_behalf_of_email, assets - ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, - $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, - $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, - $36, $37 - )"#, - target_workspace_id, - new_hash, - script.path, - script.parent_hashes.as_deref(), - script.summary, - script.description, - script.content, - target_username, - script.created_at, - script.archived, - script.schema, - script.deleted, - script.is_template, - script.extra_perms, - script.lock, - script.lock_error_logs, - script.language as _, - script_kind_for_db as _, - script.tag, - script.draft_only, - script.envs.as_deref(), - script.concurrent_limit, - script.concurrency_time_window_s, - script.cache_ttl, - script.dedicated_worker, - script.ws_error_handler_muted, - script.priority, - script.timeout, - script.delete_after_use, - script.restart_unless_cancelled, - script.concurrency_key, - script.visible_to_runner_only, - script.no_main_func, - script.codebase, - script.has_preprocessor, - script.on_behalf_of_email, - script.assets, - ) - .execute(&mut **tx) - .await?; - } - - Ok(script_hash_mapping) + Ok(()) } async fn clone_flows( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, ) -> Result<()> { // First, clone flows without versions sqlx::query!( @@ -2845,15 +2720,14 @@ async fn clone_flows( ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, concurrency_key, versions, on_behalf_of_email, lock_error_logs ) - SELECT $2, path, summary, description, value, $3, edited_at, + SELECT $2, path, summary, description, value, edited_by, edited_at, archived, schema, extra_perms, NULL, draft_only, tag, ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, concurrency_key, ARRAY[]::bigint[], on_behalf_of_email, lock_error_logs - FROM flow + FROM flow WHERE workspace_id = $1", source_workspace_id, target_workspace_id, - target_username, ) .execute(&mut **tx) .await?; @@ -2878,7 +2752,7 @@ async fn clone_flows( version.path, version.value, version.schema, - target_username, + version.created_by, version.created_at, ) .fetch_one(&mut **tx) @@ -2925,7 +2799,6 @@ async fn clone_apps( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - target_username: &str, ) -> Result> { // Get all apps from source workspace let apps = sqlx::query!( @@ -2978,7 +2851,7 @@ async fn clone_apps( VALUES ($1, $2, $3, $4, $5)", new_app_id, version.value, - target_username, + version.created_by, version.created_at, version.raw_app, ) @@ -3060,38 +2933,30 @@ async fn clone_workspace_dependencies( tx: &mut Transaction<'_, Postgres>, source_workspace_id: &str, target_workspace_id: &str, - script_hash_mapping: &HashMap, ) -> Result<()> { - let dependencies = sqlx::query!( - "SELECT flow_path, runnable_path, script_hash, runnable_is_flow, app_path - FROM workspace_runnable_dependencies - WHERE workspace_id = $1", + // Clone workspace_runnable_dependencies + sqlx::query!( + "INSERT INTO workspace_runnable_dependencies (flow_path, runnable_path, script_hash, runnable_is_flow, workspace_id, app_path) + SELECT flow_path, runnable_path, script_hash, runnable_is_flow, $1, app_path + FROM workspace_runnable_dependencies + WHERE workspace_id = $2", + target_workspace_id, source_workspace_id ) - .fetch_all(&mut **tx) + .execute(&mut **tx) .await?; - for dep in dependencies { - let new_script_hash = if let Some(old_hash) = dep.script_hash { - script_hash_mapping.get(&old_hash).copied() - } else { - None - }; - - sqlx::query!( - "INSERT INTO workspace_runnable_dependencies ( - flow_path, runnable_path, script_hash, runnable_is_flow, workspace_id, app_path - ) VALUES ($1, $2, $3, $4, $5, $6)", - dep.flow_path, - dep.runnable_path, - new_script_hash, - dep.runnable_is_flow, - target_workspace_id, - dep.app_path, - ) - .execute(&mut **tx) - .await?; - } + // Clone dependency_map to preserve import relationships + sqlx::query!( + "INSERT INTO dependency_map (workspace_id, importer_path, importer_kind, imported_path, importer_node_id) + SELECT $1, importer_path, importer_kind, imported_path, importer_node_id + FROM dependency_map + WHERE workspace_id = $2", + target_workspace_id, + source_workspace_id + ) + .execute(&mut **tx) + .await?; Ok(()) } @@ -3191,7 +3056,7 @@ async fn create_workspace_fork( .await?; // Clone all data from the parent workspace using Rust implementation - clone_workspace_data(&mut tx, &nw.parent_workspace_id, &forked_id, &username, &db).await?; + clone_workspace_data(&mut tx, &nw.parent_workspace_id, &forked_id, &db).await?; sqlx::query!( "INSERT INTO workspace_invite (workspace_id, email, is_admin, operator)