mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-10 16:05:58 +00:00
Merge remote-tracking branch 'origin/main' into glm/replace_menuV2
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [1.458.4](https://github.com/windmill-labs/windmill/compare/v1.458.3...v1.458.4) (2025-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix concurrent limit jobs non restarting ([4828a77](https://github.com/windmill-labs/windmill/commit/4828a77f21fe62f36632490f811fb01b39977662))
|
||||
|
||||
## [1.458.3](https://github.com/windmill-labs/windmill/compare/v1.458.2...v1.458.3) (2025-02-10)
|
||||
|
||||
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT workspace_id, path, url, script_path, is_flow, edited_by, email, edited_at, server_id, last_server_ping, extra_perms, error, enabled, filters as \"filters: _\", initial_messages as \"initial_messages: _\", url_runnable_args as \"url_runnable_args: _\", can_return_message FROM websocket_trigger\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "url",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "script_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "is_flow",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "edited_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "server_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "last_server_ping",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "extra_perms",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "error",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "enabled",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "filters: _",
|
||||
"type_info": "JsonbArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "initial_messages: _",
|
||||
"type_info": "JsonbArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "url_runnable_args: _",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "can_return_message",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09"
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT workspace_id, path, route_path, route_path_key, script_path, is_flow, edited_by, edited_at, email, extra_perms, is_async, requires_auth, http_method as \"http_method: _\", static_asset_config as \"static_asset_config: _\", is_static_website FROM http_trigger\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "route_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "route_path_key",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "script_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "is_flow",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "edited_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "extra_perms",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "is_async",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "requires_auth",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "http_method: _",
|
||||
"type_info": {
|
||||
"Custom": {
|
||||
"name": "http_method",
|
||||
"kind": {
|
||||
"Enum": [
|
||||
"get",
|
||||
"post",
|
||||
"put",
|
||||
"delete",
|
||||
"patch"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "static_asset_config: _",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "is_static_website",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8"
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT * FROM nats_trigger\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "nats_resource_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "subjects",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "stream_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "consumer_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "use_jetstream",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "script_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_flow",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "edited_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "extra_perms",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "server_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "last_server_ping",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "error",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "enabled",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "WITH ping AS (UPDATE v2_job_runtime SET ping = NULL WHERE id = $2 RETURNING id)\n UPDATE v2_job_queue SET\n running = false,\n started_at = null,\n scheduled_for = $1\n WHERE id = (SELECT id FROM ping)",
|
||||
"query": "WITH ping AS (UPDATE v2_job_runtime SET ping = NULL WHERE id = $2 RETURNING id)\n UPDATE v2_job_queue SET\n running = false,\n started_at = null,\n scheduled_for = $1\n WHERE id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -11,5 +11,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "51ddbfec67af268d9bbee12b2730d6109d2a6633e62ce708bad8af1a9f8c3925"
|
||||
"hash": "7145a1a6cf0ccfae5874c882e63ff0d370cf1ab4d41f68494a940951eaa52bc3"
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT * FROM postgres_trigger\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "script_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "is_flow",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "edited_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "extra_perms",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "postgres_resource_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "error",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "server_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "last_server_ping",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "replication_slot_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "publication_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "enabled",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf"
|
||||
}
|
||||
+21
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n -- slack_team_id, \n -- slack_name, \n -- slack_command_script, \n -- CASE WHEN slack_email = 'missing@email.xyz' THEN NULL ELSE slack_email END AS slack_email,\n auto_invite_domain IS NOT NULL AS \"auto_invite_enabled!\",\n CASE WHEN auto_invite_operator IS TRUE THEN 'operator' ELSE 'developer' END AS \"auto_invite_as!\", \n CASE WHEN auto_add IS TRUE THEN 'add' ELSE 'invite' END AS \"auto_invite_mode!\", \n webhook, \n deploy_to, \n error_handler, \n ai_resource, \n ai_models,\n code_completion_model,\n error_handler_extra_args, \n error_handler_muted_on_cancel, \n large_file_storage, \n git_sync,\n default_app,\n default_scripts,\n workspace.name\n FROM workspace_settings\n LEFT JOIN workspace ON workspace.id = workspace_settings.workspace_id\n WHERE workspace_id = $1",
|
||||
"query": "SELECT\n -- slack_team_id, \n -- slack_name, \n -- slack_command_script, \n -- CASE WHEN slack_email = 'missing@email.xyz' THEN NULL ELSE slack_email END AS slack_email,\n auto_invite_domain IS NOT NULL AS \"auto_invite_enabled!\",\n CASE WHEN auto_invite_operator IS TRUE THEN 'operator' ELSE 'developer' END AS \"auto_invite_as!\", \n CASE WHEN auto_add IS TRUE THEN 'add' ELSE 'invite' END AS \"auto_invite_mode!\", \n webhook, \n deploy_to, \n error_handler, \n ai_resource, \n ai_models,\n code_completion_model,\n error_handler_extra_args, \n error_handler_muted_on_cancel, \n large_file_storage, \n git_sync,\n default_app,\n default_scripts,\n workspace.name,\n mute_critical_alerts,\n color,\n operator_settings\n FROM workspace_settings\n LEFT JOIN workspace ON workspace.id = workspace_settings.workspace_id\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -82,6 +82,21 @@
|
||||
"ordinal": 15,
|
||||
"name": "name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "mute_critical_alerts",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "color",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "operator_settings",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -105,8 +120,11 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "51648e377d47815d0b15694572d5c9cc0a303d70980346e1f3c4096a8922d7d5"
|
||||
"hash": "91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589"
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT * FROM kafka_trigger\n WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "kafka_resource_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "topics",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "group_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "script_path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "is_flow",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "edited_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "edited_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "extra_perms",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "server_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "last_server_ping",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "error",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "enabled",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2"
|
||||
}
|
||||
Generated
+27
-27
@@ -8548,9 +8548,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "stacker"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b"
|
||||
checksum = "1d08feb8f695b465baed819b03c128dc23f57a694510ab1f06c77f763975685e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
@@ -10858,7 +10858,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -10901,7 +10901,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -10994,7 +10994,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -11012,7 +11012,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -11025,7 +11025,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -11039,7 +11039,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -11098,7 +11098,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -11112,7 +11112,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -11135,7 +11135,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
@@ -11147,7 +11147,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -11156,7 +11156,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -11168,7 +11168,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-csharp"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -11180,7 +11180,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -11192,7 +11192,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -11204,7 +11204,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -11215,7 +11215,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -11226,7 +11226,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -11246,7 +11246,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -11263,7 +11263,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -11275,7 +11275,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -11293,7 +11293,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.15",
|
||||
@@ -11315,7 +11315,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -11325,7 +11325,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -11358,7 +11358,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -11368,7 +11368,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -30,7 +30,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
3dab441fe1eb5c9a042a6a4d9933ddea29c1bf4e
|
||||
8dab3198496461e40610145e4c818fce2345e20a
|
||||
@@ -65,6 +65,7 @@ static PYTHON_IMPORTS_REPLACEMENT: phf::Map<&'static str, &'static str> = phf_ma
|
||||
"pythonjsonlogger" => "python-json-logger",
|
||||
"socks" => "PySocks",
|
||||
"taiga" => "python-taiga",
|
||||
"docx" => "python-docx",
|
||||
};
|
||||
|
||||
fn replace_import(x: String) -> String {
|
||||
|
||||
@@ -1713,7 +1713,7 @@ async fn handle_zombie_jobs(db: &Pool<Postgres>, base_internal_url: &str, worker
|
||||
worker_name,
|
||||
send_result_never_used,
|
||||
#[cfg(feature = "benchmark")]
|
||||
&mut windmill_common::bench::BenchmarkIter::new(),
|
||||
&mut windmill_worker::bench::BenchmarkIter::new(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -4498,4 +4498,124 @@ mod job_payload {
|
||||
};
|
||||
test_for_versions(VERSION_FLAGS.iter().cloned(), test).await;
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("base", "hello"))]
|
||||
async fn test_raw_flow_payload_with_restarted_from(db: Pool<Postgres>) {
|
||||
initialize_tracing().await;
|
||||
let server = ApiServer::start(db.clone()).await;
|
||||
let port = server.addr.port();
|
||||
|
||||
let db = &db;
|
||||
let test = |restarted_from, arg, result| async move {
|
||||
let job = RunJob::from(JobPayload::RawFlow {
|
||||
value: serde_json::from_value(json!({
|
||||
"modules": [{
|
||||
"id": "a",
|
||||
"value": {
|
||||
"type": "rawscript",
|
||||
"content": r#"export function main(world: string) {
|
||||
return `Hello ${world}!`;
|
||||
}"#,
|
||||
"language": "deno",
|
||||
"input_transforms": {
|
||||
"world": { "type": "javascript", "expr": "flow_input.world" }
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "b",
|
||||
"value": {
|
||||
"type": "rawscript",
|
||||
"content": r#"export function main(world: string, a: string) {
|
||||
return `${a} ${world}!`;
|
||||
}"#,
|
||||
"language": "deno",
|
||||
"input_transforms": {
|
||||
"world": { "type": "javascript", "expr": "flow_input.world" },
|
||||
"a": { "type": "javascript", "expr": "results.a" }
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "c",
|
||||
"value": {
|
||||
"type": "forloopflow",
|
||||
"iterator": { "type": "javascript", "expr": "['a', 'b', 'c']" },
|
||||
"modules": [{
|
||||
"value": {
|
||||
"input_transforms": {
|
||||
"world": { "type": "javascript", "expr": "flow_input.world" },
|
||||
"b": { "type": "javascript", "expr": "results.b" },
|
||||
"x": { "type": "javascript", "expr": "flow_input.iter.value" }
|
||||
},
|
||||
"type": "rawscript",
|
||||
"language": "deno",
|
||||
"content": r#"export function main(world: string, b: string, x: string) {
|
||||
return `${x}: ${b} ${world}!`;
|
||||
}"#,
|
||||
},
|
||||
}],
|
||||
}
|
||||
}],
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": { "world": { "type": "string" } },
|
||||
"type": "object",
|
||||
"order": [ "world" ]
|
||||
}
|
||||
}))
|
||||
.unwrap(),
|
||||
path: None,
|
||||
restarted_from,
|
||||
})
|
||||
.arg("world", arg)
|
||||
.run_until_complete(db, port)
|
||||
.await;
|
||||
|
||||
assert_eq!(job.json_result().unwrap(), result);
|
||||
job.id
|
||||
};
|
||||
let flow_job_id = test(
|
||||
None,
|
||||
json!("foo"),
|
||||
json!([
|
||||
"a: Hello foo! foo! foo!",
|
||||
"b: Hello foo! foo! foo!",
|
||||
"c: Hello foo! foo! foo!"
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
let flow_job_id = test(
|
||||
Some(RestartedFrom { flow_job_id, step_id: "a".into(), branch_or_iteration_n: None }),
|
||||
json!("foo"),
|
||||
json!([
|
||||
"a: Hello foo! foo! foo!",
|
||||
"b: Hello foo! foo! foo!",
|
||||
"c: Hello foo! foo! foo!"
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
let flow_job_id = test(
|
||||
Some(RestartedFrom { flow_job_id, step_id: "b".into(), branch_or_iteration_n: None }),
|
||||
json!("bar"),
|
||||
json!([
|
||||
"a: Hello foo! bar! bar!",
|
||||
"b: Hello foo! bar! bar!",
|
||||
"c: Hello foo! bar! bar!"
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
let _ = test(
|
||||
Some(RestartedFrom {
|
||||
flow_job_id,
|
||||
step_id: "c".into(),
|
||||
branch_or_iteration_n: Some(1),
|
||||
}),
|
||||
json!("yolo"),
|
||||
json!([
|
||||
"a: Hello foo! bar! bar!",
|
||||
"b: Hello foo! bar! yolo!",
|
||||
"c: Hello foo! bar! yolo!"
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.458.3
|
||||
version: 1.458.4
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -72,6 +72,7 @@ pub struct NewGroup {
|
||||
pub struct GroupInfo {
|
||||
pub workspace_id: String,
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub summary: Option<String>,
|
||||
pub members: Vec<String>,
|
||||
pub extra_perms: serde_json::Value,
|
||||
|
||||
@@ -114,22 +114,23 @@ struct NewTrigger {
|
||||
}
|
||||
|
||||
#[derive(FromRow, Serialize)]
|
||||
struct HttpTrigger {
|
||||
workspace_id: String,
|
||||
path: String,
|
||||
route_path: String,
|
||||
route_path_key: String,
|
||||
script_path: String,
|
||||
is_flow: bool,
|
||||
edited_by: String,
|
||||
email: String,
|
||||
edited_at: chrono::DateTime<chrono::Utc>,
|
||||
extra_perms: serde_json::Value,
|
||||
is_async: bool,
|
||||
requires_auth: bool,
|
||||
http_method: HttpMethod,
|
||||
static_asset_config: Option<sqlx::types::Json<S3Object>>,
|
||||
is_static_website: bool,
|
||||
pub struct HttpTrigger {
|
||||
pub workspace_id: String,
|
||||
pub path: String,
|
||||
pub route_path: String,
|
||||
pub route_path_key: String,
|
||||
pub script_path: String,
|
||||
pub is_flow: bool,
|
||||
pub edited_by: String,
|
||||
pub email: String,
|
||||
pub edited_at: chrono::DateTime<chrono::Utc>,
|
||||
pub extra_perms: serde_json::Value,
|
||||
pub is_async: bool,
|
||||
pub requires_auth: bool,
|
||||
pub http_method: HttpMethod,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub static_asset_config: Option<sqlx::types::Json<S3Object>>,
|
||||
pub is_static_website: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
||||
@@ -18,3 +18,25 @@ pub fn start_kafka_consumers(
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum KafkaTriggerConfigConnection {}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct KafkaTrigger {
|
||||
pub workspace_id: String,
|
||||
pub path: String,
|
||||
pub kafka_resource_path: String,
|
||||
pub group_id: String,
|
||||
pub topics: Vec<String>,
|
||||
pub script_path: String,
|
||||
pub is_flow: bool,
|
||||
pub edited_by: String,
|
||||
pub email: String,
|
||||
pub edited_at: chrono::DateTime<chrono::Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub server_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub extra_perms: serde_json::Value,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
@@ -15,3 +15,29 @@ pub fn start_nats_consumers(_db: DB, mut _killpill_rx: tokio::sync::broadcast::R
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum NatsTriggerConfigConnection {}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct NatsTrigger {
|
||||
pub workspace_id: String,
|
||||
pub path: String,
|
||||
pub nats_resource_path: String,
|
||||
pub subjects: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub stream_name: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub consumer_name: Option<String>,
|
||||
pub use_jetstream: bool,
|
||||
pub script_path: String,
|
||||
pub is_flow: bool,
|
||||
pub edited_by: String,
|
||||
pub email: String,
|
||||
pub edited_at: chrono::DateTime<chrono::Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub server_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub extra_perms: serde_json::Value,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
@@ -221,12 +221,16 @@ pub struct PostgresTrigger {
|
||||
pub edited_by: String,
|
||||
pub email: String,
|
||||
pub edited_at: chrono::DateTime<chrono::Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub extra_perms: Option<serde_json::Value>,
|
||||
pub postgres_resource_path: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub server_id: Option<String>,
|
||||
pub replication_slot_name: String,
|
||||
pub publication_name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use handler::{
|
||||
create_template_script, delete_postgres_trigger, delete_publication, drop_slot_name,
|
||||
exists_postgres_trigger, get_postgres_trigger, get_publication_info, get_template_script,
|
||||
is_database_in_logical_level, list_database_publication, list_postgres_triggers,
|
||||
list_slot_name, set_enabled, update_postgres_trigger, Database, PostgresTrigger,
|
||||
list_slot_name, set_enabled, update_postgres_trigger, Database,
|
||||
};
|
||||
use windmill_common::{db::UserDB, error::Error, utils::StripPath};
|
||||
use windmill_queue::PushArgsOwned;
|
||||
@@ -30,6 +30,7 @@ mod relation;
|
||||
mod replication_message;
|
||||
mod trigger;
|
||||
|
||||
pub use handler::PostgresTrigger;
|
||||
pub use trigger::start_database;
|
||||
|
||||
pub async fn get_database_resource(
|
||||
|
||||
@@ -88,23 +88,27 @@ enum InitialMessage {
|
||||
|
||||
#[derive(FromRow, Serialize, Clone)]
|
||||
pub struct WebsocketTrigger {
|
||||
workspace_id: String,
|
||||
path: String,
|
||||
url: String,
|
||||
script_path: String,
|
||||
is_flow: bool,
|
||||
edited_by: String,
|
||||
email: String,
|
||||
edited_at: chrono::DateTime<chrono::Utc>,
|
||||
server_id: Option<String>,
|
||||
last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
|
||||
extra_perms: serde_json::Value,
|
||||
error: Option<String>,
|
||||
enabled: bool,
|
||||
filters: Vec<SqlxJson<Box<RawValue>>>,
|
||||
initial_messages: Option<Vec<SqlxJson<Box<RawValue>>>>,
|
||||
url_runnable_args: Option<SqlxJson<Box<RawValue>>>,
|
||||
can_return_message: bool,
|
||||
pub workspace_id: String,
|
||||
pub path: String,
|
||||
pub url: String,
|
||||
pub script_path: String,
|
||||
pub is_flow: bool,
|
||||
pub edited_by: String,
|
||||
pub email: String,
|
||||
pub edited_at: chrono::DateTime<chrono::Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub server_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub extra_perms: serde_json::Value,
|
||||
pub error: Option<String>,
|
||||
pub enabled: bool,
|
||||
pub filters: Vec<SqlxJson<Box<RawValue>>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub initial_messages: Option<Vec<SqlxJson<Box<RawValue>>>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub url_runnable_args: Option<SqlxJson<Box<RawValue>>>,
|
||||
pub can_return_message: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
||||
@@ -165,32 +165,54 @@ struct Workspace {
|
||||
#[derive(FromRow, Serialize, Debug)]
|
||||
pub struct WorkspaceSettings {
|
||||
pub workspace_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub slack_team_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub slack_name: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub slack_command_script: Option<String>,
|
||||
pub slack_email: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub auto_invite_domain: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub auto_invite_operator: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub auto_add: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub customer_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub plan: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub webhook: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deploy_to: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub ai_resource: Option<serde_json::Value>,
|
||||
pub ai_models: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub code_completion_model: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error_handler: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error_handler_extra_args: Option<serde_json::Value>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error_handler_muted_on_cancel: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub large_file_storage: Option<serde_json::Value>, // effectively: DatasetsStorage
|
||||
pub git_sync: Option<serde_json::Value>, // effectively: WorkspaceGitSyncSettings
|
||||
pub deploy_ui: Option<serde_json::Value>, // effectively: WorkspaceDeploymentUISettings
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub git_sync: Option<serde_json::Value>, // effectively: WorkspaceGitSyncSettings
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deploy_ui: Option<serde_json::Value>, // effectively: WorkspaceDeploymentUISettings
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub default_app: Option<String>,
|
||||
pub automatic_billing: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub default_scripts: Option<serde_json::Value>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mute_critical_alerts: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub color: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub operator_settings: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ pub(crate) struct ArchiveQueryParams {
|
||||
skip_variables: Option<bool>,
|
||||
skip_resources: Option<bool>,
|
||||
include_schedules: Option<bool>,
|
||||
include_triggers: Option<bool>,
|
||||
include_users: Option<bool>,
|
||||
include_groups: Option<bool>,
|
||||
include_settings: Option<bool>,
|
||||
@@ -185,6 +186,8 @@ where
|
||||
"has_draft",
|
||||
"draft_only",
|
||||
"error",
|
||||
"last_server_ping",
|
||||
"server_id",
|
||||
],
|
||||
ignore_keys.unwrap_or(vec![]),
|
||||
]
|
||||
@@ -221,6 +224,7 @@ struct SimplifiedUser {
|
||||
#[derive(Serialize)]
|
||||
struct SimplifiedGroup {
|
||||
name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
summary: Option<String>,
|
||||
members: Vec<String>,
|
||||
admins: Vec<String>,
|
||||
@@ -235,20 +239,35 @@ struct SimplifiedSettings {
|
||||
auto_invite_enabled: bool,
|
||||
auto_invite_as: String,
|
||||
auto_invite_mode: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
webhook: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
deploy_to: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
error_handler: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
error_handler_extra_args: Option<Value>,
|
||||
error_handler_muted_on_cancel: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
ai_resource: Option<serde_json::Value>,
|
||||
ai_models: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
code_completion_model: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
large_file_storage: Option<Value>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
git_sync: Option<Value>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
default_app: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
default_scripts: Option<Value>,
|
||||
name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
mute_critical_alerts: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
color: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
operator_settings: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
pub(crate) async fn tarball_workspace(
|
||||
@@ -264,6 +283,7 @@ pub(crate) async fn tarball_workspace(
|
||||
skip_secrets,
|
||||
skip_variables,
|
||||
include_schedules,
|
||||
include_triggers,
|
||||
include_users,
|
||||
include_groups,
|
||||
include_settings,
|
||||
@@ -510,6 +530,113 @@ pub(crate) async fn tarball_workspace(
|
||||
}
|
||||
}
|
||||
|
||||
if include_triggers.unwrap_or(false) {
|
||||
#[cfg(feature = "http_trigger")]
|
||||
{
|
||||
let http_triggers = sqlx::query_as!(
|
||||
crate::http_triggers::HttpTrigger,
|
||||
"SELECT workspace_id, path, route_path, route_path_key, script_path, is_flow, edited_by, edited_at, email, extra_perms, is_async, requires_auth, http_method as \"http_method: _\", static_asset_config as \"static_asset_config: _\", is_static_website FROM http_trigger
|
||||
WHERE workspace_id = $1",
|
||||
&w_id
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for trigger in http_triggers {
|
||||
let trigger_str = &to_string_without_metadata(&trigger, false, None).unwrap();
|
||||
archive
|
||||
.write_to_archive(&trigger_str, &format!("{}.http_trigger.json", trigger.path))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "websocket")]
|
||||
{
|
||||
let websocket_triggers = sqlx::query_as!(
|
||||
crate::websocket_triggers::WebsocketTrigger,
|
||||
"SELECT workspace_id, path, url, script_path, is_flow, edited_by, email, edited_at, server_id, last_server_ping, extra_perms, error, enabled, filters as \"filters: _\", initial_messages as \"initial_messages: _\", url_runnable_args as \"url_runnable_args: _\", can_return_message FROM websocket_trigger
|
||||
WHERE workspace_id = $1",
|
||||
&w_id
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for trigger in websocket_triggers {
|
||||
let trigger_str = &to_string_without_metadata(&trigger, false, None).unwrap();
|
||||
archive
|
||||
.write_to_archive(
|
||||
&trigger_str,
|
||||
&format!("{}.websocket_trigger.json", trigger.path),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "enterprise", feature = "kafka"))]
|
||||
{
|
||||
let kafka_triggers = sqlx::query_as!(
|
||||
crate::kafka_triggers_ee::KafkaTrigger,
|
||||
"SELECT * FROM kafka_trigger
|
||||
WHERE workspace_id = $1",
|
||||
&w_id
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for trigger in kafka_triggers {
|
||||
let trigger_str = &to_string_without_metadata(&trigger, false, None).unwrap();
|
||||
archive
|
||||
.write_to_archive(
|
||||
&trigger_str,
|
||||
&format!("{}.kafka_trigger.json", trigger.path),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "enterprise", feature = "nats"))]
|
||||
{
|
||||
let nats_triggers = sqlx::query_as!(
|
||||
crate::nats_triggers_ee::NatsTrigger,
|
||||
"SELECT * FROM nats_trigger
|
||||
WHERE workspace_id = $1",
|
||||
&w_id
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for trigger in nats_triggers {
|
||||
let trigger_str: &String =
|
||||
&to_string_without_metadata(&trigger, false, None).unwrap();
|
||||
archive
|
||||
.write_to_archive(&trigger_str, &format!("{}.nats_trigger.json", trigger.path))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "postgres_trigger")]
|
||||
{
|
||||
let postgres_triggers = sqlx::query_as!(
|
||||
crate::postgres_triggers::PostgresTrigger,
|
||||
"SELECT * FROM postgres_trigger
|
||||
WHERE workspace_id = $1",
|
||||
&w_id
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for trigger in postgres_triggers {
|
||||
let trigger_str = &to_string_without_metadata(&trigger, false, None).unwrap();
|
||||
archive
|
||||
.write_to_archive(
|
||||
&trigger_str,
|
||||
&format!("{}.postgres_trigger.json", trigger.path),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if include_users.unwrap_or(false) {
|
||||
let users = sqlx::query!(
|
||||
"SELECT * FROM usr
|
||||
@@ -532,12 +659,7 @@ pub(crate) async fn tarball_workspace(
|
||||
disabled: user.disabled,
|
||||
email: user.email,
|
||||
};
|
||||
let user_str = &to_string_without_metadata(
|
||||
&user,
|
||||
false,
|
||||
Some(vec!["is_admin", "operator", "email"]),
|
||||
)
|
||||
.unwrap();
|
||||
let user_str = &to_string_without_metadata(&user, false, Some(vec!["email"])).unwrap();
|
||||
archive
|
||||
.write_to_archive(&user_str, &format!("users/{}.user.json", user.email))
|
||||
.await?;
|
||||
@@ -627,7 +749,10 @@ pub(crate) async fn tarball_workspace(
|
||||
git_sync,
|
||||
default_app,
|
||||
default_scripts,
|
||||
workspace.name
|
||||
workspace.name,
|
||||
mute_critical_alerts,
|
||||
color,
|
||||
operator_settings
|
||||
FROM workspace_settings
|
||||
LEFT JOIN workspace ON workspace.id = workspace_settings.workspace_id
|
||||
WHERE workspace_id = $1"#,
|
||||
|
||||
@@ -19,8 +19,6 @@ use sqlx::{Pool, Postgres};
|
||||
|
||||
pub mod apps;
|
||||
pub mod auth;
|
||||
#[cfg(feature = "benchmark")]
|
||||
pub mod bench;
|
||||
pub mod cache;
|
||||
pub mod db;
|
||||
pub mod ee;
|
||||
|
||||
@@ -2040,13 +2040,14 @@ pub async fn pull(
|
||||
running = false,
|
||||
started_at = null,
|
||||
scheduled_for = $1
|
||||
WHERE id = (SELECT id FROM ping)",
|
||||
WHERE id = $2",
|
||||
estimated_next_schedule_timestamp,
|
||||
job_uuid,
|
||||
)
|
||||
.fetch_all(&mut *tx)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| Error::internal_err(format!("Could not update and re-queue job {job_uuid}. The job will be marked as running but it is not running: {e:#}")))?;
|
||||
|
||||
tx.commit().await?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
use serde::Serialize;
|
||||
use tokio::time::Instant;
|
||||
use windmill_common::{
|
||||
worker::{write_file, TMP_DIR},
|
||||
DB,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use tokio::time::Instant;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct BenchmarkInfo {
|
||||
@@ -79,7 +79,7 @@ impl BenchmarkIter {
|
||||
}
|
||||
|
||||
pub async fn benchmark_init(benchmark_jobs: i32, db: &DB) {
|
||||
use crate::{jobs::JobKind, scripts::ScriptLang};
|
||||
use windmill_common::{jobs::JobKind, scripts::ScriptLang};
|
||||
|
||||
let benchmark_kind = std::env::var("BENCHMARK_KIND").unwrap_or("noop".to_string());
|
||||
|
||||
@@ -9,6 +9,8 @@ mod snowflake_executor;
|
||||
mod ansible_executor;
|
||||
mod bash_executor;
|
||||
|
||||
#[cfg(feature = "benchmark")]
|
||||
pub mod bench;
|
||||
mod bun_executor;
|
||||
pub mod common;
|
||||
mod config;
|
||||
@@ -38,6 +40,7 @@ mod rust_executor;
|
||||
mod worker;
|
||||
mod worker_flow;
|
||||
mod worker_lockfiles;
|
||||
|
||||
pub use worker::*;
|
||||
|
||||
pub use result_processor::handle_job_error;
|
||||
|
||||
@@ -26,7 +26,7 @@ use windmill_common::{
|
||||
};
|
||||
|
||||
#[cfg(feature = "benchmark")]
|
||||
use windmill_common::bench::{BenchmarkInfo, BenchmarkIter};
|
||||
use crate::bench::{BenchmarkInfo, BenchmarkIter};
|
||||
|
||||
use windmill_queue::{append_logs, get_queued_job, CanceledBy, WrappedError};
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ use crate::mssql_executor::do_mssql;
|
||||
use crate::bigquery_executor::do_bigquery;
|
||||
|
||||
#[cfg(feature = "benchmark")]
|
||||
use windmill_common::bench::{benchmark_init, BenchmarkInfo, BenchmarkIter};
|
||||
use crate::bench::{benchmark_init, BenchmarkInfo, BenchmarkIter};
|
||||
|
||||
use windmill_common::add_time;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
#[cfg(feature = "benchmark")]
|
||||
use crate::bench::BenchmarkIter;
|
||||
use crate::common::{cached_result_path, save_in_cache};
|
||||
use crate::js_eval::{eval_timeout, IdContext};
|
||||
use crate::{
|
||||
@@ -30,8 +32,6 @@ use tracing::instrument;
|
||||
use uuid::Uuid;
|
||||
use windmill_common::add_time;
|
||||
use windmill_common::auth::JobPerms;
|
||||
#[cfg(feature = "benchmark")]
|
||||
use windmill_common::bench::BenchmarkIter;
|
||||
use windmill_common::cache::{self, RawData};
|
||||
use windmill_common::db::Authed;
|
||||
use windmill_common::flow_status::{
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
|
||||
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
|
||||
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
|
||||
|
||||
export const VERSION = "v1.458.3";
|
||||
export const VERSION = "v1.458.4";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
@@ -12,6 +12,7 @@ export interface SyncOptions {
|
||||
skipResources?: boolean;
|
||||
skipSecrets?: boolean;
|
||||
includeSchedules?: boolean;
|
||||
includeTriggers?: boolean;
|
||||
includeUsers?: boolean;
|
||||
includeGroups?: boolean;
|
||||
includeSettings?: boolean;
|
||||
|
||||
@@ -54,7 +54,7 @@ export const OpenAPI: OpenAPIConfig = {
|
||||
PASSWORD: undefined,
|
||||
TOKEN: getEnv("WM_TOKEN"),
|
||||
USERNAME: undefined,
|
||||
VERSION: '1.454.1',
|
||||
VERSION: '1.457.1',
|
||||
WITH_CREDENTIALS: true,
|
||||
interceptors: {
|
||||
request: new Interceptors(),
|
||||
|
||||
@@ -2895,7 +2895,7 @@ export const deleteScriptByHash = (data: DeleteScriptByHashData): CancelableProm
|
||||
}); };
|
||||
|
||||
/**
|
||||
* delete all scripts at a given path (require admin)
|
||||
* delete script at a given path (require admin)
|
||||
* @param data The data for the request.
|
||||
* @param data.workspace
|
||||
* @param data.path
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
|
||||
export type AIProvider = 'openai' | 'anthropic' | 'mistral' | 'deepseek' | 'customai';
|
||||
export type AIProvider = 'openai' | 'anthropic' | 'mistral' | 'deepseek' | 'groq' | 'openrouter' | 'customai';
|
||||
|
||||
export type AIResource = {
|
||||
path: string;
|
||||
@@ -168,6 +168,7 @@ export type QueuedJob = {
|
||||
self_wait_time_ms?: number;
|
||||
aggregate_wait_time_ms?: number;
|
||||
suspend?: number;
|
||||
preprocessed?: boolean;
|
||||
};
|
||||
|
||||
export type job_kind = 'script' | 'preview' | 'dependencies' | 'flowdependencies' | 'appdependencies' | 'flow' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow' | 'flowscript' | 'flownode' | 'appscript';
|
||||
@@ -212,6 +213,7 @@ export type CompletedJob = {
|
||||
labels?: Array<(string)>;
|
||||
self_wait_time_ms?: number;
|
||||
aggregate_wait_time_ms?: number;
|
||||
preprocessed?: boolean;
|
||||
};
|
||||
|
||||
export type ObscuredJob = {
|
||||
@@ -575,6 +577,7 @@ export type HttpTrigger = TriggerExtraProperty & {
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
is_async: boolean;
|
||||
requires_auth: boolean;
|
||||
is_static_website: boolean;
|
||||
};
|
||||
|
||||
export type http_method = 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
@@ -592,6 +595,7 @@ export type NewHttpTrigger = {
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
is_async: boolean;
|
||||
requires_auth: boolean;
|
||||
is_static_website: boolean;
|
||||
};
|
||||
|
||||
export type EditHttpTrigger = {
|
||||
@@ -607,6 +611,7 @@ export type EditHttpTrigger = {
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
is_async: boolean;
|
||||
requires_auth: boolean;
|
||||
is_static_website: boolean;
|
||||
};
|
||||
|
||||
export type TriggersCount = {
|
||||
@@ -2598,7 +2603,7 @@ export type GetCopilotInfoData = {
|
||||
};
|
||||
|
||||
export type GetCopilotInfoResponse = ({
|
||||
ai_provider: AIProvider;
|
||||
ai_provider?: AIProvider;
|
||||
exists_ai_resource: boolean;
|
||||
code_completion_model?: string;
|
||||
ai_models: Array<(string)>;
|
||||
@@ -5571,6 +5576,7 @@ export type ExistsRouteData = {
|
||||
requestBody: {
|
||||
route_path: string;
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
trigger_path?: string;
|
||||
};
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
@@ -363,6 +363,7 @@ async function instancePull(opts: InstanceSyncOptions) {
|
||||
baseUrl: undefined,
|
||||
includeGroups: true,
|
||||
includeSchedules: true,
|
||||
includeTriggers: true,
|
||||
includeSettings: true,
|
||||
includeUsers: true,
|
||||
includeKey: true,
|
||||
@@ -529,6 +530,7 @@ async function instancePush(opts: InstanceSyncOptions) {
|
||||
baseUrl: undefined,
|
||||
includeGroups: true,
|
||||
includeSchedules: true,
|
||||
includeTriggers: true,
|
||||
includeSettings: true,
|
||||
includeUsers: true,
|
||||
includeKey: true,
|
||||
|
||||
+5
-1
@@ -17,6 +17,7 @@ import variable from "./variable.ts";
|
||||
import hub from "./hub.ts";
|
||||
import folder from "./folder.ts";
|
||||
import schedule from "./schedule.ts";
|
||||
import trigger from "./trigger.ts";
|
||||
import sync from "./sync.ts";
|
||||
import instance from "./instance.ts";
|
||||
import workerGroups from "./worker_groups.ts";
|
||||
@@ -44,6 +45,7 @@ export {
|
||||
hub,
|
||||
folder,
|
||||
schedule,
|
||||
trigger,
|
||||
sync,
|
||||
instance,
|
||||
dev,
|
||||
@@ -60,7 +62,7 @@ export {
|
||||
// }
|
||||
// });
|
||||
|
||||
export const VERSION = "1.458.3";
|
||||
export const VERSION = "1.458.4";
|
||||
|
||||
const command = new Command()
|
||||
.name("wmill")
|
||||
@@ -108,6 +110,7 @@ const command = new Command()
|
||||
skipResources: true,
|
||||
skipSecrets: true,
|
||||
includeSchedules: false,
|
||||
includeTriggers: false,
|
||||
})
|
||||
);
|
||||
log.info(colors.green("wmill.yaml created"));
|
||||
@@ -122,6 +125,7 @@ const command = new Command()
|
||||
.command("hub", hub)
|
||||
.command("folder", folder)
|
||||
.command("schedule", schedule)
|
||||
.command("trigger", trigger)
|
||||
.command("dev", dev)
|
||||
.command("sync", sync)
|
||||
.command("instance", instance)
|
||||
|
||||
+6
-5
@@ -11,6 +11,7 @@ export async function downloadZip(
|
||||
skipResources?: boolean,
|
||||
skipSecrets?: boolean,
|
||||
includeSchedules?: boolean,
|
||||
includeTriggers?: boolean,
|
||||
includeUsers?: boolean,
|
||||
includeGroups?: boolean,
|
||||
includeSettings?: boolean,
|
||||
@@ -38,11 +39,11 @@ export async function downloadZip(
|
||||
skipResources ?? false
|
||||
}&skip_secrets=${skipSecrets ?? false}&include_schedules=${
|
||||
includeSchedules ?? false
|
||||
}&include_users=${includeUsers ?? false}&include_groups=${
|
||||
includeGroups ?? false
|
||||
}&include_settings=${includeSettings ?? false}&include_key=${
|
||||
includeKey ?? false
|
||||
}&default_ts=${defaultTs ?? "bun"}`,
|
||||
}&include_triggers=${includeTriggers ?? false}&include_users=${
|
||||
includeUsers ?? false
|
||||
}&include_groups=${includeGroups ?? false}&include_settings=${
|
||||
includeSettings ?? false
|
||||
}&include_key=${includeKey ?? false}&default_ts=${defaultTs ?? "bun"}`,
|
||||
{
|
||||
headers: requestHeaders,
|
||||
method: "GET",
|
||||
|
||||
+39
-5
@@ -28,6 +28,9 @@ export interface SimplifiedSettings {
|
||||
default_app?: string;
|
||||
default_scripts?: any;
|
||||
name: string;
|
||||
mute_critical_alerts?: boolean;
|
||||
color?: string;
|
||||
operator_settings?: any;
|
||||
}
|
||||
|
||||
const INSTANCE_SETTINGS_PATH = "instance_settings.yaml";
|
||||
@@ -85,6 +88,9 @@ export async function pushWorkspaceSettings(
|
||||
default_app: remoteSettings.default_app,
|
||||
default_scripts: remoteSettings.default_scripts,
|
||||
name: workspaceName,
|
||||
mute_critical_alerts: remoteSettings.mute_critical_alerts,
|
||||
color: remoteSettings.color,
|
||||
operator_settings: remoteSettings.operator_settings,
|
||||
};
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to get workspace settings: ${err}`);
|
||||
@@ -166,12 +172,12 @@ export async function pushWorkspaceSettings(
|
||||
});
|
||||
}
|
||||
if (
|
||||
localSettings.error_handler !== settings.error_handler ||
|
||||
localSettings.error_handler != settings.error_handler ||
|
||||
!deepEqual(
|
||||
localSettings.error_handler_extra_args,
|
||||
settings.error_handler_extra_args
|
||||
) ||
|
||||
localSettings.error_handler_muted_on_cancel !==
|
||||
localSettings.error_handler_muted_on_cancel !=
|
||||
settings.error_handler_muted_on_cancel
|
||||
) {
|
||||
log.debug(`Updating error handler...`);
|
||||
@@ -185,7 +191,7 @@ export async function pushWorkspaceSettings(
|
||||
},
|
||||
});
|
||||
}
|
||||
if (localSettings.deploy_to !== settings.deploy_to) {
|
||||
if (localSettings.deploy_to != settings.deploy_to) {
|
||||
log.debug(`Updating deploy to...`);
|
||||
await wmill.editDeployTo({
|
||||
workspace,
|
||||
@@ -221,7 +227,7 @@ export async function pushWorkspaceSettings(
|
||||
requestBody: localSettings.default_scripts,
|
||||
});
|
||||
}
|
||||
if (localSettings.default_app !== settings.default_app) {
|
||||
if (localSettings.default_app != settings.default_app) {
|
||||
log.debug(`Updating default app...`);
|
||||
await wmill.editWorkspaceDefaultApp({
|
||||
workspace,
|
||||
@@ -231,7 +237,7 @@ export async function pushWorkspaceSettings(
|
||||
});
|
||||
}
|
||||
|
||||
if (localSettings.name !== settings.name) {
|
||||
if (localSettings.name != settings.name) {
|
||||
log.debug(`Updating workspace name...`);
|
||||
await wmill.changeWorkspaceName({
|
||||
workspace,
|
||||
@@ -240,6 +246,34 @@ export async function pushWorkspaceSettings(
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (localSettings.mute_critical_alerts != settings.mute_critical_alerts) {
|
||||
log.debug(`Updating mute critical alerts...`);
|
||||
await wmill.workspaceMuteCriticalAlertsUi({
|
||||
workspace,
|
||||
requestBody: {
|
||||
mute_critical_alerts: localSettings.mute_critical_alerts,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (localSettings.color != settings.color) {
|
||||
log.debug(`Updating workspace color...`);
|
||||
await wmill.changeWorkspaceColor({
|
||||
workspace,
|
||||
requestBody: {
|
||||
color: localSettings.color,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (localSettings.operator_settings != settings.operator_settings) {
|
||||
log.debug(`Updating operator settings...`);
|
||||
await wmill.updateOperatorSettings({
|
||||
workspace,
|
||||
requestBody: localSettings.operator_settings,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function pushWorkspaceKey(
|
||||
|
||||
+165
-67
@@ -116,7 +116,7 @@ async function addCodebaseDigestIfRelevant(
|
||||
const parsed: any = yamlParseContent(path, content);
|
||||
if (parsed && typeof parsed == "object") {
|
||||
parsed["codebase"] = c.digest;
|
||||
parsed["lock"] = '';
|
||||
parsed["lock"] = "";
|
||||
return yamlStringify(parsed, yamlOptions);
|
||||
} else {
|
||||
throw Error(
|
||||
@@ -159,8 +159,12 @@ export async function FSFSElement(
|
||||
// },
|
||||
async getContentText(): Promise<string> {
|
||||
const content = await Deno.readTextFile(localP);
|
||||
const itemPath = localP.substring(p.length + 1)
|
||||
const r = await addCodebaseDigestIfRelevant(itemPath, content, codebases);
|
||||
const itemPath = localP.substring(p.length + 1);
|
||||
const r = await addCodebaseDigestIfRelevant(
|
||||
itemPath,
|
||||
content,
|
||||
codebases
|
||||
);
|
||||
return r;
|
||||
},
|
||||
};
|
||||
@@ -352,12 +356,12 @@ function ZipFSElement(
|
||||
)
|
||||
? "flow"
|
||||
: p.endsWith("app.json")
|
||||
? "app"
|
||||
: p.endsWith("script.json")
|
||||
? "script"
|
||||
: p.endsWith("resource.json")
|
||||
? "resource"
|
||||
: "other";
|
||||
? "app"
|
||||
: p.endsWith("script.json")
|
||||
? "script"
|
||||
: p.endsWith("resource.json")
|
||||
? "resource"
|
||||
: "other";
|
||||
|
||||
const isJson = p.endsWith(".json");
|
||||
|
||||
@@ -387,7 +391,7 @@ function ZipFSElement(
|
||||
yield {
|
||||
isDirectory: false,
|
||||
path: path.join(finalPath, s.path),
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return s.content;
|
||||
@@ -398,7 +402,7 @@ function ZipFSElement(
|
||||
yield {
|
||||
isDirectory: false,
|
||||
path: path.join(finalPath, "flow.yaml"),
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return yamlStringify(flow, yamlOptions);
|
||||
@@ -414,7 +418,7 @@ function ZipFSElement(
|
||||
yield {
|
||||
isDirectory: false,
|
||||
path: path.join(finalPath, s.path),
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return s.content;
|
||||
@@ -425,7 +429,7 @@ function ZipFSElement(
|
||||
yield {
|
||||
isDirectory: false,
|
||||
path: path.join(finalPath, "app.yaml"),
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return yamlStringify(app, yamlOptions);
|
||||
@@ -490,7 +494,7 @@ function ZipFSElement(
|
||||
r.push({
|
||||
isDirectory: false,
|
||||
path: removeSuffix(finalPath, ".json") + ".lock",
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return lock;
|
||||
@@ -513,7 +517,7 @@ function ZipFSElement(
|
||||
removeSuffix(finalPath, ".resource.json") +
|
||||
".resource.file." +
|
||||
formatExtension,
|
||||
async *getChildren() { },
|
||||
async *getChildren() {},
|
||||
// deno-lint-ignore require-await
|
||||
async getContentText() {
|
||||
return fileContent;
|
||||
@@ -574,19 +578,19 @@ export async function* readDirRecursiveWithIgnore(
|
||||
// getContentBytes(): Promise<Uint8Array>;
|
||||
getContentText(): Promise<string>;
|
||||
}[] = [
|
||||
{
|
||||
path: root.path,
|
||||
ignored: ignore(root.path, root.isDirectory),
|
||||
isDirectory: root.isDirectory,
|
||||
c: root.getChildren,
|
||||
// getContentBytes(): Promise<Uint8Array> {
|
||||
// throw undefined;
|
||||
// },
|
||||
getContentText(): Promise<string> {
|
||||
throw undefined;
|
||||
},
|
||||
{
|
||||
path: root.path,
|
||||
ignored: ignore(root.path, root.isDirectory),
|
||||
isDirectory: root.isDirectory,
|
||||
c: root.getChildren,
|
||||
// getContentBytes(): Promise<Uint8Array> {
|
||||
// throw undefined;
|
||||
// },
|
||||
getContentText(): Promise<string> {
|
||||
throw undefined;
|
||||
},
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const e = stack.pop()!;
|
||||
@@ -606,7 +610,13 @@ export async function* readDirRecursiveWithIgnore(
|
||||
|
||||
type Added = { name: "added"; path: string; content: string };
|
||||
type Deleted = { name: "deleted"; path: string };
|
||||
type Edit = { name: "edited"; path: string; before: string; after: string; codebase?: string };
|
||||
type Edit = {
|
||||
name: "edited";
|
||||
path: string;
|
||||
before: string;
|
||||
after: string;
|
||||
codebase?: string;
|
||||
};
|
||||
|
||||
type Change = Added | Deleted | Edit;
|
||||
|
||||
@@ -624,6 +634,15 @@ export async function elementsToMap(
|
||||
if (!json && path.endsWith(".json") && !isFileResource(path)) continue;
|
||||
const ext = json ? ".json" : ".yaml";
|
||||
if (!skips.includeSchedules && path.endsWith(".schedule" + ext)) continue;
|
||||
if (
|
||||
!skips.includeTriggers &&
|
||||
(path.endsWith(".http_trigger" + ext) ||
|
||||
path.endsWith(".websocket_trigger" + ext) ||
|
||||
path.endsWith(".kafka_trigger" + ext) ||
|
||||
path.endsWith(".nats_trigger" + ext) ||
|
||||
path.endsWith(".postgres_trigger" + ext))
|
||||
)
|
||||
continue;
|
||||
if (!skips.includeUsers && path.endsWith(".user" + ext)) continue;
|
||||
if (!skips.includeGroups && path.endsWith(".group" + ext)) continue;
|
||||
if (!skips.includeSettings && path === "settings" + ext) continue;
|
||||
@@ -683,6 +702,7 @@ export interface Skips {
|
||||
skipSecrets?: boolean | undefined;
|
||||
skipScriptsMetadata?: boolean | undefined;
|
||||
includeSchedules?: boolean | undefined;
|
||||
includeTriggers?: boolean | undefined;
|
||||
includeUsers?: boolean | undefined;
|
||||
includeGroups?: boolean | undefined;
|
||||
includeSettings?: boolean | undefined;
|
||||
@@ -700,9 +720,9 @@ async function compareDynFSElement(
|
||||
): Promise<Change[]> {
|
||||
const [m1, m2] = els2
|
||||
? await Promise.all([
|
||||
elementsToMap(els1, ignore, json, skips),
|
||||
elementsToMap(els2, ignore, json, skips),
|
||||
])
|
||||
elementsToMap(els1, ignore, json, skips),
|
||||
elementsToMap(els2, ignore, json, skips),
|
||||
])
|
||||
: [await elementsToMap(els1, ignore, json, skips), {}];
|
||||
|
||||
const changes: Change[] = [];
|
||||
@@ -738,7 +758,8 @@ async function compareDynFSElement(
|
||||
}
|
||||
const codebaseChanges: Record<string, string> = {};
|
||||
for (let [k, v] of Object.entries(m1)) {
|
||||
const isScriptMetadata = k.endsWith(".script.yaml") || k.endsWith(".script.json");
|
||||
const isScriptMetadata =
|
||||
k.endsWith(".script.yaml") || k.endsWith(".script.json");
|
||||
const skipMetadata = skips.skipScriptsMetadata && isScriptMetadata;
|
||||
|
||||
if (m2[k] === undefined) {
|
||||
@@ -749,8 +770,7 @@ async function compareDynFSElement(
|
||||
} else {
|
||||
if (m2[k] == v) {
|
||||
continue;
|
||||
}
|
||||
else if (k.endsWith(".json")) {
|
||||
} else if (k.endsWith(".json")) {
|
||||
if (deepEqual(JSON.parse(v), JSON.parse(m2[k]))) {
|
||||
continue;
|
||||
}
|
||||
@@ -775,14 +795,23 @@ async function compareDynFSElement(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
changes.push({ name: "edited", path: k, after: v, before: m2[k], codebase: codebaseChanges[k] });
|
||||
changes.push({
|
||||
name: "edited",
|
||||
path: k,
|
||||
after: v,
|
||||
before: m2[k],
|
||||
codebase: codebaseChanges[k],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const remoteCodebase: Record<string, string> = {};
|
||||
for (const [k] of Object.entries(m2)) {
|
||||
if (m1[k] === undefined) {
|
||||
if (!ignoreMetadataDeletion || (!k?.endsWith(".script.yaml") && !k?.endsWith(".script.json"))) {
|
||||
if (
|
||||
!ignoreMetadataDeletion ||
|
||||
(!k?.endsWith(".script.yaml") && !k?.endsWith(".script.json"))
|
||||
) {
|
||||
changes.push({ name: "deleted", path: k });
|
||||
} else if (k?.endsWith(".script.yaml")) {
|
||||
let o = parseYaml(k, m2[k]);
|
||||
@@ -795,12 +824,22 @@ async function compareDynFSElement(
|
||||
|
||||
for (const [k, v] of Object.entries(remoteCodebase)) {
|
||||
const tsFile = k.replace(".script.yaml", ".ts");
|
||||
if (changes.find(c => c.path == tsFile && (c.name == "edited" || c.name == "deleted"))) {
|
||||
if (
|
||||
changes.find(
|
||||
(c) => c.path == tsFile && (c.name == "edited" || c.name == "deleted")
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
let c = findCodebase(tsFile, codebases);
|
||||
if (c?.digest != v) {
|
||||
changes.push({ name: "edited", path: tsFile, codebase: v, before: m1[tsFile], after: m2[tsFile] });
|
||||
changes.push({
|
||||
name: "edited",
|
||||
path: tsFile,
|
||||
codebase: v,
|
||||
before: m1[tsFile],
|
||||
after: m2[tsFile],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,16 +880,24 @@ function getOrderFromPath(p: string) {
|
||||
return 6;
|
||||
} else if (typ == "schedule") {
|
||||
return 7;
|
||||
} else if (typ == "variable") {
|
||||
} else if (
|
||||
typ == "http_trigger" ||
|
||||
typ == "websocket_trigger" ||
|
||||
typ == "kafka_trigger" ||
|
||||
typ == "nats_trigger" ||
|
||||
typ == "postgres_trigger"
|
||||
) {
|
||||
return 8;
|
||||
} else if (typ == "user") {
|
||||
} else if (typ == "variable") {
|
||||
return 9;
|
||||
} else if (typ == "group") {
|
||||
} else if (typ == "user") {
|
||||
return 10;
|
||||
} else if (typ == "encryption_key") {
|
||||
} else if (typ == "group") {
|
||||
return 11;
|
||||
} else {
|
||||
} else if (typ == "encryption_key") {
|
||||
return 12;
|
||||
} else {
|
||||
return 13;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,8 +1003,7 @@ async function addToChangedIfNotExists(p: string, tracker: ChangeTracker) {
|
||||
const isScript = exts.some((e) => p.endsWith(e));
|
||||
if (isScript) {
|
||||
if (p.includes(".flow" + SEP)) {
|
||||
const folder =
|
||||
p.substring(0, p.indexOf(".flow" + SEP)) + ".flow" + SEP;
|
||||
const folder = p.substring(0, p.indexOf(".flow" + SEP)) + ".flow" + SEP;
|
||||
if (!tracker.flows.includes(folder)) {
|
||||
tracker.flows.push(folder);
|
||||
}
|
||||
@@ -1031,6 +1077,7 @@ export async function pull(opts: GlobalOptions & SyncOptions) {
|
||||
opts.skipResources,
|
||||
opts.skipSecrets,
|
||||
opts.includeSchedules,
|
||||
opts.includeTriggers,
|
||||
opts.includeUsers,
|
||||
opts.includeGroups,
|
||||
opts.includeSettings,
|
||||
@@ -1071,8 +1118,6 @@ export async function pull(opts: GlobalOptions & SyncOptions) {
|
||||
|
||||
const conflicts = [];
|
||||
|
||||
|
||||
|
||||
log.info(colors.gray(`Applying changes to files ...`));
|
||||
for await (const change of changes) {
|
||||
const target = path.join(Deno.cwd(), change.path);
|
||||
@@ -1224,7 +1269,11 @@ function prettyChanges(changes: Change[]) {
|
||||
);
|
||||
} else if (change.name === "edited") {
|
||||
log.info(
|
||||
colors.yellow(`~ ${getTypeStrFromPath(change.path)} ` + change.path + (change.codebase ? ` (codebase changed)` : ""))
|
||||
colors.yellow(
|
||||
`~ ${getTypeStrFromPath(change.path)} ` +
|
||||
change.path +
|
||||
(change.codebase ? ` (codebase changed)` : "")
|
||||
)
|
||||
);
|
||||
if (change.before != change.after) {
|
||||
showDiff(change.before, change.after);
|
||||
@@ -1300,6 +1349,7 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
opts.skipResources,
|
||||
opts.skipSecrets,
|
||||
opts.includeSchedules,
|
||||
opts.includeTriggers,
|
||||
opts.includeUsers,
|
||||
opts.includeGroups,
|
||||
opts.includeSettings,
|
||||
@@ -1322,7 +1372,6 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
codebases
|
||||
);
|
||||
|
||||
|
||||
const globalDeps = await findGlobalDeps();
|
||||
|
||||
const tracker: ChangeTracker = await buildTracker(changes);
|
||||
@@ -1346,28 +1395,38 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
}
|
||||
|
||||
if (staleScripts.length > 0) {
|
||||
log.info("")
|
||||
log.warn("Stale scripts metadata found, you may want to update them using 'wmill script generate-metadata' before pushing:");
|
||||
log.info("");
|
||||
log.warn(
|
||||
"Stale scripts metadata found, you may want to update them using 'wmill script generate-metadata' before pushing:"
|
||||
);
|
||||
for (const stale of staleScripts) {
|
||||
log.warn(stale);
|
||||
}
|
||||
|
||||
log.info("")
|
||||
log.info("");
|
||||
}
|
||||
|
||||
for (const change of tracker.flows) {
|
||||
const stale = await generateFlowLockInternal(change, true, workspace, false, true);
|
||||
const stale = await generateFlowLockInternal(
|
||||
change,
|
||||
true,
|
||||
workspace,
|
||||
false,
|
||||
true
|
||||
);
|
||||
if (stale) {
|
||||
staleFlows.push(stale);
|
||||
}
|
||||
}
|
||||
|
||||
if (staleFlows.length > 0) {
|
||||
log.warn("Stale flows locks found, you may want to update them using 'wmill flow generate-locks' before pushing:");
|
||||
log.warn(
|
||||
"Stale flows locks found, you may want to update them using 'wmill flow generate-locks' before pushing:"
|
||||
);
|
||||
for (const stale of staleFlows) {
|
||||
log.warn(stale);
|
||||
}
|
||||
log.info("")
|
||||
log.info("");
|
||||
}
|
||||
|
||||
const version = await fetchVersion(workspace.remote);
|
||||
@@ -1393,7 +1452,6 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
const start = performance.now();
|
||||
log.info(colors.gray(`Applying changes to files ...`));
|
||||
|
||||
|
||||
let stateful = opts.stateful;
|
||||
if (stateful) {
|
||||
try {
|
||||
@@ -1406,21 +1464,26 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
// Group changes by base path (before first dot)
|
||||
const groupedChanges = new Map<string, typeof changes>();
|
||||
for (const change of changes) {
|
||||
const basePath = change.path.split('.')[0];
|
||||
const basePath = change.path.split(".")[0];
|
||||
if (!groupedChanges.has(basePath)) {
|
||||
groupedChanges.set(basePath, []);
|
||||
}
|
||||
groupedChanges.get(basePath)!.push(change);
|
||||
}
|
||||
|
||||
|
||||
|
||||
let parallelizationFactor = opts.parallel ?? 1;
|
||||
if (parallelizationFactor <= 0) {
|
||||
parallelizationFactor = 1;
|
||||
}
|
||||
const groupedChangesArray = Array.from(groupedChanges.entries());
|
||||
log.info(`found changes for ${groupedChangesArray.length} items with a total of ${groupedChangesArray.reduce((acc, [_, changes]) => acc + changes.length, 0)} files to process`);
|
||||
log.info(
|
||||
`found changes for ${
|
||||
groupedChangesArray.length
|
||||
} items with a total of ${groupedChangesArray.reduce(
|
||||
(acc, [_, changes]) => acc + changes.length,
|
||||
0
|
||||
)} files to process`
|
||||
);
|
||||
if (parallelizationFactor > 1) {
|
||||
log.info(`Parallelizing ${parallelizationFactor} changes at a time`);
|
||||
}
|
||||
@@ -1481,7 +1544,9 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
}
|
||||
if (stateTarget) {
|
||||
await ensureDir(path.dirname(stateTarget));
|
||||
log.info(`Editing ${getTypeStrFromPath(change.path)} ${change.path}`);
|
||||
log.info(
|
||||
`Editing ${getTypeStrFromPath(change.path)} ${change.path}`
|
||||
);
|
||||
}
|
||||
|
||||
if (isFileResource(change.path)) {
|
||||
@@ -1545,7 +1610,9 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
}
|
||||
if (stateTarget) {
|
||||
await ensureDir(path.dirname(stateTarget));
|
||||
log.info(`Adding ${getTypeStrFromPath(change.path)} ${change.path}`);
|
||||
log.info(
|
||||
`Adding ${getTypeStrFromPath(change.path)} ${change.path}`
|
||||
);
|
||||
}
|
||||
const obj = parseFromPath(change.path, change.content);
|
||||
await pushObj(
|
||||
@@ -1622,6 +1689,36 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
path: removeSuffix(target, ".schedule.json"),
|
||||
});
|
||||
break;
|
||||
case "http_trigger":
|
||||
await wmill.deleteHttpTrigger({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(target, ".http_trigger.json"),
|
||||
});
|
||||
break;
|
||||
case "websocket_trigger":
|
||||
await wmill.deleteWebsocketTrigger({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(target, ".websocket_trigger.json"),
|
||||
});
|
||||
break;
|
||||
case "kafka_trigger":
|
||||
await wmill.deleteKafkaTrigger({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(target, ".kafka_trigger.json"),
|
||||
});
|
||||
break;
|
||||
case "nats_trigger":
|
||||
await wmill.deleteNatsTrigger({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(target, ".nats_trigger.json"),
|
||||
});
|
||||
break;
|
||||
case "postgres_trigger":
|
||||
await wmill.deletePostgresTrigger({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(target, ".postgres_trigger.json"),
|
||||
});
|
||||
break;
|
||||
case "variable":
|
||||
await wmill.deleteVariable({
|
||||
workspace: workspaceId,
|
||||
@@ -1682,7 +1779,9 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
}
|
||||
log.info(
|
||||
colors.bold.green.underline(
|
||||
`\nDone! All ${changes.length} changes pushed to the remote workspace ${workspace.workspaceId} named ${workspace.name} (${(performance.now() - start).toFixed(0)}ms)`
|
||||
`\nDone! All ${changes.length} changes pushed to the remote workspace ${
|
||||
workspace.workspaceId
|
||||
} named ${workspace.name} (${(performance.now() - start).toFixed(0)}ms)`
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1706,6 +1805,7 @@ const command = new Command()
|
||||
.option("--skip-resources", "Skip syncing resources")
|
||||
// .option("--skip-scripts-metadata", "Skip syncing scripts metadata, focus solely on logic")
|
||||
.option("--include-schedules", "Include syncing schedules")
|
||||
.option("--include-triggers", "Include syncing triggers")
|
||||
.option("--include-users", "Include syncing users")
|
||||
.option("--include-groups", "Include syncing groups")
|
||||
.option("--include-settings", "Include syncing workspace settings")
|
||||
@@ -1734,6 +1834,7 @@ const command = new Command()
|
||||
.option("--skip-resources", "Skip syncing resources")
|
||||
// .option("--skip-scripts-metadata", "Skip syncing scripts metadata, focus solely on logic")
|
||||
.option("--include-schedules", "Include syncing schedules")
|
||||
.option("--include-triggers", "Include syncing triggers")
|
||||
.option("--include-users", "Include syncing users")
|
||||
.option("--include-groups", "Include syncing groups")
|
||||
.option("--include-settings", "Include syncing workspace settings")
|
||||
@@ -1754,10 +1855,7 @@ const command = new Command()
|
||||
"--message <message:string>",
|
||||
"Include a message that will be added to all scripts/flows/apps updated during this push"
|
||||
)
|
||||
.option(
|
||||
"--parallel <number>",
|
||||
"Number of changes to process in parallel"
|
||||
)
|
||||
.option("--parallel <number>", "Number of changes to process in parallel")
|
||||
// deno-lint-ignore no-explicit-any
|
||||
.action(push as any);
|
||||
|
||||
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
import * as wmill from "./gen/services.gen.ts";
|
||||
import {
|
||||
HttpTrigger,
|
||||
KafkaTrigger,
|
||||
NatsTrigger,
|
||||
PostgresTrigger,
|
||||
WebsocketTrigger,
|
||||
} from "./gen/types.gen.ts";
|
||||
import { colors, Command, log, SEP, Table } from "./deps.ts";
|
||||
import {
|
||||
GlobalOptions,
|
||||
isSuperset,
|
||||
parseFromFile,
|
||||
removeType,
|
||||
} from "./types.ts";
|
||||
import { requireLogin } from "./context.ts";
|
||||
import { validatePath } from "./context.ts";
|
||||
import { resolveWorkspace } from "./context.ts";
|
||||
|
||||
type Trigger = {
|
||||
http: HttpTrigger;
|
||||
websocket: WebsocketTrigger;
|
||||
kafka: KafkaTrigger;
|
||||
nats: NatsTrigger;
|
||||
postgres: PostgresTrigger;
|
||||
};
|
||||
|
||||
type TriggerFile<K extends TriggerType> = Omit<
|
||||
Trigger[K],
|
||||
| "path"
|
||||
| "workspace"
|
||||
| "edited_by"
|
||||
| "edited_at"
|
||||
| "error"
|
||||
| "last_server_ping"
|
||||
| "server_id"
|
||||
>;
|
||||
|
||||
type TriggerType = keyof Trigger;
|
||||
|
||||
async function getTrigger<K extends TriggerType>(
|
||||
triggerType: K,
|
||||
workspace: string,
|
||||
path: string
|
||||
): Promise<Trigger[K]> {
|
||||
const triggerFunctions: {
|
||||
[K in TriggerType]: (args: {
|
||||
workspace: string;
|
||||
path: string;
|
||||
}) => Promise<Trigger[K]>;
|
||||
} = {
|
||||
http: wmill.getHttpTrigger,
|
||||
websocket: wmill.getWebsocketTrigger,
|
||||
kafka: wmill.getKafkaTrigger,
|
||||
nats: wmill.getNatsTrigger,
|
||||
postgres: wmill.getPostgresTrigger,
|
||||
};
|
||||
const triggerFunction = triggerFunctions[triggerType];
|
||||
|
||||
const trigger = await triggerFunction({ workspace, path });
|
||||
return trigger;
|
||||
}
|
||||
|
||||
async function updateTrigger<K extends TriggerType>(
|
||||
triggerType: K,
|
||||
workspace: string,
|
||||
path: string,
|
||||
trigger: Trigger[K]
|
||||
): Promise<void> {
|
||||
const triggerFunctions: {
|
||||
[K in TriggerType]: (args: {
|
||||
workspace: string;
|
||||
path: string;
|
||||
requestBody: Trigger[K];
|
||||
}) => Promise<any>;
|
||||
} = {
|
||||
http: wmill.updateHttpTrigger,
|
||||
websocket: wmill.updateWebsocketTrigger,
|
||||
kafka: wmill.updateKafkaTrigger,
|
||||
nats: wmill.updateNatsTrigger,
|
||||
postgres: wmill.updatePostgresTrigger,
|
||||
};
|
||||
const triggerFunction = triggerFunctions[triggerType];
|
||||
await triggerFunction({ workspace, path, requestBody: trigger });
|
||||
}
|
||||
|
||||
async function createTrigger<K extends TriggerType>(
|
||||
triggerType: K,
|
||||
workspace: string,
|
||||
path: string,
|
||||
trigger: Trigger[K]
|
||||
): Promise<void> {
|
||||
const triggerFunctions: {
|
||||
[K in TriggerType]: (args: {
|
||||
workspace: string;
|
||||
path: string;
|
||||
requestBody: Trigger[K];
|
||||
}) => Promise<any>;
|
||||
} = {
|
||||
http: wmill.createHttpTrigger,
|
||||
websocket: wmill.createWebsocketTrigger,
|
||||
kafka: wmill.createKafkaTrigger,
|
||||
nats: wmill.createNatsTrigger,
|
||||
postgres: wmill.createPostgresTrigger,
|
||||
};
|
||||
const triggerFunction = triggerFunctions[triggerType];
|
||||
await triggerFunction({ workspace, path, requestBody: trigger });
|
||||
}
|
||||
|
||||
export async function pushTrigger<K extends TriggerType>(
|
||||
triggerType: K,
|
||||
workspace: string,
|
||||
path: string,
|
||||
trigger: TriggerFile<K> | Trigger[K] | undefined,
|
||||
localTrigger: TriggerFile<K>
|
||||
): Promise<void> {
|
||||
path = removeType(path, triggerType + "_trigger").replaceAll(SEP, "/");
|
||||
log.debug(`Processing local ${triggerType} trigger ${path}`);
|
||||
|
||||
try {
|
||||
trigger = await getTrigger(triggerType, workspace, path);
|
||||
log.debug(`${triggerType} trigger ${path} exists on remote`);
|
||||
} catch {
|
||||
log.debug(`${triggerType} trigger ${path} does not exist on remote`);
|
||||
//ignore
|
||||
}
|
||||
|
||||
if (trigger) {
|
||||
if (isSuperset(localTrigger, trigger)) {
|
||||
log.debug(`${triggerType} trigger ${path} is up to date`);
|
||||
return;
|
||||
}
|
||||
log.debug(`${triggerType} trigger ${path} is not up-to-date, updating...`);
|
||||
try {
|
||||
await updateTrigger(triggerType, workspace, path, {
|
||||
...localTrigger,
|
||||
path,
|
||||
} as Trigger[K]);
|
||||
} catch (e) {
|
||||
console.error(e.body);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
colors.bold.yellow(`Creating new ${triggerType} trigger: ${path}`)
|
||||
);
|
||||
try {
|
||||
await createTrigger(triggerType, workspace, path, {
|
||||
...localTrigger,
|
||||
path,
|
||||
} as Trigger[K]);
|
||||
} catch (e) {
|
||||
console.error(e.body);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function list(opts: GlobalOptions) {
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
|
||||
const httpTriggers = await wmill.listHttpTriggers({
|
||||
workspace: workspace.workspaceId,
|
||||
});
|
||||
const websocketTriggers = await wmill.listWebsocketTriggers({
|
||||
workspace: workspace.workspaceId,
|
||||
});
|
||||
const kafkaTriggers = await wmill.listKafkaTriggers({
|
||||
workspace: workspace.workspaceId,
|
||||
});
|
||||
const natsTriggers = await wmill.listNatsTriggers({
|
||||
workspace: workspace.workspaceId,
|
||||
});
|
||||
const postgresTriggers = await wmill.listPostgresTriggers({
|
||||
workspace: workspace.workspaceId,
|
||||
});
|
||||
|
||||
const triggers = [
|
||||
...httpTriggers.map((x) => ({ path: x.path, kind: "http" })),
|
||||
...websocketTriggers.map((x) => ({ path: x.path, kind: "websocket" })),
|
||||
...kafkaTriggers.map((x) => ({ path: x.path, kind: "kafka" })),
|
||||
...natsTriggers.map((x) => ({ path: x.path, kind: "nats" })),
|
||||
...postgresTriggers.map((x) => ({ path: x.path, kind: "postgres" })),
|
||||
];
|
||||
|
||||
new Table()
|
||||
.header(["Path", "Kind"])
|
||||
.padding(2)
|
||||
.border(true)
|
||||
.body(triggers.map((x) => [x.path, x.kind]))
|
||||
.render();
|
||||
}
|
||||
|
||||
function checkIfValidTrigger(kind: string | undefined): kind is TriggerType {
|
||||
if (
|
||||
kind &&
|
||||
["http", "websocket", "kafka", "nats", "postgres"].includes(kind)
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function push(opts: GlobalOptions, filePath: string, remotePath: string) {
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
|
||||
if (!validatePath(remotePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fstat = await Deno.stat(filePath);
|
||||
if (!fstat.isFile) {
|
||||
throw new Error("file path must refer to a file.");
|
||||
}
|
||||
|
||||
console.log(colors.bold.yellow("Pushing trigger..."));
|
||||
|
||||
const triggerKind = filePath.split(".")[1].split("_")[0];
|
||||
if (!checkIfValidTrigger(triggerKind)) {
|
||||
throw new Error("Invalid trigger kind: " + triggerKind);
|
||||
}
|
||||
await pushTrigger(
|
||||
triggerKind,
|
||||
workspace.workspaceId,
|
||||
remotePath,
|
||||
undefined,
|
||||
parseFromFile(filePath)
|
||||
);
|
||||
console.log(colors.bold.underline.green("Trigger pushed"));
|
||||
}
|
||||
|
||||
const command = new Command()
|
||||
.description("trigger related commands")
|
||||
.action(list as any)
|
||||
.command(
|
||||
"push",
|
||||
"push a local trigger spec. This overrides any remote versions."
|
||||
)
|
||||
.arguments("<file_path:string> <remote_path:string>")
|
||||
.action(push as any);
|
||||
|
||||
export default command;
|
||||
+24
-3
@@ -22,6 +22,7 @@ import { pushSchedule } from "./schedule.ts";
|
||||
import { pushWorkspaceUser } from "./user.ts";
|
||||
import { pushGroup } from "./user.ts";
|
||||
import { pushWorkspaceSettings, pushWorkspaceKey } from "./settings.ts";
|
||||
import { pushTrigger } from "./trigger.ts";
|
||||
|
||||
export interface DifferenceCreate {
|
||||
type: "CREATE";
|
||||
@@ -80,7 +81,7 @@ export function showDiff(local: string, remote: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const part of Diff.diffLines(local ?? '', remote ?? '')) {
|
||||
for (const part of Diff.diffLines(local ?? "", remote ?? "")) {
|
||||
if (part.removed) {
|
||||
// print red if removed without newline
|
||||
finalString += `\x1b[31m${part.value}\x1b[0m`;
|
||||
@@ -139,6 +140,16 @@ export async function pushObj(
|
||||
await pushResourceType(workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "schedule") {
|
||||
await pushSchedule(workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "http_trigger") {
|
||||
await pushTrigger("http", workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "websocket_trigger") {
|
||||
await pushTrigger("websocket", workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "kafka_trigger") {
|
||||
await pushTrigger("kafka", workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "nats_trigger") {
|
||||
await pushTrigger("nats", workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "postgres_trigger") {
|
||||
await pushTrigger("postgres", workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "user") {
|
||||
await pushWorkspaceUser(workspace, p, befObj, newObj);
|
||||
} else if (typeEnding === "group") {
|
||||
@@ -158,8 +169,8 @@ export function parseFromPath(p: string, content: string): any {
|
||||
return p.endsWith(".yaml")
|
||||
? yamlParseContent(p, content)
|
||||
: p.endsWith(".json")
|
||||
? JSON.parse(content)
|
||||
: content;
|
||||
? JSON.parse(content)
|
||||
: content;
|
||||
}
|
||||
export function parseFromFile(p: string): any {
|
||||
if (p.endsWith(".json")) {
|
||||
@@ -181,6 +192,11 @@ export function getTypeStrFromPath(
|
||||
| "folder"
|
||||
| "app"
|
||||
| "schedule"
|
||||
| "http_trigger"
|
||||
| "websocket_trigger"
|
||||
| "kafka_trigger"
|
||||
| "nats_trigger"
|
||||
| "postgres_trigger"
|
||||
| "user"
|
||||
| "group"
|
||||
| "settings"
|
||||
@@ -221,6 +237,11 @@ export function getTypeStrFromPath(
|
||||
typeEnding === "resource-type" ||
|
||||
typeEnding === "app" ||
|
||||
typeEnding === "schedule" ||
|
||||
typeEnding === "http_trigger" ||
|
||||
typeEnding === "websocket_trigger" ||
|
||||
typeEnding === "kafka_trigger" ||
|
||||
typeEnding === "nats_trigger" ||
|
||||
typeEnding === "postgres_trigger" ||
|
||||
typeEnding === "user" ||
|
||||
typeEnding === "group" ||
|
||||
typeEnding === "settings" ||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.458.3",
|
||||
"version": "1.458.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.458.3",
|
||||
"version": "1.458.4",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.32.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.458.3",
|
||||
"version": "1.458.4",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -120,6 +120,8 @@
|
||||
}
|
||||
if (e.detail == 'date-time') {
|
||||
format = 'date-time'
|
||||
} else if (format) {
|
||||
format = undefined
|
||||
}
|
||||
if (e.detail == 'none') {
|
||||
pattern = undefined
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
goto('/user/workspaces')
|
||||
}
|
||||
|
||||
const defaultExtraTriggerLinks = [
|
||||
$: defaultExtraTriggerLinks = [
|
||||
{
|
||||
label: 'HTTP',
|
||||
href: '/routes',
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.458.3"
|
||||
wmill_pg = ">=1.458.3"
|
||||
wmill = ">=1.458.4"
|
||||
wmill_pg = ">=1.458.4"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.458.3
|
||||
version: 1.458.4
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'WindmillClient.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.458.3'
|
||||
ModuleVersion = '1.458.4'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
description = "A client library for accessing Windmill server wrapping the Windmill client API"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill-pg"
|
||||
version = "1.458.3"
|
||||
version = "1.458.4"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@windmill/windmill",
|
||||
"version": "1.458.3",
|
||||
"version": "1.458.4",
|
||||
"exports": "./src/index.ts",
|
||||
"publish": {
|
||||
"exclude": ["!src", "./s3Types.ts", "./client.ts"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "windmill-client",
|
||||
"description": "Windmill SDK client for browsers and Node.js",
|
||||
"version": "1.458.3",
|
||||
"version": "1.458.4",
|
||||
"author": "Ruben Fiszel",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.458.3
|
||||
1.458.4
|
||||
|
||||
Reference in New Issue
Block a user