Compare commits
38 Commits
folder-dep
...
alp/postgr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
387a0c854d | ||
|
|
43d2cf4522 | ||
|
|
3f55f226c3 | ||
|
|
1904ffcaaa | ||
|
|
18eb6e0df7 | ||
|
|
adc9fe722d | ||
|
|
0aea49f960 | ||
|
|
ba214709b9 | ||
|
|
bffa61e33f | ||
|
|
27ca417201 | ||
|
|
c4c9ef5fd7 | ||
|
|
b960598431 | ||
|
|
f234df97ec | ||
|
|
a3073ad824 | ||
|
|
ceaa613522 | ||
|
|
0317d5891c | ||
|
|
7485a5db04 | ||
|
|
0cfa462c37 | ||
|
|
6656b46f10 | ||
|
|
5b7fa63bf1 | ||
|
|
cdf3c29664 | ||
|
|
81ab777cbb | ||
|
|
61a867f086 | ||
|
|
8581a3300d | ||
|
|
ff5fa9f64f | ||
|
|
55e8a5cff1 | ||
|
|
1a39bd538d | ||
|
|
1049c1026b | ||
|
|
619ebb65ce | ||
|
|
d2d6810db9 | ||
|
|
39af1b75af | ||
|
|
d569e9e29c | ||
|
|
381011a4a8 | ||
|
|
f0437eba19 | ||
|
|
d8edaad99c | ||
|
|
7fd0bf974d | ||
|
|
6a5cfbc159 | ||
|
|
8c3c97f7a6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,3 +29,4 @@ frontend/.svelte-kit
|
||||
backend/chrome_profiler.json
|
||||
.fast-check/
|
||||
__pycache__/
|
||||
.playwright-mcp/
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## [1.673.0](https://github.com/windmill-labs/windmill/compare/v1.672.0...v1.673.0) (2026-04-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add endpoint to restart workers in a worker group ([#8659](https://github.com/windmill-labs/windmill/issues/8659)) ([f0437eb](https://github.com/windmill-labs/windmill/commit/f0437eba1925a9aa4c430008027d637a0c89ee39))
|
||||
* add Entra ID (Azure Workload Identity) database auth ([#8526](https://github.com/windmill-labs/windmill/issues/8526)) ([6a5cfbc](https://github.com/windmill-labs/windmill/commit/6a5cfbc159a0ad7925fd7ce5eefc8eaa21bbb70b))
|
||||
* add LIMIT_WINDOWS_TO_1CU env var for Windows worker memory limits ([#8681](https://github.com/windmill-labs/windmill/issues/8681)) ([d2d6810](https://github.com/windmill-labs/windmill/commit/d2d6810db954114f3333853bd3476cb8fc735f92))
|
||||
* restore bun for dedicated workers, fix dispatch & serialization, cross-workspace deps ([#8645](https://github.com/windmill-labs/windmill/issues/8645)) ([619ebb6](https://github.com/windmill-labs/windmill/commit/619ebb65ce8dce8264add31c3147919802a8286a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add HMAC signature verification to Slack interactive callback endpoint ([#8611](https://github.com/windmill-labs/windmill/issues/8611)) ([55e8a5c](https://github.com/windmill-labs/windmill/commit/55e8a5cff1f185b1dbd332d37b877972efa1ed7d))
|
||||
* correct raw app flow inputs ([#8667](https://github.com/windmill-labs/windmill/issues/8667)) ([28c0730](https://github.com/windmill-labs/windmill/commit/28c073056c65d4ed1600e39679497e5af964347f))
|
||||
* pass selected language to AI agent when generating flow scripts ([#8680](https://github.com/windmill-labs/windmill/issues/8680)) ([381011a](https://github.com/windmill-labs/windmill/commit/381011a4a8e48454e9c146c64db502293e646b99))
|
||||
* poll for preview results to avoid undici headers timeout ([#8682](https://github.com/windmill-labs/windmill/issues/8682)) ([ff5fa9f](https://github.com/windmill-labs/windmill/commit/ff5fa9f64fe4aaf33e06b20f02373894b5df0f95))
|
||||
* pre-fix trigger edited_by for superadmins not in workspace ([#8669](https://github.com/windmill-labs/windmill/issues/8669)) ([350ffdc](https://github.com/windmill-labs/windmill/commit/350ffdce297ba5b84f9dd247eede6da0c6b0956c))
|
||||
* resolve race condition where flow sync push reverts to stale version ([#8673](https://github.com/windmill-labs/windmill/issues/8673)) ([d569e9e](https://github.com/windmill-labs/windmill/commit/d569e9e29c588243a90b1cd25f866efb0d178640))
|
||||
* respect disabled fields in JSON input mode ([#8663](https://github.com/windmill-labs/windmill/issues/8663)) ([7fd0bf9](https://github.com/windmill-labs/windmill/commit/7fd0bf974d2ba2644bb01dd5e9ddc84749e166f5))
|
||||
* Run typed pg queries in a single protocol conversation ([#8679](https://github.com/windmill-labs/windmill/issues/8679)) ([8581a33](https://github.com/windmill-labs/windmill/commit/8581a3300d056040b7e3ab77d629c74f034c9c97))
|
||||
* sanitize MCP tool schemas for JSON Schema draft 2020-12 compliance ([#8666](https://github.com/windmill-labs/windmill/issues/8666)) ([8c3c97f](https://github.com/windmill-labs/windmill/commit/8c3c97f7a670d47019cc666219f8187f48499672))
|
||||
* skip generate-metadata confirmation prompt in non-interactive CI ([#8678](https://github.com/windmill-labs/windmill/issues/8678)) ([39af1b7](https://github.com/windmill-labs/windmill/commit/39af1b75afc8458f85dec4fe51dfaed3d0cb000d))
|
||||
* strip f/ prefix from folder paths when deploying from workspace forks ([#8662](https://github.com/windmill-labs/windmill/issues/8662)) ([7ab0ea5](https://github.com/windmill-labs/windmill/commit/7ab0ea581d349fbfdb56d22cf9903a90efa045bb))
|
||||
* support branch-specific folder.meta.yaml in missing-meta check ([#8661](https://github.com/windmill-labs/windmill/issues/8661)) ([c87a6a0](https://github.com/windmill-labs/windmill/commit/c87a6a0f2c1346bf5e21f128d32d89bdca039243))
|
||||
* validate rd redirect on login with same rules as logout ([#8655](https://github.com/windmill-labs/windmill/issues/8655)) ([bcce627](https://github.com/windmill-labs/windmill/commit/bcce62738791a4e9b9f4dbc64731eef163230172))
|
||||
|
||||
## [1.672.0](https://github.com/windmill-labs/windmill/compare/v1.671.0...v1.672.0) (2026-04-01)
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ Open-source platform for internal tools, workflows, API integrations, background
|
||||
- **DB**: `psql postgres://postgres:changeme@localhost:5432/windmill`
|
||||
- **Login**: `admin@windmill.dev` / `changeme`
|
||||
- **Instance settings**: navigate to `/#superadmin-settings`
|
||||
- **Migrations**: use `cargo sqlx migrate add -r <name>` from `backend/` to create new migrations (never generate timestamps manually)
|
||||
|
||||
## Banned Patterns
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO websocket_trigger (\n workspace_id,\n path,\n url,\n script_path,\n is_flow,\n mode,\n filters,\n filter_logic,\n initial_messages,\n url_runnable_args,\n edited_by,\n can_return_message,\n can_return_error_result,\n permissioned_as,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, now(), $15, $16, $17\n )\n ",
|
||||
"query": "\n INSERT INTO websocket_trigger (\n workspace_id,\n path,\n url,\n script_path,\n is_flow,\n mode,\n filters,\n filter_logic,\n initial_messages,\n url_runnable_args,\n edited_by,\n can_return_message,\n can_return_error_result,\n permissioned_as,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry,\n heartbeat\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, now(), $15, $16, $17, $18\n )\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -32,10 +32,11 @@
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6948eb5aabf82f2f4a08dd4410eb472080ecab3ed652912397245e5216ae0389"
|
||||
"hash": "11fd92de8688ef6b4d524aade507850a9cb3e097f2d957219d04ad134a5e0399"
|
||||
}
|
||||
@@ -43,7 +43,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO schedule (\n workspace_id, path, schedule, timezone, edited_by, script_path,\n is_flow, args, enabled, email, permissioned_as,\n on_failure, on_failure_times, on_failure_exact, on_failure_extra_args,\n on_recovery, on_recovery_times, on_recovery_extra_args,\n on_success, on_success_extra_args,\n ws_error_handler_muted, retry, summary, no_flow_overlap,\n tag, paused_until, cron_version, description, dynamic_skip\n ) VALUES (\n $1, $2, $3, $4, $5, $6,\n $7, $8, $9, $10, $11,\n $12, $13, $14, $15,\n $16, $17, $18,\n $19, $20,\n $21, $22, $23, $24,\n $25, $26, $27, $28, $29\n )\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip\n ",
|
||||
"query": "\n INSERT INTO schedule (\n workspace_id, path, schedule, timezone, edited_by, script_path,\n is_flow, args, enabled, email, permissioned_as,\n on_failure, on_failure_times, on_failure_exact, on_failure_extra_args,\n on_recovery, on_recovery_times, on_recovery_extra_args,\n on_success, on_success_extra_args,\n ws_error_handler_muted, retry, summary, no_flow_overlap,\n tag, paused_until, cron_version, description, dynamic_skip, labels\n ) VALUES (\n $1, $2, $3, $4, $5, $6,\n $7, $8, $9, $10, $11,\n $12, $13, $14, $15,\n $16, $17, $18,\n $19, $20,\n $21, $22, $23, $24,\n $25, $26, $27, $28, $29, $30\n )\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip,\n labels\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -162,6 +162,11 @@
|
||||
"ordinal": 31,
|
||||
"name": "dynamic_skip",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -194,7 +199,8 @@
|
||||
"Timestamptz",
|
||||
"Text",
|
||||
"Text",
|
||||
"Varchar"
|
||||
"Varchar",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
@@ -229,8 +235,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "dd20f94d560238096390371c98ded1f80825a11cd61c0bb431678ad9ab4a138e"
|
||||
"hash": "2effe885aafaa0c5fc1f969b8c6ffbd38c53fb586251ba780b75a007e5a47ed6"
|
||||
}
|
||||
16
backend/.sqlx/query-32f26d69b15a74fc96dd585f9eb3c998447ca8b97894bb1a2b238f984c1dc588.json
generated
Normal file
16
backend/.sqlx/query-32f26d69b15a74fc96dd585f9eb3c998447ca8b97894bb1a2b238f984c1dc588.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE flow SET versions = array_append(versions, $1) WHERE path = $2 AND workspace_id = $3 AND (versions[array_upper(versions, 1)] IS DISTINCT FROM $1)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "32f26d69b15a74fc96dd585f9eb3c998447ca8b97894bb1a2b238f984c1dc588"
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO resource\n (workspace_id, path, value, description, resource_type, created_by, edited_at)\n VALUES ($1, $2, $3, $4, $5, $6, now()) ON CONFLICT (workspace_id, path)\n DO UPDATE SET value = EXCLUDED.value, description = EXCLUDED.description, resource_type = EXCLUDED.resource_type, edited_at = now()",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "39426bd3018b390ea2073419884cf6cb506c75e84c65438c9026831eb10d340b"
|
||||
}
|
||||
@@ -45,31 +45,36 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "is_expired",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"name": "is_refreshed",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"name": "refresh_error",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"name": "is_linked",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 13,
|
||||
"name": "is_oauth?",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 14,
|
||||
"name": "account",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
@@ -89,6 +94,7 @@
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
"ordinal": 7,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -57,6 +62,7 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO variable\n (workspace_id, path, value, is_secret, description, account, is_oauth, expires_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
"query": "INSERT INTO variable\n (workspace_id, path, value, is_secret, description, account, is_oauth, expires_at, labels)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -12,10 +12,11 @@
|
||||
"Varchar",
|
||||
"Int4",
|
||||
"Bool",
|
||||
"Timestamptz"
|
||||
"Timestamptz",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2be66f23536223549db9b50025932b6b1bad90b8fa47d97acb7d75aa3c37ef86"
|
||||
"hash": "48efd8f89df9c1dd8f8a4eb2b2640fcb380f2470c8488371b207a42cb7d4cd26"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE\n websocket_trigger\n SET\n url = $1,\n script_path = $2,\n path = $3,\n is_flow = $4,\n filters = $5,\n filter_logic = $6,\n initial_messages = $7,\n url_runnable_args = $8,\n edited_by = $9,\n permissioned_as = $10,\n can_return_message = $11,\n can_return_error_result = $12,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $15,\n error_handler_args = $16,\n retry = $17\n WHERE\n workspace_id = $13 AND path = $14\n ",
|
||||
"query": "\n UPDATE\n websocket_trigger\n SET\n url = $1,\n script_path = $2,\n path = $3,\n is_flow = $4,\n filters = $5,\n filter_logic = $6,\n initial_messages = $7,\n url_runnable_args = $8,\n edited_by = $9,\n permissioned_as = $10,\n can_return_message = $11,\n can_return_error_result = $12,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $15,\n error_handler_args = $16,\n retry = $17,\n heartbeat = $18\n WHERE\n workspace_id = $13 AND path = $14\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -21,10 +21,11 @@
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "e3d4f89ce36337af15d237b543eaca47771b480ff194884f9c947dcaf71d6cf9"
|
||||
"hash": "492edd53e497a45c314d41044e85a5e3492227b5049dc6870d60817ad929e7af"
|
||||
}
|
||||
16
backend/.sqlx/query-4c333861e736b8138162f0ff3bf2844c71b95c75bd8f173eac51336ab176ccc0.json
generated
Normal file
16
backend/.sqlx/query-4c333861e736b8138162f0ff3bf2844c71b95c75bd8f173eac51336ab176ccc0.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE variable SET labels = $1 WHERE path = $2 AND workspace_id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "4c333861e736b8138162f0ff3bf2844c71b95c75bd8f173eac51336ab176ccc0"
|
||||
}
|
||||
@@ -70,7 +70,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO script\n (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, cache_ignore_s3_path, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, runnable_settings_handle, modules)\n\n SELECT workspace_id, $1, path, array_prepend($2::bigint, COALESCE(parent_hashes, '{}'::bigint[])), summary, description, content, created_by, schema, is_template, extra_perms, NULL, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, cache_ignore_s3_path, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, runnable_settings_handle, modules\n\n FROM script WHERE hash = $2 AND workspace_id = $3;\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "51f09f073842a6990535b887d8267fab305c21e4d7703bedbadf405b5c2d7582"
|
||||
}
|
||||
@@ -34,7 +34,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "WITH inserted_job AS (\n INSERT INTO v2_job (\n id, -- 1\n workspace_id, -- 2\n raw_code, -- 3\n raw_lock, -- 4\n raw_flow, -- 5\n tag, -- 6\n parent_job, -- 7\n created_by, -- 8\n permissioned_as, -- 9\n runnable_id, -- 10\n runnable_path, -- 11\n args, -- 12\n kind, -- 13\n trigger, -- 14\n script_lang, -- 15\n same_worker, -- 16\n pre_run_error, -- 17 \n permissioned_as_email, -- 18\n visible_to_owner, -- 19\n flow_innermost_root_job, -- 20\n root_job, -- 38\n concurrent_limit, -- 21\n concurrency_time_window_s, -- 22\n timeout, -- 23\n flow_step_id, -- 24\n cache_ttl, -- 25\n priority, -- 26\n trigger_kind, -- 39\n script_entrypoint_override, -- 12\n preprocessed -- 27,\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18,\n $19, $20, $38, $21, $22, $23, $24, $25, $26, $39::job_trigger_kind,\n ($12::JSONB)->>'_ENTRYPOINT_OVERRIDE', $27)\n ),\n inserted_runtime AS (\n INSERT INTO v2_job_runtime (id, ping) VALUES ($1, null)\n ),\n inserted_job_perms AS (\n INSERT INTO job_perms (job_id, email, username, is_admin, is_operator, folders, groups, workspace_id, end_user_email) \n values ($1, $32, $33, $34, $35, $36, $37, $2, $41) \n ON CONFLICT (job_id) DO UPDATE SET email = EXCLUDED.email, username = EXCLUDED.username, is_admin = EXCLUDED.is_admin, is_operator = EXCLUDED.is_operator, folders = EXCLUDED.folders, groups = EXCLUDED.groups, workspace_id = EXCLUDED.workspace_id, end_user_email = EXCLUDED.end_user_email\n )\n INSERT INTO v2_job_queue\n (workspace_id, id, running, scheduled_for, started_at, tag, priority, cache_ignore_s3_path, runnable_settings_handle)\n VALUES ($2, $1, $28, COALESCE($29, now()), CASE WHEN $27 OR $40 THEN now() END, $30, $31, $42, $43)",
|
||||
"query": "WITH inserted_job AS (\n INSERT INTO v2_job (\n id, -- 1\n workspace_id, -- 2\n raw_code, -- 3\n raw_lock, -- 4\n raw_flow, -- 5\n tag, -- 6\n parent_job, -- 7\n created_by, -- 8\n permissioned_as, -- 9\n runnable_id, -- 10\n runnable_path, -- 11\n args, -- 12\n kind, -- 13\n trigger, -- 14\n script_lang, -- 15\n same_worker, -- 16\n pre_run_error, -- 17 \n permissioned_as_email, -- 18\n visible_to_owner, -- 19\n flow_innermost_root_job, -- 20\n root_job, -- 38\n concurrent_limit, -- 21\n concurrency_time_window_s, -- 22\n timeout, -- 23\n flow_step_id, -- 24\n cache_ttl, -- 25\n priority, -- 26\n trigger_kind, -- 39\n script_entrypoint_override, -- 12\n preprocessed, -- 27,\n labels -- 44\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18,\n $19, $20, $38, $21, $22, $23, $24, $25, $26, $39::job_trigger_kind,\n ($12::JSONB)->>'_ENTRYPOINT_OVERRIDE', $27, $44)\n ),\n inserted_runtime AS (\n INSERT INTO v2_job_runtime (id, ping) VALUES ($1, null)\n ),\n inserted_job_perms AS (\n INSERT INTO job_perms (job_id, email, username, is_admin, is_operator, folders, groups, workspace_id, end_user_email) \n values ($1, $32, $33, $34, $35, $36, $37, $2, $41) \n ON CONFLICT (job_id) DO UPDATE SET email = EXCLUDED.email, username = EXCLUDED.username, is_admin = EXCLUDED.is_admin, is_operator = EXCLUDED.is_operator, folders = EXCLUDED.folders, groups = EXCLUDED.groups, workspace_id = EXCLUDED.workspace_id, end_user_email = EXCLUDED.end_user_email\n )\n INSERT INTO v2_job_queue\n (workspace_id, id, running, scheduled_for, started_at, tag, priority, cache_ignore_s3_path, runnable_settings_handle)\n VALUES ($2, $1, $28, COALESCE($29, now()), CASE WHEN $27 OR $40 THEN now() END, $30, $31, $42, $43)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -76,7 +76,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -131,10 +132,11 @@
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Int8"
|
||||
"Int8",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "14276a040cb4db88d71fccdc3579e8c0bb132b70668301b535872d1632753e30"
|
||||
"hash": "5425e2c5e29fc5145dde5ea53d5307ca90d8dd76da2ca560b310b12820be2576"
|
||||
}
|
||||
@@ -148,7 +148,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n script_lang as \"language: _\",\n COUNT(*) as \"count!\",\n SUM(duration_ms)::BIGINT as \"total_duration!\"\n FROM\n v2_job_completed\n JOIN\n v2_job\n ON\n v2_job.id = v2_job_completed.id\n WHERE\n created_at > NOW() - INTERVAL '48 hours'\n GROUP BY\n script_lang\n ",
|
||||
"query": "\n SELECT\n NULLIF(script_lang, 'other')::script_lang as \"language: _\",\n SUM(job_count)::BIGINT as \"count!\",\n SUM(total_duration_ms)::BIGINT as \"total_duration!\"\n FROM worker_group_job_stats\n WHERE hour >= $1\n GROUP BY script_lang\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -33,7 +33,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -51,13 +52,15 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "464895f217536bf713ec381b6c3b7c0417161bf69e596e2e34fc8d9384824776"
|
||||
"hash": "5c0d0c7111b70b119b3182c9195361388ead36dc6ab03c6a7c17fb97d2b60a67"
|
||||
}
|
||||
@@ -43,7 +43,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n script_lang as \"language: _\",\n COUNT(*) as \"count!\",\n SUM(duration_ms)::BIGINT as \"total_duration!\"\n FROM\n v2_job_completed\n JOIN\n v2_job\n ON\n v2_job.id = v2_job_completed.id\n WHERE\n created_at >= CURRENT_DATE - INTERVAL '1 day'\n AND created_at < CURRENT_DATE\n GROUP BY\n script_lang\n ",
|
||||
"query": "\n SELECT\n NULLIF(script_lang, 'other')::script_lang as \"language: _\",\n SUM(job_count)::BIGINT as \"count!\",\n SUM(total_duration_ms)::BIGINT as \"total_duration!\"\n FROM worker_group_job_stats\n WHERE hour >= $1 AND hour < $2\n GROUP BY script_lang\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -33,7 +33,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -51,13 +52,16 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "19478c2a3c05b2ed17b110f8ff58d48ce3ede5fdd7f8d64840f8c62cf89f99e7"
|
||||
"hash": "6348061d79b0b6b25bda7425f7a37344e04107f060f949cc197b4df9bca18fb8"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE schedule SET\n enabled = $1,\n email = $2\n WHERE path = $3 AND workspace_id = $4\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip\n ",
|
||||
"query": "\n UPDATE schedule SET\n enabled = $1,\n email = $2\n WHERE path = $3 AND workspace_id = $4\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip,\n labels\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -162,6 +162,11 @@
|
||||
"ordinal": 31,
|
||||
"name": "dynamic_skip",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -204,8 +209,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "ad96768ff61fab1cfb9421683bb13b64f5f157fafe114d50fb910dc36ebe0f91"
|
||||
"hash": "642ca096c1c151fc01445593c8d2ed879a9a7be6ff044a9ce1b581ba725665fe"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO flow\n (workspace_id, path, summary, description, archived, extra_perms, dependency_job, draft_only, tag, ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, on_behalf_of_email, concurrency_key, versions, value, schema, edited_by, edited_at)\n SELECT workspace_id, $1, summary, description, archived, extra_perms, dependency_job, draft_only, tag, ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, on_behalf_of_email, concurrency_key, versions, value, schema, edited_by, edited_at\n FROM flow\n WHERE path = $2 AND workspace_id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "676c758d9c4492dada50edd3ad06dc628e2ba56eab5e1a50c99481da9793759e"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n flow_version.id AS version,\n flow_version.value->>'early_return' as early_return,\n flow_version.value->>'preprocessor_module' IS NOT NULL as has_preprocessor,\n (flow_version.value->>'chat_input_enabled')::boolean as chat_input_enabled,\n flow.tag,\n flow.dedicated_worker,\n flow.on_behalf_of_email,\n flow.edited_by\n FROM\n flow_version\n INNER JOIN flow\n ON flow.path = flow_version.path AND\n flow.workspace_id = flow_version.workspace_id\n WHERE\n flow_version.workspace_id = $1 AND\n flow_version.path = $2 AND\n flow_version.id = $3\n ",
|
||||
"query": "\n SELECT\n flow_version.id AS version,\n flow_version.value->>'early_return' as early_return,\n flow_version.value->>'preprocessor_module' IS NOT NULL as has_preprocessor,\n (flow_version.value->>'chat_input_enabled')::boolean as chat_input_enabled,\n flow.tag,\n flow.dedicated_worker,\n flow.on_behalf_of_email,\n flow.edited_by,\n flow.labels\n FROM\n flow_version\n INNER JOIN flow\n ON flow.path = flow_version.path AND\n flow.workspace_id = flow_version.workspace_id\n WHERE\n flow_version.workspace_id = $1 AND\n flow_version.path = $2 AND\n flow_version.id = $3\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -42,6 +42,11 @@
|
||||
"ordinal": 7,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -59,8 +64,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "209dc4c1b91eeab1c12ffcd9f9e16f315c689ca772c736b333dcdf07c8086087"
|
||||
"hash": "6d992a933bb878733b7afd7a4295b9ad6f5276b60ce20e0378d6148976e02777"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "select hash, tag, concurrency_key, concurrent_limit, concurrency_time_window_s, debounce_key, debounce_delay_s, cache_ttl, cache_ignore_s3_path, runnable_settings_handle, language as \"language: ScriptLang\", dedicated_worker, priority, timeout, on_behalf_of_email, created_by FROM script\n WHERE path = $1 AND workspace_id = $2 AND archived = false AND (lock IS NOT NULL OR $3 = false)\n ORDER BY created_at DESC LIMIT 1",
|
||||
"query": "select hash, tag, concurrency_key, concurrent_limit, concurrency_time_window_s, debounce_key, debounce_delay_s, cache_ttl, cache_ignore_s3_path, runnable_settings_handle, language as \"language: ScriptLang\", dedicated_worker, priority, timeout, on_behalf_of_email, created_by, labels FROM script\n WHERE path = $1 AND workspace_id = $2 AND archived = false AND (lock IS NOT NULL OR $3 = false)\n ORDER BY created_at DESC LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -83,7 +83,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -113,6 +114,11 @@
|
||||
"ordinal": 15,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -138,8 +144,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "a33673ebc4d1eb4c3513987dbc43e2c80974598e1d9fe7203145bfc29928ba65"
|
||||
"hash": "71767e6684957af5dff56a1bb64f980f712f92798d11feaeb0832962ad9ddb2e"
|
||||
}
|
||||
14
backend/.sqlx/query-78f7c4efd7be2aad03f0ec67ab882e1f9aaa7141ab75046a71ac789ab659bdc6.json
generated
Normal file
14
backend/.sqlx/query-78f7c4efd7be2aad03f0ec67ab882e1f9aaa7141ab75046a71ac789ab659bdc6.json
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO notify_event (channel, payload) VALUES ('restart_worker_group', $1)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "78f7c4efd7be2aad03f0ec67ab882e1f9aaa7141ab75046a71ac789ab659bdc6"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, cache_ignore_s3_path, runnable_settings_handle, modules) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $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, $38, $39)",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, cache_ignore_s3_path, runnable_settings_handle, modules, labels) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $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, $38, $39, $40)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -44,7 +44,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -88,10 +89,11 @@
|
||||
"Int4",
|
||||
"Bool",
|
||||
"Int8",
|
||||
"Jsonb"
|
||||
"Jsonb",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "4d983f1e3e63a1a70edf5d867d9f23f2069a7a4ba1dcc1331ecccdf1c6a95cb8"
|
||||
"hash": "790d79ec7abe6ebe1092afd9de4c5fc383272d2057ac5b47a7425f095f4e8788"
|
||||
}
|
||||
@@ -76,7 +76,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
16
backend/.sqlx/query-86c0ef92652085b93979a8836bedb33a366a84426a115c75f58dcc43ab91705e.json
generated
Normal file
16
backend/.sqlx/query-86c0ef92652085b93979a8836bedb33a366a84426a115c75f58dcc43ab91705e.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE http_trigger SET labels = $1 WHERE workspace_id = $2 AND path = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "86c0ef92652085b93979a8836bedb33a366a84426a115c75f58dcc43ab91705e"
|
||||
}
|
||||
@@ -41,7 +41,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
16
backend/.sqlx/query-a969194571dd3f12e628ce0f01b0ddc09bbcf4506eff2290664c295d16fec4ae.json
generated
Normal file
16
backend/.sqlx/query-a969194571dd3f12e628ce0f01b0ddc09bbcf4506eff2290664c295d16fec4ae.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO script\n (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, cache_ignore_s3_path, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, runnable_settings_handle, modules, labels)\n\n SELECT workspace_id, $1, path, array_prepend($2::bigint, COALESCE(parent_hashes, '{}'::bigint[])), summary, description, content, created_by, schema, is_template, extra_perms, NULL, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, cache_ignore_s3_path, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, auto_kind, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets, debounce_key, debounce_delay_s, runnable_settings_handle, modules, labels\n\n FROM script WHERE hash = $2 AND workspace_id = $3;\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a969194571dd3f12e628ce0f01b0ddc09bbcf4506eff2290664c295d16fec4ae"
|
||||
}
|
||||
@@ -153,7 +153,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
16
backend/.sqlx/query-b657b718ec381fbb1d41841c88118b88c4d7ea8f0cde663ed8f8226faf75b0f6.json
generated
Normal file
16
backend/.sqlx/query-b657b718ec381fbb1d41841c88118b88c4d7ea8f0cde663ed8f8226faf75b0f6.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE app SET labels = $1 WHERE path = $2 AND workspace_id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "b657b718ec381fbb1d41841c88118b88c4d7ea8f0cde663ed8f8226faf75b0f6"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO flow (\n workspace_id, path, summary, description,\n dependency_job, lock_error_logs, draft_only, tag,\n dedicated_worker, visible_to_runner_only, on_behalf_of_email,\n ws_error_handler_muted,\n value, schema, edited_by, edited_at\n ) VALUES (\n $1, $2, $3, $4,\n NULL, '', $5, $6,\n $7, $8, $9,\n $10,\n $11, $12::text::json, $13, now()\n )",
|
||||
"query": "INSERT INTO flow (\n workspace_id, path, summary, description,\n dependency_job, lock_error_logs, draft_only, tag,\n dedicated_worker, visible_to_runner_only, on_behalf_of_email,\n ws_error_handler_muted,\n value, schema, edited_by, edited_at, labels\n ) VALUES (\n $1, $2, $3, $4,\n NULL, '', $5, $6,\n $7, $8, $9,\n $10,\n $11, $12::text::json, $13, now(), $14\n )",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -17,10 +17,11 @@
|
||||
"Bool",
|
||||
"Jsonb",
|
||||
"Text",
|
||||
"Varchar"
|
||||
"Varchar",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6bde827da007b470b9d0acccfc3e00ce6aac650b9138a236f34c614eed753849"
|
||||
"hash": "b6f95b3fd1d0431d96d0409424dbb20cb3020f93454978d078082482b86cbebe"
|
||||
}
|
||||
22
backend/.sqlx/query-b782179261b4054289a1a595f6e06ee2035ae9811bc49abce903a04439baf800.json
generated
Normal file
22
backend/.sqlx/query-b782179261b4054289a1a595f6e06ee2035ae9811bc49abce903a04439baf800.json
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT DISTINCT unnest(labels) as \"label!\" FROM (\n SELECT labels FROM script WHERE workspace_id = $1 AND labels IS NOT NULL\n UNION ALL SELECT labels FROM flow WHERE workspace_id = $1 AND labels IS NOT NULL\n UNION ALL SELECT labels FROM resource WHERE workspace_id = $1 AND labels IS NOT NULL\n UNION ALL SELECT labels FROM variable WHERE workspace_id = $1 AND labels IS NOT NULL\n UNION ALL SELECT labels FROM schedule WHERE workspace_id = $1 AND labels IS NOT NULL\n UNION ALL SELECT labels FROM app WHERE workspace_id = $1 AND labels IS NOT NULL\n ) t ORDER BY 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "label!",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "b782179261b4054289a1a595f6e06ee2035ae9811bc49abce903a04439baf800"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE schedule SET\n schedule = $1,\n timezone = $2,\n args = $3,\n on_failure = $4,\n on_failure_times = $5,\n on_failure_exact = $6,\n on_failure_extra_args = $7,\n on_recovery = $8,\n on_recovery_times = $9,\n on_recovery_extra_args = $10,\n on_success = $11,\n on_success_extra_args = $12,\n ws_error_handler_muted = $13,\n retry = $14,\n summary = $15,\n no_flow_overlap = $16,\n tag = $17,\n paused_until = $18,\n path = $19,\n workspace_id = $20,\n cron_version = COALESCE($21, cron_version),\n description = $22,\n dynamic_skip = $23,\n email = $24,\n edited_by = $25,\n permissioned_as = $26\n WHERE path = $19 AND workspace_id = $20\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip\n ",
|
||||
"query": "\n UPDATE schedule SET\n schedule = $1,\n timezone = $2,\n args = $3,\n on_failure = $4,\n on_failure_times = $5,\n on_failure_exact = $6,\n on_failure_extra_args = $7,\n on_recovery = $8,\n on_recovery_times = $9,\n on_recovery_extra_args = $10,\n on_success = $11,\n on_success_extra_args = $12,\n ws_error_handler_muted = $13,\n retry = $14,\n summary = $15,\n no_flow_overlap = $16,\n tag = $17,\n paused_until = $18,\n path = $19,\n workspace_id = $20,\n cron_version = COALESCE($21, cron_version),\n description = $22,\n dynamic_skip = $23,\n email = $24,\n edited_by = $25,\n permissioned_as = $26,\n labels = COALESCE($27, labels)\n WHERE path = $19 AND workspace_id = $20\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip,\n labels\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -162,6 +162,11 @@
|
||||
"ordinal": 31,
|
||||
"name": "dynamic_skip",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"name": "labels",
|
||||
"type_info": "TextArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -191,7 +196,8 @@
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
"Varchar",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
@@ -226,8 +232,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "54b4c762add9b1ebfdb2a6d5abd6d20e86dc0e6544f0bb22fa4ec68aa54a4dc8"
|
||||
"hash": "bd2609f999054c5a2a85f2aafe4005bc22731c27f0bf27b3b06ec426a05eda2e"
|
||||
}
|
||||
@@ -40,7 +40,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE\n flow\n SET\n path = $1,\n summary = $2,\n description = $3,\n dependency_job = NULL,\n lock_error_logs = '',\n draft_only = NULL,\n tag = $4,\n dedicated_worker = $5,\n visible_to_runner_only = $6,\n on_behalf_of_email = $7,\n ws_error_handler_muted = $8,\n value = $9,\n schema = $10::text::json,\n edited_by = $11,\n edited_at = now()\n WHERE\n path = $12 AND workspace_id = $13",
|
||||
"query": "\n UPDATE\n flow\n SET\n path = $1,\n summary = $2,\n description = $3,\n dependency_job = NULL,\n lock_error_logs = '',\n draft_only = NULL,\n tag = $4,\n dedicated_worker = $5,\n visible_to_runner_only = $6,\n on_behalf_of_email = $7,\n ws_error_handler_muted = $8,\n value = $9,\n schema = $10::text::json,\n edited_by = $11,\n edited_at = now(),\n labels = COALESCE($14, labels)\n WHERE\n path = $12 AND workspace_id = $13",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -17,10 +17,11 @@
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text"
|
||||
"Text",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "77ac7257be02fb04c4b3213e2221e6f60621b4b2909d770de744ef5671e12ed9"
|
||||
"hash": "c06796e8647cf278c6e0809562aaaa872403890eae3e606f379343671c2fff02"
|
||||
}
|
||||
23
backend/.sqlx/query-c569535d4aded82ffef5e5066e24948c8fcdb8d36913775449b982782c8583e9.json
generated
Normal file
23
backend/.sqlx/query-c569535d4aded82ffef5e5066e24948c8fcdb8d36913775449b982782c8583e9.json
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT value AS \"value!: Json<Box<RawValue>>\" FROM flow WHERE path = $1 AND workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "value!: Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "c569535d4aded82ffef5e5066e24948c8fcdb8d36913775449b982782c8583e9"
|
||||
}
|
||||
@@ -68,7 +68,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
16
backend/.sqlx/query-ddda19024473b4e5b1d450bf56c667056f6b3696dea7d73758e53f825bfce13e.json
generated
Normal file
16
backend/.sqlx/query-ddda19024473b4e5b1d450bf56c667056f6b3696dea7d73758e53f825bfce13e.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO flow\n (workspace_id, path, summary, description, archived, extra_perms, dependency_job, draft_only, tag, ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, on_behalf_of_email, concurrency_key, versions, value, schema, edited_by, edited_at, labels)\n SELECT workspace_id, $1, summary, description, archived, extra_perms, dependency_job, draft_only, tag, ws_error_handler_muted, dedicated_worker, timeout, visible_to_runner_only, on_behalf_of_email, concurrency_key, versions, value, schema, edited_by, edited_at, labels\n FROM flow\n WHERE path = $2 AND workspace_id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "ddda19024473b4e5b1d450bf56c667056f6b3696dea7d73758e53f825bfce13e"
|
||||
}
|
||||
20
backend/.sqlx/query-deac41298e8b0d0870e314fef0813c24dd55d63bda78a0a5f35ed6f22bea6bef.json
generated
Normal file
20
backend/.sqlx/query-deac41298e8b0d0870e314fef0813c24dd55d63bda78a0a5f35ed6f22bea6bef.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO resource\n (workspace_id, path, value, description, resource_type, created_by, edited_at, labels)\n VALUES ($1, $2, $3, $4, $5, $6, now(), $7) ON CONFLICT (workspace_id, path)\n DO UPDATE SET value = EXCLUDED.value, description = EXCLUDED.description, resource_type = EXCLUDED.resource_type, edited_at = now(), labels = EXCLUDED.labels",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "deac41298e8b0d0870e314fef0813c24dd55d63bda78a0a5f35ed6f22bea6bef"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO app\n (workspace_id, path, summary, policy, versions, draft_only, custom_path)\n VALUES ($1, $2, $3, $4, '{}', $5, $6) RETURNING id",
|
||||
"query": "INSERT INTO app\n (workspace_id, path, summary, policy, versions, draft_only, custom_path, labels)\n VALUES ($1, $2, $3, $4, '{}', $5, $6, $7) RETURNING id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -16,12 +16,13 @@
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Bool",
|
||||
"Text"
|
||||
"Text",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6b53f7c4bb73177316d6134698f3979f51b53dcd4d8ec50d312c9e7fe31ad5f5"
|
||||
"hash": "e4836a1ee97e4723bddc28b94e23a54b6aa1f458f3ecca8f35432153e54b143d"
|
||||
}
|
||||
@@ -133,7 +133,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
64
backend/.sqlx/query-edd6c09b7f012588788fd3c572d20eb439a80d52ae75ebd25128ffce759cd313.json
generated
Normal file
64
backend/.sqlx/query-edd6c09b7f012588788fd3c572d20eb439a80d52ae75ebd25128ffce759cd313.json
generated
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT workspace_id, name, language AS \"language: windmill_common::scripts::ScriptLang\"\n FROM workspace_dependencies\n WHERE archived = false\n ORDER BY workspace_id, name",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "language: windmill_common::scripts::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",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "edd6c09b7f012588788fd3c572d20eb439a80d52ae75ebd25128ffce759cd313"
|
||||
}
|
||||
72
backend/.sqlx/query-f0858450021df721d8a48b1b5dc887c5424562acd9769c80c5899193ef16b56b.json
generated
Normal file
72
backend/.sqlx/query-f0858450021df721d8a48b1b5dc887c5424562acd9769c80c5899193ef16b56b.json
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT DISTINCT ON (workspace_id, path)\n workspace_id, path, language AS \"language: windmill_common::scripts::ScriptLang\", content\n FROM script\n WHERE archived = false\n AND dedicated_worker = true\n AND language = ANY($1::text[]::SCRIPT_LANG[])\n ORDER BY workspace_id, path, created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "language: windmill_common::scripts::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",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "content",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f0858450021df721d8a48b1b5dc887c5424562acd9769c80c5899193ef16b56b"
|
||||
}
|
||||
@@ -40,7 +40,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -84,7 +85,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
"nu",
|
||||
"java",
|
||||
"duckdb",
|
||||
"ruby"
|
||||
"ruby",
|
||||
"rlang"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
16
backend/.sqlx/query-f6f850c419771b193f506ceca63de805cbe6bdee314ca40d912010db307bd13e.json
generated
Normal file
16
backend/.sqlx/query-f6f850c419771b193f506ceca63de805cbe6bdee314ca40d912010db307bd13e.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE resource SET labels = $1 WHERE path = $2 AND workspace_id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "f6f850c419771b193f506ceca63de805cbe6bdee314ca40d912010db307bd13e"
|
||||
}
|
||||
296
backend/Cargo.lock
generated
296
backend/Cargo.lock
generated
@@ -2108,7 +2108,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"safetensors",
|
||||
"thiserror 2.0.18",
|
||||
"yoke 0.8.1",
|
||||
"yoke 0.8.2",
|
||||
"zip",
|
||||
]
|
||||
|
||||
@@ -2373,9 +2373,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cmov"
|
||||
version = "0.5.2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3"
|
||||
checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746"
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
@@ -2805,9 +2805,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctutils"
|
||||
version = "0.4.0"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4"
|
||||
checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
|
||||
dependencies = [
|
||||
"cmov",
|
||||
]
|
||||
@@ -7224,22 +7224,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
|
||||
checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"potential_utf",
|
||||
"yoke 0.8.1",
|
||||
"utf8_iter",
|
||||
"yoke 0.8.2",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_core"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
|
||||
checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
@@ -7250,9 +7251,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
|
||||
checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
|
||||
dependencies = [
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
@@ -7264,15 +7265,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
|
||||
checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "2.1.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
|
||||
checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
|
||||
dependencies = [
|
||||
"icu_collections",
|
||||
"icu_locale_core",
|
||||
@@ -7284,20 +7285,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "2.1.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
|
||||
checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
|
||||
checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locale_core",
|
||||
"writeable",
|
||||
"yoke 0.8.1",
|
||||
"yoke 0.8.2",
|
||||
"zerofrom",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
@@ -8046,9 +8047,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.183"
|
||||
version = "0.2.184"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
||||
|
||||
[[package]]
|
||||
name = "libffi"
|
||||
@@ -8204,9 +8205,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.8.1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
|
||||
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
@@ -10427,9 +10428,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
|
||||
checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
|
||||
dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
@@ -12117,6 +12118,15 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ece8e78b2f38ec51c51f5d475df0a7187ba5111b2a28bdc761ee05b075d40a71"
|
||||
|
||||
[[package]]
|
||||
name = "scc"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc"
|
||||
dependencies = [
|
||||
"sdd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.29"
|
||||
@@ -12222,6 +12232,12 @@ dependencies = [
|
||||
"untrusted 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdd"
|
||||
version = "3.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca"
|
||||
|
||||
[[package]]
|
||||
name = "seahash"
|
||||
version = "4.1.0"
|
||||
@@ -12558,6 +12574,32 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f"
|
||||
dependencies = [
|
||||
"futures-executor",
|
||||
"futures-util",
|
||||
"log",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"scc",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
@@ -14235,9 +14277,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
||||
checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"zerovec",
|
||||
@@ -14625,9 +14667,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.1.1+spec-1.1.0"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9"
|
||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||
dependencies = [
|
||||
"winnow 1.0.1",
|
||||
]
|
||||
@@ -15941,7 +15983,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-nats",
|
||||
@@ -15970,6 +16012,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_yml",
|
||||
"serial_test",
|
||||
"sha1",
|
||||
"sha2 0.10.9",
|
||||
"sql-builder",
|
||||
@@ -16019,7 +16062,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-alerting"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16032,7 +16075,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -16173,7 +16216,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-agent-workers"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16196,7 +16239,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-assets"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16209,7 +16252,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-auth"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16235,7 +16278,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"reqwest 0.12.28",
|
||||
"serde",
|
||||
@@ -16245,7 +16288,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-configs"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16262,7 +16305,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-debug"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"base64 0.22.1",
|
||||
@@ -16285,7 +16328,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-embeddings"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16308,7 +16351,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-flow-conversations"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16324,7 +16367,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-flows"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16344,7 +16387,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-groups"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16364,7 +16407,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-inputs"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16378,7 +16421,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-integration-tests"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-nats",
|
||||
@@ -16409,7 +16452,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-jobs"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16434,7 +16477,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-npm-proxy"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"flate2",
|
||||
@@ -16452,7 +16495,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-openapi"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16474,7 +16517,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-schedule"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16494,7 +16537,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-scripts"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16524,7 +16567,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-settings"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16551,7 +16594,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-sse"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"serde",
|
||||
@@ -16563,7 +16606,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-users"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"axum 0.8.4",
|
||||
@@ -16588,7 +16631,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-workers"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16602,7 +16645,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-workspaces"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"axum 0.8.4",
|
||||
"chrono",
|
||||
@@ -16634,7 +16677,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
@@ -16648,7 +16691,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum 0.8.4",
|
||||
@@ -16667,7 +16710,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"aho-corasick",
|
||||
@@ -16769,7 +16812,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-dep-map"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"itertools 0.14.0",
|
||||
@@ -16788,7 +16831,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -16803,7 +16846,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"astral-tokio-tar",
|
||||
@@ -16827,7 +16870,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-jseval"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
@@ -16844,7 +16887,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
@@ -16860,7 +16903,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-mcp"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -16881,7 +16924,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-native-triggers"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -16912,7 +16955,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-oauth"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-oauth2",
|
||||
@@ -16936,7 +16979,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-object-store"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -16970,7 +17013,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-operator"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
@@ -16988,7 +17031,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -16997,7 +17040,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -17009,7 +17052,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-csharp"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -17021,7 +17064,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -17033,7 +17076,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -17045,7 +17088,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-java"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -17057,7 +17100,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-nu"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nu-parser",
|
||||
@@ -17068,7 +17111,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -17079,7 +17122,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -17091,7 +17134,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-asset"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"rustpython-ast",
|
||||
@@ -17102,7 +17145,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -17124,7 +17167,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-r"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -17136,7 +17179,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ruby"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -17150,7 +17193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -17167,7 +17210,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -17180,7 +17223,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql-asset"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -17192,7 +17235,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -17210,7 +17253,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts-asset"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde-wasm-bindgen",
|
||||
@@ -17226,7 +17269,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wac"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"rustpython-ast",
|
||||
@@ -17242,7 +17285,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -17253,7 +17296,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -17290,7 +17333,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-runtime-nativets"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"const_format",
|
||||
@@ -17328,7 +17371,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"wasm-bindgen",
|
||||
@@ -17339,7 +17382,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-store"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -17368,7 +17411,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-test-utils"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17392,7 +17435,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17425,7 +17468,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-email"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17445,7 +17488,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-gcp"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17479,7 +17522,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-http"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17515,7 +17558,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-kafka"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17538,7 +17581,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-mqtt"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17562,7 +17605,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-nats"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-nats",
|
||||
@@ -17586,7 +17629,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-postgres"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17621,7 +17664,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-sqs"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17649,7 +17692,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-trigger-websocket"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -17672,7 +17715,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-types"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.4",
|
||||
@@ -17691,7 +17734,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-once-cell",
|
||||
@@ -17795,13 +17838,14 @@ dependencies = [
|
||||
"windmill-runtime-nativets",
|
||||
"windmill-types",
|
||||
"windmill-worker-volumes",
|
||||
"windows 0.61.3",
|
||||
"x509-parser 0.16.0",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker-volumes"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
@@ -18501,9 +18545,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
|
||||
checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
|
||||
|
||||
[[package]]
|
||||
name = "wtf8"
|
||||
@@ -18636,12 +18680,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
|
||||
checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
"yoke-derive 0.8.1",
|
||||
"yoke-derive 0.8.2",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
@@ -18659,9 +18703,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.8.1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
||||
checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -18691,18 +18735,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -18732,31 +18776,31 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
|
||||
checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke 0.8.1",
|
||||
"yoke 0.8.2",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.11.5"
|
||||
version = "0.11.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
|
||||
checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
|
||||
dependencies = [
|
||||
"yoke 0.8.1",
|
||||
"yoke 0.8.2",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec-derive"
|
||||
version = "0.11.2"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
|
||||
checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -85,7 +85,7 @@ members = [
|
||||
exclude = ["./windmill-duckdb-ffi-internal", "./parsers/windmill-parser-wasm"]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.672.0"
|
||||
version = "1.673.0"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -267,6 +267,7 @@ windmill-types.workspace = true
|
||||
opentelemetry = { workspace = true }
|
||||
opentelemetry_sdk = { workspace = true }
|
||||
windmill-trigger.workspace = true
|
||||
serial_test = "3"
|
||||
windmill-trigger-websocket.workspace = true
|
||||
windmill-trigger-postgres.workspace = true
|
||||
windmill-trigger-mqtt.workspace = true
|
||||
@@ -577,7 +578,7 @@ async-stream = "^0"
|
||||
opentelemetry = "0.30.0"
|
||||
tracing-opentelemetry = "0.31.0"
|
||||
opentelemetry_sdk = { version = "0.30.0", features = ["rt-tokio", "testing"] }
|
||||
opentelemetry-otlp = { version = "0.30.0", features = ["grpc-tonic", "tls"] }
|
||||
opentelemetry-otlp = { version = "0.30.0", features = ["grpc-tonic", "tls", "http-proto"] }
|
||||
opentelemetry-appender-tracing = "0.30.0"
|
||||
opentelemetry-semantic-conventions = { version = "0.30.0", features = ["semconv_experimental"] }
|
||||
opentelemetry-proto = { version = "0.30.0", features = ["with-serde", "gen-tonic"] }
|
||||
|
||||
@@ -1 +1 @@
|
||||
e08a87450627bef9013498e40ee93a47bedda7ee
|
||||
ef37ca96f140dcd553226fac6bce3ef6d57ec03d
|
||||
16
backend/migrations/20260330000000_add_labels.down.sql
Normal file
16
backend/migrations/20260330000000_add_labels.down.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
ALTER TABLE script DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE flow DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE app DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE raw_app DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE schedule DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE http_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE websocket_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE kafka_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE nats_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE mqtt_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE postgres_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE sqs_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE gcp_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE email_trigger DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE resource DROP COLUMN IF EXISTS labels;
|
||||
ALTER TABLE variable DROP COLUMN IF EXISTS labels;
|
||||
33
backend/migrations/20260330000000_add_labels.up.sql
Normal file
33
backend/migrations/20260330000000_add_labels.up.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
ALTER TABLE script ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE flow ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE app ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE raw_app ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE schedule ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE http_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE websocket_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE kafka_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE nats_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE mqtt_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE postgres_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE sqs_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE gcp_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE email_trigger ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE resource ADD COLUMN IF NOT EXISTS labels text[];
|
||||
ALTER TABLE variable ADD COLUMN IF NOT EXISTS labels text[];
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_script_labels ON script USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_flow_labels ON flow USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_app_labels ON app USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_raw_app_labels ON raw_app USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_labels ON schedule USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_labels ON resource USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_variable_labels ON variable USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_http_trigger_labels ON http_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_websocket_trigger_labels ON websocket_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_kafka_trigger_labels ON kafka_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_nats_trigger_labels ON nats_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_mqtt_trigger_labels ON mqtt_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_postgres_trigger_labels ON postgres_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_sqs_trigger_labels ON sqs_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_gcp_trigger_labels ON gcp_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_email_trigger_labels ON email_trigger USING GIN (labels) WHERE labels IS NOT NULL;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Remove the //nodejs annotation that was prepended by the up migration.
|
||||
-- Only removes it if it's at the very start of the content.
|
||||
UPDATE script
|
||||
SET content = regexp_replace(content, E'^//nodejs\n// dedicated workers were previously running in nodejs mode by default, remove this annotation to use bun\n', '')
|
||||
WHERE language = 'bun'
|
||||
AND dedicated_worker = true;
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Bun dedicated workers were previously forced to run in nodejs mode at runtime.
|
||||
-- Now that bun is the default again, add the //nodejs annotation to existing
|
||||
-- bun dedicated scripts that don't already have it, so their behavior is preserved.
|
||||
UPDATE script
|
||||
SET content = '//nodejs
|
||||
// dedicated workers were previously running in nodejs mode by default, remove this annotation to use bun
|
||||
' || content
|
||||
WHERE language = 'bun'
|
||||
AND dedicated_worker = true
|
||||
AND content !~ '^//\s*nodejs';
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE websocket_trigger DROP COLUMN heartbeat;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE websocket_trigger ADD COLUMN heartbeat JSONB NULL;
|
||||
@@ -22,22 +22,82 @@ pub fn parse_bash_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing bash script".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// PowerShell common parameter names that are automatically added by [CmdletBinding()].
|
||||
/// These should be filtered from the parsed signature since they are not user-defined.
|
||||
const POWERSHELL_COMMON_PARAMS: &[&str] = &[
|
||||
"verbose",
|
||||
"debug",
|
||||
"erroraction",
|
||||
"errorvariable",
|
||||
"informationaction",
|
||||
"informationvariable",
|
||||
"outvariable",
|
||||
"outbuffer",
|
||||
"pipelinevariable",
|
||||
"warningaction",
|
||||
"warningvariable",
|
||||
"whatif",
|
||||
"confirm",
|
||||
"progressaction",
|
||||
];
|
||||
|
||||
/// Detects whether the script uses [CmdletBinding()] and whether it declares SupportsShouldProcess.
|
||||
fn detect_cmdlet_binding(code: &str) -> (bool, bool) {
|
||||
let attr_region = match extract_powershell_param_block_with_attributes(code, true) {
|
||||
Some((region, _)) => region,
|
||||
None => return (false, false),
|
||||
};
|
||||
// Strip comment lines to avoid false positives from commented-out [CmdletBinding()]
|
||||
let uncommented: String = attr_region
|
||||
.lines()
|
||||
.filter(|line| !line.trim_start().starts_with('#'))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let lower = uncommented.to_lowercase();
|
||||
let has_cmd_binding = lower.contains("[cmdletbinding");
|
||||
let supports_should_process = has_cmd_binding
|
||||
&& lower.contains("supportsshouldprocess")
|
||||
&& !lower.contains("supportsshouldprocess=$false")
|
||||
&& !lower.contains("supportsshouldprocess = $false");
|
||||
(has_cmd_binding, supports_should_process)
|
||||
}
|
||||
|
||||
pub fn parse_powershell_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
let parsed = parse_powershell_file(&code)?;
|
||||
if let Some(x) = parsed {
|
||||
let args = x;
|
||||
if let Some(args) = parsed {
|
||||
let (has_cmd_binding, supports_should_process) = detect_cmdlet_binding(code);
|
||||
|
||||
// Filter out common parameters only when CmdletBinding is present
|
||||
// (without CmdletBinding, $Verbose etc. are regular user-defined parameters)
|
||||
let args = if has_cmd_binding {
|
||||
args.into_iter()
|
||||
.filter(|arg| !POWERSHELL_COMMON_PARAMS.contains(&arg.name.to_lowercase().as_str()))
|
||||
.collect()
|
||||
} else {
|
||||
args
|
||||
};
|
||||
|
||||
Ok(MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
has_cmd_binding: if has_cmd_binding { Some(true) } else { None },
|
||||
supports_should_process: if supports_should_process {
|
||||
Some(true)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing powershell script".to_string()))
|
||||
@@ -96,7 +156,10 @@ fn parse_bash_file(code: &str) -> anyhow::Result<Option<Vec<Arg>>> {
|
||||
/// This function uses the existing extract_powershell_param_block validation, which already
|
||||
/// ensures that only comments, whitespace, and attributes appear before param. So we can
|
||||
/// simply return everything from the beginning to the end of the param block.
|
||||
pub fn extract_powershell_param_block_with_attributes(code: &str, include_attributes: bool) -> Option<(&str, &str)> {
|
||||
pub fn extract_powershell_param_block_with_attributes(
|
||||
code: &str,
|
||||
include_attributes: bool,
|
||||
) -> Option<(&str, &str)> {
|
||||
// First, use the existing function to validate and find the param block
|
||||
let param_block = extract_powershell_param_block(code, true)?;
|
||||
|
||||
@@ -450,11 +513,15 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
// Check if this is a Parameter attribute with Mandatory (case-insensitive)
|
||||
let lower = bracket_content.to_lowercase();
|
||||
if lower.starts_with("parameter(") || lower.starts_with("parameter ") {
|
||||
if lower.starts_with("parameter(")
|
||||
|| lower.starts_with("parameter ")
|
||||
{
|
||||
// Check for Mandatory (case-insensitive)
|
||||
if lower.contains("mandatory") {
|
||||
// Check if it's explicitly set to false
|
||||
if !lower.contains("mandatory=$false") && !lower.contains("mandatory = $false") {
|
||||
if !lower.contains("mandatory=$false")
|
||||
&& !lower.contains("mandatory = $false")
|
||||
{
|
||||
is_mandatory = true;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +538,11 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
// Check if this looks like a type (simple word, possibly with [])
|
||||
let is_type = !bracket_content.contains('(')
|
||||
&& !bracket_content.contains('=')
|
||||
&& (bracket_content.chars().next().unwrap_or(' ').is_alphabetic()
|
||||
&& (bracket_content
|
||||
.chars()
|
||||
.next()
|
||||
.unwrap_or(' ')
|
||||
.is_alphabetic()
|
||||
|| bracket_content.starts_with('['));
|
||||
|
||||
if is_type && !found_dollar {
|
||||
@@ -529,7 +600,9 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
while let Some((i, ch)) = chars.peek().copied() {
|
||||
if in_string {
|
||||
if ch == string_char && content.chars().nth(i.saturating_sub(1)) != Some('`') {
|
||||
if ch == string_char
|
||||
&& content.chars().nth(i.saturating_sub(1)) != Some('`')
|
||||
{
|
||||
in_string = false;
|
||||
default_end = i + 1;
|
||||
chars.next();
|
||||
@@ -544,7 +617,9 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
chars.next();
|
||||
} else if ch == ',' {
|
||||
break;
|
||||
} else if ch.is_whitespace() && chars.clone().skip(1).next().map(|(_, c)| c) == Some(',') {
|
||||
} else if ch.is_whitespace()
|
||||
&& chars.clone().skip(1).next().map(|(_, c)| c) == Some(',')
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
default_end = i + 1;
|
||||
@@ -552,12 +627,19 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
}
|
||||
}
|
||||
|
||||
default_value = Some(content[default_start..default_end].trim().to_string());
|
||||
default_value =
|
||||
Some(content[default_start..default_end].trim().to_string());
|
||||
}
|
||||
',' => {
|
||||
// End of parameter, finalize it
|
||||
if let Some(name) = var_name.take() {
|
||||
args.push(finalize_parameter(name, type_annotation.take(), default_value.take(), is_mandatory, validate_set.take())?);
|
||||
args.push(finalize_parameter(
|
||||
name,
|
||||
type_annotation.take(),
|
||||
default_value.take(),
|
||||
is_mandatory,
|
||||
validate_set.take(),
|
||||
)?);
|
||||
}
|
||||
|
||||
// Reset for next parameter
|
||||
@@ -576,7 +658,13 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
// Finalize last parameter
|
||||
if let Some(name) = var_name {
|
||||
args.push(finalize_parameter(name, type_annotation, default_value, is_mandatory, validate_set)?);
|
||||
args.push(finalize_parameter(
|
||||
name,
|
||||
type_annotation,
|
||||
default_value,
|
||||
is_mandatory,
|
||||
validate_set,
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(args)
|
||||
@@ -722,7 +810,8 @@ non_required="${5:-}"
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -813,14 +902,19 @@ non_required="${5:-}"
|
||||
Arg {
|
||||
otyp: Some("string".to_string()), // [string] (last type bracket with Mandatory and ValidateSet)
|
||||
name: "Message".to_string(),
|
||||
typ: Typ::Str(Some(vec!["Green".to_string(), "Blue".to_string(), "Red".to_string()])), // ValidateSet enum
|
||||
typ: Typ::Str(Some(vec![
|
||||
"Green".to_string(),
|
||||
"Blue".to_string(),
|
||||
"Red".to_string()
|
||||
])), // ValidateSet enum
|
||||
default: None,
|
||||
has_default: false, // Required (Mandatory attribute)
|
||||
oidx: None
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
@@ -970,19 +1064,13 @@ non_required="${5:-}"
|
||||
|
||||
// Valid: CmdletBinding with comments
|
||||
assert_eq!(
|
||||
extract_powershell_param_block(
|
||||
"# My function\n[CmdletBinding()]\nparam($Name)",
|
||||
false
|
||||
),
|
||||
extract_powershell_param_block("# My function\n[CmdletBinding()]\nparam($Name)", false),
|
||||
Some("$Name")
|
||||
);
|
||||
|
||||
// Valid: CmdletBinding with whitespace variations
|
||||
assert_eq!(
|
||||
extract_powershell_param_block(
|
||||
"[CmdletBinding()] \n param($Name)",
|
||||
false
|
||||
),
|
||||
extract_powershell_param_block("[CmdletBinding()] \n param($Name)", false),
|
||||
Some("$Name")
|
||||
);
|
||||
|
||||
@@ -1204,17 +1292,32 @@ param(
|
||||
// Test with CmdletBinding with parameters
|
||||
let code3 = "[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)";
|
||||
let result3 = extract_powershell_param_block_with_attributes(code3, true);
|
||||
assert_eq!(result3, Some(("[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)", "")));
|
||||
assert_eq!(
|
||||
result3,
|
||||
Some((
|
||||
"[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)",
|
||||
""
|
||||
))
|
||||
);
|
||||
|
||||
// Test with multiple attributes
|
||||
let code4 = "[CmdletBinding()]\n[OutputType([string])]\nparam($Value)";
|
||||
let result4 = extract_powershell_param_block_with_attributes(code4, true);
|
||||
assert_eq!(result4, Some(("[CmdletBinding()]\n[OutputType([string])]\nparam($Value)", "")));
|
||||
assert_eq!(
|
||||
result4,
|
||||
Some((
|
||||
"[CmdletBinding()]\n[OutputType([string])]\nparam($Value)",
|
||||
""
|
||||
))
|
||||
);
|
||||
|
||||
// Test with comment before attributes
|
||||
let code5 = "# My function\n[CmdletBinding()]\nparam($Name)";
|
||||
let result5 = extract_powershell_param_block_with_attributes(code5, true);
|
||||
assert_eq!(result5, Some(("# My function\n[CmdletBinding()]\nparam($Name)", "")));
|
||||
assert_eq!(
|
||||
result5,
|
||||
Some(("# My function\n[CmdletBinding()]\nparam($Name)", ""))
|
||||
);
|
||||
|
||||
// Test with include_attributes = false (should only get param block, not attributes)
|
||||
let code6 = "[CmdletBinding()]\nparam($Name)";
|
||||
@@ -1224,7 +1327,10 @@ param(
|
||||
// Test with code after param
|
||||
let code7 = "[CmdletBinding()]\nparam($Name)\nWrite-Host 'Hello'";
|
||||
let result7 = extract_powershell_param_block_with_attributes(code7, true);
|
||||
assert_eq!(result7, Some(("[CmdletBinding()]\nparam($Name)", "\nWrite-Host 'Hello'")));
|
||||
assert_eq!(
|
||||
result7,
|
||||
Some(("[CmdletBinding()]\nparam($Name)", "\nWrite-Host 'Hello'"))
|
||||
);
|
||||
|
||||
// Test with code after param (without attributes)
|
||||
let code8 = "[CmdletBinding()]\nparam($Name)\nWrite-Host 'Hello'";
|
||||
@@ -1392,10 +1498,85 @@ param(
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_detect_cmdlet_binding() {
|
||||
// Basic CmdletBinding
|
||||
let (has_cb, has_ssp) = detect_cmdlet_binding("[CmdletBinding()]\nparam($Name)");
|
||||
assert!(has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// CmdletBinding with SupportsShouldProcess
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[CmdletBinding(SupportsShouldProcess=$true)]\nparam($Path)");
|
||||
assert!(has_cb);
|
||||
assert!(has_ssp);
|
||||
|
||||
// CmdletBinding with SupportsShouldProcess=false
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[CmdletBinding(SupportsShouldProcess=$false)]\nparam($Path)");
|
||||
assert!(has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// No CmdletBinding
|
||||
let (has_cb, has_ssp) = detect_cmdlet_binding("param($Name)");
|
||||
assert!(!has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// Case insensitive
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[cmdletbinding(supportsshouldprocess=$true)]\nparam($X)");
|
||||
assert!(has_cb);
|
||||
assert!(has_ssp);
|
||||
|
||||
// Commented out CmdletBinding should NOT be detected
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("# [CmdletBinding(SupportsShouldProcess=$true)]\nparam($Path)");
|
||||
assert!(!has_cb);
|
||||
assert!(!has_ssp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powershell_common_param_filtering() -> anyhow::Result<()> {
|
||||
// Common parameters declared in param() should be filtered out
|
||||
let code = r#"[CmdletBinding()]
|
||||
param(
|
||||
[string]$Name,
|
||||
[switch]$Verbose,
|
||||
[string]$ErrorAction,
|
||||
[int]$Age
|
||||
)"#;
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.args.len(), 2);
|
||||
assert_eq!(sig.args[0].name, "Name");
|
||||
assert_eq!(sig.args[1].name, "Age");
|
||||
assert_eq!(sig.has_cmd_binding, Some(true));
|
||||
assert_eq!(sig.supports_should_process, None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powershell_sig_cmdlet_binding_metadata() -> anyhow::Result<()> {
|
||||
// Script without CmdletBinding
|
||||
let code = "param([string]$Name)";
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.has_cmd_binding, None);
|
||||
assert_eq!(sig.supports_should_process, None);
|
||||
|
||||
// Script with CmdletBinding + SupportsShouldProcess
|
||||
let code = "[CmdletBinding(SupportsShouldProcess=$true)]\nparam([string]$Path)";
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.has_cmd_binding, Some(true));
|
||||
assert_eq!(sig.supports_should_process, Some(true));
|
||||
assert_eq!(sig.args.len(), 1);
|
||||
assert_eq!(sig.args[0].name, "Path");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ pub fn parse_csharp_sig_meta(code: &str) -> anyhow::Result<CsharpMainSigMeta> {
|
||||
args,
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(CsharpMainSigMeta { is_async, returns_void, class_name, main_sig, is_public })
|
||||
|
||||
@@ -43,6 +43,7 @@ pub fn parse_go_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -51,6 +52,7 @@ pub fn parse_go_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -244,7 +246,8 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ pub fn parse_graphql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -126,7 +127,8 @@ query($i: Int, $arr: [String]!, $wahoo: String = "wahoo") {
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ pub fn parse_java_sig_meta(code: &str) -> anyhow::Result<JavaMainSigMeta> {
|
||||
args,
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(JavaMainSigMeta { returns_void, class_name, main_sig, is_public })
|
||||
|
||||
@@ -56,6 +56,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -83,6 +84,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -120,6 +122,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -232,6 +235,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -279,6 +283,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -343,6 +348,7 @@ mod test {
|
||||
// },],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
@@ -373,6 +379,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -420,6 +427,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -448,6 +456,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -480,6 +489,7 @@ mod test {
|
||||
// },],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
@@ -542,6 +552,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -635,6 +646,7 @@ mod test {
|
||||
// ],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
|
||||
@@ -101,6 +101,7 @@ pub fn parse_php_signature(
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -109,6 +110,7 @@ pub fn parse_php_signature(
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -180,7 +182,8 @@ function main(string $input1 = \"hey\", bool $input2 = false, int $input3 = 3, f
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -366,6 +366,7 @@ pub fn parse_python_signature(
|
||||
Some("lib".to_string())
|
||||
},
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -477,6 +478,7 @@ pub fn parse_python_signature(
|
||||
.collect(),
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -489,6 +491,7 @@ pub fn parse_python_signature(
|
||||
None
|
||||
},
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -755,7 +758,8 @@ def main(test1: str, name: datetime.datetime = datetime.now(), byte: bytes = byt
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -820,7 +824,8 @@ def main(test1: str,
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -880,7 +885,8 @@ def main(test1: str,
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -924,7 +930,8 @@ def main(test1: Literal["foo", "bar"], test2: List[Literal["foo", "bar"]]): retu
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -955,7 +962,8 @@ def main(test1: DynSelect_foo): return
|
||||
oidx: None
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -979,7 +987,8 @@ def hello(): return
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1007,7 +1016,8 @@ def main(): return
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true)
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1072,7 +1082,8 @@ def main(a: list, e: List[int], b: list = [1,2,3,4], c = [1,2,3,4], d = ["a", "b
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1121,7 +1132,8 @@ def main(a: str, b: Optional[str], c: str | None): return
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_r_sig_meta(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: args.unwrap_or_default(),
|
||||
has_preprocessor: None,
|
||||
auto_kind: None,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(main_sig)
|
||||
|
||||
@@ -41,6 +41,7 @@ pub fn parse_ruby_sig_meta(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: args.unwrap_or_default(),
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(main_sig)
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_rust_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -38,6 +39,7 @@ pub fn parse_rust_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_mysql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -46,6 +47,7 @@ pub fn parse_oracledb_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -67,6 +69,7 @@ pub fn parse_pgsql_sig_with_typed_schema(code: &str) -> anyhow::Result<(MainArgS
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
typed_schema,
|
||||
))
|
||||
@@ -85,6 +88,7 @@ pub fn parse_bigquery_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -100,6 +104,7 @@ pub fn parse_duckdb_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -116,6 +121,7 @@ pub fn parse_snowflake_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -132,6 +138,7 @@ pub fn parse_mssql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -944,7 +951,8 @@ SELECT * FROM table WHERE token=$1::TEXT AND image=$2::BIGINT
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -993,7 +1001,8 @@ SELECT $2::TEXT;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1120,7 +1129,8 @@ SELECT ?, ?;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1168,7 +1178,8 @@ SELECT :param2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1208,7 +1219,8 @@ SELECT @token;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1256,7 +1268,8 @@ SELECT ?;
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1304,7 +1317,8 @@ SELECT @P2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1353,7 +1367,8 @@ SELECT * FROM table_name WHERE thing = :name4;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1391,7 +1406,8 @@ SELECT * FROM users WHERE id = $1 AND email = $2::text;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1429,7 +1445,8 @@ SELECT * FROM users LIMIT $1 OFFSET $2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1479,7 +1496,8 @@ WHERE id = $1
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1506,7 +1524,8 @@ SELECT * FROM users WHERE id = ANY($1);
|
||||
oidx: Some(1),
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1535,7 +1554,8 @@ SELECT $1::integer;
|
||||
oidx: Some(1),
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1567,7 +1587,8 @@ SELECT x
|
||||
oidx: None,
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -462,6 +462,7 @@ pub fn parse_deno_signature(
|
||||
},
|
||||
auto_kind,
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
};
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ mod tests {
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -105,6 +106,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -154,6 +156,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -203,6 +206,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -234,6 +238,7 @@ mod tests {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -265,6 +270,7 @@ mod tests {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -305,6 +311,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -343,6 +350,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -401,6 +409,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -459,6 +468,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -508,6 +518,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -557,6 +568,7 @@ mod tests {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -584,6 +596,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -613,6 +626,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -642,6 +656,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -691,6 +706,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -731,6 +747,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -761,6 +778,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,8 @@ export function main(test1?: string, test2: string = \"burkina\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -220,7 +221,8 @@ export function main(test2 = \"burkina\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -271,7 +273,8 @@ export function main(foo: FooBar, {a, b}: FooBar, {c, d}: FooBar = {a: \"foo\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -303,7 +306,8 @@ export function main(foo: (\"foo\" | \"bar\")[]) {
|
||||
oidx: None
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -447,7 +451,8 @@ Write-Output 'Testing...'
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ pub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,6 +95,7 @@ pub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ pub struct MainArgSignature {
|
||||
pub args: Vec<Arg>,
|
||||
pub auto_kind: Option<String>,
|
||||
pub has_preprocessor: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub has_cmd_binding: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub supports_should_process: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug, PartialEq)]
|
||||
|
||||
@@ -41,50 +41,69 @@ pub async fn connect_db(
|
||||
};
|
||||
|
||||
let pool = connect(database_url.clone(), max_connections, worker_mode).await?;
|
||||
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
let pool2 = pool.clone();
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
if let DatabaseUrl::IamRds(database_url) = database_url {
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = killpill_rx.recv() => {
|
||||
break;
|
||||
}
|
||||
_ = tokio::time::sleep(std::time::Duration::from_secs(10)) => {
|
||||
let needs_refresh = {
|
||||
let read_guard = database_url.read().await;
|
||||
read_guard.needs_refresh()
|
||||
};
|
||||
if needs_refresh {
|
||||
let new_url = tokio::time::timeout(std::time::Duration::from_secs(10), get_database_url()).await;
|
||||
{
|
||||
let needs_token_refresh = matches!(
|
||||
database_url,
|
||||
DatabaseUrl::IamRds(_) | DatabaseUrl::EntraId(_)
|
||||
);
|
||||
let label = match &database_url {
|
||||
DatabaseUrl::IamRds(_) => "IAM RDS",
|
||||
DatabaseUrl::EntraId(_) => "Entra ID",
|
||||
DatabaseUrl::Static(_) => "",
|
||||
};
|
||||
if needs_token_refresh {
|
||||
let pool2 = pool.clone();
|
||||
let database_url2 = database_url.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = killpill_rx.recv() => {
|
||||
break;
|
||||
}
|
||||
_ = tokio::time::sleep(std::time::Duration::from_secs(10)) => {
|
||||
if !database_url2.needs_refresh().await {
|
||||
continue;
|
||||
}
|
||||
let new_url = tokio::time::timeout(
|
||||
std::time::Duration::from_secs(10),
|
||||
get_database_url(),
|
||||
)
|
||||
.await;
|
||||
match new_url {
|
||||
Ok(Ok(new_url)) => {
|
||||
match new_url.connect_options().await {
|
||||
Ok(connect_options) => {
|
||||
pool2.set_connect_options(connect_options);
|
||||
tracing::info!("Refreshed IAM RDS URL successfully");
|
||||
tracing::info!("Refreshed {label} URL successfully");
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting IAM RDS connect options, retrying in 10s: {}", e);
|
||||
tracing::error!(
|
||||
"Error getting {label} connect options, retrying in 10s: {e}"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
tracing::error!("Error refreshing IAM RDS URL, trying again in 10s: {}", e);
|
||||
tracing::error!(
|
||||
"Error refreshing {label} URL, trying again in 10s: {e}"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Timeout after 10s refreshing IAM RDS URL, trying again in 10 seconds: {}", e);
|
||||
tracing::error!(
|
||||
"Timeout after 10s refreshing {label} URL, trying again in 10s: {e}"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(pool)
|
||||
|
||||
@@ -1597,6 +1597,12 @@ async fn process_notify_event(
|
||||
tracing::debug!("config changed but did not target this server/worker");
|
||||
}
|
||||
}
|
||||
"restart_worker_group" => {
|
||||
if worker_mode && payload == *WORKER_GROUP {
|
||||
tracing::info!("Restart requested for worker group '{payload}'");
|
||||
spawn_graceful_killpill(tx, db, 10, "worker group restart requested").await;
|
||||
}
|
||||
}
|
||||
"notify_webhook_change" => {
|
||||
tracing::info!(
|
||||
"Webhook change detected, invalidating webhook cache: {}",
|
||||
|
||||
@@ -38,7 +38,7 @@ account: workspace_id(char), id(int), expires_at(ts), refresh_token(char), clien
|
||||
agent_token_blacklist: token(char), expires_at(ts), blacklisted_at(ts), blacklisted_by(char)
|
||||
ai_agent_memory: workspace_id(char), conversation_id(uuid), step_id(char), messages(jsonb), created_at(ts), updated_at(ts)
|
||||
alerts: id(int), alert_type(char), message(text), created_at(ts), acknowledged(bool), workspace_id(text), acknowledged_workspace(bool), resource(text)
|
||||
app: id(bigint), workspace_id(char), path(char), summary(char), policy(jsonb), versions(bigint[]), extra_perms(jsonb), draft_only(bool), custom_path(text)
|
||||
app: id(bigint), workspace_id(char), path(char), summary(char), policy(jsonb), versions(bigint[]), extra_perms(jsonb), draft_only(bool), custom_path(text), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
app_bundles: app_version_id(bigint), w_id(char), file_type(char), data(bytes)
|
||||
app_script: id(bigint), app(bigint), hash(char(64)), lock(text), code(text), code_sha256(char(64))
|
||||
@@ -72,9 +72,9 @@ deployment_metadata: workspace_id(char), path(char), script_hash(bigint), app_ve
|
||||
draft: workspace_id(char), path(char), typ(draft_type), value(json), created_at(ts)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
email_to_igroup: email(char), igroup(char)
|
||||
email_trigger: path(char), local_part(char), workspaced_local_part(bool), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
|
||||
email_trigger: path(char), local_part(char), workspaced_local_part(bool), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), labels(text[])
|
||||
favorite: usr(char), workspace_id(char), path(char), favorite_kind(favorite_kind)
|
||||
flow: workspace_id(char), path(char), summary(text), description(text), value(jsonb), edited_by(char), edited_at(ts), archived(bool), schema(json), extra_perms(jsonb), dependency_job(uuid), draft_only(bool), tag(char), ws_error_handler_muted(bool), dedicated_worker(bool), timeout(int), visible_to_runner_only(bool), concurrency_key(char), versions(bigint[]), on_behalf_of_email(text), lock_error_logs(text)
|
||||
flow: workspace_id(char), path(char), summary(text), description(text), value(jsonb), edited_by(char), edited_at(ts), archived(bool), schema(json), extra_perms(jsonb), dependency_job(uuid), draft_only(bool), tag(char), ws_error_handler_muted(bool), dedicated_worker(bool), timeout(int), visible_to_runner_only(bool), concurrency_key(char), versions(bigint[]), on_behalf_of_email(text), lock_error_logs(text), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
flow_conversation: id(uuid), workspace_id(char), flow_path(char), title(char), created_at(ts), updated_at(ts), created_by(char)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
@@ -91,14 +91,14 @@ folder: name(char), workspace_id(char), display_name(char), owners(char), extra_
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
folder_permission_history: id(bigint), workspace_id(char), folder_name(char), changed_by(char), changed_at(ts), change_type(char), affected(char)
|
||||
FK: (workspace_id, folder_name) -> folder(workspace_id, name)
|
||||
gcp_trigger: gcp_resource_path(char), topic_id(char), subscription_id(char), delivery_type(delivery_mode), delivery_config(jsonb), path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), subscription_mode(gcp_subscription_mode), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), auto_acknowledge_msg(bool), ack_deadline(int), mode(trigger_mode)
|
||||
gcp_trigger: gcp_resource_path(char), topic_id(char), subscription_id(char), delivery_type(delivery_mode), delivery_config(jsonb), path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), subscription_mode(gcp_subscription_mode), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), auto_acknowledge_msg(bool), ack_deadline(int), mode(trigger_mode), labels(text[])
|
||||
global_settings: name(char), value(jsonb), updated_at(ts)
|
||||
group_: workspace_id(char), name(char), summary(text), extra_perms(jsonb)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
group_permission_history: id(bigint), workspace_id(char), group_name(char), changed_by(char), changed_at(ts), change_type(char), member_affected(char)
|
||||
FK: (workspace_id, group_name) -> group_(workspace_id, name)
|
||||
healthchecks: id(bigint), check_type(char), healthy(bool), created_at(ts)
|
||||
http_trigger: path(char), route_path(char), route_path_key(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), authentication_method(authentication_method), http_method(http_method), static_asset_config(jsonb), is_static_website(bool), workspaced_route(bool), wrap_body(bool), raw_string(bool), authentication_resource_path(char), summary(char), description(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), request_type(request_type), mode(trigger_mode)
|
||||
http_trigger: path(char), route_path(char), route_path_key(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), authentication_method(authentication_method), http_method(http_method), static_asset_config(jsonb), is_static_website(bool), workspaced_route(bool), wrap_body(bool), raw_string(bool), authentication_resource_path(char), summary(char), description(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), request_type(request_type), mode(trigger_mode), labels(text[])
|
||||
input: id(uuid), workspace_id(char), runnable_id(char), runnable_type(runnable_type), name(text), args(jsonb), created_at(ts), created_by(char), is_public(bool)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
instance_group: name(char), summary(char), id(char), scim_display_name(char), external_id(char)
|
||||
@@ -111,7 +111,7 @@ job_stats: workspace_id(char), job_id(uuid), metric_id(char), metric_name(char),
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
kafka_pending_commits: id(bigint), workspace_id(char), kafka_trigger_path(char), topic(char), partition(int), offset(bigint), created_at(ts)
|
||||
FK: (workspace_id, kafka_trigger_path) -> kafka_trigger(workspace_id, path)
|
||||
kafka_trigger: path(char), kafka_resource_path(char), topics(char), group_id(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), filters(jsonb[]), auto_commit(bool)
|
||||
kafka_trigger: path(char), kafka_resource_path(char), topics(char), group_id(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), filters(jsonb[]), auto_commit(bool), labels(text[])
|
||||
log_file: hostname(char), log_ts(ts), ok_lines(bigint), err_lines(bigint), mode(log_mode), worker_group(char), file_path(char), json_fmt(bool)
|
||||
magic_link: email(char), token(char), expiration(ts)
|
||||
mcp_oauth_client: mcp_server_url(text), client_id(text), client_secret(text), client_secret_expires_at(ts), token_endpoint(text), created_at(ts)
|
||||
@@ -121,10 +121,10 @@ mcp_oauth_server_client: client_id(char), client_name(char), redirect_uris(text[
|
||||
mcp_oauth_server_code: code(char), client_id(char), user_email(char), workspace_id(char), scopes(text[]), redirect_uri(text), code_challenge(char), code_challenge_method(char), created_at(ts), expires_at(ts)
|
||||
FK: (client_id) -> mcp_oauth_server_client(client_id)
|
||||
metrics: id(char), value(jsonb), created_at(ts)
|
||||
mqtt_trigger: mqtt_resource_path(char), subscribe_topics(jsonb[]), client_version(mqtt_client_version), v5_config(jsonb), v3_config(jsonb), client_id(char), path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
|
||||
mqtt_trigger: mqtt_resource_path(char), subscribe_topics(jsonb[]), client_version(mqtt_client_version), v5_config(jsonb), v3_config(jsonb), client_id(char), path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), labels(text[])
|
||||
native_trigger: external_id(char), workspace_id(char), service_name(native_trigger_service), script_path(char), is_flow(bool), webhook_token_hash(char), service_config(jsonb), error(text), created_at(ts), updated_at(ts)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
nats_trigger: path(char), nats_resource_path(char), subjects(char), stream_name(char), consumer_name(char), use_jetstream(bool), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
|
||||
nats_trigger: path(char), nats_resource_path(char), subjects(char), stream_name(char), consumer_name(char), use_jetstream(bool), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
notify_event: id(bigint), channel(text), payload(text), created_at(ts)
|
||||
otel_traces: trace_id(bytes), span_id(bytes), trace_state(text), parent_span_id(bytes), flags(int), name(text), kind(int), start_time_unix_nano(bigint), end_time_unix_nano(bigint), attributes(jsonb), dropped_attributes_count(int), events(jsonb), dropped_events_count(int), links(jsonb), dropped_links_count(int), status(jsonb)
|
||||
@@ -133,23 +133,23 @@ parallel_monitor_lock: parent_flow_id(uuid), job_id(uuid), last_ping(ts)
|
||||
password: email(char), password_hash(char), login_type(char), super_admin(bool), verified(bool), name(char), company(char), first_time_user(bool), username(char), devops(bool)
|
||||
pending_user: email(char), created_at(ts), username(char)
|
||||
pip_resolution_cache: hash(char), expiration(ts), lockfile(text)
|
||||
postgres_trigger: path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), postgres_resource_path(char), error(text), server_id(char), last_server_ping(ts), replication_slot_name(char), publication_name(char), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
|
||||
postgres_trigger: path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), postgres_resource_path(char), error(text), server_id(char), last_server_ping(ts), replication_slot_name(char), publication_name(char), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
raw_app: path(char), version(int), workspace_id(char), summary(char), edited_at(ts), data(text), extra_perms(jsonb)
|
||||
raw_app: path(char), version(int), workspace_id(char), summary(char), edited_at(ts), data(text), extra_perms(jsonb), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
resource: workspace_id(char), path(char), value(jsonb), description(text), resource_type(char), extra_perms(jsonb), edited_at(ts), created_by(char)
|
||||
resource: workspace_id(char), path(char), value(jsonb), description(text), resource_type(char), extra_perms(jsonb), edited_at(ts), created_by(char), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
resource_type: workspace_id(char), name(char), schema(jsonb), description(text), edited_at(ts), created_by(char), format_extension(char), is_fileset(bool)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
resume_job: id(uuid), job(uuid), flow(uuid), created_at(ts), value(jsonb), approver(char), resume_id(int), approved(bool)
|
||||
FK: (flow) -> v2_job_queue(id)
|
||||
runnable_settings: hash(bigint), debouncing_settings(bigint), concurrency_settings(bigint)
|
||||
schedule: workspace_id(char), path(char), edited_by(char), edited_at(ts), schedule(char), enabled(bool), script_path(char), args(jsonb), extra_perms(jsonb), is_flow(bool), email(char), error(text), timezone(char), on_failure(char), on_recovery(char), on_failure_times(int), on_failure_exact(bool), on_failure_extra_args(jsonb), on_recovery_times(int), on_recovery_extra_args(jsonb), ws_error_handler_muted(bool), retry(jsonb), summary(char), no_flow_overlap(bool), tag(char), paused_until(ts), on_success(char), on_success_extra_args(jsonb), cron_version(text), description(text), dynamic_skip(char)
|
||||
schedule: workspace_id(char), path(char), edited_by(char), edited_at(ts), schedule(char), enabled(bool), script_path(char), args(jsonb), extra_perms(jsonb), is_flow(bool), email(char), error(text), timezone(char), on_failure(char), on_recovery(char), on_failure_times(int), on_failure_exact(bool), on_failure_extra_args(jsonb), on_recovery_times(int), on_recovery_extra_args(jsonb), ws_error_handler_muted(bool), retry(jsonb), summary(char), no_flow_overlap(bool), tag(char), paused_until(ts), on_success(char), on_success_extra_args(jsonb), cron_version(text), description(text), dynamic_skip(char), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
script: workspace_id(char), hash(bigint), path(char), parent_hashes(bigint[]), summary(text), description(text), content(text), created_by(char), created_at(ts), archived(bool), schema(json), deleted(bool), is_template(bool), extra_perms(jsonb), lock(text), lock_error_logs(text), language(script_lang), kind(script_kind), tag(char), draft_only(bool), envs(char), concurrent_limit(int), concurrency_time_window_s(int), cache_ttl(int), dedicated_worker(bool), ws_error_handler_muted(bool), priority(smallint), timeout(int), delete_after_use(bool), restart_unless_cancelled(bool), concurrency_key(char), visible_to_runner_only(bool), auto_kind(varchar), codebase(char), has_preprocessor(bool), on_behalf_of_email(text), schema_validation(bool), assets(jsonb), debounce_key(char), debounce_delay_s(int), cache_ignore_s3_path(bool), runnable_settings_handle(bigint)
|
||||
script: workspace_id(char), hash(bigint), path(char), parent_hashes(bigint[]), summary(text), description(text), content(text), created_by(char), created_at(ts), archived(bool), schema(json), deleted(bool), is_template(bool), extra_perms(jsonb), lock(text), lock_error_logs(text), language(script_lang), kind(script_kind), tag(char), draft_only(bool), envs(char), concurrent_limit(int), concurrency_time_window_s(int), cache_ttl(int), dedicated_worker(bool), ws_error_handler_muted(bool), priority(smallint), timeout(int), delete_after_use(bool), restart_unless_cancelled(bool), concurrency_key(char), visible_to_runner_only(bool), auto_kind(varchar), codebase(char), has_preprocessor(bool), on_behalf_of_email(text), schema_validation(bool), assets(jsonb), debounce_key(char), debounce_delay_s(int), cache_ignore_s3_path(bool), runnable_settings_handle(bigint), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
skip_workspace_diff_tally: workspace_id(char), added_at(ts)
|
||||
sqs_trigger: path(char), queue_url(char), aws_resource_path(char), message_attributes(text[]), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), error(text), server_id(char), last_server_ping(ts), aws_auth_resource_type(aws_auth_resource_type), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
|
||||
sqs_trigger: path(char), queue_url(char), aws_resource_path(char), message_attributes(text[]), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), error(text), server_id(char), last_server_ping(ts), aws_auth_resource_type(aws_auth_resource_type), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
trashbin: id(bigint), workspace_id(char), item_kind(char), item_path(char), item_data(jsonb), deleted_by(char), deleted_at(ts), expires_at(ts)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
@@ -173,9 +173,9 @@ v2_job_runtime: id(uuid), ping(ts), memory_peak(int)
|
||||
FK: (id) -> v2_job_queue(id)
|
||||
v2_job_status: id(uuid), flow_status(jsonb), flow_leaf_jobs(jsonb), workflow_as_code_status(jsonb)
|
||||
FK: (id) -> v2_job_queue(id)
|
||||
variable: workspace_id(char), path(char), value(char), is_secret(bool), description(char), extra_perms(jsonb), account(int), is_oauth(bool), expires_at(ts)
|
||||
variable: workspace_id(char), path(char), value(char), is_secret(bool), description(char), extra_perms(jsonb), account(int), is_oauth(bool), expires_at(ts), labels(text[])
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
websocket_trigger: path(char), url(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), filters(jsonb[]), initial_messages(jsonb[]), url_runnable_args(jsonb), can_return_message(bool), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), can_return_error_result(bool), mode(trigger_mode)
|
||||
websocket_trigger: path(char), url(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), filters(jsonb[]), initial_messages(jsonb[]), url_runnable_args(jsonb), can_return_message(bool), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), can_return_error_result(bool), mode(trigger_mode), labels(text[])
|
||||
windmill_migrations: name(text), created_at(ts)
|
||||
worker_group_job_stats: hour(bigint), worker_group(text), script_lang(char), workspace_id(char), job_count(int), total_duration_ms(bigint)
|
||||
FK: (workspace_id) -> workspace(id)
|
||||
|
||||
@@ -429,6 +429,59 @@ export function main() {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_bun_job_syntax_error_unclosed_bracket(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
let port = server.addr.port();
|
||||
|
||||
// Reproduces the "Unexpected end of file at main.ts:0" error reported
|
||||
// when a TS file has a missing closing bracket — Bun's bundler gives no
|
||||
// useful location info.
|
||||
let content = r#"
|
||||
export async function main() {
|
||||
if (true) {
|
||||
return "hello";
|
||||
// missing closing bracket for the function
|
||||
"#
|
||||
.to_owned();
|
||||
|
||||
let job = JobPayload::Code(RawCode {
|
||||
hash: None,
|
||||
content,
|
||||
path: None,
|
||||
language: ScriptLang::Bun,
|
||||
lock: None,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
modules: None,
|
||||
});
|
||||
|
||||
let completed = run_job_in_new_worker_until_complete(&db, false, job, port).await;
|
||||
|
||||
assert!(!completed.success);
|
||||
let result = completed
|
||||
.result
|
||||
.as_ref()
|
||||
.and_then(|v| v.get("error"))
|
||||
.and_then(|v| v.get("message"))
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
assert!(
|
||||
result.contains("Unexpected end of file"),
|
||||
"should contain bun parser error, got: {result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("syntax error"),
|
||||
"should contain helpful hint about syntax errors, got: {result}"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Annotation Mode Tests
|
||||
// ============================================================================
|
||||
@@ -1013,8 +1066,8 @@ mod dedicated_worker_protocol {
|
||||
let mut results = Vec::new();
|
||||
|
||||
for job_args in jobs {
|
||||
// Protocol: exec:<script_path>:<json_args>
|
||||
writeln!(stdin, "exec:{}:{}", TEST_SCRIPT_PATH, job_args.to_string()).unwrap();
|
||||
// Protocol: execd:<json_args> (single-script, no path needed)
|
||||
writeln!(stdin, "execd:{}", job_args.to_string()).unwrap();
|
||||
stdin.flush().unwrap();
|
||||
|
||||
let mut response = String::new();
|
||||
@@ -1600,8 +1653,6 @@ mod dedicated_worker_protocol_deno {
|
||||
use windmill_test_utils::{parse_dedicated_worker_line, DedicatedWorkerResult};
|
||||
use windmill_worker::{generate_deno_dedicated_worker_wrapper, DENO_PATH};
|
||||
|
||||
const TEST_SCRIPT_PATH: &str = "f/test/script";
|
||||
|
||||
fn run_deno_worker_test(
|
||||
script: &str,
|
||||
jobs: Vec<serde_json::Value>,
|
||||
@@ -1651,7 +1702,7 @@ mod dedicated_worker_protocol_deno {
|
||||
|
||||
let mut results = Vec::new();
|
||||
for job_args in jobs {
|
||||
writeln!(stdin, "exec:{}:{}", TEST_SCRIPT_PATH, job_args.to_string()).unwrap();
|
||||
writeln!(stdin, "execd:{}", job_args.to_string()).unwrap();
|
||||
stdin.flush().unwrap();
|
||||
|
||||
loop {
|
||||
@@ -1772,7 +1823,13 @@ export function main(msg: string): never {
|
||||
let mut results = Vec::new();
|
||||
|
||||
for (cmd, args) in &commands {
|
||||
writeln!(stdin, "{}:{}:{}", cmd, TEST_SCRIPT_PATH, args).unwrap();
|
||||
// Single-script Deno wrapper uses execd:/execd_preprocess: (no path)
|
||||
let direct_cmd = if *cmd == "exec_preprocess" {
|
||||
"execd_preprocess"
|
||||
} else {
|
||||
"execd"
|
||||
};
|
||||
writeln!(stdin, "{}:{}", direct_cmd, args).unwrap();
|
||||
stdin.flush().unwrap();
|
||||
|
||||
let expected_lines = if *cmd == "exec_preprocess" { 2 } else { 1 };
|
||||
|
||||
1551
backend/tests/dedicated_workers.rs
Normal file
1551
backend/tests/dedicated_workers.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -450,6 +450,7 @@ def main():
|
||||
on_behalf_of_email: None,
|
||||
preserve_on_behalf_of: None,
|
||||
ws_error_handler_muted: None,
|
||||
labels: None,
|
||||
})
|
||||
.send()
|
||||
.await
|
||||
@@ -511,6 +512,7 @@ def main():
|
||||
deployment_message: None,
|
||||
custom_path: None,
|
||||
preserve_on_behalf_of: None,
|
||||
labels: None,
|
||||
})
|
||||
.send()
|
||||
.await
|
||||
|
||||
@@ -162,7 +162,7 @@ export async function main(path: string, email: string, job_id: string, is_flow:
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: ConcurrencySettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.run_until_complete(&db, false, server.addr.port())
|
||||
.await;
|
||||
@@ -285,7 +285,7 @@ async fn test_error_handler_muted_on_script(db: Pool<Postgres>) -> anyhow::Resul
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: ConcurrencySettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.run_until_complete(&db, false, server.addr.port())
|
||||
.await;
|
||||
@@ -380,7 +380,7 @@ async fn test_error_handler_not_triggered_on_success(db: Pool<Postgres>) -> anyh
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: ConcurrencySettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(),
|
||||
debouncing_settings: DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.run_until_complete(&db, false, server.addr.port())
|
||||
.await;
|
||||
|
||||
599
backend/tests/fixtures/dedicated_flows.sql
vendored
Normal file
599
backend/tests/fixtures/dedicated_flows.sql
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
-- Fixtures for dedicated worker E2E tests
|
||||
|
||||
-- A simple Bun script for testing dedicated Script steps in flows
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'export function main(x: number) { return x * 2; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/dedicated_double', 300001, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- Flow with a single RawScript inline bun step (the "Script not found" bug case)
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_rawscript_flow',
|
||||
'{3000000000000001}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 10; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000001,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_rawscript_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 10; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with a Script step referencing the external dedicated_double script
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_script_flow',
|
||||
'{3000000000000002}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'{"modules":[{"id":"a","value":{"type":"script","path":"f/system/dedicated_double","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000002,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_script_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'{"modules":[{"id":"a","value":{"type":"script","path":"f/system/dedicated_double","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with two inline RawScript steps (tests multi-step key uniqueness)
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_multi_step_flow',
|
||||
'{3000000000000003}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 1; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x * 3; }","language":"bun","input_transforms":{"x":{"expr":"results.a","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000003,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_multi_step_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 1; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x * 3; }","language":"bun","input_transforms":{"x":{"expr":"results.a","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Two scripts sharing a workspace dependency for runner group testing.
|
||||
-- Both reference the same external dep "f/system/dedicated_double" via extra_package_json annotation.
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'// extra_package_json: f/system/dedicated_double\nexport function main(x: number) { return x + 100; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/rg_script_a', 300010, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'// extra_package_json: f/system/dedicated_double\nexport function main(x: number) { return x + 200; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/rg_script_b', 300011, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- Flow with a Deno inline RawScript step
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_deno_flow',
|
||||
'{3000000000000005}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"deno","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000005,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_deno_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"deno","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with a Python inline RawScript step
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_python_flow',
|
||||
'{3000000000000006}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"def main(x: int):\\n return x + 100","language":"python3","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000006,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_python_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"def main(x: int):\\n return x + 100","language":"python3","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with a Bunnative (//native) inline RawScript step
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_bunnative_flow',
|
||||
'{3000000000000007}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"//native\\nexport function main(x: number) { return x + 100; }","language":"bunnative","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000007,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_bunnative_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"//native\\nexport function main(x: number) { return x + 100; }","language":"bunnative","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with a Bun + //nodejs annotation inline RawScript step
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_nodejs_flow',
|
||||
'{3000000000000008}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"//nodejs\\nexport function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000008,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_nodejs_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"//nodejs\\nexport function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow with a squashed for-loop for testing flow runners.
|
||||
-- The for-loop iterates over [1, 2, 3], each iteration runs a simple bun rawscript.
|
||||
-- squash=true triggers spawn_flow_module_runners to create dedicated subprocesses.
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_flow_runners',
|
||||
'{3000000000000004}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":true,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value * 10; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000004,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_flow_runners',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":true,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value * 10; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Two flows with conflicting step IDs (both have module "a") but different RawScript content.
|
||||
-- Tests that runnable_path-based lookup correctly disambiguates them.
|
||||
-- Flow A: x + 1000
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/conflict_flow_a',
|
||||
'{3000000000000009}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 1000; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000009,
|
||||
'test-workspace',
|
||||
'f/system/conflict_flow_a',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 1000; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- Flow B: x + 2000
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/conflict_flow_b',
|
||||
'{3000000000000010}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 2000; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000010,
|
||||
'test-workspace',
|
||||
'f/system/conflict_flow_b',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 2000; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- A dedicated worker script with a preprocessor function.
|
||||
-- preprocessor doubles x, main adds 100.
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'export function preprocessor(x: number) { return { x: x * 2 }; }\nexport function main(x: number) { return x + 100; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/preprocess_script', 300030, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- Second workspace for cross-workspace isolation testing.
|
||||
INSERT INTO workspace(id, name, owner) VALUES ('test-workspace-2', 'test-workspace-2', 'test-user');
|
||||
INSERT INTO usr(workspace_id, email, username, is_admin, role) VALUES
|
||||
('test-workspace-2', 'test@windmill.dev', 'test-user', true, 'Admin');
|
||||
INSERT INTO workspace_key(workspace_id, kind, key) VALUES
|
||||
('test-workspace-2', 'cloud', 'test-key-2');
|
||||
INSERT INTO workspace_settings (workspace_id) VALUES ('test-workspace-2');
|
||||
INSERT INTO group_ (workspace_id, name, summary, extra_perms) VALUES
|
||||
('test-workspace-2', 'all', 'All users', '{}');
|
||||
|
||||
-- Same path as dedicated_double but in workspace 2, returns x * 3 instead of x * 2.
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace-2',
|
||||
'system',
|
||||
E'export function main(x: number) { return x * 3; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/dedicated_double', 300040, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: flow Script step + standalone conflict
|
||||
-- Flow references dedicated_double (also configured as standalone).
|
||||
-- Standalone worker should handle both its own jobs and the flow's Script step jobs.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_conflict_standalone_flow',
|
||||
'{3000000000000011}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'{"modules":[{"id":"a","value":{"type":"script","path":"f/system/dedicated_double","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000011,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_conflict_standalone_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'{"modules":[{"id":"a","value":{"type":"script","path":"f/system/dedicated_double","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: non-dedicated step inside dedicated flow
|
||||
-- Flow with bun step (x + 10) then bash step (echo result * 2).
|
||||
-- The bun step runs on dedicated worker; bash falls back to normal execution.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_mixed_lang_flow',
|
||||
'{3000000000000012}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 10; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"b","value":{"type":"rawscript","content":"echo done","language":"bash","input_transforms":{"results_a":{"expr":"results.a","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000012,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_mixed_lang_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"rawscript","content":"export function main(x: number) { return x + 10; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"b","value":{"type":"rawscript","content":"echo done","language":"bash","input_transforms":{"results_a":{"expr":"results.a","type":"javascript"}}}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: non-dedicated step inside flow runners (squashed loop)
|
||||
-- Squashed for-loop with a bash step. Bash can't spawn a flow runner,
|
||||
-- so each iteration falls back to normal execution.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_flow_runners_bash',
|
||||
'{3000000000000013}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":true,"modules":[{"id":"b","value":{"type":"rawscript","content":"echo done","language":"bash","input_transforms":{"iter_value":{"expr":"flow_input.iter.value","type":"javascript"}}}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000013,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_flow_runners_bash',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":true,"modules":[{"id":"b","value":{"type":"rawscript","content":"echo done","language":"bash","input_transforms":{"iter_value":{"expr":"flow_input.iter.value","type":"javascript"}}}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Python runner group
|
||||
-- Two Python scripts sharing a workspace dependency annotation.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'# extra_requirements: f/system/dedicated_double\ndef main(x: int):\n return x + 100',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_rg_script_a', 300050, 'python3', '', true);
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'# extra_requirements: f/system/dedicated_double\ndef main(x: int):\n return x + 200',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_rg_script_b', 300051, 'python3', '', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: preprocessor in runner group
|
||||
-- Two bun scripts sharing a workspace dep, one has a preprocessor.
|
||||
-- Tests exec_preprocess:{path}:{args} protocol in runner groups.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'// extra_package_json: f/system/dedicated_double\nexport function preprocessor(x: number) { return { x: x * 2 }; }\nexport function main(x: number) { return x + 100; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/rg_preprocess_script', 300052, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'// extra_package_json: f/system/dedicated_double\nexport function main(x: number) { return x + 300; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/rg_preprocess_other', 300053, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: flow with BranchOne
|
||||
-- Flow with branchone: condition true → branch (x + 100), default → (x + 200).
|
||||
-- Tests recursive module traversal for spawning dedicated workers.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_branch_flow',
|
||||
'{3000000000000014}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"branchone","branches":[{"expr":"flow_input.x > 10","modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}],"default":[{"id":"c","value":{"type":"rawscript","content":"export function main(x: number) { return x + 200; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000014,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_branch_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"branchone","branches":[{"expr":"flow_input.x > 10","modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}],"default":[{"id":"c","value":{"type":"rawscript","content":"export function main(x: number) { return x + 200; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Python standalone preprocessor
|
||||
-- Python script with preprocessor function. Tests execd_preprocess: protocol.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'def preprocessor(x: int):\n return {"x": x * 2}\n\ndef main(x: int):\n return x + 100',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_preprocess_script', 300054, 'python3', '', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Deno standalone preprocessor
|
||||
-- Deno script with preprocessor function. Tests execd_preprocess: protocol.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'export function preprocessor(x: number) { return { x: x * 2 }; }\nexport function main(x: number) { return x + 100; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/deno_preprocess_script', 300055, 'deno', '', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Python runner group preprocessor
|
||||
-- Two Python scripts sharing a workspace dep, one has a preprocessor.
|
||||
-- Tests exec_preprocess:{path}:{args} protocol for Python runner groups.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'# extra_requirements: f/system/py_preprocess_script\ndef preprocessor(x: int):\n return {"x": x * 2}\n\ndef main(x: int):\n return x + 100',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_rg_preprocess_a', 300056, 'python3', '', true);
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'# extra_requirements: f/system/py_preprocess_script\ndef main(x: int):\n return x + 300',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_rg_preprocess_b', 300057, 'python3', '', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Bunnative standalone preprocessor
|
||||
-- Bunnative script with preprocessor function. Tests V8 isolate preprocessing.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'//native\nexport function preprocessor(x: number) { return { x: x * 2 }; }\nexport function main(x: number) { return x + 100; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/bunnative_preprocess_script', 300058, 'bunnative', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Bun dedicated worker with relative imports
|
||||
-- Helper script at f/system/dedicated_helper (returns x * 10).
|
||||
-- Dedicated script imports from it using a relative path.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'export function helper(x: number) { return x * 10; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/dedicated_helper', 300060, 'bun', E'{}\n//bun.lock\n<empty>');
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'import { helper } from "./dedicated_helper.ts";\n\nexport function main(x: number) { return helper(x) + 1; }',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/dedicated_with_import', 300061, 'bun', E'{}\n//bun.lock\n<empty>', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: Python dedicated worker with relative imports
|
||||
-- Helper script at f/system/py_dedicated_helper (returns x * 10).
|
||||
-- Dedicated script imports from it using a relative path.
|
||||
-- ============================================================
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'def helper(x: int):\n return x * 10',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_dedicated_helper', 300062, 'python3', '');
|
||||
|
||||
INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock, dedicated_worker) VALUES (
|
||||
'test-workspace',
|
||||
'system',
|
||||
E'from .py_dedicated_helper import helper\n\ndef main(x: int):\n return helper(x) + 1',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
'', '',
|
||||
'f/system/py_dedicated_with_import', 300063, 'python3', '', true);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: non-squashed for-loop in dedicated flow
|
||||
-- For-loop iterates over [1, 2, 3], inner bun step returns iter.value * 10.
|
||||
-- NOT squashed, so inner steps use the dedicated worker map (not flow runners).
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_forloop_flow',
|
||||
'{3000000000000015}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value * 10; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000015,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_forloop_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value * 10; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: non-simple for-loop in dedicated flow (multi-step)
|
||||
-- For-loop iterates over [1, 2, 3], two steps: step b (iter.value + 1), step c (results.b * 10).
|
||||
-- Two steps makes is_simple_modules false, so inner steps run as separate jobs.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_forloop_multi_step_flow',
|
||||
'{3000000000000019}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value + 1; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"c","value":{"type":"rawscript","content":"export function main(prev: number) { return prev * 10; }","language":"bun","input_transforms":{"prev":{"expr":"results.b","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000019,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_forloop_multi_step_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2, 3]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(iter: {value: number, index: number}) { return iter.value + 1; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}},{"id":"c","value":{"type":"rawscript","content":"export function main(prev: number) { return prev * 10; }","language":"bun","input_transforms":{"prev":{"expr":"results.b","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: while-loop in dedicated flow
|
||||
-- While-loop with an inner bun step that returns x + 1.
|
||||
-- Early stop breaks when result >= 3.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_whileloop_flow',
|
||||
'{3000000000000016}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"whileloopflow","skip_failures":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(n: number) { return n + 1; }","language":"bun","input_transforms":{"n":{"expr":"results.b ?? flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"},"stop_after_if":{"expr":"result >= 3","skip_if_stopped":false}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000016,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_whileloop_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"whileloopflow","skip_failures":false,"squash":false,"modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(n: number) { return n + 1; }","language":"bun","input_transforms":{"n":{"expr":"results.b ?? flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"},"stop_after_if":{"expr":"result >= 3","skip_if_stopped":false}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: branchall in dedicated flow
|
||||
-- BranchAll with 2 parallel branches, each with a bun step.
|
||||
-- Branch 0: x + 100, Branch 1: x + 200.
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_branchall_flow',
|
||||
'{3000000000000017}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"branchall","parallel":true,"branches":[{"expr":"true","modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]},{"expr":"true","modules":[{"id":"c","value":{"type":"rawscript","content":"export function main(x: number) { return x + 200; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000017,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_branchall_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"x":{"type":"number","description":""}},"required":["x"],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"branchall","parallel":true,"branches":[{"expr":"true","modules":[{"id":"b","value":{"type":"rawscript","content":"export function main(x: number) { return x + 100; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]},{"expr":"true","modules":[{"id":"c","value":{"type":"rawscript","content":"export function main(x: number) { return x + 200; }","language":"bun","input_transforms":{"x":{"expr":"flow_input.x","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Test: nested branch inside loop in dedicated flow
|
||||
-- For-loop [1,2] with inner branchone: if iter.value > 1 → x + 100, else → x + 200.
|
||||
-- Tests deeply nested dispatch (forloop-N/branchone-0/step_id).
|
||||
-- ============================================================
|
||||
INSERT INTO public.flow(workspace_id, summary, description, path, versions, schema, value, edited_by) VALUES (
|
||||
'test-workspace', '', '',
|
||||
'f/system/dedicated_nested_flow',
|
||||
'{3000000000000018}',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"branchone","branches":[{"expr":"flow_input.iter.value > 1","modules":[{"id":"c","value":{"type":"rawscript","content":"export function main(iter: {value: number}) { return iter.value + 100; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}],"default":[{"id":"d","value":{"type":"rawscript","content":"export function main(iter: {value: number}) { return iter.value + 200; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
INSERT INTO public.flow_version(id, workspace_id, path, schema, value, created_by) VALUES (
|
||||
3000000000000018,
|
||||
'test-workspace',
|
||||
'f/system/dedicated_nested_flow',
|
||||
'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}',
|
||||
E'{"modules":[{"id":"a","value":{"type":"forloopflow","iterator":{"type":"javascript","expr":"[1, 2]"},"skip_failures":false,"parallel":false,"squash":false,"modules":[{"id":"b","value":{"type":"branchone","branches":[{"expr":"flow_input.iter.value > 1","modules":[{"id":"c","value":{"type":"rawscript","content":"export function main(iter: {value: number}) { return iter.value + 100; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}],"default":[{"id":"d","value":{"type":"rawscript","content":"export function main(iter: {value: number}) { return iter.value + 200; }","language":"bun","input_transforms":{"iter":{"expr":"flow_input.iter","type":"javascript"}},"lock":"{}\\n//bun.lock\\n<empty>"}}]}}]}}]}',
|
||||
'system'
|
||||
);
|
||||
|
||||
@@ -240,7 +240,10 @@ async fn test_from_db_worker_config_prefix_stripping(db: Pool<Postgres>) {
|
||||
config.worker_configs.contains_key("my_group_name"),
|
||||
"worker__ prefix should be stripped"
|
||||
);
|
||||
assert_eq!(config.worker_configs["my_group_name"].extra["cache_clear"], serde_json::json!(5));
|
||||
assert_eq!(
|
||||
config.worker_configs["my_group_name"].extra["cache_clear"],
|
||||
serde_json::json!(5)
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
@@ -400,12 +403,11 @@ async fn test_apply_settings_diff_complex_json(db: Pool<Postgres>) {
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_apply_settings_diff_delete_nonexistent_is_noop(db: Pool<Postgres>) {
|
||||
let diff =
|
||||
SettingsDiff {
|
||||
upserts: BTreeMap::new(),
|
||||
deletes: vec!["does_not_exist".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
let diff = SettingsDiff {
|
||||
upserts: BTreeMap::new(),
|
||||
deletes: vec!["does_not_exist".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Should not error
|
||||
apply_settings_diff(&db, &diff).await.unwrap();
|
||||
@@ -657,11 +659,8 @@ async fn test_roundtrip_to_settings_map_from_db_consistency(db: Pool<Postgres>)
|
||||
};
|
||||
|
||||
let map = original.to_settings_map();
|
||||
let diff = SettingsDiff {
|
||||
upserts: map.into_iter().collect(),
|
||||
deletes: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
let diff =
|
||||
SettingsDiff { upserts: map.into_iter().collect(), deletes: vec![], ..Default::default() };
|
||||
|
||||
apply_settings_diff(&db, &diff).await.unwrap();
|
||||
|
||||
@@ -866,7 +865,10 @@ async fn test_full_config_roundtrip(db: Pool<Postgres>) {
|
||||
assert_eq!(otel.tracing_enabled, Some(true));
|
||||
|
||||
assert_eq!(config.worker_configs.len(), 2);
|
||||
assert_eq!(config.worker_configs["default"].extra["cache_clear"], serde_json::json!(7));
|
||||
assert_eq!(
|
||||
config.worker_configs["default"].extra["cache_clear"],
|
||||
serde_json::json!(7)
|
||||
);
|
||||
let gpu_auto = config.worker_configs["gpu"].autoscaling.as_ref().unwrap();
|
||||
assert!(gpu_auto.enabled);
|
||||
assert_eq!(gpu_auto.min_workers, Some(0));
|
||||
@@ -1006,3 +1008,146 @@ async fn test_replace_mode_protects_settings_in_integration(db: Pool<Postgres>)
|
||||
Some(serde_json::json!("yes"))
|
||||
);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// jwt_secret and rsa_keys declarative roundtrip
|
||||
// ========================================================================
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_jwt_secret_roundtrip_as_string_or_secret_ref(db: Pool<Postgres>) {
|
||||
clear_settings_and_configs(&db).await;
|
||||
|
||||
// Simulate what the operator does: parse a GlobalSettings with jwt_secret
|
||||
// as a resolved StringOrSecretRef::Literal, write to DB, read back.
|
||||
let settings = windmill_common::instance_config::GlobalSettings {
|
||||
jwt_secret: Some(
|
||||
windmill_common::instance_config::StringOrSecretRef::Literal(
|
||||
"my-jwt-secret-from-k8s".to_string(),
|
||||
),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let map = settings.to_settings_map();
|
||||
|
||||
// The serialized form should be a plain JSON string (not an object)
|
||||
assert_eq!(
|
||||
map["jwt_secret"],
|
||||
serde_json::json!("my-jwt-secret-from-k8s")
|
||||
);
|
||||
|
||||
let diff =
|
||||
SettingsDiff { upserts: map.into_iter().collect(), deletes: vec![], ..Default::default() };
|
||||
apply_settings_diff(&db, &diff).await.unwrap();
|
||||
|
||||
// Read back from DB — jwt_secret should survive the roundtrip
|
||||
let config = InstanceConfig::from_db(&db).await.unwrap();
|
||||
assert_eq!(
|
||||
config
|
||||
.global_settings
|
||||
.jwt_secret
|
||||
.as_ref()
|
||||
.and_then(|v| v.as_literal()),
|
||||
Some("my-jwt-secret-from-k8s")
|
||||
);
|
||||
|
||||
// Verify the raw DB value is a plain string (not wrapped in an object)
|
||||
let raw = get_global_setting(&db, "jwt_secret").await.unwrap();
|
||||
assert!(
|
||||
raw.is_string(),
|
||||
"jwt_secret in DB should be a plain JSON string"
|
||||
);
|
||||
assert_eq!(raw.as_str().unwrap(), "my-jwt-secret-from-k8s");
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_rsa_keys_roundtrip_via_extra(db: Pool<Postgres>) {
|
||||
clear_settings_and_configs(&db).await;
|
||||
|
||||
// rsa_keys is not a typed field — it flows through GlobalSettings.extra.
|
||||
// Simulate a resolved secretKeyRef: the operator resolves the ref and
|
||||
// writes the plain value to extra before syncing to DB.
|
||||
let json_str = r#"{
|
||||
"rsa_keys": {
|
||||
"private_key": "-----BEGIN RSA PRIVATE KEY-----\ntest-key-data\n-----END RSA PRIVATE KEY-----"
|
||||
}
|
||||
}"#;
|
||||
let settings: windmill_common::instance_config::GlobalSettings =
|
||||
serde_json::from_str(json_str).unwrap();
|
||||
|
||||
// rsa_keys should land in extra
|
||||
assert!(settings.extra.contains_key("rsa_keys"));
|
||||
|
||||
let map = settings.to_settings_map();
|
||||
let diff =
|
||||
SettingsDiff { upserts: map.into_iter().collect(), deletes: vec![], ..Default::default() };
|
||||
apply_settings_diff(&db, &diff).await.unwrap();
|
||||
|
||||
// Read back from DB
|
||||
let config = InstanceConfig::from_db(&db).await.unwrap();
|
||||
assert_eq!(
|
||||
config.global_settings.extra["rsa_keys"]["private_key"],
|
||||
"-----BEGIN RSA PRIVATE KEY-----\ntest-key-data\n-----END RSA PRIVATE KEY-----"
|
||||
);
|
||||
|
||||
// Verify the raw DB value is a JSON object with private_key
|
||||
let raw = get_global_setting(&db, "rsa_keys").await.unwrap();
|
||||
assert!(raw.is_object());
|
||||
assert_eq!(
|
||||
raw["private_key"].as_str().unwrap(),
|
||||
"-----BEGIN RSA PRIVATE KEY-----\ntest-key-data\n-----END RSA PRIVATE KEY-----"
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_replace_mode_protects_jwt_secret_and_rsa_keys(db: Pool<Postgres>) {
|
||||
clear_settings_and_configs(&db).await;
|
||||
|
||||
// Seed jwt_secret and rsa_keys (both are PROTECTED_SETTINGS)
|
||||
insert_global_setting(&db, "jwt_secret", serde_json::json!("existing-secret")).await;
|
||||
insert_global_setting(
|
||||
&db,
|
||||
"rsa_keys",
|
||||
serde_json::json!({"private_key": "existing-rsa-key"}),
|
||||
)
|
||||
.await;
|
||||
insert_global_setting(&db, "normal_setting", serde_json::json!("will-go")).await;
|
||||
|
||||
let config = InstanceConfig::from_db(&db).await.unwrap();
|
||||
let current_map = config.global_settings.to_settings_map();
|
||||
|
||||
// Desired state: only base_url — jwt_secret and rsa_keys should survive
|
||||
let mut desired_map = BTreeMap::new();
|
||||
desired_map.insert(
|
||||
"base_url".to_string(),
|
||||
serde_json::json!("https://example.com"),
|
||||
);
|
||||
|
||||
let diff = diff_global_settings(¤t_map, &desired_map, ApplyMode::Replace);
|
||||
|
||||
assert!(
|
||||
!diff.deletes.contains(&"jwt_secret".to_string()),
|
||||
"jwt_secret is protected from deletion"
|
||||
);
|
||||
assert!(
|
||||
!diff.deletes.contains(&"rsa_keys".to_string()),
|
||||
"rsa_keys is protected from deletion"
|
||||
);
|
||||
assert!(
|
||||
diff.deletes.contains(&"normal_setting".to_string()),
|
||||
"normal_setting should be deleted"
|
||||
);
|
||||
|
||||
apply_settings_diff(&db, &diff).await.unwrap();
|
||||
|
||||
// Both protected settings survive
|
||||
assert_eq!(
|
||||
get_global_setting(&db, "jwt_secret").await,
|
||||
Some(serde_json::json!("existing-secret"))
|
||||
);
|
||||
assert_eq!(
|
||||
get_global_setting(&db, "rsa_keys").await,
|
||||
Some(serde_json::json!({"private_key": "existing-rsa-key"}))
|
||||
);
|
||||
assert!(get_global_setting(&db, "normal_setting").await.is_none());
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
@@ -89,7 +89,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.run_until_complete_with(db, false, port, |id| async move {
|
||||
let job = sqlx::query!("SELECT preprocessed FROM v2_job WHERE id = $1", id)
|
||||
@@ -424,7 +424,7 @@ mod job_payload {
|
||||
path: "f/system/hello_with_nodes_flow".to_string(),
|
||||
dedicated_worker: None,
|
||||
apply_preprocessor: false,
|
||||
version: 1443253234253454,
|
||||
version: 1443253234253454, labels: None,
|
||||
})
|
||||
.run_until_complete(&db, false, port)
|
||||
.await
|
||||
@@ -473,7 +473,7 @@ mod job_payload {
|
||||
path: "f/system/hello_with_preprocessor".to_string(),
|
||||
dedicated_worker: None,
|
||||
apply_preprocessor: true,
|
||||
version: 1443253234253456,
|
||||
version: 1443253234253456, labels: None,
|
||||
})
|
||||
.run_until_complete_with(db, false, port, |id| async move {
|
||||
let job = sqlx::query!("SELECT preprocessed FROM v2_job WHERE id = $1", id)
|
||||
@@ -543,7 +543,7 @@ mod job_payload {
|
||||
path: "f/system/hello_with_nodes_flow".to_string(),
|
||||
dedicated_worker: None,
|
||||
apply_preprocessor: true,
|
||||
version: 1443253234253454,
|
||||
version: 1443253234253454, labels: None,
|
||||
})
|
||||
.run_until_complete(&db, false, port)
|
||||
.await
|
||||
@@ -789,7 +789,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.arg("foo", json!("hello"))
|
||||
.arg("bar", json!("world"))
|
||||
@@ -839,7 +839,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.arg("foo", json!("hello"))
|
||||
.arg("bar", json!("world"))
|
||||
@@ -889,7 +889,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.arg("foo", json!("hello"))
|
||||
.arg("bar", json!("world"))
|
||||
@@ -939,7 +939,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.arg("foo", json!("hello"))
|
||||
.arg("bar", json!("world"))
|
||||
@@ -991,7 +991,7 @@ mod job_payload {
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default(),
|
||||
debouncing_settings:
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
windmill_common::runnable_settings::DebouncingSettings::default(), labels: None,
|
||||
})
|
||||
.arg("foo", json!("hello"))
|
||||
.arg("bar", json!("world"))
|
||||
|
||||
@@ -64,8 +64,8 @@ async fn test_list_jobs_without_include_args(db: Pool<Postgres>) -> anyhow::Resu
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -121,8 +121,8 @@ async fn test_list_jobs_with_include_args(db: Pool<Postgres>) -> anyhow::Result<
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -192,8 +192,8 @@ async fn test_list_jobs_completed_with_include_args(db: Pool<Postgres>) -> anyho
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -265,8 +265,8 @@ async fn test_list_jobs_mixed_queue_and_completed(db: Pool<Postgres>) -> anyhow:
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -286,8 +286,8 @@ async fn test_list_jobs_mixed_queue_and_completed(db: Pool<Postgres>) -> anyhow:
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -349,7 +349,9 @@ async fn test_list_jobs_mixed_queue_and_completed(db: Pool<Postgres>) -> anyhow:
|
||||
|
||||
/// Test list_jobs with multiple queued jobs and include_args
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_list_jobs_multiple_queued_with_include_args(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
async fn test_list_jobs_multiple_queued_with_include_args(
|
||||
db: Pool<Postgres>,
|
||||
) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
@@ -369,8 +371,8 @@ async fn test_list_jobs_multiple_queued_with_include_args(db: Pool<Postgres>) ->
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -387,8 +389,8 @@ async fn test_list_jobs_multiple_queued_with_include_args(db: Pool<Postgres>) ->
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -411,9 +413,13 @@ async fn test_list_jobs_multiple_queued_with_include_args(db: Pool<Postgres>) ->
|
||||
let jobs: Vec<ListJobsResponse> = response.json().await?;
|
||||
|
||||
// Find both jobs
|
||||
let job1 = jobs.iter().find(|j| j.id == job1_id.to_string())
|
||||
let job1 = jobs
|
||||
.iter()
|
||||
.find(|j| j.id == job1_id.to_string())
|
||||
.expect("should find job1");
|
||||
let job2 = jobs.iter().find(|j| j.id == job2_id.to_string())
|
||||
let job2 = jobs
|
||||
.iter()
|
||||
.find(|j| j.id == job2_id.to_string())
|
||||
.expect("should find job2");
|
||||
|
||||
// Both should have args
|
||||
@@ -461,8 +467,8 @@ async fn test_queue_list_without_include_args(db: Pool<Postgres>) -> anyhow::Res
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -480,10 +486,7 @@ async fn test_queue_list_without_include_args(db: Pool<Postgres>) -> anyhow::Res
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
response.status().is_success(),
|
||||
"queue/list should succeed"
|
||||
);
|
||||
assert!(response.status().is_success(), "queue/list should succeed");
|
||||
|
||||
let jobs: Vec<QueueJobResponse> = response.json().await?;
|
||||
|
||||
@@ -524,8 +527,8 @@ async fn test_queue_list_with_include_args(db: Pool<Postgres>) -> anyhow::Result
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -594,8 +597,8 @@ async fn test_queue_list_multiple_jobs_with_include_args(db: Pool<Postgres>) ->
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -612,8 +615,8 @@ async fn test_queue_list_multiple_jobs_with_include_args(db: Pool<Postgres>) ->
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -631,10 +634,7 @@ async fn test_queue_list_multiple_jobs_with_include_args(db: Pool<Postgres>) ->
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
response.status().is_success(),
|
||||
"queue/list should succeed"
|
||||
);
|
||||
assert!(response.status().is_success(), "queue/list should succeed");
|
||||
|
||||
let jobs: Vec<QueueJobResponse> = response.json().await?;
|
||||
|
||||
@@ -694,8 +694,8 @@ async fn test_completed_list_without_include_args(db: Pool<Postgres>) -> anyhow:
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -760,8 +760,8 @@ async fn test_completed_list_with_include_args(db: Pool<Postgres>) -> anyhow::Re
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -835,8 +835,8 @@ async fn test_completed_list_multiple_jobs_with_include_args(
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -856,8 +856,8 @@ async fn test_completed_list_multiple_jobs_with_include_args(
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings:
|
||||
windmill_common::runnable_settings::ConcurrencySettings::default().into(),
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
@@ -912,3 +912,273 @@ async fn test_completed_list_multiple_jobs_with_include_args(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Labels integration tests
|
||||
// =============================================================================
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_job_labels_propagated_at_push_time(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
let port = server.addr.port();
|
||||
let client = windmill_api_client::create_client(
|
||||
&format!("http://localhost:{port}"),
|
||||
"SECRET_TOKEN".to_string(),
|
||||
);
|
||||
|
||||
// Push a script job with labels
|
||||
let job_id = RunJob::from(JobPayload::ScriptHash {
|
||||
hash: windmill_common::scripts::ScriptHash(0),
|
||||
path: "u/admin/test_labels_script".to_string(),
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
language: ScriptLang::Python3,
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
labels: Some(vec!["prod".to_string(), "deploy".to_string()]),
|
||||
})
|
||||
.push(&db)
|
||||
.await;
|
||||
|
||||
// Verify labels in queue listing
|
||||
let response = client
|
||||
.client()
|
||||
.get(format!("{}/w/test-workspace/jobs/list", client.baseurl()))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(response.status().is_success());
|
||||
let jobs: Vec<serde_json::Value> = response.json().await?;
|
||||
let job = jobs
|
||||
.iter()
|
||||
.find(|j| j["id"].as_str() == Some(&job_id.to_string()))
|
||||
.expect("should find job");
|
||||
|
||||
let labels = job["labels"].as_array().expect("labels should be an array");
|
||||
assert!(labels.contains(&json!("prod")));
|
||||
assert!(labels.contains(&json!("deploy")));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_job_without_labels_has_no_labels_field(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
let port = server.addr.port();
|
||||
let client = windmill_api_client::create_client(
|
||||
&format!("http://localhost:{port}"),
|
||||
"SECRET_TOKEN".to_string(),
|
||||
);
|
||||
|
||||
// Push a job without labels
|
||||
let job_id = RunJob::from(JobPayload::Code(RawCode {
|
||||
hash: None,
|
||||
content: "def main(): return 1".to_string(),
|
||||
path: None,
|
||||
language: ScriptLang::Python3,
|
||||
lock: None,
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}))
|
||||
.push(&db)
|
||||
.await;
|
||||
|
||||
let response = client
|
||||
.client()
|
||||
.get(format!("{}/w/test-workspace/jobs/list", client.baseurl()))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(response.status().is_success());
|
||||
let jobs: Vec<serde_json::Value> = response.json().await?;
|
||||
let job = jobs
|
||||
.iter()
|
||||
.find(|j| j["id"].as_str() == Some(&job_id.to_string()))
|
||||
.expect("should find job");
|
||||
|
||||
// Labels should be null/missing for jobs without labels
|
||||
assert!(
|
||||
job.get("labels").is_none() || job["labels"].is_null(),
|
||||
"job without labels should not have labels field"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_job_label_filter(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
let port = server.addr.port();
|
||||
let client = windmill_api_client::create_client(
|
||||
&format!("http://localhost:{port}"),
|
||||
"SECRET_TOKEN".to_string(),
|
||||
);
|
||||
|
||||
// Push two jobs with different labels, then complete them via SQL
|
||||
// Label filtering only works on completed jobs
|
||||
let job_prod_id = RunJob::from(JobPayload::ScriptHash {
|
||||
hash: windmill_common::scripts::ScriptHash(0),
|
||||
path: "u/admin/prod_script".to_string(),
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
language: ScriptLang::Bun,
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
labels: Some(vec!["prod".to_string()]),
|
||||
})
|
||||
.push(&db)
|
||||
.await;
|
||||
|
||||
let job_staging_id = RunJob::from(JobPayload::ScriptHash {
|
||||
hash: windmill_common::scripts::ScriptHash(0),
|
||||
path: "u/admin/staging_script".to_string(),
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
language: ScriptLang::Bun,
|
||||
priority: None,
|
||||
apply_preprocessor: false,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
labels: Some(vec!["staging".to_string()]),
|
||||
})
|
||||
.push(&db)
|
||||
.await;
|
||||
|
||||
// Complete both jobs directly via SQL so label filter can find them
|
||||
for job_id in &[job_prod_id, job_staging_id] {
|
||||
sqlx::query(
|
||||
"INSERT INTO v2_job_completed (workspace_id, id, result, status, duration_ms) VALUES ('test-workspace', $1, '{}'::jsonb, 'success', 0)",
|
||||
)
|
||||
.bind(job_id)
|
||||
.execute(&db)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Filter by label=prod
|
||||
let response = client
|
||||
.client()
|
||||
.get(format!(
|
||||
"{}/w/test-workspace/jobs/list?label=prod",
|
||||
client.baseurl()
|
||||
))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(response.status().is_success());
|
||||
let jobs: Vec<serde_json::Value> = response.json().await?;
|
||||
|
||||
// Should find the prod job
|
||||
assert!(
|
||||
jobs.iter()
|
||||
.any(|j| j["id"].as_str() == Some(&job_prod_id.to_string())),
|
||||
"prod job should appear in label=prod filter"
|
||||
);
|
||||
|
||||
// Should NOT find the staging job
|
||||
assert!(
|
||||
!jobs
|
||||
.iter()
|
||||
.any(|j| j["id"].as_str() == Some(&job_staging_id.to_string())),
|
||||
"staging job should not appear in label=prod filter"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_wm_labels_from_result_merged_with_static_labels(
|
||||
db: Pool<Postgres>,
|
||||
) -> anyhow::Result<()> {
|
||||
initialize_tracing().await;
|
||||
|
||||
let server = ApiServer::start(db.clone()).await?;
|
||||
let port = server.addr.port();
|
||||
let client = windmill_api_client::create_client(
|
||||
&format!("http://localhost:{port}"),
|
||||
"SECRET_TOKEN".to_string(),
|
||||
);
|
||||
|
||||
// Use Code(RawCode) to run a Bun script that returns wm_labels,
|
||||
// then set static labels on the job row before execution
|
||||
let job = RunJob::from(JobPayload::Code(RawCode {
|
||||
hash: None,
|
||||
content: r#"export async function main() { return { wm_labels: ["runtime-label"] }; }"#
|
||||
.to_string(),
|
||||
path: None,
|
||||
language: ScriptLang::Bun,
|
||||
lock: None,
|
||||
cache_ttl: None,
|
||||
cache_ignore_s3_path: None,
|
||||
dedicated_worker: None,
|
||||
concurrency_settings: windmill_common::runnable_settings::ConcurrencySettings::default()
|
||||
.into(),
|
||||
debouncing_settings: windmill_common::runnable_settings::DebouncingSettings::default(),
|
||||
modules: None,
|
||||
}));
|
||||
|
||||
let completed = job
|
||||
.run_until_complete_with(&db, false, port, |uuid| {
|
||||
let db = db.clone();
|
||||
async move {
|
||||
// Set static labels before the worker picks up the job
|
||||
sqlx::query(
|
||||
"UPDATE v2_job SET labels = ARRAY['static-label']::text[] WHERE id = $1",
|
||||
)
|
||||
.bind(uuid)
|
||||
.execute(&db)
|
||||
.await
|
||||
.expect("should set labels");
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
// Fetch the job via API and check labels
|
||||
let response = client
|
||||
.client()
|
||||
.get(format!(
|
||||
"{}/w/test-workspace/jobs_u/get/{}",
|
||||
client.baseurl(),
|
||||
completed.id
|
||||
))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert!(response.status().is_success());
|
||||
let job: serde_json::Value = response.json().await?;
|
||||
let labels = job["labels"].as_array().expect("labels should be an array");
|
||||
|
||||
// Should contain both the static label and runtime label from wm_labels
|
||||
assert!(
|
||||
labels.contains(&json!("static-label")),
|
||||
"should contain static label set at push time, got: {:?}",
|
||||
labels
|
||||
);
|
||||
assert!(
|
||||
labels.contains(&json!("runtime-label")),
|
||||
"should contain runtime label from wm_labels in result, got: {:?}",
|
||||
labels
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -445,4 +445,89 @@ mod tests {
|
||||
Some(serde_json::json!("value"))
|
||||
);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// jwt_secret and rsa_keys via sync_global_settings
|
||||
// ========================================================================
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_sync_jwt_secret_via_settings_map(db: Pool<Postgres>) {
|
||||
// Simulate the full operator pipeline: parse GlobalSettings with a
|
||||
// resolved jwt_secret (StringOrSecretRef::Literal), convert to
|
||||
// settings map, and sync to DB.
|
||||
let settings = windmill_common::instance_config::GlobalSettings {
|
||||
jwt_secret: Some(
|
||||
windmill_common::instance_config::StringOrSecretRef::Literal(
|
||||
"resolved-jwt-value".to_string(),
|
||||
),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let map = settings.to_settings_map();
|
||||
windmill_operator::db_sync::sync_global_settings(&db, &map)
|
||||
.await
|
||||
.expect("sync should succeed");
|
||||
|
||||
let stored = get_global_setting(&db, "jwt_secret")
|
||||
.await
|
||||
.expect("jwt_secret should exist");
|
||||
assert_eq!(stored, serde_json::json!("resolved-jwt-value"));
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_sync_rsa_keys_via_settings_map(db: Pool<Postgres>) {
|
||||
// rsa_keys flows through GlobalSettings.extra as opaque JSON.
|
||||
// After operator resolves secretKeyRef, the value is a plain JSON
|
||||
// object that gets synced to DB.
|
||||
let json_str = r#"{
|
||||
"rsa_keys": {
|
||||
"private_key": "-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----"
|
||||
}
|
||||
}"#;
|
||||
let settings: windmill_common::instance_config::GlobalSettings =
|
||||
serde_json::from_str(json_str).unwrap();
|
||||
|
||||
let map = settings.to_settings_map();
|
||||
windmill_operator::db_sync::sync_global_settings(&db, &map)
|
||||
.await
|
||||
.expect("sync should succeed");
|
||||
|
||||
let stored = get_global_setting(&db, "rsa_keys")
|
||||
.await
|
||||
.expect("rsa_keys should exist");
|
||||
assert_eq!(
|
||||
stored["private_key"],
|
||||
"-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----"
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base"))]
|
||||
async fn test_sync_protects_jwt_secret_and_rsa_keys(db: Pool<Postgres>) {
|
||||
// Pre-populate both protected settings
|
||||
insert_global_setting(&db, "jwt_secret", serde_json::json!("original-jwt")).await;
|
||||
insert_global_setting(
|
||||
&db,
|
||||
"rsa_keys",
|
||||
serde_json::json!({"private_key": "original-rsa"}),
|
||||
)
|
||||
.await;
|
||||
|
||||
// Sync with empty desired — protected keys should survive
|
||||
let desired = BTreeMap::new();
|
||||
windmill_operator::db_sync::sync_global_settings(&db, &desired)
|
||||
.await
|
||||
.expect("sync should succeed");
|
||||
|
||||
assert_eq!(
|
||||
get_global_setting(&db, "jwt_secret").await,
|
||||
Some(serde_json::json!("original-jwt")),
|
||||
"jwt_secret is protected and should survive empty sync"
|
||||
);
|
||||
assert_eq!(
|
||||
get_global_setting(&db, "rsa_keys").await,
|
||||
Some(serde_json::json!({"private_key": "original-rsa"})),
|
||||
"rsa_keys is protected and should survive empty sync"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,6 +227,8 @@ mod dedicated_worker_protocol_python {
|
||||
enum ProtocolCmd {
|
||||
Exec { path: String, args: serde_json::Value },
|
||||
ExecPreprocess { path: String, args: serde_json::Value },
|
||||
Execd { args: serde_json::Value },
|
||||
ExecdPreprocess { args: serde_json::Value },
|
||||
}
|
||||
|
||||
/// Run a Python worker test with raw protocol commands
|
||||
@@ -265,13 +267,15 @@ mod dedicated_worker_protocol_python {
|
||||
ProtocolCmd::ExecPreprocess { path, args } => {
|
||||
format!("exec_preprocess:{}:{}", path, args)
|
||||
}
|
||||
ProtocolCmd::Execd { args } => format!("execd:{}", args),
|
||||
ProtocolCmd::ExecdPreprocess { args } => format!("execd_preprocess:{}", args),
|
||||
};
|
||||
writeln!(stdin, "{}", line).unwrap();
|
||||
stdin.flush().unwrap();
|
||||
|
||||
let expected_lines = match cmd {
|
||||
ProtocolCmd::ExecPreprocess { .. } => 2,
|
||||
ProtocolCmd::Exec { .. } => 1,
|
||||
ProtocolCmd::ExecPreprocess { .. } | ProtocolCmd::ExecdPreprocess { .. } => 2,
|
||||
ProtocolCmd::Exec { .. } | ProtocolCmd::Execd { .. } => 1,
|
||||
};
|
||||
|
||||
for _ in 0..expected_lines {
|
||||
@@ -374,6 +378,93 @@ def main(x: int):
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== execd / execd_preprocess Tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_python_execd_single_script() {
|
||||
let results = run_py_raw_protocol_test(
|
||||
&[(
|
||||
"f/test/add",
|
||||
"def main(a: int, b: int):\n return a + b\n",
|
||||
)],
|
||||
vec![ProtocolCmd::Execd { args: serde_json::json!({"a": 3, "b": 4}) }],
|
||||
);
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(
|
||||
results[0],
|
||||
DedicatedWorkerResult::Success(serde_json::json!(7))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_python_execd_preprocess() {
|
||||
let script = r#"
|
||||
def preprocessor(x: int):
|
||||
return {"x": x * 10}
|
||||
|
||||
def main(x: int):
|
||||
return x + 1
|
||||
"#;
|
||||
let results = run_py_raw_protocol_test(
|
||||
&[("f/test/pre", script)],
|
||||
vec![ProtocolCmd::ExecdPreprocess { args: serde_json::json!({"x": 5}) }],
|
||||
);
|
||||
assert_eq!(results.len(), 2);
|
||||
assert_eq!(
|
||||
results[0],
|
||||
DedicatedWorkerResult::PreprocessedArgs(serde_json::json!({"x": 50}))
|
||||
);
|
||||
// main(50) => 51
|
||||
assert_eq!(
|
||||
results[1],
|
||||
DedicatedWorkerResult::Success(serde_json::json!(51))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_python_execd_preprocess_missing_preprocessor() {
|
||||
let script = "def main(x: int):\n return x\n";
|
||||
let results = run_py_raw_protocol_test(
|
||||
&[("f/test/nopre", script)],
|
||||
vec![ProtocolCmd::ExecdPreprocess { args: serde_json::json!({"x": 5}) }],
|
||||
);
|
||||
assert_eq!(results.len(), 1);
|
||||
assert!(matches!(results[0], DedicatedWorkerResult::Error(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_python_execd_preprocess_then_execd() {
|
||||
let script = r#"
|
||||
def preprocessor(x: int):
|
||||
return {"x": x * 2}
|
||||
|
||||
def main(x: int):
|
||||
return x + 100
|
||||
"#;
|
||||
let results = run_py_raw_protocol_test(
|
||||
&[("f/test/mixed", script)],
|
||||
vec![
|
||||
ProtocolCmd::ExecdPreprocess { args: serde_json::json!({"x": 5}) },
|
||||
ProtocolCmd::Execd { args: serde_json::json!({"x": 7}) },
|
||||
],
|
||||
);
|
||||
// preprocess: preprocessor(5) => {"x":10}, main(10) => 110
|
||||
// execd: main(7) => 107
|
||||
assert_eq!(results.len(), 3);
|
||||
assert_eq!(
|
||||
results[0],
|
||||
DedicatedWorkerResult::PreprocessedArgs(serde_json::json!({"x": 10}))
|
||||
);
|
||||
assert_eq!(
|
||||
results[1],
|
||||
DedicatedWorkerResult::Success(serde_json::json!(110))
|
||||
);
|
||||
assert_eq!(
|
||||
results[2],
|
||||
DedicatedWorkerResult::Success(serde_json::json!(107))
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== Argument Transformation Tests ====================
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -101,7 +101,9 @@ mod relock_skip {
|
||||
before
|
||||
}
|
||||
|
||||
#[cfg(feature = "python")]
|
||||
// Requires `private` feature for the dependency job concurrency limit that prevents
|
||||
// race conditions between concurrent dep jobs for the same flow/app.
|
||||
#[cfg(all(feature = "python", feature = "private"))]
|
||||
#[sqlx::test(fixtures("base", "dependency_map"))]
|
||||
async fn relock_skip_on_script_redeployment(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
std::env::set_var("DEPENDENCY_JOB_DEBOUNCE_DELAY", "0");
|
||||
@@ -128,8 +130,9 @@ def main():
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// leaf_1(1) + branch(1) + root_script(2: leaf_1+branch) + root_flow(2) + root_app(2) = 8 jobs
|
||||
wait_for_jobs(&mut completed, 8).await;
|
||||
// leaf_1(1) + branch(1) + root_script(1-2) + root_flow(1-2) + root_app(1-2) = 5-8 jobs
|
||||
// With debouncing (private feature), duplicate dep jobs from branch cascade may be coalesced.
|
||||
wait_for_jobs_ge(&mut completed, 5).await;
|
||||
|
||||
let skipping_count = count_pattern_in_job_logs(&db, "Skipping relock", before).await;
|
||||
let relocking_count = count_pattern_in_job_logs(&db, "Relocking", before).await;
|
||||
@@ -236,7 +239,9 @@ def main():
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "python")]
|
||||
// Requires `private` feature for the dependency job concurrency limit that prevents
|
||||
// race conditions between concurrent dep jobs for the same flow/app.
|
||||
#[cfg(all(feature = "python", feature = "private"))]
|
||||
#[sqlx::test(fixtures("base", "dependency_map"))]
|
||||
async fn relock_skip_on_workspace_deps_redeployment(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
use windmill_common::scripts::ScriptLang;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user