diff --git a/backend/.sqlx/query-08ca7828d9f10bb7e4ee1c1df4bafd70b39ecae360773bf10d65f5db7b1821c5.json b/backend/.sqlx/query-08ca7828d9f10bb7e4ee1c1df4bafd70b39ecae360773bf10d65f5db7b1821c5.json new file mode 100644 index 0000000000..3b75a37617 --- /dev/null +++ b/backend/.sqlx/query-08ca7828d9f10bb7e4ee1c1df4bafd70b39ecae360773bf10d65f5db7b1821c5.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO deployment_metadata (workspace_id, path, callback_job_ids) VALUES ($1, $2, $3) ON CONFLICT (workspace_id, path) WHERE script_hash IS NULL AND app_version IS NULL DO UPDATE SET callback_job_ids = $3", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "UuidArray" + ] + }, + "nullable": [] + }, + "hash": "08ca7828d9f10bb7e4ee1c1df4bafd70b39ecae360773bf10d65f5db7b1821c5" +} diff --git a/backend/.sqlx/query-11ae5e1aade2bc9a78af2d956ece73766ae3330319619a68383b508a76f2d19c.json b/backend/.sqlx/query-11ae5e1aade2bc9a78af2d956ece73766ae3330319619a68383b508a76f2d19c.json index d54ce25120..2cb08ba2d4 100644 --- a/backend/.sqlx/query-11ae5e1aade2bc9a78af2d956ece73766ae3330319619a68383b508a76f2d19c.json +++ b/backend/.sqlx/query-11ae5e1aade2bc9a78af2d956ece73766ae3330319619a68383b508a76f2d19c.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json b/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json index adf3055d35..5b50d07303 100644 --- a/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json +++ b/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json @@ -87,6 +87,11 @@ "ordinal": 16, "name": "large_file_storage", "type_info": "Jsonb" + }, + { + "ordinal": 17, + "name": "git_sync", + "type_info": "Jsonb" } ], "parameters": { @@ -111,6 +116,7 @@ false, true, false, + true, true ] }, diff --git a/backend/.sqlx/query-238ab39af085912580b92ae7a482dae44b565a5f205fa33e9b5b35a34744b61d.json b/backend/.sqlx/query-238ab39af085912580b92ae7a482dae44b565a5f205fa33e9b5b35a34744b61d.json new file mode 100644 index 0000000000..1f62653819 --- /dev/null +++ b/backend/.sqlx/query-238ab39af085912580b92ae7a482dae44b565a5f205fa33e9b5b35a34744b61d.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO deployment_metadata (workspace_id, path, app_version, callback_job_ids) VALUES ($1, $2, $3, $4)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "Int8", + "UuidArray" + ] + }, + "nullable": [] + }, + "hash": "238ab39af085912580b92ae7a482dae44b565a5f205fa33e9b5b35a34744b61d" +} diff --git a/backend/.sqlx/query-254776959f60455a00a2c29a1783ee6b27c836197df6454d3bb5c59441c34f44.json b/backend/.sqlx/query-254776959f60455a00a2c29a1783ee6b27c836197df6454d3bb5c59441c34f44.json index 297c78d0e7..4348a5ffd0 100644 --- a/backend/.sqlx/query-254776959f60455a00a2c29a1783ee6b27c836197df6454d3bb5c59441c34f44.json +++ b/backend/.sqlx/query-254776959f60455a00a2c29a1783ee6b27c836197df6454d3bb5c59441c34f44.json @@ -45,7 +45,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } @@ -67,7 +68,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-2dd55a9987fce9187fcaf00e4d8bcbe42f0d233f6f973ec77b44518a5c361b2c.json b/backend/.sqlx/query-2dd55a9987fce9187fcaf00e4d8bcbe42f0d233f6f973ec77b44518a5c361b2c.json new file mode 100644 index 0000000000..4168d0ec14 --- /dev/null +++ b/backend/.sqlx/query-2dd55a9987fce9187fcaf00e4d8bcbe42f0d233f6f973ec77b44518a5c361b2c.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO deployment_metadata (workspace_id, path, script_hash, callback_job_ids) VALUES ($1, $2, $3, $4)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "Int8", + "UuidArray" + ] + }, + "nullable": [] + }, + "hash": "2dd55a9987fce9187fcaf00e4d8bcbe42f0d233f6f973ec77b44518a5c361b2c" +} diff --git a/backend/.sqlx/query-51d253d3cba9e2a36c291f6f9cf7023834484e89d91f0267d9dcaaafe406c64c.json b/backend/.sqlx/query-51d253d3cba9e2a36c291f6f9cf7023834484e89d91f0267d9dcaaafe406c64c.json new file mode 100644 index 0000000000..a035385cef --- /dev/null +++ b/backend/.sqlx/query-51d253d3cba9e2a36c291f6f9cf7023834484e89d91f0267d9dcaaafe406c64c.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings SET git_sync = NULL WHERE workspace_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "51d253d3cba9e2a36c291f6f9cf7023834484e89d91f0267d9dcaaafe406c64c" +} diff --git a/backend/.sqlx/query-52ad1773a9f5a1b6be1bb16af408f051f27d3f21b615c468b85aa75b64d943db.json b/backend/.sqlx/query-52ad1773a9f5a1b6be1bb16af408f051f27d3f21b615c468b85aa75b64d943db.json index f383776194..bf25140825 100644 --- a/backend/.sqlx/query-52ad1773a9f5a1b6be1bb16af408f051f27d3f21b615c468b85aa75b64d943db.json +++ b/backend/.sqlx/query-52ad1773a9f5a1b6be1bb16af408f051f27d3f21b615c468b85aa75b64d943db.json @@ -28,7 +28,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-5445083864b2b092b012e894bff7630a1d7b9deb8d33e9f909061f351f96844e.json b/backend/.sqlx/query-5445083864b2b092b012e894bff7630a1d7b9deb8d33e9f909061f351f96844e.json index 525891e500..a571eb385e 100644 --- a/backend/.sqlx/query-5445083864b2b092b012e894bff7630a1d7b9deb8d33e9f909061f351f96844e.json +++ b/backend/.sqlx/query-5445083864b2b092b012e894bff7630a1d7b9deb8d33e9f909061f351f96844e.json @@ -87,6 +87,11 @@ "ordinal": 16, "name": "large_file_storage", "type_info": "Jsonb" + }, + { + "ordinal": 17, + "name": "git_sync", + "type_info": "Jsonb" } ], "parameters": { @@ -111,6 +116,7 @@ false, true, false, + true, true ] }, diff --git a/backend/.sqlx/query-620ddf29c5e867079df4c2aa6e80bccb19beeb9ddfa308ca97f254cd5ba8157e.json b/backend/.sqlx/query-620ddf29c5e867079df4c2aa6e80bccb19beeb9ddfa308ca97f254cd5ba8157e.json index bc67744b37..4161dd7065 100644 --- a/backend/.sqlx/query-620ddf29c5e867079df4c2aa6e80bccb19beeb9ddfa308ca97f254cd5ba8157e.json +++ b/backend/.sqlx/query-620ddf29c5e867079df4c2aa6e80bccb19beeb9ddfa308ca97f254cd5ba8157e.json @@ -40,7 +40,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } @@ -60,7 +61,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json b/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json index 6008792091..90db377fbf 100644 --- a/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json +++ b/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json @@ -24,7 +24,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } @@ -40,7 +41,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-a9915d3c72a278ff08fbe6571c2a4fc993507e255004107345b7151322e063de.json b/backend/.sqlx/query-a9915d3c72a278ff08fbe6571c2a4fc993507e255004107345b7151322e063de.json index 54d56094f2..212a2a5f66 100644 --- a/backend/.sqlx/query-a9915d3c72a278ff08fbe6571c2a4fc993507e255004107345b7151322e063de.json +++ b/backend/.sqlx/query-a9915d3c72a278ff08fbe6571c2a4fc993507e255004107345b7151322e063de.json @@ -30,7 +30,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } @@ -46,7 +47,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-b6074eb9369de071f79165bf506fbc44f1688035e1928b4c3649d875187b1e1d.json b/backend/.sqlx/query-b6074eb9369de071f79165bf506fbc44f1688035e1928b4c3649d875187b1e1d.json index ac27ab1d70..f5122a7f3c 100644 --- a/backend/.sqlx/query-b6074eb9369de071f79165bf506fbc44f1688035e1928b4c3649d875187b1e1d.json +++ b/backend/.sqlx/query-b6074eb9369de071f79165bf506fbc44f1688035e1928b4c3649d875187b1e1d.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-c7febee7146a28481ce36f3570bceb38751a6527827525a582d9f8804981f552.json b/backend/.sqlx/query-c7febee7146a28481ce36f3570bceb38751a6527827525a582d9f8804981f552.json index 18342de0fe..603bea689f 100644 --- a/backend/.sqlx/query-c7febee7146a28481ce36f3570bceb38751a6527827525a582d9f8804981f552.json +++ b/backend/.sqlx/query-c7febee7146a28481ce36f3570bceb38751a6527827525a582d9f8804981f552.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-d48070ef889723f408ed6c1a97b5ab9f0e98340cd33c6e29824f6030f0089071.json b/backend/.sqlx/query-d48070ef889723f408ed6c1a97b5ab9f0e98340cd33c6e29824f6030f0089071.json index 5b24664a2f..53974ad40e 100644 --- a/backend/.sqlx/query-d48070ef889723f408ed6c1a97b5ab9f0e98340cd33c6e29824f6030f0089071.json +++ b/backend/.sqlx/query-d48070ef889723f408ed6c1a97b5ab9f0e98340cd33c6e29824f6030f0089071.json @@ -37,7 +37,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-ec4f70d9e6392ade016245de73e7a2831d430838307b086c96511f91e76a214a.json b/backend/.sqlx/query-ec4f70d9e6392ade016245de73e7a2831d430838307b086c96511f91e76a214a.json new file mode 100644 index 0000000000..3f39f6beff --- /dev/null +++ b/backend/.sqlx/query-ec4f70d9e6392ade016245de73e7a2831d430838307b086c96511f91e76a214a.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings SET git_sync = $1 WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Jsonb", + "Text" + ] + }, + "nullable": [] + }, + "hash": "ec4f70d9e6392ade016245de73e7a2831d430838307b086c96511f91e76a214a" +} diff --git a/backend/.sqlx/query-fc2ec6fc4e22e46cc35b00503eff1eac35a6fdbc82a634b7eb9da4d7931f3582.json b/backend/.sqlx/query-fc2ec6fc4e22e46cc35b00503eff1eac35a6fdbc82a634b7eb9da4d7931f3582.json index 145dd54e3d..eb43db0504 100644 --- a/backend/.sqlx/query-fc2ec6fc4e22e46cc35b00503eff1eac35a6fdbc82a634b7eb9da4d7931f3582.json +++ b/backend/.sqlx/query-fc2ec6fc4e22e46cc35b00503eff1eac35a6fdbc82a634b7eb9da4d7931f3582.json @@ -39,7 +39,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } @@ -61,7 +62,8 @@ "graphql", "postgresql", "noop", - "appdependencies" + "appdependencies", + "deploymentcallback" ] } } diff --git a/backend/migrations/20231129164511_git_repo_workspace_setting.down.sql b/backend/migrations/20231129164511_git_repo_workspace_setting.down.sql new file mode 100644 index 0000000000..f511f8bb9b --- /dev/null +++ b/backend/migrations/20231129164511_git_repo_workspace_setting.down.sql @@ -0,0 +1,4 @@ +-- Add down migration script here +ALTER TABLE workspace_settings DROP COLUMN git_sync; + +DROP TABLE IF EXISTS deployment_metadata; diff --git a/backend/migrations/20231129164511_git_repo_workspace_setting.up.sql b/backend/migrations/20231129164511_git_repo_workspace_setting.up.sql new file mode 100644 index 0000000000..ed820cf694 --- /dev/null +++ b/backend/migrations/20231129164511_git_repo_workspace_setting.up.sql @@ -0,0 +1,16 @@ +-- Add up migration script here +ALTER TYPE JOB_KIND ADD VALUE IF NOT EXISTS 'deploymentcallback'; +ALTER TABLE workspace_settings ADD COLUMN IF NOT EXISTS git_sync JSONB; + +CREATE TABLE deployment_metadata( + workspace_id VARCHAR(50) NOT NULL REFERENCES workspace(id), + path VARCHAR(255) NOT NULL, + script_hash BIGINT, + app_version BIGSERIAL, + callback_job_ids UUID[], + deployment_msg TEXT +); + +CREATE UNIQUE INDEX IF NOT EXISTS deployment_metadata_script ON deployment_metadata (workspace_id, script_hash) WHERE script_hash IS NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS deployment_metadata_flow ON deployment_metadata (workspace_id, path) WHERE script_hash IS NULL AND app_version IS NULL; +CREATE UNIQUE INDEX IF NOT EXISTS deployment_metadata_app ON deployment_metadata (workspace_id, path, app_version) WHERE app_version IS NOT NULL; diff --git a/backend/windmill-api/openapi-deref.yaml b/backend/windmill-api/openapi-deref.yaml index 451c47cf4f..230eb7371d 100644 --- a/backend/windmill-api/openapi-deref.yaml +++ b/backend/windmill-api/openapi-deref.yaml @@ -1,6 +1,6 @@ openapi: 3.0.3 info: - version: 1.217.0 + version: 1.219.1 title: Windmill API contact: name: Windmill Team @@ -87,7 +87,7 @@ paths: - name: id in: path required: true - schema: &ref_23 + schema: &ref_25 type: integer responses: '200': @@ -231,34 +231,34 @@ paths: - name: before description: filter on created before (exclusive) timestamp in: query - schema: &ref_97 + schema: &ref_99 type: string format: date-time - name: after description: filter on created after (exclusive) timestamp in: query - schema: &ref_96 + schema: &ref_98 type: string format: date-time - name: username description: filter on exact username of user in: query - schema: &ref_98 + schema: &ref_100 type: string - name: operation description: filter on exact or prefix name of operation in: query - schema: &ref_99 + schema: &ref_101 type: string - name: resource description: filter on exact or prefix name of resource in: query - schema: &ref_100 + schema: &ref_102 type: string - name: action_kind description: filter on type of operation in: query - schema: &ref_101 + schema: &ref_103 type: string enum: - Create @@ -290,12 +290,12 @@ paths: application/json: schema: type: object - properties: &ref_111 + properties: &ref_113 email: type: string password: type: string - required: &ref_112 + required: &ref_114 - email - password responses: @@ -351,14 +351,14 @@ paths: application/json: schema: type: object - properties: &ref_113 + properties: &ref_115 email: type: string username: type: string is_admin: type: boolean - required: &ref_114 + required: &ref_116 - email - username - is_admin @@ -393,7 +393,7 @@ paths: application/json: schema: type: object - properties: &ref_115 + properties: &ref_117 is_admin: type: boolean operator: @@ -421,7 +421,7 @@ paths: - name: path in: path required: true - schema: &ref_16 + schema: &ref_18 type: string responses: '200': @@ -616,7 +616,7 @@ paths: application/json: schema: type: object - properties: &ref_143 + properties: &ref_145 email: type: string workspaces: @@ -634,7 +634,7 @@ paths: - id - name - username - required: &ref_144 + required: &ref_146 - email - workspaces /workspaces/list_as_superadmin: @@ -676,14 +676,14 @@ paths: application/json: schema: type: object - properties: &ref_145 + properties: &ref_147 id: type: string name: type: string username: type: string - required: &ref_146 + required: &ref_148 - id - name - username @@ -1124,7 +1124,7 @@ paths: type: string usage: type: object - properties: &ref_110 + properties: &ref_112 executions: type: number required: &ref_9 @@ -1524,6 +1524,16 @@ paths: - S3Storage s3_resource_path: type: string + git_sync: + type: object + properties: &ref_16 + script_path: + type: string + git_repo_resource_path: + type: string + required: &ref_17 + - script_path + - git_repo_resource_path required: - code_completion_enabled /w/{workspace}/workspaces/get_deploy_to: @@ -1859,6 +1869,35 @@ paths: content: application/json: schema: {} + /w/{workspace}/workspaces/edit_git_sync_config: + post: + summary: edit workspace git sync settings + operationId: editWorkspaceGitSyncConfig + tags: + - workspace + parameters: + - name: workspace + in: path + required: true + schema: *ref_0 + requestBody: + description: Workspace Git sync settings + required: true + content: + application/json: + schema: + type: object + properties: + git_sync_settings: + type: object + properties: *ref_16 + required: *ref_17 + responses: + '200': + description: status + content: + application/json: + schema: {} /w/{workspace}/workspaces/get_large_file_storage_config: get: summary: get large file storage config @@ -1933,7 +1972,7 @@ paths: application/json: schema: type: object - properties: &ref_118 + properties: &ref_120 label: type: string expiration: @@ -1963,7 +2002,7 @@ paths: application/json: schema: type: object - properties: &ref_119 + properties: &ref_121 label: type: string expiration: @@ -1971,7 +2010,7 @@ paths: format: date-time impersonate_email: type: string - required: &ref_120 + required: &ref_122 - impersonate_email responses: '201': @@ -2019,7 +2058,7 @@ paths: type: array items: type: object - properties: &ref_116 + properties: &ref_118 label: type: string expiration: @@ -2037,7 +2076,7 @@ paths: type: array items: type: string - required: &ref_117 + required: &ref_119 - token_prefix - created_at - last_used_at @@ -2063,7 +2102,7 @@ paths: application/json: schema: type: object - properties: &ref_123 + properties: &ref_125 path: type: string value: @@ -2076,7 +2115,7 @@ paths: type: integer is_oauth: type: boolean - required: &ref_124 + required: &ref_126 - path - value - is_secret @@ -2127,7 +2166,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: variable deleted @@ -2149,7 +2188,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: already_encrypted in: query schema: @@ -2161,7 +2200,7 @@ paths: application/json: schema: type: object - properties: &ref_125 + properties: &ref_127 path: type: string value: @@ -2191,7 +2230,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: decrypt_secret description: | ask to decrypt secret if this variable is secret @@ -2206,7 +2245,7 @@ paths: application/json: schema: type: object - properties: &ref_17 + properties: &ref_19 workspace_id: type: string path: @@ -2233,7 +2272,7 @@ paths: type: boolean is_refreshed: type: boolean - required: &ref_18 + required: &ref_20 - workspace_id - path - is_secret @@ -2252,7 +2291,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: variable @@ -2274,7 +2313,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: variable @@ -2302,8 +2341,8 @@ paths: type: array items: type: object - properties: *ref_17 - required: *ref_18 + properties: *ref_19 + required: *ref_20 /w/{workspace}/variables/list_contextual: get: summary: list contextual variables @@ -2324,14 +2363,14 @@ paths: type: array items: type: object - properties: &ref_121 + properties: &ref_123 name: type: string value: type: string description: type: string - required: &ref_122 + required: &ref_124 - name - value - description @@ -2346,7 +2385,7 @@ paths: - name: client_name in: path required: true - schema: &ref_19 + schema: &ref_21 type: string requestBody: description: Partially filled script @@ -2419,7 +2458,7 @@ paths: - name: client_name in: path required: true - schema: *ref_19 + schema: *ref_21 requestBody: description: code endpoint required: true @@ -2442,7 +2481,7 @@ paths: application/json: schema: type: object - properties: &ref_157 + properties: &ref_159 access_token: type: string expires_in: @@ -2453,7 +2492,7 @@ paths: type: array items: type: string - required: &ref_158 + required: &ref_160 - access_token /w/{workspace}/oauth/create_account: post: @@ -2507,7 +2546,7 @@ paths: - name: id in: path required: true - schema: &ref_20 + schema: &ref_22 type: integer requestBody: description: variable path @@ -2542,7 +2581,7 @@ paths: - name: id in: path required: true - schema: *ref_20 + schema: *ref_22 responses: '200': description: disconnected client @@ -2634,7 +2673,7 @@ paths: application/json: schema: type: object - properties: &ref_128 + properties: &ref_130 path: type: string value: {} @@ -2642,7 +2681,7 @@ paths: type: string resource_type: type: string - required: &ref_129 + required: &ref_131 - path - value - resource_type @@ -2667,7 +2706,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource deleted @@ -2689,7 +2728,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 requestBody: description: updated resource required: true @@ -2697,7 +2736,7 @@ paths: application/json: schema: type: object - properties: &ref_130 + properties: &ref_132 path: type: string description: @@ -2724,7 +2763,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 requestBody: description: updated resource required: true @@ -2755,7 +2794,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource @@ -2763,7 +2802,7 @@ paths: application/json: schema: type: object - properties: &ref_131 + properties: &ref_133 workspace_id: type: string path: @@ -2779,7 +2818,7 @@ paths: type: object additionalProperties: type: boolean - required: &ref_132 + required: &ref_134 - path - resource_type - is_oauth @@ -2797,7 +2836,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: job_id description: job id in: query @@ -2824,7 +2863,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource value @@ -2845,7 +2884,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: does resource exists @@ -2891,7 +2930,7 @@ paths: type: array items: type: object - properties: &ref_133 + properties: &ref_135 workspace_id: type: string path: @@ -2917,7 +2956,7 @@ paths: type: boolean account: type: number - required: &ref_134 + required: &ref_136 - path - resource_type - is_oauth @@ -2964,7 +3003,7 @@ paths: - name: name in: path required: true - schema: &ref_76 + schema: &ref_78 type: string responses: '200': @@ -3001,7 +3040,7 @@ paths: application/json: schema: type: object - properties: &ref_21 + properties: &ref_23 workspace_id: type: string name: @@ -3009,7 +3048,7 @@ paths: schema: {} description: type: string - required: &ref_22 + required: &ref_24 - name responses: '201': @@ -3032,7 +3071,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource_type deleted @@ -3054,7 +3093,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 requestBody: description: updated resource_type required: true @@ -3062,7 +3101,7 @@ paths: application/json: schema: type: object - properties: &ref_135 + properties: &ref_137 schema: {} description: type: string @@ -3087,7 +3126,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource_type deleted @@ -3095,8 +3134,8 @@ paths: application/json: schema: type: object - properties: *ref_21 - required: *ref_22 + properties: *ref_23 + required: *ref_24 /w/{workspace}/resources/type/exists/{path}: get: summary: does resource_type exists @@ -3111,7 +3150,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: does resource_type exist @@ -3139,8 +3178,8 @@ paths: type: array items: type: object - properties: *ref_21 - required: *ref_22 + properties: *ref_23 + required: *ref_24 /w/{workspace}/resources/type/listnames: get: summary: list resource_types names @@ -3279,7 +3318,7 @@ paths: - name: id in: path required: true - schema: *ref_23 + schema: *ref_25 responses: '200': description: flow @@ -3290,43 +3329,32 @@ paths: properties: flow: type: object - properties: &ref_41 + properties: &ref_43 summary: type: string description: type: string value: type: object - properties: &ref_48 + properties: &ref_50 modules: type: array items: type: object - properties: &ref_26 + properties: &ref_28 id: type: string value: - oneOf: &ref_184 + oneOf: &ref_186 - type: object - properties: &ref_168 + properties: &ref_170 input_transforms: type: object additionalProperties: - oneOf: &ref_24 - - type: object - properties: &ref_164 - value: {} - type: - type: string - enum: - - javascript - required: &ref_165 - - expr - - type + oneOf: &ref_26 - type: object properties: &ref_166 - expr: - type: string + value: {} type: type: string enum: @@ -3334,7 +3362,18 @@ paths: required: &ref_167 - expr - type - discriminator: &ref_25 + - type: object + properties: &ref_168 + expr: + type: string + type: + type: string + enum: + - javascript + required: &ref_169 + - expr + - type + discriminator: &ref_27 propertyName: type mapping: static: '#/components/schemas/StaticTransform' @@ -3371,18 +3410,18 @@ paths: type: number concurrency_time_window_s: type: number - required: &ref_169 + required: &ref_171 - type - content - language - input_transforms - type: object - properties: &ref_170 + properties: &ref_172 input_transforms: type: object additionalProperties: - oneOf: *ref_24 - discriminator: *ref_25 + oneOf: *ref_26 + discriminator: *ref_27 path: type: string hash: @@ -3391,40 +3430,40 @@ paths: type: string enum: - script - required: &ref_171 - - type - - path - - input_transforms - - type: object - properties: &ref_172 - input_transforms: - type: object - additionalProperties: - oneOf: *ref_24 - discriminator: *ref_25 - path: - type: string - type: - type: string - enum: - - flow required: &ref_173 - type - path - input_transforms - type: object properties: &ref_174 + input_transforms: + type: object + additionalProperties: + oneOf: *ref_26 + discriminator: *ref_27 + path: + type: string + type: + type: string + enum: + - flow + required: &ref_175 + - type + - path + - input_transforms + - type: object + properties: &ref_176 modules: type: array items: type: object - properties: *ref_26 - required: &ref_27 + properties: *ref_28 + required: &ref_29 - value - id iterator: - oneOf: *ref_24 - discriminator: *ref_25 + oneOf: *ref_26 + discriminator: *ref_27 skip_failures: type: boolean type: @@ -3435,13 +3474,13 @@ paths: type: boolean parallelism: type: integer - required: &ref_175 + required: &ref_177 - modules - iterator - skip_failures - type - type: object - properties: &ref_176 + properties: &ref_178 branches: type: array items: @@ -3455,8 +3494,8 @@ paths: type: array items: type: object - properties: *ref_26 - required: *ref_27 + properties: *ref_28 + required: *ref_29 required: - modules - expr @@ -3464,20 +3503,20 @@ paths: type: array items: type: object - properties: *ref_26 - required: *ref_27 + properties: *ref_28 + required: *ref_29 required: - modules type: type: string enum: - branchone - required: &ref_177 + required: &ref_179 - branches - default - type - type: object - properties: &ref_178 + properties: &ref_180 branches: type: array items: @@ -3491,8 +3530,8 @@ paths: type: array items: type: object - properties: *ref_26 - required: *ref_27 + properties: *ref_28 + required: *ref_29 required: - modules - expr @@ -3502,28 +3541,28 @@ paths: - branchall parallel: type: boolean - required: &ref_179 - - branches - - type - - type: object - properties: &ref_180 - type: - type: string - enum: - - identity - flow: - type: boolean required: &ref_181 + - branches - type - type: object properties: &ref_182 type: type: string enum: - - graphql + - identity + flow: + type: boolean required: &ref_183 - type - discriminator: &ref_185 + - type: object + properties: &ref_184 + type: + type: string + enum: + - graphql + required: &ref_185 + - type + discriminator: &ref_187 propertyName: type mapping: rawscript: '#/components/schemas/RawScript' @@ -3544,12 +3583,14 @@ paths: required: - expr sleep: - oneOf: *ref_24 - discriminator: *ref_25 + oneOf: *ref_26 + discriminator: *ref_27 cache_ttl: type: number timeout: type: number + delete_after_use: + type: boolean summary: type: string mock: @@ -3573,13 +3614,13 @@ paths: user_auth_required: type: boolean user_groups_required: - oneOf: *ref_24 - discriminator: *ref_25 + oneOf: *ref_26 + discriminator: *ref_27 priority: type: number retry: type: object - properties: &ref_186 + properties: &ref_188 constant: type: object properties: @@ -3596,11 +3637,11 @@ paths: type: integer seconds: type: integer - required: *ref_27 + required: *ref_29 failure_module: type: object - properties: *ref_26 - required: *ref_27 + properties: *ref_28 + required: *ref_29 same_worker: type: boolean concurrent_limit: @@ -3615,11 +3656,11 @@ paths: type: number early_return: type: string - required: &ref_49 + required: &ref_51 - modules schema: type: object - required: &ref_42 + required: &ref_44 - summary - value /apps/hub/list: @@ -3672,7 +3713,7 @@ paths: - name: id in: path required: true - schema: *ref_23 + schema: *ref_25 responses: '200': description: app @@ -3702,7 +3743,7 @@ paths: - name: path in: path required: true - schema: &ref_28 + schema: &ref_30 type: string responses: '200': @@ -3721,7 +3762,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script details @@ -3792,7 +3833,7 @@ paths: type: number kind: name: kind - schema: &ref_29 + schema: &ref_31 type: string enum: - script @@ -3865,7 +3906,7 @@ paths: type: string kind: name: kind - schema: *ref_29 + schema: *ref_31 score: type: number required: @@ -3926,12 +3967,12 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: &ref_39 + schema: &ref_41 type: boolean - name: created_by description: mask to filter exact matching user creator in: query - schema: &ref_40 + schema: &ref_42 type: string - name: path_start description: mask to filter matching starting path @@ -4024,7 +4065,7 @@ paths: type: array items: type: object - properties: &ref_30 + properties: &ref_32 workspace_id: type: string hash: @@ -4113,7 +4154,13 @@ paths: type: boolean priority: type: integer - required: &ref_31 + restart_unless_cancelled: + type: boolean + timeout: + type: integer + delete_after_use: + type: boolean + required: &ref_33 - hash - path - summary @@ -4209,7 +4256,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: draft deleted @@ -4235,7 +4282,7 @@ paths: application/json: schema: type: object - properties: &ref_33 + properties: &ref_35 path: type: string parent_hash: @@ -4298,7 +4345,13 @@ paths: type: boolean priority: type: integer - required: &ref_34 + restart_unless_cancelled: + type: boolean + timeout: + type: integer + delete_after_use: + type: boolean + required: &ref_36 - path - summary - description @@ -4325,7 +4378,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: Workspace error handler enabled required: true @@ -4374,7 +4427,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script archived @@ -4396,7 +4449,7 @@ paths: - name: hash in: path required: true - schema: &ref_32 + schema: &ref_34 type: string responses: '200': @@ -4405,8 +4458,8 @@ paths: application/json: schema: type: object - properties: *ref_30 - required: *ref_31 + properties: *ref_32 + required: *ref_33 /w/{workspace}/scripts/delete/h/{hash}: post: summary: delete script by hash (erase content but keep hash, require admin) @@ -4421,7 +4474,7 @@ paths: - name: hash in: path required: true - schema: *ref_32 + schema: *ref_34 responses: '200': description: script details @@ -4429,8 +4482,8 @@ paths: application/json: schema: type: object - properties: *ref_30 - required: *ref_31 + properties: *ref_32 + required: *ref_33 /w/{workspace}/scripts/delete/p/{path}: post: summary: delete all scripts at a given path (require admin) @@ -4445,7 +4498,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script path @@ -4467,7 +4520,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script details @@ -4475,8 +4528,8 @@ paths: application/json: schema: type: object - properties: *ref_30 - required: *ref_31 + properties: *ref_32 + required: *ref_33 /w/{workspace}/scripts/get/draft/{path}: get: summary: get script by path with draft @@ -4491,23 +4544,23 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script details content: application/json: schema: - allOf: &ref_104 + allOf: &ref_106 - type: object - properties: *ref_33 - required: *ref_34 + properties: *ref_35 + required: *ref_36 - type: object properties: draft: type: object - properties: *ref_33 - required: *ref_34 + properties: *ref_35 + required: *ref_36 hash: type: string required: @@ -4526,7 +4579,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script content @@ -4550,12 +4603,12 @@ paths: - name: token in: path required: true - schema: &ref_92 + schema: &ref_94 type: string - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script content @@ -4577,7 +4630,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: does it exists @@ -4599,7 +4652,7 @@ paths: - name: hash in: path required: true - schema: *ref_32 + schema: *ref_34 responses: '200': description: script details @@ -4607,8 +4660,8 @@ paths: application/json: schema: type: object - properties: *ref_30 - required: *ref_31 + properties: *ref_32 + required: *ref_33 /w/{workspace}/scripts/raw/h/{path}: get: summary: raw script by hash @@ -4623,7 +4676,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: script content @@ -4645,7 +4698,7 @@ paths: - name: hash in: path required: true - schema: *ref_32 + schema: *ref_34 responses: '200': description: script details @@ -4672,7 +4725,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: scheduled_for description: when to schedule this job (leave empty for immediate run) in: query @@ -4689,7 +4742,7 @@ paths: The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: &ref_35 + schema: &ref_37 type: string format: uuid - name: job_id @@ -4699,7 +4752,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: &ref_36 + schema: &ref_38 type: string format: uuid - name: invisible_to_owner @@ -4737,13 +4790,13 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -4751,7 +4804,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -4760,14 +4813,14 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: &ref_37 + schema: &ref_39 type: string - name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: &ref_38 + schema: &ref_40 type: string requestBody: description: script args @@ -4797,13 +4850,13 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -4811,7 +4864,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -4820,13 +4873,13 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: *ref_38 + schema: *ref_40 requestBody: description: script args required: true @@ -4854,13 +4907,13 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -4868,7 +4921,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -4877,13 +4930,13 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: *ref_38 + schema: *ref_40 - name: payload description: > The base64 encoded payload that has been encoded as a JSON. e.g how @@ -4891,7 +4944,7 @@ paths: `encodeURIComponent(btoa(JSON.stringify({a: 2})))` in: query - schema: &ref_73 + schema: &ref_75 type: string responses: '200': @@ -4913,7 +4966,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -4922,13 +4975,13 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: *ref_38 + schema: *ref_40 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -4936,7 +4989,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 requestBody: description: script args required: true @@ -4965,7 +5018,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -4974,13 +5027,13 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: *ref_38 + schema: *ref_40 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -4988,7 +5041,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 requestBody: description: script args required: true @@ -5099,11 +5152,11 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: path_start description: mask to filter matching starting path in: query @@ -5143,12 +5196,12 @@ paths: type: array items: allOf: - - allOf: &ref_43 + - allOf: &ref_45 - type: object - properties: *ref_41 - required: *ref_42 + properties: *ref_43 + required: *ref_44 - type: object - properties: &ref_147 + properties: &ref_149 workspace_id: type: string path: @@ -5176,7 +5229,9 @@ paths: type: integer dedicated_worker: type: boolean - required: &ref_148 + timeout: + type: number + required: &ref_150 - path - edited_by - edited_at @@ -5202,14 +5257,14 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: flow details content: application/json: schema: - allOf: *ref_43 + allOf: *ref_45 /w/{workspace}/flows/toggle_workspace_error_handler/{path}: post: summary: Toggle ON and OFF the workspace error handler for a given flow @@ -5224,7 +5279,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: Workspace error handler enabled required: true @@ -5256,7 +5311,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: flow details with draft @@ -5264,11 +5319,11 @@ paths: application/json: schema: allOf: - - allOf: *ref_43 + - allOf: *ref_45 - type: object properties: draft: - allOf: *ref_43 + allOf: *ref_45 /w/{workspace}/flows/exists/{path}: get: summary: exists flow by path @@ -5283,7 +5338,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: flow details @@ -5309,10 +5364,10 @@ paths: application/json: schema: allOf: - - allOf: &ref_44 + - allOf: &ref_46 - type: object - properties: *ref_41 - required: *ref_42 + properties: *ref_43 + required: *ref_44 - type: object properties: path: @@ -5325,6 +5380,8 @@ paths: type: integer dedicated_worker: type: boolean + timeout: + type: number required: - path - type: object @@ -5352,14 +5409,14 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: Partially filled flow required: true content: application/json: schema: - allOf: *ref_44 + allOf: *ref_46 responses: '200': description: flow updated @@ -5381,7 +5438,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: archiveFlow required: true @@ -5413,7 +5470,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: flow delete @@ -5435,7 +5492,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: page description: which page to return (start at 1, default 1) in: query @@ -5453,7 +5510,7 @@ paths: type: array items: type: object - properties: &ref_83 + properties: &ref_85 id: type: string name: @@ -5469,7 +5526,7 @@ paths: type: boolean success: type: boolean - required: &ref_84 + required: &ref_86 - id - name - args @@ -5498,11 +5555,11 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: path_start description: mask to filter matching starting path in: query @@ -5529,7 +5586,7 @@ paths: type: array items: type: object - properties: &ref_154 + properties: &ref_156 workspace_id: type: string path: @@ -5547,7 +5604,7 @@ paths: edited_at: type: string format: date-time - required: &ref_155 + required: &ref_157 - workspace_id - path - summary @@ -5568,7 +5625,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app exists @@ -5590,12 +5647,12 @@ paths: - name: version in: path required: true - schema: &ref_91 + schema: &ref_93 type: number - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: app details @@ -5652,11 +5709,11 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: path_start description: mask to filter matching starting path in: query @@ -5683,7 +5740,7 @@ paths: type: array items: type: object - properties: &ref_152 + properties: &ref_154 id: type: integer workspace_id: @@ -5709,7 +5766,7 @@ paths: - viewer - publisher - anonymous - required: &ref_153 + required: &ref_155 - id - workspace_id - path @@ -5744,7 +5801,7 @@ paths: type: string policy: type: object - properties: &ref_45 + properties: &ref_47 triggerables: type: object additionalProperties: @@ -5787,7 +5844,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app exists @@ -5809,7 +5866,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: app details @@ -5817,7 +5874,7 @@ paths: application/json: schema: type: object - properties: &ref_46 + properties: &ref_48 id: type: integer workspace_id: @@ -5838,7 +5895,7 @@ paths: value: {} policy: type: object - properties: *ref_45 + properties: *ref_47 execution_mode: type: string enum: @@ -5849,7 +5906,7 @@ paths: type: object additionalProperties: type: boolean - required: &ref_47 + required: &ref_49 - id - workspace_id - path @@ -5875,17 +5932,17 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 responses: '200': description: app details with draft content: application/json: schema: - allOf: &ref_156 + allOf: &ref_158 - type: object - properties: *ref_46 - required: *ref_47 + properties: *ref_48 + required: *ref_49 - type: object properties: draft_only: @@ -5905,7 +5962,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app details @@ -5913,8 +5970,8 @@ paths: application/json: schema: type: object - properties: *ref_46 - required: *ref_47 + properties: *ref_48 + required: *ref_49 /w/{workspace}/apps_u/public_resource/{path}: get: summary: get public resource @@ -5929,7 +5986,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: resource value @@ -5950,7 +6007,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app secret @@ -5972,7 +6029,7 @@ paths: - name: id in: path required: true - schema: *ref_23 + schema: *ref_25 responses: '200': description: app details @@ -5980,8 +6037,8 @@ paths: application/json: schema: type: object - properties: *ref_46 - required: *ref_47 + properties: *ref_48 + required: *ref_49 /w/{workspace}/raw_apps/create: post: summary: create raw app @@ -6032,7 +6089,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: updateraw app required: true @@ -6068,7 +6125,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app deleted @@ -6090,7 +6147,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: app deleted @@ -6112,7 +6169,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: update app required: true @@ -6128,7 +6185,7 @@ paths: value: {} policy: type: object - properties: *ref_45 + properties: *ref_47 responses: '200': description: app updated @@ -6150,7 +6207,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 requestBody: description: update app required: true @@ -6204,7 +6261,7 @@ paths: - name: path in: path required: true - schema: *ref_28 + schema: *ref_30 - name: scheduled_for description: when to schedule this job (leave empty for immediate run) in: query @@ -6221,7 +6278,7 @@ paths: The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -6229,7 +6286,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -6238,7 +6295,7 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: invisible_to_owner description: make the run invisible to the the flow owner (default false) in: query @@ -6274,7 +6331,7 @@ paths: - name: id in: path required: true - schema: &ref_70 + schema: &ref_72 type: string format: uuid - name: step_id @@ -6307,7 +6364,7 @@ paths: The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -6315,7 +6372,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -6324,7 +6381,7 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: invisible_to_owner description: make the run invisible to the the flow owner (default false) in: query @@ -6360,7 +6417,7 @@ paths: - name: hash in: path required: true - schema: *ref_32 + schema: *ref_34 - name: scheduled_for description: when to schedule this job (leave empty for immediate run) in: query @@ -6377,7 +6434,7 @@ paths: The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: job_id description: >- The job id to assign to the created job. if missing, job is chosen @@ -6385,7 +6442,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 - name: include_header description: > List of headers's keys (separated with ',') whove value are added to @@ -6394,7 +6451,7 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: invisible_to_owner description: make the run invisible to the the script owner (default false) in: query @@ -6434,7 +6491,7 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: invisible_to_owner description: make the run invisible to the the script owner (default false) in: query @@ -6447,7 +6504,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 requestBody: description: preview required: true @@ -6455,7 +6512,7 @@ paths: application/json: schema: type: object - properties: &ref_126 + properties: &ref_128 content: type: string path: @@ -6489,7 +6546,7 @@ paths: - http dedicated_worker: type: boolean - required: &ref_127 + required: &ref_129 - args responses: '201': @@ -6518,7 +6575,7 @@ paths: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 - name: invisible_to_owner description: make the run invisible to the the script owner (default false) in: query @@ -6531,7 +6588,7 @@ paths: queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 requestBody: description: preview required: true @@ -6539,11 +6596,11 @@ paths: application/json: schema: type: object - properties: &ref_149 + properties: &ref_151 value: type: object - properties: *ref_48 - required: *ref_49 + properties: *ref_50 + required: *ref_51 path: type: string args: @@ -6553,7 +6610,7 @@ paths: type: string restarted_from: type: object - properties: &ref_151 + properties: &ref_153 flow_job_id: type: string format: uuid @@ -6561,7 +6618,7 @@ paths: type: string branch_or_iteration_n: type: integer - required: &ref_150 + required: &ref_152 - value - content - args @@ -6587,89 +6644,89 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: script_path_exact description: mask to filter exact matching path in: query - schema: &ref_52 + schema: &ref_54 type: string - name: script_path_start description: mask to filter matching starting path in: query - schema: &ref_53 + schema: &ref_55 type: string - name: schedule_path description: mask to filter by schedule path in: query - schema: &ref_54 + schema: &ref_56 type: string - name: script_hash description: mask to filter exact matching path in: query - schema: &ref_55 + schema: &ref_57 type: string - name: started_before description: filter on started before (inclusive) timestamp in: query - schema: &ref_56 + schema: &ref_58 type: string format: date-time - name: started_after description: filter on started after (exclusive) timestamp in: query - schema: &ref_57 + schema: &ref_59 type: string format: date-time - name: success description: filter on successful jobs in: query - schema: &ref_58 + schema: &ref_60 type: boolean - name: job_kinds description: >- filter on job kind (values 'preview', 'script', 'dependencies', 'flow') separated by, in: query - schema: &ref_59 + schema: &ref_61 type: string - name: suspended description: filter on suspended jobs in: query - schema: &ref_95 + schema: &ref_97 type: boolean - name: running description: filter on running jobs in: query - schema: &ref_65 + schema: &ref_67 type: boolean - name: args description: >- filter on jobs containing those args as a json subset (@> in postgres) in: query - schema: &ref_60 + schema: &ref_62 type: string - name: result description: >- filter on jobs containing those result as a json subset (@> in postgres) in: query - schema: &ref_61 + schema: &ref_63 type: string - name: tag description: filter on jobs with a given tag/worker group in: query - schema: &ref_62 + schema: &ref_64 type: string responses: '200': @@ -6680,7 +6737,7 @@ paths: type: array items: type: object - properties: &ref_68 + properties: &ref_70 workspace_id: type: string id: @@ -6734,6 +6791,7 @@ paths: - flowpreview - script_hub - identity + - deploymentcallback schedule_path: type: string permissioned_as: @@ -6745,14 +6803,14 @@ paths: by extension its DT_TOKEN. flow_status: type: object - properties: &ref_63 + properties: &ref_65 step: type: integer modules: type: array items: type: object - properties: &ref_50 + properties: &ref_52 type: type: string enum: @@ -6816,13 +6874,13 @@ paths: required: - resume_id - approver - required: &ref_51 + required: &ref_53 - type failure_module: allOf: - type: object - properties: *ref_50 - required: *ref_51 + properties: *ref_52 + required: *ref_53 - type: object properties: parent_module: @@ -6837,14 +6895,14 @@ paths: items: type: string format: uuid - required: &ref_64 + required: &ref_66 - step - modules - failure_module raw_flow: type: object - properties: *ref_48 - required: *ref_49 + properties: *ref_50 + required: *ref_51 is_flow_step: type: boolean language: @@ -6873,7 +6931,7 @@ paths: type: string priority: type: integer - required: &ref_69 + required: &ref_71 - id - running - canceled @@ -6963,67 +7021,67 @@ paths: - name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: script_path_exact description: mask to filter exact matching path in: query - schema: *ref_52 + schema: *ref_54 - name: script_path_start description: mask to filter matching starting path in: query - schema: *ref_53 + schema: *ref_55 - name: schedule_path description: mask to filter by schedule path in: query - schema: *ref_54 + schema: *ref_56 - name: script_hash description: mask to filter exact matching path in: query - schema: *ref_55 + schema: *ref_57 - name: started_before description: filter on started before (inclusive) timestamp in: query - schema: *ref_56 + schema: *ref_58 - name: started_after description: filter on started after (exclusive) timestamp in: query - schema: *ref_57 + schema: *ref_59 - name: success description: filter on successful jobs in: query - schema: *ref_58 + schema: *ref_60 - name: job_kinds description: >- filter on job kind (values 'preview', 'script', 'dependencies', 'flow') separated by, in: query - schema: *ref_59 + schema: *ref_61 - name: args description: >- filter on jobs containing those args as a json subset (@> in postgres) in: query - schema: *ref_60 + schema: *ref_62 - name: result description: >- filter on jobs containing those result as a json subset (@> in postgres) in: query - schema: *ref_61 + schema: *ref_63 - name: tag description: filter on jobs with a given tag/worker group in: query - schema: *ref_62 + schema: *ref_64 - name: is_skipped description: is the job skipped in: query @@ -7043,7 +7101,7 @@ paths: type: array items: type: object - properties: &ref_66 + properties: &ref_68 workspace_id: type: string id: @@ -7096,6 +7154,7 @@ paths: - flowpreview - script_hub - identity + - deploymentcallback schedule_path: type: string permissioned_as: @@ -7107,12 +7166,12 @@ paths: by extension its DT_TOKEN. flow_status: type: object - properties: *ref_63 - required: *ref_64 + properties: *ref_65 + required: *ref_66 raw_flow: type: object - properties: *ref_48 - required: *ref_49 + properties: *ref_50 + required: *ref_51 is_flow_step: type: boolean language: @@ -7143,7 +7202,7 @@ paths: type: string priority: type: integer - required: &ref_67 + required: &ref_69 - id - created_by - duration_ms @@ -7172,55 +7231,55 @@ paths: - name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 - name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 - name: script_path_exact description: mask to filter exact matching path in: query - schema: *ref_52 + schema: *ref_54 - name: script_path_start description: mask to filter matching starting path in: query - schema: *ref_53 + schema: *ref_55 - name: schedule_path description: mask to filter by schedule path in: query - schema: *ref_54 + schema: *ref_56 - name: script_hash description: mask to filter exact matching path in: query - schema: *ref_55 + schema: *ref_57 - name: started_before description: filter on started before (inclusive) timestamp in: query - schema: *ref_56 + schema: *ref_58 - name: started_after description: filter on started after (exclusive) timestamp in: query - schema: *ref_57 + schema: *ref_59 - name: created_or_started_before description: >- filter on created_at for non non started job and started_at otherwise before (inclusive) timestamp in: query - schema: &ref_94 + schema: &ref_96 type: string format: date-time - name: running description: filter on running jobs in: query - schema: *ref_65 + schema: *ref_67 - name: created_or_started_after description: >- filter on created_at for non non started job and started_at otherwise after (exclusive) timestamp in: query - schema: &ref_93 + schema: &ref_95 type: string format: date-time - name: job_kinds @@ -7228,23 +7287,23 @@ paths: filter on job kind (values 'preview', 'script', 'dependencies', 'flow') separated by, in: query - schema: *ref_59 + schema: *ref_61 - name: args description: >- filter on jobs containing those args as a json subset (@> in postgres) in: query - schema: *ref_60 + schema: *ref_62 - name: tag description: filter on jobs with a given tag/worker group in: query - schema: *ref_62 + schema: *ref_64 - name: result description: >- filter on jobs containing those result as a json subset (@> in postgres) in: query - schema: *ref_61 + schema: *ref_63 - name: is_skipped description: is the job skipped in: query @@ -7268,14 +7327,14 @@ paths: schema: type: array items: - allOf: &ref_71 + allOf: &ref_73 - oneOf: - - type: object - properties: *ref_66 - required: *ref_67 - type: object properties: *ref_68 required: *ref_69 + - type: object + properties: *ref_70 + required: *ref_71 - type: object properties: type: @@ -7283,7 +7342,7 @@ paths: enum: - CompletedJob - QueuedJob - discriminator: &ref_72 + discriminator: &ref_74 propertyName: type /jobs/db_clock: get: @@ -7312,15 +7371,15 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 responses: '200': description: job details content: application/json: schema: - allOf: *ref_71 - discriminator: *ref_72 + allOf: *ref_73 + discriminator: *ref_74 /w/{workspace}/jobs_u/get_logs/{id}: get: summary: get job logs @@ -7335,7 +7394,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 responses: '200': description: job details @@ -7357,7 +7416,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: running in: query schema: @@ -7396,7 +7455,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 responses: '200': description: job details @@ -7404,8 +7463,8 @@ paths: application/json: schema: type: object - properties: *ref_66 - required: *ref_67 + properties: *ref_68 + required: *ref_69 /w/{workspace}/jobs_u/completed/get_result/{id}: get: summary: get completed job result @@ -7420,7 +7479,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 responses: '200': description: result @@ -7441,10 +7500,10 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: get_started in: query - schema: &ref_103 + schema: &ref_105 type: boolean responses: '200': @@ -7476,7 +7535,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 responses: '200': description: job details @@ -7484,8 +7543,8 @@ paths: application/json: schema: type: object - properties: *ref_66 - required: *ref_67 + properties: *ref_68 + required: *ref_69 /w/{workspace}/jobs_u/queue/cancel/{id}: post: summary: cancel queued job @@ -7500,7 +7559,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 requestBody: description: reason required: true @@ -7532,7 +7591,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 requestBody: description: reason required: true @@ -7564,7 +7623,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7595,7 +7654,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7637,7 +7696,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: payload description: > The base64 encoded payload that has been encoded as a JSON. e.g how @@ -7645,7 +7704,7 @@ paths: `encodeURIComponent(btoa(JSON.stringify({a: 2})))` in: query - schema: *ref_73 + schema: *ref_75 - name: resume_id in: path required: true @@ -7680,7 +7739,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7722,7 +7781,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 requestBody: required: true content: @@ -7750,7 +7809,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7785,7 +7844,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7827,7 +7886,7 @@ paths: - name: id in: path required: true - schema: *ref_70 + schema: *ref_72 - name: resume_id in: path required: true @@ -7851,8 +7910,8 @@ paths: type: object properties: job: - allOf: *ref_71 - discriminator: *ref_72 + allOf: *ref_73 + discriminator: *ref_74 approvers: type: array items: @@ -7917,7 +7976,7 @@ paths: application/json: schema: type: object - properties: &ref_137 + properties: &ref_139 path: type: string schedule: @@ -7951,7 +8010,7 @@ paths: additionalProperties: *ref_14 ws_error_handler_muted: type: boolean - required: &ref_138 + required: &ref_140 - path - schedule - timezone @@ -7979,7 +8038,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 requestBody: description: updated schedule required: true @@ -7987,7 +8046,7 @@ paths: application/json: schema: type: object - properties: &ref_139 + properties: &ref_141 schedule: type: string timezone: @@ -8013,7 +8072,7 @@ paths: additionalProperties: *ref_14 ws_error_handler_muted: type: boolean - required: &ref_140 + required: &ref_142 - schedule - timezone - script_path @@ -8040,7 +8099,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 requestBody: description: updated schedule enable required: true @@ -8074,7 +8133,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: schedule deleted @@ -8096,7 +8155,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: schedule deleted @@ -8104,7 +8163,7 @@ paths: application/json: schema: type: object - properties: &ref_74 + properties: &ref_76 path: type: string edited_by: @@ -8151,7 +8210,7 @@ paths: additionalProperties: *ref_14 ws_error_handler_muted: type: boolean - required: &ref_75 + required: &ref_77 - path - edited_by - edited_at @@ -8176,7 +8235,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: schedule exists @@ -8221,8 +8280,8 @@ paths: type: array items: type: object - properties: *ref_74 - required: *ref_75 + properties: *ref_76 + required: *ref_77 /w/{workspace}/schedules/list_with_jobs: get: summary: list schedules with last 20 jobs @@ -8250,10 +8309,10 @@ paths: schema: type: array items: - allOf: &ref_136 + allOf: &ref_138 - type: object - properties: *ref_74 - required: *ref_75 + properties: *ref_76 + required: *ref_77 - type: object properties: jobs: @@ -8328,14 +8387,14 @@ paths: type: array items: type: object - properties: &ref_77 + properties: &ref_79 name: type: string emails: type: array items: type: string - required: &ref_78 + required: &ref_80 - name /groups/get/{name}: get: @@ -8347,7 +8406,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: instance group @@ -8355,8 +8414,8 @@ paths: application/json: schema: type: object - properties: *ref_77 - required: *ref_78 + properties: *ref_79 + required: *ref_80 /w/{workspace}/groups/list: get: summary: list groups @@ -8385,7 +8444,7 @@ paths: type: array items: type: object - properties: &ref_79 + properties: &ref_81 name: type: string summary: @@ -8398,7 +8457,7 @@ paths: type: object additionalProperties: type: boolean - required: &ref_80 + required: &ref_82 - name /w/{workspace}/groups/listnames: get: @@ -8471,7 +8530,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: updated group required: true @@ -8503,7 +8562,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: group deleted @@ -8525,7 +8584,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: group @@ -8533,8 +8592,8 @@ paths: application/json: schema: type: object - properties: *ref_79 - required: *ref_80 + properties: *ref_81 + required: *ref_82 /w/{workspace}/groups/adduser/{name}: post: summary: add user to group @@ -8549,7 +8608,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: added user to group required: true @@ -8581,7 +8640,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: added user to group required: true @@ -8627,7 +8686,7 @@ paths: type: array items: type: object - properties: &ref_81 + properties: &ref_83 name: type: string owners: @@ -8638,7 +8697,7 @@ paths: type: object additionalProperties: type: boolean - required: &ref_82 + required: &ref_84 - name - owners - extra_perms @@ -8718,7 +8777,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: update folder required: true @@ -8755,7 +8814,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: folder deleted @@ -8777,7 +8836,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: folder @@ -8785,8 +8844,8 @@ paths: application/json: schema: type: object - properties: *ref_81 - required: *ref_82 + properties: *ref_83 + required: *ref_84 /w/{workspace}/folders/getusage/{name}: get: summary: get folder usage @@ -8801,7 +8860,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: folder @@ -8843,7 +8902,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: owner user to folder required: true @@ -8875,7 +8934,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: added owner to folder required: true @@ -8917,7 +8976,7 @@ paths: type: array items: type: object - properties: &ref_141 + properties: &ref_143 worker: type: string worker_instance: @@ -8939,7 +8998,7 @@ paths: type: string wm_version: type: string - required: &ref_142 + required: &ref_144 - worker - worker_instance - ping_at @@ -8980,7 +9039,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: a config @@ -8997,7 +9056,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 requestBody: description: worker group required: true @@ -9020,7 +9079,7 @@ paths: - name: name in: path required: true - schema: *ref_76 + schema: *ref_78 responses: '200': description: Delete config @@ -9042,7 +9101,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: kind in: path required: true @@ -9081,7 +9140,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: kind in: path required: true @@ -9132,7 +9191,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 - name: kind in: path required: true @@ -9181,7 +9240,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '204': description: flow preview captured @@ -9199,7 +9258,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '201': description: flow preview capture created @@ -9216,7 +9275,7 @@ paths: - name: path in: path required: true - schema: *ref_16 + schema: *ref_18 responses: '200': description: captured flow preview @@ -9296,13 +9355,13 @@ paths: schema: *ref_0 - name: runnable_id in: query - schema: &ref_85 + schema: &ref_87 type: string - name: runnable_type in: query - schema: &ref_86 + schema: &ref_88 type: string - enum: &ref_109 + enum: &ref_111 - ScriptHash - ScriptPath - FlowPath @@ -9323,8 +9382,8 @@ paths: type: array items: type: object - properties: *ref_83 - required: *ref_84 + properties: *ref_85 + required: *ref_86 /w/{workspace}/inputs/list: get: summary: List saved Inputs for a Runnable @@ -9338,10 +9397,10 @@ paths: schema: *ref_0 - name: runnable_id in: query - schema: *ref_85 + schema: *ref_87 - name: runnable_type in: query - schema: *ref_86 + schema: *ref_88 - name: page description: which page to return (start at 1, default 1) in: query @@ -9359,8 +9418,8 @@ paths: type: array items: type: object - properties: *ref_83 - required: *ref_84 + properties: *ref_85 + required: *ref_86 /w/{workspace}/inputs/create: post: summary: Create an Input for future use in a script or flow @@ -9374,10 +9433,10 @@ paths: schema: *ref_0 - name: runnable_id in: query - schema: *ref_85 + schema: *ref_87 - name: runnable_type in: query - schema: *ref_86 + schema: *ref_88 requestBody: description: Input required: true @@ -9385,12 +9444,12 @@ paths: application/json: schema: type: object - properties: &ref_105 + properties: &ref_107 name: type: string args: type: object - required: &ref_106 + required: &ref_108 - name - args - created_by @@ -9420,14 +9479,14 @@ paths: application/json: schema: type: object - properties: &ref_107 + properties: &ref_109 id: type: string name: type: string is_public: type: boolean - required: &ref_108 + required: &ref_110 - id - name - is_public @@ -9453,7 +9512,7 @@ paths: - name: input in: path required: true - schema: &ref_102 + schema: &ref_104 type: string responses: '200': @@ -9486,7 +9545,7 @@ paths: properties: s3_resource: type: object - properties: &ref_87 + properties: &ref_89 bucket: type: string region: @@ -9501,7 +9560,7 @@ paths: type: string pathStyle: type: boolean - required: &ref_88 + required: &ref_90 - bucket - region - endPoint @@ -9577,8 +9636,8 @@ paths: properties: s3_resource: type: object - properties: *ref_87 - required: *ref_88 + properties: *ref_89 + required: *ref_90 responses: '200': description: Connection settings @@ -9599,10 +9658,10 @@ paths: type: boolean client_kwargs: type: object - properties: &ref_89 + properties: &ref_91 region_name: type: string - required: &ref_90 + required: &ref_92 - region_name required: - endpoint_url @@ -9657,8 +9716,8 @@ paths: type: boolean client_kwargs: type: object - properties: *ref_89 - required: *ref_90 + properties: *ref_91 + required: *ref_92 required: - endpoint_url - use_ssl @@ -9735,10 +9794,10 @@ paths: type: array items: type: object - properties: &ref_159 + properties: &ref_161 s3: type: string - required: &ref_160 + required: &ref_162 - s3 required: - windmill_large_files @@ -9765,7 +9824,7 @@ paths: application/json: schema: type: object - properties: &ref_161 + properties: &ref_163 mime_type: type: string size_in_bytes: @@ -9825,7 +9884,7 @@ paths: application/json: schema: type: object - properties: &ref_162 + properties: &ref_164 msg: type: string content: @@ -9837,7 +9896,7 @@ paths: - Csv - Parquet - Unknown - required: &ref_163 + required: &ref_165 - content_type components: securitySchemes: @@ -9863,52 +9922,52 @@ components: name: version in: path required: true - schema: *ref_91 + schema: *ref_93 Token: name: token in: path required: true - schema: *ref_92 + schema: *ref_94 AccountId: name: id in: path required: true - schema: *ref_20 + schema: *ref_22 ClientName: name: client_name in: path required: true - schema: *ref_19 + schema: *ref_21 ScriptPath: name: path in: path required: true - schema: *ref_28 + schema: *ref_30 ScriptHash: name: hash in: path required: true - schema: *ref_32 + schema: *ref_34 JobId: name: id in: path required: true - schema: *ref_70 + schema: *ref_72 Path: name: path in: path required: true - schema: *ref_16 + schema: *ref_18 PathId: name: id in: path required: true - schema: *ref_23 + schema: *ref_25 Name: name: name in: path required: true - schema: *ref_76 + schema: *ref_78 Page: name: page description: which page to return (start at 1, default 1) @@ -9923,19 +9982,19 @@ components: name: order_desc description: order by desc order (default true) in: query - schema: *ref_39 + schema: *ref_41 CreatedBy: name: created_by description: mask to filter exact matching user creator in: query - schema: *ref_40 + schema: *ref_42 ParentJob: name: parent_job description: >- The parent job that is at the origin and responsible for the execution of this script if any in: query - schema: *ref_35 + schema: *ref_37 NewJobId: name: job_id description: >- @@ -9943,7 +10002,7 @@ components: randomly using the ULID scheme. If a job id already exists in the queue or as a completed job, the request to create one will fail (Bad Request) in: query - schema: *ref_36 + schema: *ref_38 IncludeHeader: name: include_header description: > @@ -9953,14 +10012,14 @@ components: Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key in: query - schema: *ref_37 + schema: *ref_39 QueueLimit: name: queue_limit description: > The maximum size of the queue for which the request would get rejected if that job would push it above that limit in: query - schema: *ref_38 + schema: *ref_40 Payload: name: payload description: > @@ -9969,219 +10028,219 @@ components: `encodeURIComponent(btoa(JSON.stringify({a: 2})))` in: query - schema: *ref_73 + schema: *ref_75 ScriptStartPath: name: script_path_start description: mask to filter matching starting path in: query - schema: *ref_53 + schema: *ref_55 SchedulePath: name: schedule_path description: mask to filter by schedule path in: query - schema: *ref_54 + schema: *ref_56 ScriptExactPath: name: script_path_exact description: mask to filter exact matching path in: query - schema: *ref_52 + schema: *ref_54 ScriptExactHash: name: script_hash description: mask to filter exact matching path in: query - schema: *ref_55 + schema: *ref_57 StartedBefore: name: started_before description: filter on started before (inclusive) timestamp in: query - schema: *ref_56 + schema: *ref_58 StartedAfter: name: started_after description: filter on started after (exclusive) timestamp in: query - schema: *ref_57 + schema: *ref_59 CreatedOrStartedAfter: name: created_or_started_after description: >- filter on created_at for non non started job and started_at otherwise after (exclusive) timestamp in: query - schema: *ref_93 + schema: *ref_95 CreatedOrStartedBefore: name: created_or_started_before description: >- filter on created_at for non non started job and started_at otherwise before (inclusive) timestamp in: query - schema: *ref_94 + schema: *ref_96 Success: name: success description: filter on successful jobs in: query - schema: *ref_58 + schema: *ref_60 Suspended: name: suspended description: filter on suspended jobs in: query - schema: *ref_95 + schema: *ref_97 Running: name: running description: filter on running jobs in: query - schema: *ref_65 + schema: *ref_67 ArgsFilter: name: args description: filter on jobs containing those args as a json subset (@> in postgres) in: query - schema: *ref_60 + schema: *ref_62 Tag: name: tag description: filter on jobs with a given tag/worker group in: query - schema: *ref_62 + schema: *ref_64 ResultFilter: name: result description: filter on jobs containing those result as a json subset (@> in postgres) in: query - schema: *ref_61 + schema: *ref_63 After: name: after description: filter on created after (exclusive) timestamp in: query - schema: *ref_96 + schema: *ref_98 Before: name: before description: filter on created before (exclusive) timestamp in: query - schema: *ref_97 + schema: *ref_99 Username: name: username description: filter on exact username of user in: query - schema: *ref_98 + schema: *ref_100 Operation: name: operation description: filter on exact or prefix name of operation in: query - schema: *ref_99 + schema: *ref_101 ResourceName: name: resource description: filter on exact or prefix name of resource in: query - schema: *ref_100 + schema: *ref_102 ActionKind: name: action_kind description: filter on type of operation in: query - schema: *ref_101 + schema: *ref_103 JobKinds: name: job_kinds description: >- filter on job kind (values 'preview', 'script', 'dependencies', 'flow') separated by, in: query - schema: *ref_59 + schema: *ref_61 RunnableId: name: runnable_id in: query - schema: *ref_85 + schema: *ref_87 RunnableTypeQuery: name: runnable_type in: query - schema: *ref_86 + schema: *ref_88 InputId: name: input in: path required: true - schema: *ref_102 + schema: *ref_104 GetStarted: name: get_started in: query - schema: *ref_103 + schema: *ref_105 schemas: Script: type: object - properties: *ref_30 - required: *ref_31 + properties: *ref_32 + required: *ref_33 NewScript: type: object - properties: *ref_33 - required: *ref_34 + properties: *ref_35 + required: *ref_36 NewScriptWithDraft: - allOf: *ref_104 + allOf: *ref_106 ScriptArgs: type: object additionalProperties: *ref_14 Input: type: object - properties: *ref_83 - required: *ref_84 + properties: *ref_85 + required: *ref_86 CreateInput: - type: object - properties: *ref_105 - required: *ref_106 - UpdateInput: type: object properties: *ref_107 required: *ref_108 + UpdateInput: + type: object + properties: *ref_109 + required: *ref_110 RunnableType: type: string - enum: *ref_109 + enum: *ref_111 QueuedJob: + type: object + properties: *ref_70 + required: *ref_71 + CompletedJob: type: object properties: *ref_68 required: *ref_69 - CompletedJob: - type: object - properties: *ref_66 - required: *ref_67 Job: - allOf: *ref_71 - discriminator: *ref_72 + allOf: *ref_73 + discriminator: *ref_74 User: type: object properties: *ref_8 required: *ref_9 Usage: type: object - properties: *ref_110 + properties: *ref_112 Login: - type: object - properties: *ref_111 - required: *ref_112 - NewUser: type: object properties: *ref_113 required: *ref_114 - EditWorkspaceUser: + NewUser: type: object properties: *ref_115 + required: *ref_116 + EditWorkspaceUser: + type: object + properties: *ref_117 TruncatedToken: type: object - properties: *ref_116 - required: *ref_117 + properties: *ref_118 + required: *ref_119 NewToken: type: object - properties: *ref_118 + properties: *ref_120 NewTokenImpersonate: - type: object - properties: *ref_119 - required: *ref_120 - ListableVariable: - type: object - properties: *ref_17 - required: *ref_18 - ContextualVariable: type: object properties: *ref_121 required: *ref_122 - CreateVariable: + ListableVariable: + type: object + properties: *ref_19 + required: *ref_20 + ContextualVariable: type: object properties: *ref_123 required: *ref_124 - EditVariable: + CreateVariable: type: object properties: *ref_125 + required: *ref_126 + EditVariable: + type: object + properties: *ref_127 AuditLog: type: object properties: *ref_1 @@ -10304,69 +10363,69 @@ components: - type - error Preview: - type: object - properties: *ref_126 - required: *ref_127 - CreateResource: type: object properties: *ref_128 required: *ref_129 - EditResource: + CreateResource: type: object properties: *ref_130 - Resource: + required: *ref_131 + EditResource: type: object - properties: *ref_131 - required: *ref_132 - ListableResource: + properties: *ref_132 + Resource: type: object properties: *ref_133 required: *ref_134 - ResourceType: - type: object - properties: *ref_21 - required: *ref_22 - EditResourceType: + ListableResource: type: object properties: *ref_135 - Schedule: + required: *ref_136 + ResourceType: type: object - properties: *ref_74 - required: *ref_75 - ScheduleWJobs: - allOf: *ref_136 - NewSchedule: + properties: *ref_23 + required: *ref_24 + EditResourceType: type: object properties: *ref_137 - required: *ref_138 - EditSchedule: + Schedule: + type: object + properties: *ref_76 + required: *ref_77 + ScheduleWJobs: + allOf: *ref_138 + NewSchedule: type: object properties: *ref_139 required: *ref_140 - Group: - type: object - properties: *ref_79 - required: *ref_80 - InstanceGroup: - type: object - properties: *ref_77 - required: *ref_78 - Folder: - type: object - properties: *ref_81 - required: *ref_82 - WorkerPing: + EditSchedule: type: object properties: *ref_141 required: *ref_142 - UserWorkspaceList: + Group: + type: object + properties: *ref_81 + required: *ref_82 + InstanceGroup: + type: object + properties: *ref_79 + required: *ref_80 + Folder: + type: object + properties: *ref_83 + required: *ref_84 + WorkerPing: type: object properties: *ref_143 required: *ref_144 - CreateWorkspace: + UserWorkspaceList: type: object properties: *ref_145 required: *ref_146 + CreateWorkspace: + type: object + properties: *ref_147 + required: *ref_148 Workspace: type: object properties: *ref_5 @@ -10380,37 +10439,37 @@ components: properties: *ref_10 required: *ref_11 Flow: - allOf: *ref_43 + allOf: *ref_45 FlowMetadata: - type: object - properties: *ref_147 - required: *ref_148 - OpenFlowWPath: - allOf: *ref_44 - FlowPreview: type: object properties: *ref_149 required: *ref_150 - RestartedFrom: + OpenFlowWPath: + allOf: *ref_46 + FlowPreview: type: object properties: *ref_151 + required: *ref_152 + RestartedFrom: + type: object + properties: *ref_153 Policy: type: object - properties: *ref_45 + properties: *ref_47 ListableApp: - type: object - properties: *ref_152 - required: *ref_153 - ListableRawApp: type: object properties: *ref_154 required: *ref_155 + ListableRawApp: + type: object + properties: *ref_156 + required: *ref_157 AppWithLastVersion: type: object - properties: *ref_46 - required: *ref_47 + properties: *ref_48 + required: *ref_49 AppWithLastVersionWDraft: - allOf: *ref_156 + allOf: *ref_158 SlackToken: type: object properties: @@ -10432,102 +10491,106 @@ components: - bot TokenResponse: type: object - properties: *ref_157 - required: *ref_158 + properties: *ref_159 + required: *ref_160 HubScriptKind: name: kind - schema: *ref_29 + schema: *ref_31 PolarsClientKwargs: type: object - properties: *ref_89 - required: *ref_90 + properties: *ref_91 + required: *ref_92 LargeFileStorage: type: object properties: *ref_15 WindmillLargeFile: type: object - properties: *ref_159 - required: *ref_160 + properties: *ref_161 + required: *ref_162 WindmillFileMetadata: type: object - properties: *ref_161 + properties: *ref_163 WindmillFilePreview: - type: object - properties: *ref_162 - required: *ref_163 - S3Resource: - type: object - properties: *ref_87 - required: *ref_88 - StaticTransform: type: object properties: *ref_164 required: *ref_165 - JavascriptTransform: + S3Resource: + type: object + properties: *ref_89 + required: *ref_90 + WorkspaceGitSync: + type: object + properties: *ref_16 + required: *ref_17 + StaticTransform: type: object properties: *ref_166 required: *ref_167 - InputTransform: - oneOf: *ref_24 - discriminator: *ref_25 - RawScript: + JavascriptTransform: type: object properties: *ref_168 required: *ref_169 - PathScript: + InputTransform: + oneOf: *ref_26 + discriminator: *ref_27 + RawScript: type: object properties: *ref_170 required: *ref_171 - PathFlow: + PathScript: type: object properties: *ref_172 required: *ref_173 - FlowModule: - type: object - properties: *ref_26 - required: *ref_27 - ForloopFlow: + PathFlow: type: object properties: *ref_174 required: *ref_175 - BranchOne: + FlowModule: + type: object + properties: *ref_28 + required: *ref_29 + ForloopFlow: type: object properties: *ref_176 required: *ref_177 - BranchAll: + BranchOne: type: object properties: *ref_178 required: *ref_179 - Identity: + BranchAll: type: object properties: *ref_180 required: *ref_181 - Graphql: + Identity: type: object properties: *ref_182 required: *ref_183 + Graphql: + type: object + properties: *ref_184 + required: *ref_185 FlowModuleValue: - oneOf: *ref_184 - discriminator: *ref_185 + oneOf: *ref_186 + discriminator: *ref_187 Retry: type: object - properties: *ref_186 + properties: *ref_188 FlowValue: - type: object - properties: *ref_48 - required: *ref_49 - OpenFlow: - type: object - properties: *ref_41 - required: *ref_42 - FlowStatusModule: type: object properties: *ref_50 required: *ref_51 + OpenFlow: + type: object + properties: *ref_43 + required: *ref_44 + FlowStatusModule: + type: object + properties: *ref_52 + required: *ref_53 FlowStatus: type: object - properties: *ref_63 - required: *ref_64 + properties: *ref_65 + required: *ref_66 Http: type: object properties: diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index d4a41a0584..64c375a968 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -1192,6 +1192,8 @@ paths: type: boolean large_file_storage: $ref: "#/components/schemas/LargeFileStorage" + git_sync: + $ref: "#/components/schemas/WorkspaceGitSync" required: - code_completion_enabled @@ -1513,6 +1515,32 @@ paths: application/json: schema: {} + /w/{workspace}/workspaces/edit_git_sync_config: + post: + summary: edit workspace git sync settings + operationId: editWorkspaceGitSyncConfig + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: Workspace Git sync settings + required: true + content: + application/json: + schema: + type: object + properties: + git_sync_settings: + $ref: "#/components/schemas/WorkspaceGitSync" + + responses: + "200": + description: status + content: + application/json: + schema: {} + /w/{workspace}/workspaces/get_large_file_storage_config: get: summary: get large file storage config @@ -7221,6 +7249,7 @@ components: "flowpreview", "script_hub", "identity", + "deploymentcallback", ] schedule_path: type: string @@ -7329,6 +7358,7 @@ components: "flowpreview", "script_hub", "identity", + "deploymentcallback", ] schedule_path: type: string @@ -8662,3 +8692,14 @@ components: - endPoint - useSSL - pathStyle + + WorkspaceGitSync: + type: object + properties: + script_path: + type: string + git_repo_resource_path: + type: string + required: + - script_path + - git_repo_resource_path diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index d87ee3cc0b..2890fe4266 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; */ use crate::{ db::{ApiAuthed, DB}, + git_sync_helpers, users::{require_owner_of_path, OptAuthed}, variables::build_crypt, webhook_util::{WebhookMessage, WebhookShared}, @@ -512,8 +513,8 @@ async fn create_app( ) .await?; - let tx = PushIsolationLevel::Transaction(tx); - let (dependency_job_uuid, tx) = push( + let mut tx = PushIsolationLevel::Transaction(tx); + let (dependency_job_uuid, new_tx) = push( &db, tx, &w_id, @@ -538,7 +539,26 @@ async fn create_app( ) .await?; tracing::info!("Pushed app dependency job {}", dependency_job_uuid); - tx.commit().await?; + + tx = PushIsolationLevel::Transaction(new_tx); + tx = git_sync_helpers::run_workspace_repo_git_callback( + tx, + &authed, + &db, + &w_id, + git_sync_helpers::DeployedObject::App { path: app.path.clone(), version: v_id }, + ) + .await?; + + match tx { + PushIsolationLevel::Transaction(tx) => tx.commit().await?, + _ => { + return Err(Error::InternalErr( + "Expected a transaction here".to_string(), + )); + } + } + webhook.send_message( w_id.clone(), WebhookMessage::CreateApp { workspace: w_id, path: app.path.clone() }, @@ -753,11 +773,10 @@ async fn update_app( ) .await?; + let mut tx: PushIsolationLevel<'_, rsmq_async::MultiplexedRsmq> = + PushIsolationLevel::Transaction(tx); if let Some(v_id) = v_id { - let tx: PushIsolationLevel<'_, rsmq_async::MultiplexedRsmq> = - PushIsolationLevel::Transaction(tx); - - let (dependency_job_uuid, tx) = push( + let (dependency_job_uuid, new_tx) = push( &db, tx, &w_id, @@ -782,10 +801,27 @@ async fn update_app( ) .await?; tracing::info!("Pushed app dependency job {}", dependency_job_uuid); - tx.commit().await?; - } else { - tx.commit().await?; + + tx = PushIsolationLevel::Transaction(new_tx); + tx = git_sync_helpers::run_workspace_repo_git_callback( + tx, + &authed, + &db, + &w_id, + git_sync_helpers::DeployedObject::App { path: npath.clone(), version: v_id }, + ) + .await?; } + + match tx { + PushIsolationLevel::Transaction(tx) => tx.commit().await?, + _ => { + return Err(Error::InternalErr( + "Expected a transaction here".to_string(), + )); + } + } + webhook.send_message( w_id.clone(), WebhookMessage::UpdateApp { diff --git a/backend/windmill-api/src/flows.rs b/backend/windmill-api/src/flows.rs index 3aa441745f..cf153a225b 100644 --- a/backend/windmill-api/src/flows.rs +++ b/backend/windmill-api/src/flows.rs @@ -7,6 +7,7 @@ */ use crate::db::ApiAuthed; +use crate::git_sync_helpers; use crate::{ db::DB, schedule::clear_schedule, @@ -354,8 +355,8 @@ async fn create_flow( ) .await?; - let tx = PushIsolationLevel::Transaction(tx); - let (dependency_job_uuid, mut tx) = push( + let mut tx = PushIsolationLevel::Transaction(tx); + let (dependency_job_uuid, mut new_tx) = push( &db, tx, &w_id, @@ -389,9 +390,27 @@ async fn create_flow( nf.path, w_id ) - .execute(&mut tx) + .execute(&mut new_tx) .await?; - tx.commit().await?; + + tx = PushIsolationLevel::Transaction(new_tx); + tx = git_sync_helpers::run_workspace_repo_git_callback( + tx, + &authed, + &db, + &w_id, + git_sync_helpers::DeployedObject::Flow { path: nf.path.clone() }, + ) + .await?; + + match tx { + PushIsolationLevel::Transaction(tx) => tx.commit().await?, + _ => { + return Err(Error::InternalErr( + "Expected a transaction here".to_string(), + )); + } + } webhook.send_message( w_id.clone(), @@ -565,9 +584,9 @@ async fn update_flow( }, ); - let tx = PushIsolationLevel::Transaction(tx); + let mut tx = PushIsolationLevel::Transaction(tx); - let (dependency_job_uuid, mut tx) = push( + let (dependency_job_uuid, mut new_tx) = push( &db, tx, &w_id, @@ -600,17 +619,36 @@ async fn update_flow( nf.path, w_id ) - .execute(&mut tx) + .execute(&mut new_tx) .await?; if let Some(old_dep_job) = old_dep_job { sqlx::query!( "UPDATE queue SET canceled = true WHERE id = $1", old_dep_job ) - .execute(&mut tx) + .execute(&mut new_tx) .await?; } - tx.commit().await?; + + tx = PushIsolationLevel::Transaction(new_tx); + tx = git_sync_helpers::run_workspace_repo_git_callback( + tx, + &authed, + &db, + &w_id, + git_sync_helpers::DeployedObject::Flow { path: nf.path.clone() }, + ) + .await?; + + match tx { + PushIsolationLevel::Transaction(tx) => tx.commit().await?, + _ => { + return Err(Error::InternalErr( + "Expected a transaction here".to_string(), + )); + } + } + Ok(nf.path.to_string()) } diff --git a/backend/windmill-api/src/git_sync_helpers.rs b/backend/windmill-api/src/git_sync_helpers.rs new file mode 100644 index 0000000000..e1ad1eb3f6 --- /dev/null +++ b/backend/windmill-api/src/git_sync_helpers.rs @@ -0,0 +1,153 @@ +/* + * Author: Ruben Fiszel + * Copyright: Windmill Labs, Inc 2022 + * This file and its contents are licensed under the AGPLv3 License. + * Please see the included NOTICE for copyright information and + * LICENSE-AGPL for a copy of the license. + */ + +use std::collections::HashMap; + +use crate::db::ApiAuthed; +use crate::db::DB; +use crate::workspaces::{WorkspaceGitRepo, WorkspaceSettings}; + +use serde_json::json; +use windmill_common::error::{Error, Result}; +use windmill_common::jobs::JobPayload; +use windmill_common::scripts::ScriptHash; +use windmill_common::users::username_to_permissioned_as; +use windmill_queue::PushIsolationLevel; + +#[derive(Clone)] +pub enum DeployedObject { + Script { hash: ScriptHash, path: String }, + Flow { path: String }, + App { path: String, version: i64 }, +} + +impl DeployedObject { + pub fn get_path(&self) -> &str { + match self { + DeployedObject::Script { path, .. } => path, + DeployedObject::Flow { path } => path, + DeployedObject::App { path, .. } => path, + } + } +} + +pub async fn run_workspace_repo_git_callback<'c, R: rsmq_async::RsmqConnection + Send + 'c>( + mut tx: PushIsolationLevel<'c, R>, + authed: &ApiAuthed, + db: &DB, + w_id: &str, + obj: DeployedObject, +) -> Result> { + if obj.get_path().starts_with("u/") { + tracing::debug!( + "Ignoring {} from git sync as it's in a private user folder", + obj.get_path() + ); + return Ok(tx); + } + + let workspace_git_repo_setting = sqlx::query_as::<_, WorkspaceSettings>( + "SELECT * FROM workspace_settings WHERE workspace_id = $1", + ) + .bind(&w_id) + .fetch_optional(db) + .await?; + + if workspace_git_repo_setting.is_none() { + return Err(Error::InternalErr( + "No workspace settings found for workspace ID".to_string(), + )); + } + + let workspace_git_repo = workspace_git_repo_setting + .unwrap() + .git_sync + .map(|conf| serde_json::from_value::(conf).ok()) + .flatten(); + + if workspace_git_repo.is_none() { + return Ok(tx); + } + let workspace_git_repo = workspace_git_repo.unwrap(); + + let mut args: HashMap = HashMap::new(); + args.insert( + "repo_url_resource_path".to_string(), + json!(workspace_git_repo + .git_repo_resource_path + .strip_prefix("$res:")), + ); + + let commit_msg: String; // for now auto-generate a commit message + match obj.clone() { + DeployedObject::Script { path, .. } => { + args.insert("path".to_string(), json!(path.to_string())); + commit_msg = format!("Script '{}' deployed", path); // for now auto-generate a commit message + } + DeployedObject::Flow { path } => { + args.insert("path".to_string(), json!(path.to_string())); + commit_msg = format!("Flow '{}' deployed", path); + } + DeployedObject::App { path, .. } => { + args.insert("path".to_string(), json!(path.to_string())); + commit_msg = format!("App '{}' deployed", path); + } + } + args.insert("commit_msg".to_string(), json!(commit_msg)); + + let (job_uuid, mut new_tx) = windmill_queue::push( + &db, + tx, + &w_id, + JobPayload::DeploymentCallback { path: workspace_git_repo.script_path.clone() }, + args, + &authed.username, + &authed.email, + username_to_permissioned_as(&authed.username), + None, + None, + None, + None, + None, + false, + false, + None, + true, + None, + None, + None, + None, + ) + .await?; + + // We're not persisting the default commit msg as it's pretty useless. We will persist the ones manually set by users + match obj.clone() { + DeployedObject::Script { path, hash, .. } => { + sqlx::query!( + "INSERT INTO deployment_metadata (workspace_id, path, script_hash, callback_job_ids) VALUES ($1, $2, $3, $4)", + w_id, path, hash.0, &[job_uuid] + ) + }, + DeployedObject::Flow { path } => { + sqlx::query!( + "INSERT INTO deployment_metadata (workspace_id, path, callback_job_ids) VALUES ($1, $2, $3) ON CONFLICT (workspace_id, path) WHERE script_hash IS NULL AND app_version IS NULL DO UPDATE SET callback_job_ids = $3", + w_id, path, &[job_uuid] + ) + } + DeployedObject::App { path, version } => { + sqlx::query!( + "INSERT INTO deployment_metadata (workspace_id, path, app_version, callback_job_ids) VALUES ($1, $2, $3, $4)", + w_id, path, version, &[job_uuid] + ) + } + }.execute(&mut new_tx) + .await?; + + tx = PushIsolationLevel::Transaction(new_tx); + return Ok(tx); +} diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index 2d58d27486..cc8a596602 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -53,6 +53,7 @@ pub mod embeddings; mod favorite; mod flows; mod folders; +mod git_sync_helpers; mod granular_acls; mod groups; mod inputs; diff --git a/backend/windmill-api/src/scripts.rs b/backend/windmill-api/src/scripts.rs index 3ee7899957..0ec80e5cf2 100644 --- a/backend/windmill-api/src/scripts.rs +++ b/backend/windmill-api/src/scripts.rs @@ -8,6 +8,7 @@ use crate::{ db::{ApiAuthed, DB}, + git_sync_helpers, schedule::clear_schedule, users::{maybe_refresh_folders, require_owner_of_path, AuthCache}, webhook_util::{WebhookMessage, WebhookShared}, @@ -310,6 +311,7 @@ async fn create_script( )); } + let script_path = ns.path.clone(); let hash = ScriptHash(hash_script(&ns)); let authed = maybe_refresh_folders(&ns.path, &w_id, authed, &db).await; let mut tx: QueueTransaction<'_, _> = (rsmq, user_db.begin(&authed).await?).into(); @@ -636,6 +638,15 @@ async fn create_script( tx = PushIsolationLevel::Transaction(new_tx); } + tx = git_sync_helpers::run_workspace_repo_git_callback( + tx, + &authed, + &db, + &w_id, + git_sync_helpers::DeployedObject::Script { hash: hash, path: script_path }, + ) + .await?; + match tx { PushIsolationLevel::Transaction(tx) => tx.commit().await?, _ => { diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index 649d8b6a5c..5eec9fb54e 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -84,6 +84,7 @@ pub fn workspaced_service() -> Router { .route("/get_copilot_info", get(get_copilot_info) ) .route("/edit_error_handler", post(edit_error_handler)) .route("/edit_large_file_storage_config", post(edit_large_file_storage_config)) + .route("/edit_git_sync_config", post(edit_git_sync_config)) .route("/leave", post(leave_workspace)); #[cfg(feature = "enterprise")] @@ -151,6 +152,7 @@ pub struct WorkspaceSettings { pub error_handler_extra_args: Option, pub error_handler_muted_on_cancel: Option, pub large_file_storage: Option, // effectively: DatasetsStorage + pub git_sync: Option, // effectively: WorkspaceGitRepo } #[derive(FromRow, Serialize, Debug)] @@ -979,7 +981,72 @@ async fn edit_large_file_storage_config( } tx.commit().await?; - Ok(format!("Edit copilot config for workspace {}", &w_id)) + Ok(format!("Edit large file storage config for workspace {}", &w_id)) +} + +#[derive(Deserialize)] +struct EditGitSyncConfig { + git_sync_settings: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WorkspaceGitRepo { + pub script_path: String, + pub git_repo_resource_path: String, +} + +async fn edit_git_sync_config( + authed: ApiAuthed, + Extension(db): Extension, + Path(w_id): Path, + ApiAuthed { is_admin, username, .. }: ApiAuthed, + Json(new_config): Json, +) -> Result { + #[cfg(not(feature = "enterprise"))] + { + return Err(Error::BadRequest( + "Git sync is only available on Windmill Enterprise Edition".to_string(), + )); + } + + require_admin(is_admin, &username)?; + + let mut tx = db.begin().await?; + + let args_for_audit = format!("{:?}", new_config.git_sync_settings); + audit_log( + &mut *tx, + &authed.username, + "workspaces.edit_git_sync_config", + ActionKind::Update, + &w_id, + Some(&authed.email), + Some([("git_sync_settings", args_for_audit.as_str())].into()), + ) + .await?; + + if let Some(git_sync_settings) = new_config.git_sync_settings { + let serialized_config = serde_json::to_value::(git_sync_settings) + .map_err(|err| Error::InternalErr(err.to_string()))?; + + sqlx::query!( + "UPDATE workspace_settings SET git_sync = $1 WHERE workspace_id = $2", + serialized_config, + &w_id + ) + .execute(&mut *tx) + .await?; + } else { + sqlx::query!( + "UPDATE workspace_settings SET git_sync = NULL WHERE workspace_id = $1", + &w_id, + ) + .execute(&mut *tx) + .await?; + } + tx.commit().await?; + + Ok(format!("Edit git sync config for workspace {}", &w_id)) } async fn edit_error_handler( @@ -1114,7 +1181,7 @@ async fn _check_nb_of_workspaces(db: &DB) -> Result<()> { .await?; if nb_workspaces.unwrap_or(0) >= 2 { return Err(Error::BadRequest( - "You have reached the maximum number of workspaces (2 outside of default worskapce 'admins') without an enterprise license. Archive/delete another workspace to create a new one" + "You have reached the maximum number of workspaces (2 outside of default workspace 'admins') without an enterprise license. Archive/delete another workspace to create a new one" .to_string(), )); } diff --git a/backend/windmill-common/src/jobs.rs b/backend/windmill-common/src/jobs.rs index ab6013156c..202b81122f 100644 --- a/backend/windmill-common/src/jobs.rs +++ b/backend/windmill-common/src/jobs.rs @@ -28,6 +28,7 @@ pub enum JobKind { FlowDependencies, AppDependencies, Noop, + DeploymentCallback, } #[derive(sqlx::FromRow, Debug, Serialize, Clone)] @@ -307,6 +308,9 @@ pub enum JobPayload { path: Option, restarted_from: Option, }, + DeploymentCallback { + path: String, + }, Identity, Noop, } diff --git a/backend/windmill-queue/src/jobs.rs b/backend/windmill-queue/src/jobs.rs index 0f34b404cf..795796de13 100644 --- a/backend/windmill-queue/src/jobs.rs +++ b/backend/windmill-queue/src/jobs.rs @@ -2502,6 +2502,20 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection priority, ) } + JobPayload::DeploymentCallback { path } => ( + None, + Some(path), + None, + JobKind::DeploymentCallback, + None, + None, + None, + None, + None, + None, + None, + None, + ), JobPayload::Identity => ( None, None, @@ -2600,7 +2614,11 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection || job_kind == JobKind::Identity { "flow".to_string() - } else if job_kind == JobKind::Dependencies || job_kind == JobKind::FlowDependencies { + } else if job_kind == JobKind::Dependencies + || job_kind == JobKind::FlowDependencies + || job_kind == JobKind::DeploymentCallback + { + // using the dependency tag for deployment callback for now. We can create a separate tag when we need "dependency".to_string() } else { "deno".to_string() @@ -2712,6 +2730,7 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection JobKind::Noop => "jobs.run.noop", JobKind::FlowDependencies => "jobs.run.flow_dependencies", JobKind::AppDependencies => "jobs.run.app_dependencies", + JobKind::DeploymentCallback => "jobs.run.deployment_callback", }; audit_log( diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index b45b1c0261..16ca0c47fa 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -30,6 +30,7 @@ use uuid::Uuid; use windmill_common::{ error::{self, to_anyhow, Error}, flows::{FlowModule, FlowModuleValue, FlowValue}, + get_latest_deployed_hash_for_path, jobs::{JobKind, QueuedJob}, scripts::{get_full_hub_script_by_path, ScriptHash, ScriptLang}, users::{SUPERADMIN_NOTIFICATION_EMAIL, SUPERADMIN_SECRET_EMAIL}, @@ -2701,11 +2702,10 @@ struct ContentReqLangEnvs { } async fn get_hub_script_content_and_requirements( - job: &QueuedJob, + script_path: Option, db: &DB, ) -> error::Result { - let script_path = job - .script_path + let script_path = script_path .clone() .ok_or_else(|| Error::InternalErr(format!("expected script path for hub script")))?; let mut script_path_iterator = script_path.split("/"); @@ -2716,8 +2716,8 @@ async fn get_hub_script_content_and_requirements( let cache_path = format!("{HUB_CACHE_DIR}/{version}"); let script; if tokio::fs::metadata(&cache_path).await.is_err() { - script = - get_full_hub_script_by_path(StripPath(script_path.clone()), &HTTP_CLIENT, db).await?; + script = get_full_hub_script_by_path(StripPath(script_path.to_string()), &HTTP_CLIENT, db) + .await?; write_file( HUB_CACHE_DIR, &version, @@ -2738,6 +2738,23 @@ async fn get_hub_script_content_and_requirements( }) } +async fn get_script_content_by_path( + script_path: Option, + w_id: &str, + db: &DB, +) -> error::Result { + let script_path = script_path + .clone() + .ok_or_else(|| Error::InternalErr(format!("expected script path")))?; + return if script_path.starts_with("hub/") { + get_hub_script_content_and_requirements(Some(script_path), db).await + } else { + let (script_hash, ..) = + get_latest_deployed_hash_for_path(db, w_id, script_path.as_str()).await?; + get_script_content_by_hash(&script_hash, w_id, db).await + }; +} + async fn get_script_content_by_hash( script_hash: &ScriptHash, w_id: &str, @@ -2786,7 +2803,9 @@ async fn handle_code_execution_job( language: job.language.to_owned(), envs: None, }, - JobKind::Script_Hub => get_hub_script_content_and_requirements(job, db).await?, + JobKind::Script_Hub => { + get_hub_script_content_and_requirements(job.script_path.clone(), db).await? + } JobKind::Script => { get_script_content_by_hash( &job.script_hash.unwrap_or(ScriptHash(0)), @@ -2795,6 +2814,9 @@ async fn handle_code_execution_job( ) .await? } + JobKind::DeploymentCallback => { + get_script_content_by_path(job.script_path.clone(), &job.workspace_id, db).await? + } _ => unreachable!( "handle_code_execution_job should never be reachable with a non-code execution job" ), diff --git a/frontend/src/lib/components/runs/RunsFilter.svelte b/frontend/src/lib/components/runs/RunsFilter.svelte index 04108d050c..db83f0ad33 100644 --- a/frontend/src/lib/components/runs/RunsFilter.svelte +++ b/frontend/src/lib/components/runs/RunsFilter.svelte @@ -184,6 +184,12 @@ showTooltipIcon tooltip="Deploying a script, flow or an app launch a dependency job that create and then attach the lockfile to the deployed item. This mechanism ensure that logic is always executed with the exact same direct and indirect dependencies." /> +
@@ -362,6 +368,12 @@ showTooltipIcon tooltip="Deploying a script, flow or an app launch a dependency job that create and then attach the lockfile to the deployed item. This mechanism ensure that logic is always executed with the exact same direct and indirect dependencies." /> + diff --git a/frontend/src/routes/(root)/(logged)/runs/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/runs/[...path]/+page.svelte index f945573847..831d28a724 100644 --- a/frontend/src/routes/(root)/(logged)/runs/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/runs/[...path]/+page.svelte @@ -110,11 +110,13 @@ function computeJobKinds(jobKindsCat: string | undefined): string { if (jobKindsCat == 'all') { - return `${CompletedJob.job_kind.SCRIPT},${CompletedJob.job_kind.FLOW},${CompletedJob.job_kind.DEPENDENCIES},${CompletedJob.job_kind.FLOWDEPENDENCIES},${CompletedJob.job_kind.APPDEPENDENCIES},${CompletedJob.job_kind.PREVIEW},${CompletedJob.job_kind.FLOWPREVIEW},${CompletedJob.job_kind.SCRIPT_HUB}` + return `${CompletedJob.job_kind.SCRIPT},${CompletedJob.job_kind.FLOW},${CompletedJob.job_kind.DEPENDENCIES},${CompletedJob.job_kind.FLOWDEPENDENCIES},${CompletedJob.job_kind.APPDEPENDENCIES},${CompletedJob.job_kind.PREVIEW},${CompletedJob.job_kind.FLOWPREVIEW},${CompletedJob.job_kind.SCRIPT_HUB},${CompletedJob.job_kind.DEPLOYMENTCALLBACK}` } else if (jobKindsCat == 'dependencies') { return `${CompletedJob.job_kind.DEPENDENCIES},${CompletedJob.job_kind.FLOWDEPENDENCIES},${CompletedJob.job_kind.APPDEPENDENCIES}` } else if (jobKindsCat == 'previews') { return `${CompletedJob.job_kind.PREVIEW},${CompletedJob.job_kind.FLOWPREVIEW}` + } else if (jobKindsCat == 'deploymentcallbacks') { + return `${CompletedJob.job_kind.DEPLOYMENTCALLBACK}` } else { return `${CompletedJob.job_kind.SCRIPT},${CompletedJob.job_kind.FLOW}` } diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index 33890e989e..85c6066079 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -54,6 +54,7 @@ let errorHandlerMutedOnCancel: boolean | undefined = undefined let openaiResourceInitialPath: string | undefined = undefined let s3ResourceInitialPath: string | undefined = undefined + let gitSyncResourceInitialPath: string | undefined = undefined let codeCompletionEnabled: boolean = false let tab = ($page.url.searchParams.get('tab') as @@ -180,6 +181,31 @@ } } + async function editWindmillGitSyncSettings(gitRepoResourcePath: string): Promise { + gitSyncResourceInitialPath = gitRepoResourcePath + if (gitRepoResourcePath) { + let resourcePathWithPrefix = `$res:${gitRepoResourcePath}` + await WorkspaceService.editWorkspaceGitSyncConfig({ + workspace: $workspaceStore!, + requestBody: { + git_sync_settings: { + script_path: 'hub/7835/sync-script-to-git-repo-windmill', + git_repo_resource_path: resourcePathWithPrefix + } + } + }) + sendUserToast(`Workspace Git sync settings updated`) + } else { + await WorkspaceService.editWorkspaceGitSyncConfig({ + workspace: $workspaceStore!, + requestBody: { + git_sync_settings: undefined + } + }) + sendUserToast(`Workspace Git sync settings reset`) + } + } + async function loadSettings(): Promise { const settings = await WorkspaceService.getSettings({ workspace: $workspaceStore! }) team_name = settings.slack_name @@ -214,6 +240,7 @@ settings.large_file_storage?.type === LargeFileStorage.type.S3STORAGE ? settings.large_file_storage?.s3_resource_path?.replace('$res:', '') : undefined + gitSyncResourceInitialPath = settings.git_sync?.git_repo_resource_path?.replace('$res:', '') } $: { @@ -309,6 +336,9 @@
S3 Storage
+ +
Git sync
+
Delete Workspace
@@ -625,6 +655,68 @@ }}>Test Connection
+ {:else if tab == 'git_sync'} + + {#if !$enterpriseLicense} + + Automatically saving scripts to a Git repository on each deploy is a Windmill EE feature. + + {/if} + + All scripts, flows and apps located in the workspace will be pushed to the Git repository, + except the ones that are saved in private user folders (i.e. where the path starts with + `u/`). + +
+ {#key s3ResourceInitialPath} + { + editWindmillGitSyncSettings(ev.detail) + }} + /> + {/key} +
+ +
+
Git repository initial setup
+ +
+ Every time a script is deployed, only the updated script will be pushed to the remote Git + repository. + +
+ + For the git repo to be representative of the entire workspace, it is recommended to set it + up using the Windmill CLI before turning this option on. + +

+ + Not familiar with Windmill CLI? + Check out the docs + +

+ + Run the following commands from the git repo folder to push the initial workspace content + to the remote: + +
+ +
> wmill workspace add WORKSPACE_NAME WORKSPACE_ID WINDMILL_URL
+> wmill sync pull --raw --skip-variables --skip-secrets --skip-resources
+> git add -A git commit -m 'Initial commit'
+> git push
+
+
{/if} {:else}