Compare commits

..

221 Commits

Author SHA1 Message Date
Ruben Fiszel
d5953c24b8 all 2024-06-21 20:41:44 +02:00
Ruben Fiszel
ba76d8749a fix: improve support of relative paths in subflows and apps 2024-06-21 18:07:58 +02:00
Faton Ramadani
ff4ea86155 fix show all light theme (#3949) 2024-06-21 17:09:17 +02:00
Faton Ramadani
25a460be85 feat(frontend): improve approval form edition + add a delete button t… (#3946)
* feat(frontend): improve approval form edition + add a delete button to the EditableSchema

* feat(frontend): only show a few lines of code for Hub/workflow scripts by default

* feat(frontend): fix spacing

* feat(frontend): improve

* feat(frontend): fix toggle

* feat(frontend): add missing space
2024-06-21 16:57:09 +02:00
Ruben Fiszel
e5db2782f5 add tsdocs 2024-06-21 15:59:06 +02:00
Ruben Fiszel
b2111b7d11 chore(main): release 1.350.3 (#3947)
* chore(main): release 1.350.3

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-21 15:30:29 +02:00
Ruben Fiszel
1042a06a12 fix(cli): fix push flow support for windows 2024-06-21 15:27:16 +02:00
Ruben Fiszel
0567d74abf chore(main): release 1.350.2 (#3945)
* chore(main): release 1.350.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-21 14:27:34 +02:00
Ruben Fiszel
3f0cd6349d fix(cli): support windows more thoroughly + fix generate flow locks (#3944)
* all

* all

* all

* fix lock

* fix lock

* fix lock

* fix lock
2024-06-21 14:23:33 +02:00
Ruben Fiszel
f1f9fe513b chore(main): release 1.350.1 (#3942)
* chore(main): release 1.350.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-21 01:14:45 +02:00
Ruben Fiszel
a43923b326 fix(cli): fix inital sync pull generating wrong flow lockfile 2024-06-21 01:09:37 +02:00
Ruben Fiszel
9d8a75c3ca chore(main): release 1.350.0 (#3939)
* chore(main): release 1.350.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-20 22:18:37 +02:00
Ruben Fiszel
59d731c35d add timeout for cancel jobs (#3941) 2024-06-20 21:22:44 +02:00
Faton Ramadani
4bfda45c72 Correctly initialize the flowInputStore(#3940)
* fix(frontend): Correctly initialize the flowInputStore for picked scripts/flows

* fix(frontend): Correctly initialize the flowInputStore for picked scripts/flows
2024-06-20 16:24:33 +02:00
Faton Ramadani
7007f14a10 feat(frontend): add indicator when required field are missing (#3935)
* feat(frontend): add indicator when required field are missing

* feat(frontend): add indicator when required field are missing

* feat(frontend): remove reactivity

* feat(frontend): remove reactivity

* feat(frontend): remove reactivity

* feat(frontend): remove reactivity

* feat(frontend): remove reactivity

* feat(frontend): handle init flow

* feat(frontend): done

* feat(frontend): done

* feat(frontend): simplify code

* feat(frontend): improve code

* feat(frontend): improve ArgInput

* feat(frontend): fix icon alignement
2024-06-20 15:40:27 +02:00
Ruben Fiszel
da999d0f9b nit cancel improvement 2024-06-20 13:16:28 +02:00
Ruben Fiszel
37c88272f5 add more debug lines 2024-06-19 19:43:13 +02:00
Ruben Fiszel
97ee8c35ea nit remove error logs + add setTimeout to REST runtime 2024-06-19 17:58:24 +02:00
Ruben Fiszel
a82184beb1 chore(main): release 1.349.1 (#3934)
* chore(main): release 1.349.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-19 13:54:40 +02:00
Ruben Fiszel
faaef3016d use auto-complete for worker group select 2024-06-19 13:50:21 +02:00
Ruben Fiszel
5c5b98e0b8 fix: show workers without worker groups 2024-06-19 13:35:10 +02:00
Ruben Fiszel
d166c563d9 chore(main): release 1.349.0 (#3933)
* chore(main): release 1.349.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-19 12:41:08 +02:00
Ruben Fiszel
4fa9025786 small range fix 2024-06-19 12:16:37 +02:00
Faton Ramadani
a1dc0fd7c2 feat(frontend): improve range (#3924)
* feat(frontend): fix style

* feat(frontend): wip

* fix(frontend): wip

* feat(frontend): improve range component

* feat(frontend): fix intial value
2024-06-19 12:07:12 +02:00
Ruben Fiszel
a0813939fe improve workers page 2024-06-19 11:51:09 +02:00
Ruben Fiszel
7c460888be chore(main): release 1.348.2 (#3931)
* chore(main): release 1.348.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-19 11:42:23 +02:00
HugoCasa
f5e8d71f0b fix: handle past inputs with oneOf (#3932) 2024-06-19 11:35:58 +02:00
Ruben Fiszel
a2b88c0080 fix: add jobid to background runnables and fix zindex issue of inline script editor 2024-06-19 11:12:13 +02:00
Ruben Fiszel
2e7c5b0ea9 add jobId 2024-06-19 11:11:34 +02:00
Faton Ramadani
c9c017e27a fix(frontend): fix full screen mode of the EvalInputEditor (#3928)
* update datafusion

* fix(frontend): fix full screen mode of the EvalInputEditor

* fix(frontend): improve code

---------

Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
2024-06-19 10:19:15 +02:00
Ruben Fiszel
866fcb1a79 chore(main): release 1.348.1 (#3929)
* chore(main): release 1.348.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-19 08:37:19 +02:00
Ruben Fiszel
6d4b8a2e4f fix: handle better single step parallel flows 2024-06-19 08:28:15 +02:00
Ruben Fiszel
9c152d96c9 fix tests 2024-06-18 22:57:51 +02:00
Ruben Fiszel
f3e8a81923 chore(main): release 1.348.0 (#3923)
* chore(main): release 1.348.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-18 22:16:44 +02:00
wendrul
ecb0e9b961 Implement PushArgs from cloudevents+json (#3927)
* Implement PushArgs from cloudevents+json

* Remove incomplete batching, overwrite metadata

Overwrite metadata to make it available as a script parameter if
present.
2024-06-18 22:13:32 +02:00
Ruben Fiszel
a7250bfae7 update datafusion 2024-06-18 22:13:02 +02:00
Ruben Fiszel
4cd733b67d update datafusion 2024-06-18 20:51:59 +02:00
HugoCasa
b753e4d06c feat: add support for bytea in pg (#3926)
* feat: add support for bytea in pg

* fix: editor nits
2024-06-18 17:38:46 +02:00
Faton Ramadani
b904a36356 feat(frontend): worker page improvements (#3921)
* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): add search

* feat(frontend): fix style

* feat(frontend): display a select when the number of worker groups is above 5

* feat(frontend): add number of workers in the select

* fix(frontend): flatten header and rows

* feat(frontend): improve worker header design

* feat(frontend): improve worker header design

* feat(frontend): fix search

* feat(frontend): fix dark theme
2024-06-18 17:18:16 +02:00
Faton Ramadani
cfab1853ab feat(frontend): Enable changing kind for string properties (#3925)
* feat(frontend): Enable changing kind for string properties

* feat(frontend): Enable changing kind for string properties

* feat(frontend): Enable changing kind for string properties
2024-06-18 16:11:54 +02:00
Faton Ramadani
b56f77b1da fix(frontend): fix InlineScriptEditor zIndex (#3922)
* fix(frontend): fix InlineScriptEditor zIndex

* Update frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2024-06-18 13:26:40 +02:00
Ruben Fiszel
eaf5b8ebe5 chore(main): release 1.347.1 (#3920)
* chore(main): release 1.347.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-18 09:43:47 +02:00
Ruben Fiszel
ddec620324 nit test fix 2024-06-18 09:28:03 +02:00
Ruben Fiszel
a64b099084 fix: add more debug logs around http client errors 2024-06-18 09:01:55 +02:00
Ruben Fiszel
631b981b8e fix: add more debug logs around http client errors 2024-06-18 08:54:55 +02:00
Ruben Fiszel
076d2d6fe7 chore(main): release 1.347.0 (#3919)
* chore(main): release 1.347.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-17 22:55:01 +02:00
Ruben Fiszel
95cdeacef9 arg enum small fix 2024-06-17 22:42:37 +02:00
Faton Ramadani
25024a920d feat(frontend): UI customisation improvements + add support for object enums (#3910)
* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): add json editor

* feat(frontend): fix build

* feat(frontend): wip

* feat(frontend): handle deleting the custom title

* feat(frontend): fix initial value

* feat(frontend): add support to custom title for ArgEnum

* feat(frontend): add support to custom title for ArgEnum

* feat(frontend): add missing fields

* feat(frontend): disable add and remove enums in the script editor

* feat(frontend): fix type inferrence

* feat(frontend): fix ArgEnum

* Update frontend/src/lib/components/ArgEnum.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2024-06-17 22:38:09 +02:00
Ruben Fiszel
05d2197618 fix: fix permission for scoped tokens on jobs_u paths 2024-06-17 22:32:59 +02:00
HugoCasa
2df9c69023 feat: oneOf inputs (#3893)
* feat: oneOf input for typescript

* feat: oneOf order and light form

* feat: oneOf UI builder
2024-06-17 21:35:46 +02:00
Ruben Fiszel
24e3a25ca4 chore(main): release 1.346.2 (#3917)
* chore(main): release 1.346.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-17 17:29:57 +02:00
Faton Ramadani
c94c76f59b fix(frontend): revert range (#3916) 2024-06-17 17:25:34 +02:00
Ruben Fiszel
cf4d0346f6 chore(main): release 1.346.1 (#3915)
* chore(main): release 1.346.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-17 14:26:47 +02:00
HugoCasa
96dfacbfc8 fix: job perms and job logs grants (#3914)
* fix: job perms grants

* fix: add job logs grants
2024-06-17 14:22:47 +02:00
Danny Summerlin
952adff138 adding msgraph-sdk to Python module aliases (#3913) 2024-06-17 14:01:52 +02:00
Ruben Fiszel
1cc8891fb2 chore(main): release 1.346.0 (#3906)
* chore(main): release 1.346.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-17 05:51:51 +02:00
Ruben Fiszel
d518e2359d fix: fix workflow as code 2024-06-17 05:37:57 +02:00
HugoCasa
e0ac22ba4a fix: job perms for agent mode (#3911) 2024-06-14 17:36:10 +02:00
HugoCasa
21b9accca1 feat: replace ephemeral tokens by jwt (#3908)
* feat: replace ephemeral tokens by jwt

* fix: migration + sqlx

* fix: tests, agent, ee ref

* fix: sqlx

* fix: tests

* fix: jwt prefix change + fix tests

* fix: nit

* fix: handle agent mode
2024-06-14 13:07:35 +02:00
Ruben Fiszel
dc6144219f fix bun cache 2024-06-13 22:08:33 +02:00
Ruben Fiszel
28afe59a4a feat: accelerate bun through caches (#3909)
* all

* all

* all

* all

* all

* simplify extract
2024-06-13 19:09:16 +02:00
Faton Ramadani
4f0e111563 feat(frontend): event handlers (#3902)
* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): done

* feat(frontend): dark mode

* feat(frontend): fix dark mode + width issue

* feat(frontend): fix dark mode + width issue

* feat(frontend): fix layout

* feat(frontend): done

* feat(frontend): fix wording
2024-06-13 15:57:14 +02:00
Ruben Fiszel
c19f330965 chore(main): release 1.345.2 (#3905)
* chore(main): release 1.345.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-13 15:07:25 +02:00
Ruben Fiszel
96767ec042 fix: add database grants to oustanding_wait_time table 2024-06-13 14:29:33 +02:00
Ruben Fiszel
d0f47f4b03 chore(main): release 1.345.1 (#3904)
* chore(main): release 1.345.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-13 08:27:01 +02:00
Ruben Fiszel
6c2420f118 fix: enums derivable from code 2024-06-13 08:22:44 +02:00
Richard Klees
320ba754a4 fix: correct exception handling in PHP wrapper (#3901)
The `catch` is hinting on `\Exception` [1] which has not `getName`-method.
To identify the type of exception, `get_class` can be used.

[1] https://www.php.net/manual/de/class.exception.php

Co-authored-by: HugoCasa <hugo@casademont.ch>
2024-06-13 08:13:32 +02:00
Ruben Fiszel
949b9b4787 chore(main): release 1.345.0 (#3903)
* chore(main): release 1.345.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-12 18:58:31 +02:00
Faton Ramadani
2344077b34 feat(frontend): Generated UI editor + Schema Form complete refactor (#3835)
* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): add type editor

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): dnd

* feat(frontend): add missing error

* feat(frontend): fix build

* feat(frontend): fix build

* feat(frontend): clean up

* feat(frontend): fix layout

* feat(frontend): fix dark mode

* feat(frontend): Fix Dnd + resource s3 and objects

* feat(frontend): handle inner objets

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* fix(frontend): UI nits

* fix(frontend): fix type selection

* fix(frontend): Correctly handle subproperties

* fix(frontend): fix autosize + height

* fix(frontend): replace everywhere

* fix(frontend): fix dnd

* fix(frontend): fix list refresh + height issues

* fix(frontend): fix order

* fix(frontend): restore default behavior

* fix(frontend): Move the rename input

* fix(frontend): Fix rename wrt order array

* fix(frontend): Fix hub

* fix(frontend): Fix renam

* fix(frontend): Fix UI Nits + fix SchemaForm order

* fix(frontend): Handle nested order

* fix(frontend): Fix saving properties

* fix(frontend): Improve approval form

* feat(frontend): done

* feat(frontend): merge main

* feat(frontend): done

* feat(frontend): wip

* feat(frontend): SchemaFormDND

* feat(frontend): SchemaFormDND wip

* feat(frontend): improve displayWebhookWarning

* feat(frontend): DND done

* feat(frontend): DND done

* feat(frontend): improve name

* feat(frontend): improve dnd

* feat(frontend): done

* first batch

* new try

* nits

* all

* drag handle in more places

* push everything

* migrate all

* all

* fix

* fix

* fix henri bug

---------

Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
2024-06-12 18:37:18 +02:00
Ruben Fiszel
4b7ff22cc0 chore(main): release 1.344.3 (#3899)
* chore(main): release 1.344.3

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-11 21:35:02 +02:00
Ruben Fiszel
c96697928f fix: fix dependency tracking for single scripts 2024-06-11 21:32:10 +02:00
Ruben Fiszel
6c4ef79e1c chore(main): release 1.344.2 (#3898)
* chore(main): release 1.344.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-11 21:07:11 +02:00
Ruben Fiszel
28d7510584 fix: fix dependency tracking for single scripts 2024-06-11 21:04:03 +02:00
Ruben Fiszel
9307f31331 chore(main): release 1.344.1 (#3897)
* chore(main): release 1.344.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-11 20:54:43 +02:00
Ruben Fiszel
5f119de6cb fix: fix dependency tracking for single scripts 2024-06-11 20:51:57 +02:00
Ruben Fiszel
f8f6d8beaa fix: upgrade deno to 1.44.1 2024-06-11 19:54:57 +02:00
wendrul
b9092e591e fix: cancel jobs button missing chevron (#3896) 2024-06-11 19:33:57 +02:00
Ruben Fiszel
26e21d5c93 fix go client build 2024-06-11 19:31:28 +02:00
Ruben Fiszel
24c2cc1ed7 chore(main): release 1.344.0 (#3895)
* chore(main): release 1.344.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-11 19:07:04 +02:00
Ruben Fiszel
dcff6e9ff3 fix(backend): wrong previous result used in flow for-loop 2024-06-11 17:35:38 +02:00
wendrul
7474145f0e feat: cancel jobs based on filters (#3874)
* WIP

* Add endpoint to cancel jobs

* Fix endpoints and add modal to cancel jobs

* Add useful tooltips and warnings

* Fix openapi.yml

* Prepare sqlx

* Prepare sqlx

* Select jobs to cancel

* Prepare sqlx

* Remove unused variable

* Make small fixes

- gap between buttons
- dropdown in one button with chevron instead of two buttons
- filters shown on the cancel filtered modal
2024-06-11 17:12:30 +02:00
Faton Ramadani
609f332116 fix(frontend): Fix Timeline/Node Status tab zIndex (#3894) 2024-06-11 16:41:37 +02:00
Ruben Fiszel
da03a45d81 chore(main): release 1.343.3 (#3892)
* chore(main): release 1.343.3

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-11 14:07:57 +02:00
Ruben Fiszel
1be0bfaf7b fix: flow args should always render in test flow 2024-06-11 13:57:53 +02:00
Ruben Fiszel
eb068fd086 fix: improve init script handling of windows newlines 2024-06-11 00:55:28 +02:00
Ruben Fiszel
ce65d5c1b0 add lokalize exception to import map 2024-06-10 22:14:13 +02:00
Ruben Fiszel
2adb2fcbda chore(main): release 1.343.2 (#3891)
* chore(main): release 1.343.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-10 19:12:44 +02:00
Ruben Fiszel
36d0c4e992 fix: fix nativets scripts 2024-06-10 19:09:38 +02:00
Ruben Fiszel
0f7f900ad6 chore(main): release 1.343.1 (#3889)
* chore(main): release 1.343.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-10 18:35:28 +02:00
Ruben Fiszel
ec248ddaec fix: update deno_core to latest to work better with rust 1.78 (#3890) 2024-06-10 18:31:16 +02:00
Ruben Fiszel
61bb069da3 fix: fix reorder of args in schema form 2024-06-10 15:38:24 +02:00
Ruben Fiszel
c72c53083b chore(main): release 1.343.0 (#3875)
* chore(main): release 1.343.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-10 13:29:10 +02:00
Ruben Fiszel
1957ca03b3 feat(cli): add wmill flow generate-locks 2024-06-10 11:44:53 +02:00
Ruben Fiszel
38ed825d09 remove all warnings 2024-06-08 18:06:04 +02:00
Ruben Fiszel
13cda8be80 update tests 2024-06-08 17:51:43 +02:00
Ruben Fiszel
26822d9db8 return flow value in flow dependency job 2024-06-08 17:38:06 +02:00
Ruben Fiszel
56b33e0d1a update rust image to 1.78 2024-06-08 17:02:31 +02:00
Ruben Fiszel
5ae8592792 feat: track dependency map for bun + inline script of flows 2024-06-08 16:43:48 +02:00
HugoCasa
f29f71bfde fix: remove main decorator after split from end of file during py imports parsing (#3887)
* fix: remove main decorator after split from end of file during py imports parsing

* fix: nit
2024-06-07 22:08:22 +02:00
wendrul
d2d87f4c97 feat: towards cloud events webhook compliance (#3883)
* Cloud events webhook compliance

* Only on OPTIONS
2024-06-07 14:24:04 +02:00
Ruben Fiszel
da1ea04c79 fix: retrigger bun dependencies jobs for importers when using common deps 2024-06-07 13:34:07 +02:00
HugoCasa
66e6fe374c fix(frontend): job detail horizontal padding small screens (#3881) 2024-06-06 17:55:26 +02:00
Faton Ramadani
6c4e7d0e93 fix(frontend):Add missing InitializeComponent for components Flow Status by id and Log by Job id (#3882) 2024-06-06 17:34:32 +02:00
HugoCasa
387ea4469f fix(frontend): encrypt openai key on workspace creation (#3879) 2024-06-05 23:38:40 +02:00
Ruben Fiszel
b1f9272d9f feat: support selecting by columns in table 2024-06-05 19:57:54 +02:00
Faton Ramadani
ef2329bb87 fix(frontend): Remove useless RunnableWrapper on Log and Flow status … (#3877)
* fix(frontend): Remove useless RunnableWrapper on Log and Flow status component

* fix(frontend): fix wording

* fix(frontend): fix wording

* fix(frontend): add missing render prop
2024-06-05 16:21:33 +02:00
Ruben Fiszel
63f962bef0 bump ee private 2024-06-05 16:14:34 +02:00
Ruben Fiszel
7d6868a0cb increase token length to 32 chars 2024-06-05 15:49:21 +02:00
Faton Ramadani
be092d2527 fix(frontend): Fix AgChart when the component is hidden (#3876) 2024-06-05 13:34:09 +02:00
Ruben Fiszel
3e969b291f fix sqlx 2024-06-05 13:32:23 +02:00
Ruben Fiszel
0975fb6950 fix: paginate listTokens page 2024-06-05 13:24:58 +02:00
Hamir Mahal
11fba4fbca fix: deprecated Node.js usage in checkout@v3 (#3872) 2024-06-05 13:09:21 +02:00
Ruben Fiszel
ebf37eb16b fix: use full hostname as worker ping hostname and add it in other contexts 2024-06-05 11:28:51 +02:00
Ruben Fiszel
d02430a2e0 chore(main): release 1.342.0 (#3870)
* chore(main): release 1.342.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-05 00:42:06 +02:00
HugoCasa
14bd5fe051 feat: customer portal link (#3868)
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2024-06-04 23:55:54 +02:00
Ruben Fiszel
b756a3b31e fix: handle csv with different separators in csv preview 2024-06-04 23:53:45 +02:00
Ruben Fiszel
bb6ae23cbc frontend nits 2024-06-04 23:09:52 +02:00
Ruben Fiszel
5152e0f2a0 frontend nits 2024-06-04 23:06:34 +02:00
Ruben Fiszel
c7a86a8bce chore(main): release 1.341.1 (#3864)
* chore(main): release 1.341.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-04 21:20:20 +02:00
Ruben Fiszel
ef9ad1af49 fix: fix writing binary file from global cache in go 2024-06-04 21:17:05 +02:00
Ruben Fiszel
4408e4fb86 standardize date display 2024-06-04 16:55:55 +02:00
Ruben Fiszel
a9bf5a4683 fix: make typescript client compatible with cf workers (#3807)
* make typescript client compatible with cf workers

* Update build.sh
2024-06-04 16:23:23 +02:00
Ruben Fiszel
f54cfd3640 fix: improve flow status viewer to display the step details on third tab 2024-06-04 15:07:08 +02:00
Faton Ramadani
2b85bc63b7 Limit the where clause of the Database Studio to static only (#3866) 2024-06-04 09:32:40 +02:00
Ruben Fiszel
b6016abb22 fix: flow status viewer takes all the width on the runs page 2024-06-04 09:27:18 +02:00
Ruben Fiszel
439ab8ab14 fix: lock steps inside whileloops for flows 2024-06-03 19:37:42 +02:00
wendrul
98869efdab fix: Filter on path not working (#3863) 2024-06-03 17:31:55 +02:00
Ruben Fiszel
0fb96ec3c3 chore(main): release 1.341.0 (#3861)
* chore(main): release 1.341.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-06-03 17:24:33 +02:00
Ruben Fiszel
44c36cdeb5 fix: fix python client for S3Object 2024-06-03 17:20:29 +02:00
Ruben Fiszel
fb953b7fc7 fix rawresult 2024-06-03 16:10:26 +02:00
wendrul
203264b871 feat: warn when jobs spent a long time waiting in queue (#3856)
* Store jobs that waited for too long

* Add warnings as badges for long waited jobs

* Separate into self_wait_time and aggregate

Change the UI accordingly

* Prepare sqlx

* Update backend/windmill-queue/src/jobs.rs

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Fix incorrect query

* Prepare sqlx

* Move insert to pull + UI fixes

Insert as soon as the job is pulled and therefore started.
Add a badge on the lfow timeline to show the self wait time

* Move to after the pull in the worker

Move the logic to after the pull in the worker in the case its not a
noop

* Remove weird line

* Remove unnecessary async

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2024-06-03 16:05:15 +02:00
Faton Ramadani
76b65771a0 feat(frontend): Fix how runnable tied to a table actions are triggered + Display the sync columnDef error only in the editor (#3862) 2024-06-03 16:02:21 +02:00
Ruben Fiszel
5ff7477c7d fix rawresult 2024-06-03 15:46:19 +02:00
Ruben Fiszel
181cb7dec9 fix: further restrict job api to logged in workspace users or anonymous jobs only" (#3860) 2024-06-03 15:13:15 +02:00
Ruben Fiszel
2c19fde250 chore(main): release 1.340.2 (#3855)
* chore(main): release 1.340.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-31 22:37:23 +02:00
Ruben Fiszel
2359cdc128 fix: add audit log exception to schedules 2024-05-31 22:29:15 +02:00
Ruben Fiszel
326446e5ce fix: fix csv preview for storage renderer 2024-05-31 14:23:27 +02:00
Ruben Fiszel
5c5b475261 chore(main): release 1.340.1 (#3854)
* chore(main): release 1.340.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-31 13:30:01 +02:00
Ruben Fiszel
9e822d4c75 fix: typescript file upload supports arbitrary storage 2024-05-31 13:26:51 +02:00
Ruben Fiszel
2c16a20814 chore(main): release 1.340.0 (#3849)
* chore(main): release 1.340.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-31 12:58:38 +02:00
Ruben Fiszel
8ffceb9a31 fix go client build 2024-05-31 12:58:17 +02:00
Ruben Fiszel
be160f6e46 fix: simple subflow approval step triggering timeouts 2024-05-31 12:50:29 +02:00
Ruben Fiszel
9308e2a63c fix compile issue 2024-05-31 12:30:58 +02:00
Ruben Fiszel
d53fbfc039 fix compile issue 2024-05-31 12:15:25 +02:00
Ruben Fiszel
a22dc985fa feat: support multiple object storage + parquet_csv + polars -> datafusion" (#3853)
* multiple storage

* all

* rm symlinks

* all

* all
2024-05-31 11:59:51 +02:00
wendrul
5156e291fa feat: chart interactivity: click points on the graph to select the corresponding jobs (#3851)
* Make click on RunChart higlight and select job

* Select job when clicking on graph point

* Fix type of chart data object

* Persist selection on refresh and other changes
2024-05-30 19:26:11 +02:00
Ruben Fiszel
9b7b650d8b table small improvements 2024-05-30 15:05:42 +02:00
Ruben Fiszel
24889fb3a0 further fix to normal tables 2024-05-30 11:31:45 +02:00
Ruben Fiszel
96246cd697 fix: wait for api to be read to load explorer table 2024-05-30 11:30:18 +02:00
Ruben Fiszel
cefa12b551 remove donePromise 2024-05-30 11:01:55 +02:00
Ruben Fiszel
660f38ecd0 remove donePromise 2024-05-30 10:59:10 +02:00
Ruben Fiszel
198ee29110 add renew license key for tests 2024-05-30 08:19:42 +02:00
Ruben Fiszel
3b051c4992 improve sort and search for parquet preview 2024-05-30 00:50:52 +02:00
Ruben Fiszel
76d517ef01 fix ee.rs 2024-05-29 23:51:38 +02:00
Ruben Fiszel
e07c2621e9 feat: replace polars with datafusion for data preview 2024-05-29 23:38:36 +02:00
Ruben Fiszel
2558cfa9f5 chore(main): release 1.339.2 (#3846)
* chore(main): release 1.339.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-29 19:16:18 +02:00
HugoCasa
e052dd5f6e fix: worker memory usage (#3845) 2024-05-29 18:16:41 +02:00
Ruben Fiszel
8a4d9c9ff3 chore(main): release 1.339.1 (#3844)
* chore(main): release 1.339.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-29 17:18:49 +02:00
Ruben Fiszel
7238274d1c fix: allow_user_resoruces default deserialization 2024-05-29 17:10:20 +02:00
Ruben Fiszel
3dea341a30 chore(main): release 1.339.0 (#3843)
* chore(main): release 1.339.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-29 16:32:13 +02:00
HugoCasa
dc2d7e1c8f feat: display last key renewal attempt (#3839)
* feat: display last key renewal attempt

* feat: improve UI + add renew button + dev instance

* fix: nits

* chore: update ee ref

* fix: nit

* fix: tests
2024-05-29 16:28:00 +02:00
Ruben Fiszel
6b2299f7a8 resource others page fix 2024-05-29 15:02:52 +02:00
Ruben Fiszel
2294ce2f3b chore(main): release 1.338.3 (#3841)
* chore(main): release 1.338.3

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-29 13:00:48 +02:00
Ruben Fiszel
717ecb93dd remove unecessary formatter black since ruff format now 2024-05-29 12:54:24 +02:00
Ruben Fiszel
b01e33523d fix: fix resource type search 2024-05-29 12:09:24 +02:00
Ruben Fiszel
08b16f86b1 chore(main): release 1.338.2 (#3840)
* chore(main): release 1.338.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-29 01:49:50 +02:00
Ruben Fiszel
e7763375d6 jemalloc for all 2024-05-29 01:44:37 +02:00
Ruben Fiszel
b6b5eef0f3 remove heap profiling by default 2024-05-29 01:20:23 +02:00
HugoCasa
5d2b244869 fix: worker metrics (#3837)
* fix: worker metrics

* chore: sqlx

* chore: update ee ref

* fix: remove jemalloc stats unwrap
2024-05-29 01:12:00 +02:00
Ruben Fiszel
c904d9c041 chore(main): release 1.338.1 (#3831)
* chore(main): release 1.338.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-28 17:01:20 +02:00
Ruben Fiszel
8b66636a89 fix: remove quotes around interpolated arg values of tags 2024-05-28 16:56:27 +02:00
Henri Courdent
ac8118c409 Links update & stroke width icons (#3833)
* Links update & stroke width icons

* Update frontend/src/lib/components/StringTypeNarrowing.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2024-05-28 16:05:56 +02:00
Ruben Fiszel
6166c4d7aa fix: fix retry not working on single step flow due to opt 2024-05-28 10:48:41 +02:00
Ruben Fiszel
e5db421b1b chore(main): release 1.338.0 (#3819)
* chore(main): release 1.338.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-27 20:45:46 +02:00
Faton Ramadani
c246bb0705 feat(frontend): add open/close state of the modal in the outputs (#3822)
* feat(frontend): add open/close state of the modal in the outputs

* feat(frontend): add onOpen/onClose event handlers

* feat(frontend): add onOpen/onClose event hander

* feat(frontend): improve close logic for drawers

* feat(frontend): refactor handleSideEffect into an util file

* feat(frontend): improve code

* feat(frontend): improve naming

* feat(frontend): improve code

* feat(frontend): improve code

* feat(frontend): remove on Open/Close actions

* feat(frontend): simplify the implementation

* feat(frontend): fix callbacks
2024-05-27 20:32:07 +02:00
HugoCasa
621464b550 feat: worker vcpus/memory limits + mem usage (#3828) 2024-05-27 18:43:02 +02:00
HugoCasa
256185308e feat(frontend): upgrade to gpt-4o + add AI support for php (#3820)
* feat: upgrade to gpt-4o

* feat: improve code completion + UI stuff
2024-05-27 18:29:42 +02:00
wendrul
1f7be465ad Improve filter on queue (#3829) 2024-05-27 18:21:53 +02:00
Ruben Fiszel
adcf37d313 add opensearchpy to lib.rs mapping 2024-05-27 16:41:30 +02:00
Henri Courdent
ecc8466b88 Changelog update frontend (#3824) 2024-05-27 15:58:31 +02:00
wendrul
47df9f33cc fix: filtering not always working with concurrency keys (#3823)
* fix missing filtering on ommision of obscured jobs

Also allow cron and scheduled jobs for the filtering security

* Revert incorrect change

* Revert frontend change
2024-05-27 15:58:07 +02:00
Ruben Fiszel
b58c6257a6 set last_ping to null when requeuing because of concurrency limits 2024-05-27 15:53:32 +02:00
Ruben Fiszel
40045e0c0f clarify iframe for apps 2024-05-27 14:06:27 +02:00
Ruben Fiszel
b13f42ab4e fix sqlx 2024-05-27 13:08:47 +02:00
Ruben Fiszel
e2a1219373 feat: public apps can require login (#3825) 2024-05-27 13:03:41 +02:00
Ruben Fiszel
999d2e4745 remove supabase_wizard from oauth connects 2024-05-27 09:47:55 +02:00
Ruben Fiszel
b5caf0777d fix resources connects 2024-05-27 09:26:41 +02:00
Ruben Fiszel
5877727c16 feat: allow user resources in apps with a toggle (#3821)
* all

* all

* all

* all

* all

* all

* all

* all

* all

* all

* nits

* nits
2024-05-27 07:51:49 +02:00
Ruben Fiszel
3c74da4116 increase min re-scheduling 2024-05-26 05:20:11 +02:00
Ruben Fiszel
e397a385e2 reschedule to at least 1secs in future 2024-05-26 05:04:42 +02:00
Ruben Fiszel
7a36f30fe3 fix: make all error strings more verbose 2024-05-25 22:15:15 +02:00
Ruben Fiszel
7a664b5cd4 nit improvements for concurrency jobs 2024-05-25 17:28:32 +02:00
Ruben Fiszel
545d982419 nit improvements for concurrency jobs 2024-05-25 17:26:08 +02:00
Ruben Fiszel
f2d9c3c777 fix: improve concurrency re-scheduling at scale 2024-05-25 17:20:11 +02:00
Ruben Fiszel
e187fa6263 fix: improve concurrency re-scheduling at scale 2024-05-25 15:56:56 +02:00
Ruben Fiszel
af5c31e6d4 chore(main): release 1.337.0 (#3811)
* chore(main): release 1.337.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-25 12:00:58 +02:00
Ruben Fiszel
7fdfb9b006 fix build 2024-05-25 11:47:47 +02:00
Ruben Fiszel
664dcee837 fix build 2024-05-25 10:54:14 +02:00
HugoCasa
47bb5d2492 fix: use hub script language as tag instead of 'hub' (#3816)
* fix: use hub script language as tag instead of 'hub'

* fix: remove hub tag
2024-05-25 10:38:03 +02:00
Ruben Fiszel
c070320add fix oss build 2024-05-25 10:34:11 +02:00
Ruben Fiszel
e351a93efb fix build 2024-05-25 09:59:38 +02:00
Ruben Fiszel
ee22ec5fd1 fix build 2024-05-25 09:54:02 +02:00
HugoCasa
831cf89b63 feat: automatic key renewal (#3815)
* feat: automatic ee key renewal

* chore: sqlx

* chore: update ee repo ref

---------

Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2024-05-24 19:49:45 +02:00
HugoCasa
7584c2b0bb fix: rename email_from_username to username_to_email (#3813) 2024-05-24 17:03:44 +02:00
William Butez
59f980f75a feat: add GetResumeUrls to go client (#3810)
* feat: add GetResumeUrls to go client

* add type ResumeUrls
2024-05-24 12:47:50 +02:00
Ruben Fiszel
319cfb7dc1 chore(main): release 1.336.1 (#3809)
* chore(main): release 1.336.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-24 08:23:47 +02:00
Ruben Fiszel
ba9cdb1ae2 fix: revert bun to 1.1.8 2024-05-24 08:07:41 +02:00
Ruben Fiszel
141ae06ad1 chore(main): release 1.336.0 (#3796)
* chore(main): release 1.336.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2024-05-23 22:19:05 +02:00
Ruben Fiszel
3680c292f8 add more infos about hanging monitor last ping 2024-05-23 22:14:31 +02:00
Faton Ramadani
a0acdc1217 fix(frontend): Add missing loading state for non-runnable components … (#3797)
* fix(frontend): Add missing loading state for non-runnable components + fix select and aggrid styling

* fix(frontend): remove log

* fix(frontend): improve code

* fix(frontend): improve code

* fix(frontend): Fix refreshIndicator styling
2024-05-23 20:36:39 +02:00
HugoCasa
001278cddd feat: improve parsers when no main func (#3805)
* feat: improve parsers when no main func

* chore: update parser version
2024-05-23 20:36:16 +02:00
Faton Ramadani
d11e350de3 feat(frontend): improve graph edges + fix depedencies detection (#3802)
* feat(frontend): improve graph edges + fix depedencies detection

* Update frontend/src/lib/components/graph/svelvet/edges/views/Edges/SimpleBezierEdge.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2024-05-23 20:17:34 +02:00
Ruben Fiszel
62e88169ea feat: store failed_retries per module state and display failed retries in flow status viewer 2024-05-23 19:26:20 +02:00
Ruben Fiszel
7e0be8914b feat: store failed_retries per module state and display failed retries in flow status viewer 2024-05-23 19:16:26 +02:00
HugoCasa
62f318077c feat: improve permissioned audit logs (#3799)
* fix: increase token label size in db

* Revert "Revert "feat:  improve premissioned audit logs (#3793)" (#3798)"

This reverts commit 43a24d997e.

* feat: add username to email function

* fix: nit

* fix: add docstring to global func
2024-05-23 17:23:50 +02:00
wendrul
1745a9dd16 fix: show code option in tree view (#3803)
* fix: show code option in tree view

* Update TreeViewRoot.svelte
2024-05-23 16:49:18 +02:00
wendrul
a8d9a400e2 Add concurrency key for inline scripts in flows (#3801) 2024-05-23 14:59:18 +02:00
Ruben Fiszel
43a24d997e Revert "feat: improve premissioned audit logs (#3793)" (#3798)
This reverts commit 21a077ecfa.
2024-05-23 11:12:51 +02:00
Ruben Fiszel
bfd2d27415 fix: update bun to 1.1.9 2024-05-23 09:24:38 +02:00
HugoCasa
21a077ecfa feat: improve premissioned audit logs (#3793)
* feat:  improve premissioned audit logs

* chore: update ee ref

* fix: build

* fix: sqlx
2024-05-23 08:55:48 +02:00
Jeremy Worden
068190f922 Update lib.rs (#3795)
add ldap=>python-ldap remapping
2024-05-23 08:53:42 +02:00
1317 changed files with 28957 additions and 37439 deletions

View File

@@ -1,5 +1,5 @@
ARG DEBIAN_IMAGE=debian:bookworm-slim
ARG RUST_IMAGE=rust:1.75-slim-bookworm
ARG RUST_IMAGE=rust:1.78-slim-bookworm
ARG PYTHON_IMAGE=python:3.11.4-slim-bookworm
FROM ${DEBIAN_IMAGE} as downloader
@@ -53,7 +53,7 @@ RUN wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VER
RUN /usr/local/bin/python3 -m pip install pip-tools
COPY --from=oven/bun:1.0.29 /usr/local/bin/bun /usr/bin/bun
COPY --from=oven/bun:1.1.8 /usr/local/bin/bun /usr/bin/bun
RUN [ "$TARGETPLATFORM" == "linux/amd64" ] && curl -Lsf https://github.com/denoland/deno/releases/download/v1.41.0/deno-x86_64-unknown-linux-gnu.zip -o deno.zip || true

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.75.0
toolchain: 1.78.0
# - uses: Swatinem/rust-cache@v2
# with:
# workspaces: |

View File

@@ -23,7 +23,7 @@ jobs:
build:
runs-on: ubicloud
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -31,7 +31,7 @@ jobs:
run: |
echo "ee_repo_ref=$(cat ./backend/ee-repo-ref.txt)" >> "$GITHUB_ENV"
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
repository: windmill-labs/windmill-ee-private
path: ./windmill-ee-private
@@ -74,7 +74,7 @@ jobs:
platforms: linux/amd64,linux/arm64
push: true
build-args: |
features=embedding,parquet,openidconnect
features=embedding,parquet,openidconnect,jemalloc
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev
${{ steps.meta-public.outputs.tags }}
@@ -85,7 +85,7 @@ jobs:
build_ee:
runs-on: ubicloud
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -93,7 +93,7 @@ jobs:
run: |
echo "ee_repo_ref=$(cat ./backend/ee-repo-ref.txt)" >> "$GITHUB_ENV"
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
repository: windmill-labs/windmill-ee-private
path: ./windmill-ee-private
@@ -148,7 +148,7 @@ jobs:
runs-on: ubicloud
if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -156,7 +156,7 @@ jobs:
run: |
echo "ee_repo_ref=$(cat ./backend/ee-repo-ref.txt)" >> "$GITHUB_ENV"
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
repository: windmill-labs/windmill-ee-private
path: ./windmill-ee-private
@@ -199,7 +199,7 @@ jobs:
platforms: linux/amd64
push: true
build-args: |
features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud
features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc
PYTHON_IMAGE=python:3.12.2-slim-bookworm
tags: |
${{ steps.meta-ee-public-py312.outputs.tags }}
@@ -226,7 +226,7 @@ jobs:
# --health-timeout 5s
# --health-retries 5
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4
# - name: "Docker"
# run: echo "::set-output name=id::$(docker run --network=host --rm -d -p 8000:8000 --privileged -it -e DATABASE_URL=postgres://admin:changeme@localhost:5432/windmill -e BASE_INTERNAL_URL=http://localhost:8000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest)"
# id: docker-container
@@ -247,7 +247,7 @@ jobs:
env:
ARCH: amd64
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: |
# pulling docker image with desired arch so that actions-docker-extract doesn't do it
@@ -291,7 +291,7 @@ jobs:
# env:
# ARCH: arm64
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4
# - run: |
# # pulling docker image with desired arch so that actions-docker-extract doesn't do it
@@ -332,7 +332,7 @@ jobs:
runs-on: ubicloud
needs: [build_ee]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Prepare test run
@@ -356,7 +356,7 @@ jobs:
runs-on: ubicloud
needs: [run_integration_test, build]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Login to registry
@@ -374,7 +374,7 @@ jobs:
runs-on: ubicloud
needs: [run_integration_test, build_ee]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Login to registry
@@ -434,7 +434,7 @@ jobs:
needs: [build_ee]
runs-on: ubicloud
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -482,7 +482,7 @@ jobs:
needs: [build_ee_nsjail]
runs-on: ubicloud
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
# - name: Set up Docker Buildx
@@ -532,7 +532,7 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -577,7 +577,7 @@ jobs:
needs: [build_ee]
runs-on: ubicloud
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0

View File

@@ -1,5 +1,402 @@
# Changelog
## [1.350.3](https://github.com/windmill-labs/windmill/compare/v1.350.2...v1.350.3) (2024-06-21)
### Bug Fixes
* **cli:** fix push flow support for windows ([1042a06](https://github.com/windmill-labs/windmill/commit/1042a06a12ae31d31facd1dfab10cbd2b10c86f5))
## [1.350.2](https://github.com/windmill-labs/windmill/compare/v1.350.1...v1.350.2) (2024-06-21)
### Bug Fixes
* **cli:** support windows more thoroughly + fix generate flow locks ([#3944](https://github.com/windmill-labs/windmill/issues/3944)) ([3f0cd63](https://github.com/windmill-labs/windmill/commit/3f0cd6349de37358f3942772254e2509383305b4))
## [1.350.1](https://github.com/windmill-labs/windmill/compare/v1.350.0...v1.350.1) (2024-06-20)
### Bug Fixes
* **cli:** fix inital sync pull generating wrong flow lockfile ([a43923b](https://github.com/windmill-labs/windmill/commit/a43923b3266b7b5781b0a5dc672c401377ae6e20))
## [1.350.0](https://github.com/windmill-labs/windmill/compare/v1.349.1...v1.350.0) (2024-06-20)
### Features
* **frontend:** add indicator when required field are missing ([#3935](https://github.com/windmill-labs/windmill/issues/3935)) ([7007f14](https://github.com/windmill-labs/windmill/commit/7007f14a1073f8f43b2500fae9c75d4222928802))
## [1.349.1](https://github.com/windmill-labs/windmill/compare/v1.349.0...v1.349.1) (2024-06-19)
### Bug Fixes
* show workers without worker groups ([5c5b98e](https://github.com/windmill-labs/windmill/commit/5c5b98e0b8f0926d5f81c1894de8d367201da2d8))
## [1.349.0](https://github.com/windmill-labs/windmill/compare/v1.348.2...v1.349.0) (2024-06-19)
### Features
* **frontend:** improve range ([#3924](https://github.com/windmill-labs/windmill/issues/3924)) ([a1dc0fd](https://github.com/windmill-labs/windmill/commit/a1dc0fd7c22244d97429dbb65ded23e27badec6a))
## [1.348.2](https://github.com/windmill-labs/windmill/compare/v1.348.1...v1.348.2) (2024-06-19)
### Bug Fixes
* add jobid to background runnables and fix zindex issue of inline script editor ([a2b88c0](https://github.com/windmill-labs/windmill/commit/a2b88c0080b8cfa747bf221bde9d22781e8034a9))
* **frontend:** fix full screen mode of the EvalInputEditor ([#3928](https://github.com/windmill-labs/windmill/issues/3928)) ([c9c017e](https://github.com/windmill-labs/windmill/commit/c9c017e27a71bfe618974fb0906283a6c1a82aa4))
* handle past inputs with oneOf ([#3932](https://github.com/windmill-labs/windmill/issues/3932)) ([f5e8d71](https://github.com/windmill-labs/windmill/commit/f5e8d71f0b9e527d3658547f3cb193b6dbe4bcb0))
## [1.348.1](https://github.com/windmill-labs/windmill/compare/v1.348.0...v1.348.1) (2024-06-19)
### Bug Fixes
* handle better single step parallel flows ([6d4b8a2](https://github.com/windmill-labs/windmill/commit/6d4b8a2e4f1ef5b067c2e04600ac5defa489141c))
## [1.348.0](https://github.com/windmill-labs/windmill/compare/v1.347.1...v1.348.0) (2024-06-18)
### Features
* add support for bytea in pg ([#3926](https://github.com/windmill-labs/windmill/issues/3926)) ([b753e4d](https://github.com/windmill-labs/windmill/commit/b753e4d06c431035084ba325be7573354cd3b621))
* **frontend:** Enable changing kind for string properties ([#3925](https://github.com/windmill-labs/windmill/issues/3925)) ([cfab185](https://github.com/windmill-labs/windmill/commit/cfab1853abb3557a0efc14e4d5ca05872ba27f76))
* **frontend:** worker page improvements ([#3921](https://github.com/windmill-labs/windmill/issues/3921)) ([b904a36](https://github.com/windmill-labs/windmill/commit/b904a36356849f854aaf6e91b9767653d7c6802b))
### Bug Fixes
* **frontend:** fix InlineScriptEditor zIndex ([#3922](https://github.com/windmill-labs/windmill/issues/3922)) ([b56f77b](https://github.com/windmill-labs/windmill/commit/b56f77b1da10085b9f4436a2aac5ba13cf14bdaf))
## [1.347.1](https://github.com/windmill-labs/windmill/compare/v1.347.0...v1.347.1) (2024-06-18)
### Bug Fixes
* add more debug logs around http client errors ([a64b099](https://github.com/windmill-labs/windmill/commit/a64b0990846c41988b4d1717123672e2a59289bd))
* add more debug logs around http client errors ([631b981](https://github.com/windmill-labs/windmill/commit/631b981b8e75165d4dc2ef706b415af4a1384a48))
## [1.347.0](https://github.com/windmill-labs/windmill/compare/v1.346.2...v1.347.0) (2024-06-17)
### Features
* **frontend:** UI customisation improvements + add support for object enums ([#3910](https://github.com/windmill-labs/windmill/issues/3910)) ([25024a9](https://github.com/windmill-labs/windmill/commit/25024a920db2956055a4eec6691f761c3048f6ee))
* oneOf inputs ([#3893](https://github.com/windmill-labs/windmill/issues/3893)) ([2df9c69](https://github.com/windmill-labs/windmill/commit/2df9c6902369c0f9e9dde98ddcf9d06d38646a3e))
### Bug Fixes
* fix permission for scoped tokens on jobs_u paths ([05d2197](https://github.com/windmill-labs/windmill/commit/05d219761892508db8ef9a46ffaf23bac26207f3))
## [1.346.2](https://github.com/windmill-labs/windmill/compare/v1.346.1...v1.346.2) (2024-06-17)
### Bug Fixes
* **frontend:** revert range ([#3916](https://github.com/windmill-labs/windmill/issues/3916)) ([c94c76f](https://github.com/windmill-labs/windmill/commit/c94c76f59bfbd852cfc486edf4a51ee6ab8d4501))
## [1.346.1](https://github.com/windmill-labs/windmill/compare/v1.346.0...v1.346.1) (2024-06-17)
### Bug Fixes
* job perms and job logs grants ([#3914](https://github.com/windmill-labs/windmill/issues/3914)) ([96dfacb](https://github.com/windmill-labs/windmill/commit/96dfacbfc8a2e418a39a7dc2ebc1082f00ef510f))
## [1.346.0](https://github.com/windmill-labs/windmill/compare/v1.345.2...v1.346.0) (2024-06-17)
### Features
* accelerate bun through caches ([#3909](https://github.com/windmill-labs/windmill/issues/3909)) ([28afe59](https://github.com/windmill-labs/windmill/commit/28afe59a4ab4e97a18e4ca7a893d83c329ee4078))
* **frontend:** event handlers ([#3902](https://github.com/windmill-labs/windmill/issues/3902)) ([4f0e111](https://github.com/windmill-labs/windmill/commit/4f0e111563f5f5ab7b280aa98a89f48cb3637e59))
* replace ephemeral tokens by jwt ([#3908](https://github.com/windmill-labs/windmill/issues/3908)) ([21b9acc](https://github.com/windmill-labs/windmill/commit/21b9accca1a8ab5c728fce15b3a7890375f11274))
### Bug Fixes
* fix workflow as code ([d518e23](https://github.com/windmill-labs/windmill/commit/d518e2359d522df3c8cf23baaf444eabfb11246f))
* job perms for agent mode ([#3911](https://github.com/windmill-labs/windmill/issues/3911)) ([e0ac22b](https://github.com/windmill-labs/windmill/commit/e0ac22ba4a59da4ca6c548de1ce0b5f394a49c66))
## [1.345.2](https://github.com/windmill-labs/windmill/compare/v1.345.1...v1.345.2) (2024-06-13)
### Bug Fixes
* add database grants to oustanding_wait_time table ([96767ec](https://github.com/windmill-labs/windmill/commit/96767ec042b12af6c1dfb5fa1263847934975cb9))
## [1.345.1](https://github.com/windmill-labs/windmill/compare/v1.345.0...v1.345.1) (2024-06-13)
### Bug Fixes
* correct exception handling in PHP wrapper ([#3901](https://github.com/windmill-labs/windmill/issues/3901)) ([320ba75](https://github.com/windmill-labs/windmill/commit/320ba754a4dcfb096807cfedbab8264be11dfb32))
* enums derivable from code ([6c2420f](https://github.com/windmill-labs/windmill/commit/6c2420f118d5665eca9ccc7a4f0b2ccd018738aa))
## [1.345.0](https://github.com/windmill-labs/windmill/compare/v1.344.3...v1.345.0) (2024-06-12)
### Features
* **frontend:** Generated UI editor + Schema Form complete refactor ([#3835](https://github.com/windmill-labs/windmill/issues/3835)) ([2344077](https://github.com/windmill-labs/windmill/commit/2344077b340ba22e40eb5ddb85c70f21c0c9e801))
## [1.344.3](https://github.com/windmill-labs/windmill/compare/v1.344.2...v1.344.3) (2024-06-11)
### Bug Fixes
* fix dependency tracking for single scripts ([c966979](https://github.com/windmill-labs/windmill/commit/c96697928fa0ef3cd4507f377a73f3b51560fbf7))
## [1.344.2](https://github.com/windmill-labs/windmill/compare/v1.344.1...v1.344.2) (2024-06-11)
### Bug Fixes
* fix dependency tracking for single scripts ([28d7510](https://github.com/windmill-labs/windmill/commit/28d7510584a47f98f87b7d0e87a663121b2bb5ef))
## [1.344.1](https://github.com/windmill-labs/windmill/compare/v1.344.0...v1.344.1) (2024-06-11)
### Bug Fixes
* cancel jobs button missing chevron ([#3896](https://github.com/windmill-labs/windmill/issues/3896)) ([b9092e5](https://github.com/windmill-labs/windmill/commit/b9092e591ec08fed65e2f1e1e0449461fcc9ec41))
* fix dependency tracking for single scripts ([5f119de](https://github.com/windmill-labs/windmill/commit/5f119de6cb915f234c868da1aa02050481cbc4b0))
* upgrade deno to 1.44.1 ([f8f6d8b](https://github.com/windmill-labs/windmill/commit/f8f6d8beaae2cdd754808074886d793add6144b6))
## [1.344.0](https://github.com/windmill-labs/windmill/compare/v1.343.3...v1.344.0) (2024-06-11)
### Features
* cancel jobs based on filters ([#3874](https://github.com/windmill-labs/windmill/issues/3874)) ([7474145](https://github.com/windmill-labs/windmill/commit/7474145f0edf2cb17b9ee90e35f605b367eae60d))
### Bug Fixes
* **backend:** wrong previous result used in flow for-loop ([dcff6e9](https://github.com/windmill-labs/windmill/commit/dcff6e9ff3eb2f9d75d39a8ec20d0a9d1edf14a1))
* **frontend:** Fix Timeline/Node Status tab zIndex ([#3894](https://github.com/windmill-labs/windmill/issues/3894)) ([609f332](https://github.com/windmill-labs/windmill/commit/609f332116f4fc3ab934d2d51fc34754fa30b6db))
## [1.343.3](https://github.com/windmill-labs/windmill/compare/v1.343.2...v1.343.3) (2024-06-11)
### Bug Fixes
* flow args should always render in test flow ([1be0bfa](https://github.com/windmill-labs/windmill/commit/1be0bfaf7b676cd9381ceee12dd2923620c8e90e))
* improve init script handling of windows newlines ([eb068fd](https://github.com/windmill-labs/windmill/commit/eb068fd086b9023c073c9e4adbff3b79da74c374))
## [1.343.2](https://github.com/windmill-labs/windmill/compare/v1.343.1...v1.343.2) (2024-06-10)
### Bug Fixes
* fix nativets scripts ([36d0c4e](https://github.com/windmill-labs/windmill/commit/36d0c4e992551c80c13312c255b0b6c816a0cb32))
## [1.343.1](https://github.com/windmill-labs/windmill/compare/v1.343.0...v1.343.1) (2024-06-10)
### Bug Fixes
* fix reorder of args in schema form ([61bb069](https://github.com/windmill-labs/windmill/commit/61bb069da3d24a547403234c29dd243eb147a529))
* update deno_core to latest to work better with rust 1.78 ([#3890](https://github.com/windmill-labs/windmill/issues/3890)) ([ec248dd](https://github.com/windmill-labs/windmill/commit/ec248ddaecb5adba5584d39c90cf76bcf5a8e9f2))
## [1.343.0](https://github.com/windmill-labs/windmill/compare/v1.342.0...v1.343.0) (2024-06-10)
### Features
* **cli:** add wmill flow generate-locks ([1957ca0](https://github.com/windmill-labs/windmill/commit/1957ca03b337788575dadd67d9cf83208c886933))
* support selecting by columns in table ([b1f9272](https://github.com/windmill-labs/windmill/commit/b1f9272d9f1e6ff5e73686621d24e43e46988233))
* towards cloud events webhook compliance ([#3883](https://github.com/windmill-labs/windmill/issues/3883)) ([d2d87f4](https://github.com/windmill-labs/windmill/commit/d2d87f4c9751767198be34b6adcb26385f29f05d))
* track dependency map for bun + inline script of flows ([5ae8592](https://github.com/windmill-labs/windmill/commit/5ae859279285bd63f28d2313bfd0b346131f832c))
### Bug Fixes
* `deprecated` Node.js usage in `checkout@v3` ([#3872](https://github.com/windmill-labs/windmill/issues/3872)) ([11fba4f](https://github.com/windmill-labs/windmill/commit/11fba4fbca9504a38cfcca488e336b070a40f3b5))
* **frontend:** Add missing InitializeComponent for components Flow Status by id and Log by Job id ([#3882](https://github.com/windmill-labs/windmill/issues/3882)) ([6c4e7d0](https://github.com/windmill-labs/windmill/commit/6c4e7d0e93cb50bd29c0d6d57368b7fe84bb0879))
* **frontend:** encrypt openai key on workspace creation ([#3879](https://github.com/windmill-labs/windmill/issues/3879)) ([387ea44](https://github.com/windmill-labs/windmill/commit/387ea4469f9903914f0c32802fac06d151154f9a))
* **frontend:** Fix AgChart when the component is hidden ([#3876](https://github.com/windmill-labs/windmill/issues/3876)) ([be092d2](https://github.com/windmill-labs/windmill/commit/be092d2527a685b83f4398133e67cf19eb91d9b4))
* **frontend:** job detail horizontal padding small screens ([#3881](https://github.com/windmill-labs/windmill/issues/3881)) ([66e6fe3](https://github.com/windmill-labs/windmill/commit/66e6fe374c33ee8a027c5ea37a13e83bf7ca8b30))
* **frontend:** Remove useless RunnableWrapper on Log and Flow status … ([#3877](https://github.com/windmill-labs/windmill/issues/3877)) ([ef2329b](https://github.com/windmill-labs/windmill/commit/ef2329bb87bc6439ddeb63deab5f1fa4c7a75066))
* paginate listTokens page ([0975fb6](https://github.com/windmill-labs/windmill/commit/0975fb6950020b7afbf561565a2635d2173ae2f6))
* remove main decorator after split from end of file during py imports parsing ([#3887](https://github.com/windmill-labs/windmill/issues/3887)) ([f29f71b](https://github.com/windmill-labs/windmill/commit/f29f71bfdecf1d804819023a630c3588ebd9af0a))
* retrigger bun dependencies jobs for importers when using common deps ([da1ea04](https://github.com/windmill-labs/windmill/commit/da1ea04c794e0eae7bde03898dd5c68bff9de9bd))
* use full hostname as worker ping hostname and add it in other contexts ([ebf37eb](https://github.com/windmill-labs/windmill/commit/ebf37eb16b0eecca37bece95c6fa347c9f976622))
## [1.342.0](https://github.com/windmill-labs/windmill/compare/v1.341.1...v1.342.0) (2024-06-04)
### Features
* customer portal link ([#3868](https://github.com/windmill-labs/windmill/issues/3868)) ([14bd5fe](https://github.com/windmill-labs/windmill/commit/14bd5fe0515bb2e746656cf3d6ee5bbd5c727510))
### Bug Fixes
* handle csv with different separators in csv preview ([b756a3b](https://github.com/windmill-labs/windmill/commit/b756a3b31ef62cbfacd20bcffb0da8482dd57565))
## [1.341.1](https://github.com/windmill-labs/windmill/compare/v1.341.0...v1.341.1) (2024-06-04)
### Bug Fixes
* Filter on path not working ([#3863](https://github.com/windmill-labs/windmill/issues/3863)) ([98869ef](https://github.com/windmill-labs/windmill/commit/98869efdabfd5e275c76fd811b8337c00c9574a5))
* fix writing binary file from global cache in go ([ef9ad1a](https://github.com/windmill-labs/windmill/commit/ef9ad1af49d9d22a790cba4edb21dbbfa6df0b31))
* flow status viewer takes all the width on the runs page ([b6016ab](https://github.com/windmill-labs/windmill/commit/b6016abb222481a16dfb684a782c763cf3966856))
* improve flow status viewer to display the step details on third tab ([f54cfd3](https://github.com/windmill-labs/windmill/commit/f54cfd3640a2be0bb25eacea979d9ea056e190ad))
* lock steps inside whileloops for flows ([439ab8a](https://github.com/windmill-labs/windmill/commit/439ab8ab14547991bb4e60e0b377d61e81d4b1b9))
* make typescript client compatible with cf workers ([#3807](https://github.com/windmill-labs/windmill/issues/3807)) ([a9bf5a4](https://github.com/windmill-labs/windmill/commit/a9bf5a46831cf3b3e262167af99af1ebb9336f36))
## [1.341.0](https://github.com/windmill-labs/windmill/compare/v1.340.2...v1.341.0) (2024-06-03)
### Features
* **frontend:** Fix how runnable tied to a table actions are triggered + Display the sync columnDef error only in the editor ([#3862](https://github.com/windmill-labs/windmill/issues/3862)) ([76b6577](https://github.com/windmill-labs/windmill/commit/76b65771a03e35b6d489731f210e24640efda54b))
* warn when jobs spent a long time waiting in queue ([#3856](https://github.com/windmill-labs/windmill/issues/3856)) ([203264b](https://github.com/windmill-labs/windmill/commit/203264b87174b9774819bcf008bc4c41b866ccd9))
### Bug Fixes
* fix python client for S3Object ([44c36cd](https://github.com/windmill-labs/windmill/commit/44c36cdeb53eeb577dc7af6c2d64b75824492e1d))
* further restrict job api to logged in workspace users or anonymous jobs only" ([#3860](https://github.com/windmill-labs/windmill/issues/3860)) ([181cb7d](https://github.com/windmill-labs/windmill/commit/181cb7dec99d92b6e7450e4a0f5af75994c82ec3))
## [1.340.2](https://github.com/windmill-labs/windmill/compare/v1.340.1...v1.340.2) (2024-05-31)
### Bug Fixes
* add audit log exception to schedules ([2359cdc](https://github.com/windmill-labs/windmill/commit/2359cdc128ebfdd3fc2eff97877ae9957def9270))
* fix csv preview for storage renderer ([326446e](https://github.com/windmill-labs/windmill/commit/326446e5cefb8e99142d13ea030d51c5d317eaf9))
## [1.340.1](https://github.com/windmill-labs/windmill/compare/v1.340.0...v1.340.1) (2024-05-31)
### Bug Fixes
* typescript file upload supports arbitrary storage ([9e822d4](https://github.com/windmill-labs/windmill/commit/9e822d4c75152e7a651f31c74ee0d2c9783cd993))
## [1.340.0](https://github.com/windmill-labs/windmill/compare/v1.339.2...v1.340.0) (2024-05-31)
### Features
* chart interactivity: click points on the graph to select the corresponding jobs ([#3851](https://github.com/windmill-labs/windmill/issues/3851)) ([5156e29](https://github.com/windmill-labs/windmill/commit/5156e291fa818388bcf5734cb05a3095f6bf1b11))
* replace polars with datafusion for data preview ([e07c262](https://github.com/windmill-labs/windmill/commit/e07c2621e91a44fa6de7244469aa80e20b562b01))
* support multiple object storage + parquet_csv + polars -&gt; datafusion" ([#3853](https://github.com/windmill-labs/windmill/issues/3853)) ([a22dc98](https://github.com/windmill-labs/windmill/commit/a22dc985fa6f1b49e56fa0f3d4f5152a50e16a04))
### Bug Fixes
* simple subflow approval step triggering timeouts ([be160f6](https://github.com/windmill-labs/windmill/commit/be160f6e46d766bbdc0dd2f60b5fb5e6222809d7))
* wait for api to be read to load explorer table ([96246cd](https://github.com/windmill-labs/windmill/commit/96246cd697bfa82d0890f37a3708c7a376a5de28))
## [1.339.2](https://github.com/windmill-labs/windmill/compare/v1.339.1...v1.339.2) (2024-05-29)
### Bug Fixes
* worker memory usage ([#3845](https://github.com/windmill-labs/windmill/issues/3845)) ([e052dd5](https://github.com/windmill-labs/windmill/commit/e052dd5f6e7d8f1f7799204dab2f98e023efaec1))
## [1.339.1](https://github.com/windmill-labs/windmill/compare/v1.339.0...v1.339.1) (2024-05-29)
### Bug Fixes
* allow_user_resoruces default deserialization ([7238274](https://github.com/windmill-labs/windmill/commit/7238274d1c7b80e831aa91eac3a6577d9ab462d4))
## [1.339.0](https://github.com/windmill-labs/windmill/compare/v1.338.3...v1.339.0) (2024-05-29)
### Features
* display last key renewal attempt ([#3839](https://github.com/windmill-labs/windmill/issues/3839)) ([dc2d7e1](https://github.com/windmill-labs/windmill/commit/dc2d7e1c8f5f7c50be04cfea6986ce03a3e33c7b))
## [1.338.3](https://github.com/windmill-labs/windmill/compare/v1.338.2...v1.338.3) (2024-05-29)
### Bug Fixes
* fix resource type search ([b01e335](https://github.com/windmill-labs/windmill/commit/b01e33523da72050bc08b47bd84e0d8fc88f6dda))
## [1.338.2](https://github.com/windmill-labs/windmill/compare/v1.338.1...v1.338.2) (2024-05-28)
### Bug Fixes
* worker metrics ([#3837](https://github.com/windmill-labs/windmill/issues/3837)) ([5d2b244](https://github.com/windmill-labs/windmill/commit/5d2b244869fb9a6a7d006cfc95b22d9e83d3b9bb))
## [1.338.1](https://github.com/windmill-labs/windmill/compare/v1.338.0...v1.338.1) (2024-05-28)
### Bug Fixes
* fix retry not working on single step flow due to opt ([6166c4d](https://github.com/windmill-labs/windmill/commit/6166c4d7aae9eddcee92f950959b9d2290bc917a))
* remove quotes around interpolated arg values of tags ([8b66636](https://github.com/windmill-labs/windmill/commit/8b66636a8908c0043d2be63c6462ce28acc43fd9))
## [1.338.0](https://github.com/windmill-labs/windmill/compare/v1.337.0...v1.338.0) (2024-05-27)
### Features
* allow user resources in apps with a toggle ([#3821](https://github.com/windmill-labs/windmill/issues/3821)) ([5877727](https://github.com/windmill-labs/windmill/commit/5877727c167bf9b62bedaa7eeafad3c913b1089d))
* **frontend:** add open/close state of the modal in the outputs ([#3822](https://github.com/windmill-labs/windmill/issues/3822)) ([c246bb0](https://github.com/windmill-labs/windmill/commit/c246bb07052e65e9b336529ad638bcb9cc9686cd))
* **frontend:** upgrade to gpt-4o + add AI support for php ([#3820](https://github.com/windmill-labs/windmill/issues/3820)) ([2561853](https://github.com/windmill-labs/windmill/commit/256185308e2c0f1b5395a76bc7de5d3857f867d4))
* public apps can require login ([#3825](https://github.com/windmill-labs/windmill/issues/3825)) ([e2a1219](https://github.com/windmill-labs/windmill/commit/e2a1219373cace1bf4130004c27b9bf3595f7dd9))
* worker vcpus/memory limits + mem usage ([#3828](https://github.com/windmill-labs/windmill/issues/3828)) ([621464b](https://github.com/windmill-labs/windmill/commit/621464b55025d601f747f611cbb3485d363a480a))
### Bug Fixes
* filtering not always working with concurrency keys ([#3823](https://github.com/windmill-labs/windmill/issues/3823)) ([47df9f3](https://github.com/windmill-labs/windmill/commit/47df9f33cce5a20231b6b38d4eb1ff370699fc38))
* improve concurrency re-scheduling at scale ([f2d9c3c](https://github.com/windmill-labs/windmill/commit/f2d9c3c77729fe32366a1c0628d5c0af4d603dff))
* improve concurrency re-scheduling at scale ([e187fa6](https://github.com/windmill-labs/windmill/commit/e187fa6263100cb26a24726123bcc3bbe641a6e8))
* make all error strings more verbose ([7a36f30](https://github.com/windmill-labs/windmill/commit/7a36f30fe3138089df5c3a4ce87744c4a459044d))
## [1.337.0](https://github.com/windmill-labs/windmill/compare/v1.336.1...v1.337.0) (2024-05-25)
### Features
* add GetResumeUrls to go client ([#3810](https://github.com/windmill-labs/windmill/issues/3810)) ([59f980f](https://github.com/windmill-labs/windmill/commit/59f980f75a9a507f22349f822579a5542f69b988))
* automatic key renewal ([#3815](https://github.com/windmill-labs/windmill/issues/3815)) ([831cf89](https://github.com/windmill-labs/windmill/commit/831cf89b6367009d0d861975cb8f78b616b0868e))
### Bug Fixes
* rename email_from_username to username_to_email ([#3813](https://github.com/windmill-labs/windmill/issues/3813)) ([7584c2b](https://github.com/windmill-labs/windmill/commit/7584c2b0bbc216896daa6a366028cfc3ab5af00c))
* use hub script language as tag instead of 'hub' ([#3816](https://github.com/windmill-labs/windmill/issues/3816)) ([47bb5d2](https://github.com/windmill-labs/windmill/commit/47bb5d2492856c5cecd77d386c802958f0aa7211))
## [1.336.1](https://github.com/windmill-labs/windmill/compare/v1.336.0...v1.336.1) (2024-05-24)
### Bug Fixes
* revert bun to 1.1.8 ([ba9cdb1](https://github.com/windmill-labs/windmill/commit/ba9cdb1ae2aca13fd06876b48e0acdb65f2a1b00))
## [1.336.0](https://github.com/windmill-labs/windmill/compare/v1.335.0...v1.336.0) (2024-05-23)
### Features
* **frontend:** improve graph edges + fix depedencies detection ([#3802](https://github.com/windmill-labs/windmill/issues/3802)) ([d11e350](https://github.com/windmill-labs/windmill/commit/d11e350de395811daad8a49c0eef7b3b19460ead))
* improve parsers when no main func ([#3805](https://github.com/windmill-labs/windmill/issues/3805)) ([001278c](https://github.com/windmill-labs/windmill/commit/001278cddd6e91f767f090e358db4299611f0451))
* improve permissioned audit logs ([#3799](https://github.com/windmill-labs/windmill/issues/3799)) ([62f3180](https://github.com/windmill-labs/windmill/commit/62f318077cd77d8332bbe02ac279a5bca7351e51))
* improve premissioned audit logs ([#3793](https://github.com/windmill-labs/windmill/issues/3793)) ([21a077e](https://github.com/windmill-labs/windmill/commit/21a077ecfaa2dfabe6a46e425214182845b5259e))
* store failed_retries per module state and display failed retries in flow status viewer ([62e8816](https://github.com/windmill-labs/windmill/commit/62e88169ea47e6357931bafd564ab45df40a62ff))
* store failed_retries per module state and display failed retries in flow status viewer ([7e0be89](https://github.com/windmill-labs/windmill/commit/7e0be8914bcb33caf680358f083e80edfb83d00f))
### Bug Fixes
* **frontend:** Add missing loading state for non-runnable components … ([#3797](https://github.com/windmill-labs/windmill/issues/3797)) ([a0acdc1](https://github.com/windmill-labs/windmill/commit/a0acdc1217967562bb349a2b718c82af74b8bc45))
* show code option in tree view ([#3803](https://github.com/windmill-labs/windmill/issues/3803)) ([1745a9d](https://github.com/windmill-labs/windmill/commit/1745a9dd1617de4686480e0cfc9ba2ef2da0c625))
* update bun to 1.1.9 ([bfd2d27](https://github.com/windmill-labs/windmill/commit/bfd2d27415a906f9133777b69653ddacf659de41))
## [1.335.0](https://github.com/windmill-labs/windmill/compare/v1.334.0...v1.335.0) (2024-05-22)

View File

@@ -1,5 +1,5 @@
ARG DEBIAN_IMAGE=debian:bookworm-slim
ARG RUST_IMAGE=rust:1.76-slim-bookworm
ARG RUST_IMAGE=rust:1.78-slim-bookworm
ARG PYTHON_IMAGE=python:3.11.8-slim-bookworm
FROM ${RUST_IMAGE} AS rust_base
@@ -84,8 +84,8 @@ SHELL ["/bin/bash", "-c"]
RUN apt update -y
RUN apt install -y unzip curl
RUN [ "$TARGETPLATFORM" == "linux/amd64" ] && curl -Lsf https://github.com/denoland/deno/releases/download/v1.42.0/deno-x86_64-unknown-linux-gnu.zip -o deno.zip || true
RUN [ "$TARGETPLATFORM" == "linux/arm64" ] && curl -Lsf https://github.com/denoland/deno/releases/download/v1.42.0/deno-aarch64-unknown-linux-gnu.zip -o deno.zip || true
RUN [ "$TARGETPLATFORM" == "linux/amd64" ] && curl -Lsf https://github.com/denoland/deno/releases/download/v1.44.1/deno-x86_64-unknown-linux-gnu.zip -o deno.zip || true
RUN [ "$TARGETPLATFORM" == "linux/arm64" ] && curl -Lsf https://github.com/denoland/deno/releases/download/v1.44.1/deno-aarch64-unknown-linux-gnu.zip -o deno.zip || true
RUN unzip deno.zip && rm deno.zip
@@ -171,7 +171,7 @@ COPY --from=builder /windmill/target/release/windmill ${APP}/windmill
COPY --from=downloader --chmod=755 /deno /usr/bin/deno
COPY --from=oven/bun:1.1.7 /usr/local/bin/bun /usr/bin/bun
COPY --from=oven/bun:1.1.8 /usr/local/bin/bun /usr/bin/bun
COPY --from=php:8.3.7-cli /usr/local/bin/php /usr/bin/php
COPY --from=composer:2.7.6 /usr/bin/composer /usr/bin/composer

View File

@@ -1,48 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT running, substr(concat(coalesce(queue.logs, ''), job_logs.logs), greatest($1 - job_logs.log_offset, 0)) as logs, mem_peak, \n CASE WHEN is_flow_step is true then NULL else flow_status END as flow_status,\n job_logs.log_offset + char_length(job_logs.logs) + 1 as log_offset\n FROM queue\n LEFT JOIN job_logs ON job_logs.job_id = queue.id \n WHERE queue.workspace_id = $2 AND queue.id = $3",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "running",
"type_info": "Bool"
},
{
"ordinal": 1,
"name": "logs",
"type_info": "Text"
},
{
"ordinal": 2,
"name": "mem_peak",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "flow_status",
"type_info": "Jsonb"
},
{
"ordinal": 4,
"name": "log_offset",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Int4",
"Text",
"Uuid"
]
},
"nullable": [
false,
null,
true,
null,
null
]
},
"hash": "04be51a152d7c9644f11173da2cc386a71e178685364e7da4b910d1648ea55ba"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE queue SET last_ping = now() WHERE id = $1 AND workspace_id = $2",
"query": "UPDATE queue SET last_ping = now() WHERE id = $1 AND workspace_id = $2 AND canceled = false",
"describe": {
"columns": [],
"parameters": {
@@ -11,5 +11,5 @@
},
"nullable": []
},
"hash": "45c9ecf8b1f8cbca7c75dab24a1eb6da8ceb45258ee5817ec71e73bebbe415bd"
"hash": "099e7c7a66968575f896e0c11ecd9cfe9a2ec315d6589e940be157a0563f81af"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE queue\n SET running = false\n , started_at = null\n , scheduled_for = $1\n , last_ping = null\n WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Timestamptz",
"Uuid"
]
},
"nullable": []
},
"hash": "126be8832776644e0d2c5d004acb26f6d4820a6a1fc8e028c3550c438248a82b"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE queue SET running = false, started_at = null WHERE id = $1",
"query": "UPDATE queue SET running = false, started_at = null WHERE id = $1 AND canceled = false",
"describe": {
"columns": [],
"parameters": {
@@ -10,5 +10,5 @@
},
"nullable": []
},
"hash": "c05be905e46c5b0a2186ba859a725495e55df7f2ad839aea22d0286525eb823e"
"hash": "215e0d320a304c8cb9ef12e7ea98a4eafb2456c123f9b6b96bb4ba2409166e5a"
}

View File

@@ -0,0 +1,24 @@
{
"db_name": "PostgreSQL",
"query": "SELECT COUNT(*) FROM queue LEFT JOIN concurrency_key ON concurrency_key.job_id = queue.id\n WHERE key = $1 AND running = false AND canceled = false AND scheduled_for >= $2 AND scheduled_for < $3",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "count",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Text",
"Timestamptz",
"Timestamptz"
]
},
"nullable": [
null
]
},
"hash": "293054a4d6a2b00228a5029a81c026e8891576c7e87cdab41d7fcc3afc32d583"
}

View File

@@ -1,15 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM dependency_map\n WHERE importer_path = $1 AND importer_kind = 'script'\n AND workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "30e9250edd0c4c6025322f51b758174435d6df4f835cb0883ba40897cb99a410"
}

View File

@@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT value, created_at FROM metrics WHERE id = $1 ORDER BY created_at DESC LIMIT 1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "value",
"type_info": "Jsonb"
},
{
"ordinal": 1,
"name": "created_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false
]
},
"hash": "360d13c0a776e794063c99acad935a424f79017f3769e1150faa87cbb91367a8"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes FROM token WHERE email = $1\n ORDER BY created_at DESC",
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes FROM token WHERE email = $1\n ORDER BY created_at DESC LIMIT $2 OFFSET $3",
"describe": {
"columns": [
{
@@ -36,7 +36,9 @@
],
"parameters": {
"Left": [
"Text"
"Text",
"Int8",
"Int8"
]
},
"nullable": [
@@ -48,5 +50,5 @@
true
]
},
"hash": "9ce6eecfa10c2f71cc536957ead498ad829ea8023ce449eab27225ec66738525"
"hash": "3b746f73abbaea3570b9c79af21d4d0f60232098d69b71c21fd3da985f7a5905"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM usr WHERE email = $1 AND workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "3da14e6c89a33871e4bd40524e2fd9222aa707ee76de6ce348337c3e403eb955"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes FROM token WHERE email = $1 AND label != 'ephemeral-script'\n ORDER BY created_at DESC",
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes FROM token WHERE email = $1 AND label != 'ephemeral-script'\n ORDER BY created_at DESC LIMIT $2 OFFSET $3",
"describe": {
"columns": [
{
@@ -36,7 +36,9 @@
],
"parameters": {
"Left": [
"Text"
"Text",
"Int8",
"Int8"
]
},
"nullable": [
@@ -48,5 +50,5 @@
true
]
},
"hash": "bc1f2f169b4960dae02f62e37bb4ae081146e598109860ee1f42cd3778c5ebaf"
"hash": "4115a8e75ad5ed74f737f24aa64edc68e71b29ddc32a00a754678ea4f2c167e5"
}

View File

@@ -1,21 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO token\n (workspace_id, token, owner, label, expiration, super_admin, email, job)\n VALUES ($1, $2, $3, $4, now() + ($5 || ' seconds')::interval, $6, $7, $8)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Varchar",
"Varchar",
"Text",
"Bool",
"Varchar",
"Uuid"
]
},
"nullable": []
},
"hash": "42cb4bc3abc8cba2193a7fbbae8275c1bc830081a43e3a4a897c41b6b3099b1d"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE worker_ping SET ping_at = now(), jobs_executed = $1, custom_tags = $2, occupancy_rate = $3, current_job_id = NULL, current_job_workspace_id = NULL WHERE worker = $4",
"query": "UPDATE worker_ping SET ping_at = now(), jobs_executed = $1, custom_tags = $2, occupancy_rate = $3, memory_usage = $4, wm_memory_usage = $5, current_job_id = NULL, current_job_workspace_id = NULL WHERE worker = $6",
"describe": {
"columns": [],
"parameters": {
@@ -8,10 +8,12 @@
"Int4",
"TextArray",
"Float4",
"Int8",
"Int8",
"Text"
]
},
"nullable": []
},
"hash": "54fef88cc6b9e8db7c07fccbaa845edfefa339153a32e468faad9f063008863d"
"hash": "4398bc6f701dcba647a259ec2d091a70938a3ecd7ff8a89277cc35d119e2bad4"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "SELECT id, running, is_flow_step FROM queue WHERE scheduled_for < now() AND workspace_id = $1 AND schedule_path IS NULL",
"query": "SELECT id, is_flow_step, running FROM queue WHERE id = ANY($1) AND schedule_path IS NULL",
"describe": {
"columns": [
{
@@ -10,25 +10,25 @@
},
{
"ordinal": 1,
"name": "running",
"name": "is_flow_step",
"type_info": "Bool"
},
{
"ordinal": 2,
"name": "is_flow_step",
"name": "running",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
"UuidArray"
]
},
"nullable": [
false,
false,
true
true,
false
]
},
"hash": "caeb49629b8673c1f1c84a6e40c3e2d2c3bc3fdbde530a0a6b6fd68a22b867c3"
"hash": "4c529e29a0eb084a92f4e952506d701592bc707fd8a8cb3311bf146be6078f26"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "SELECT worker, worker_instance, EXTRACT(EPOCH FROM (now() - ping_at))::integer as last_ping, started_at, ip, jobs_executed, CASE WHEN $4 IS TRUE THEN current_job_id ELSE NULL END as current_job_id, CASE WHEN $4 IS TRUE THEN current_job_workspace_id ELSE NULL END as current_job_workspace_id, custom_tags, worker_group, wm_version, occupancy_rate\n FROM worker_ping\n WHERE ($1::integer IS NULL AND ping_at > now() - interval '5 minute') OR (ping_at > now() - ($1 || ' seconds')::interval)\n ORDER BY ping_at desc LIMIT $2 OFFSET $3",
"query": "SELECT worker, worker_instance, EXTRACT(EPOCH FROM (now() - ping_at))::integer as last_ping, started_at, ip, jobs_executed, CASE WHEN $4 IS TRUE THEN current_job_id ELSE NULL END as current_job_id, CASE WHEN $4 IS TRUE THEN current_job_workspace_id ELSE NULL END as current_job_workspace_id, custom_tags, worker_group, wm_version, occupancy_rate, memory, vcpus, memory_usage, wm_memory_usage\n FROM worker_ping\n WHERE ($1::integer IS NULL AND ping_at > now() - interval '5 minute') OR (ping_at > now() - ($1 || ' seconds')::interval)\n ORDER BY ping_at desc LIMIT $2 OFFSET $3",
"describe": {
"columns": [
{
@@ -62,6 +62,26 @@
"ordinal": 11,
"name": "occupancy_rate",
"type_info": "Float4"
},
{
"ordinal": 12,
"name": "memory",
"type_info": "Int8"
},
{
"ordinal": 13,
"name": "vcpus",
"type_info": "Int8"
},
{
"ordinal": 14,
"name": "memory_usage",
"type_info": "Int8"
},
{
"ordinal": 15,
"name": "wm_memory_usage",
"type_info": "Int8"
}
],
"parameters": {
@@ -84,8 +104,12 @@
true,
false,
false,
true,
true,
true,
true,
true
]
},
"hash": "e00171cc3fc8f32922562d4fc4d3db56955fbc6ee9872d4b2e99157ebed131e0"
"hash": "55d6c6f887f1cceb311d9ab034d3485b8ccb2d07d723f184cef2696760d3ccf9"
}

View File

@@ -1,20 +1,25 @@
{
"db_name": "PostgreSQL",
"query": "SELECT CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM queue \n LEFT JOIN job_logs ON job_logs.job_id = queue.id \n WHERE queue.id = $1 AND queue.workspace_id = $2",
"query": "SELECT created_by, CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM queue \n LEFT JOIN job_logs ON job_logs.job_id = queue.id \n WHERE queue.id = $1 AND queue.workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "created_by",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "logs",
"type_info": "Text"
},
{
"ordinal": 1,
"ordinal": 2,
"name": "log_offset",
"type_info": "Int4"
},
{
"ordinal": 2,
"ordinal": 3,
"name": "log_file_index",
"type_info": "TextArray"
}
@@ -26,10 +31,11 @@
]
},
"nullable": [
false,
null,
false,
true
]
},
"hash": "bd213fca18a04d9e34405fd753c02398b72afb17b1ce650dbac947490634009d"
"hash": "57111a97ff906fd79ecd8a571212cc4fea9cb9c16fe950f082ad5469bfeefc82"
}

View File

@@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT large_file_storage->'secondary_storage'->$2 FROM workspace_settings WHERE workspace_id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "?column?",
"type_info": "Jsonb"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
null
]
},
"hash": "5bdf8d82eed7e14cb3feb2ca597aac374c160428329526715d840fc46fdb0501"
}

View File

@@ -1,23 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM usr WHERE email = $1 AND workspace_id = $2 RETURNING username",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "username",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "62cd69e3dc0f8757db3481d078921f4722bbc93d52e05656b82cb42ba9803ef6"
}

View File

@@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM job_perms WHERE job_id = $1",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": []
},
"hash": "64a3b92ce4366518423bc536efe33415b43b325d7380e0c7062c392c7ba51e59"
}

View File

@@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM dependency_map\n WHERE importer_path = $1 AND importer_kind = $3::text::IMPORTER_KIND\n AND workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "6c962f9471b0b1fe385a93789ec46bee53a07c8d1264eeb44bc94233bc06bbfd"
}

View File

@@ -0,0 +1,21 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO job_perms (job_id, email, username, is_admin, is_operator, folders, groups, workspace_id) \n values ($1, $2, $3, $4, $5, $6, $7, $8) \n ON CONFLICT (job_id) DO UPDATE SET email = $2, username = $3, is_admin = $4, is_operator = $5, folders = $6, groups = $7, workspace_id = $8",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Varchar",
"Bool",
"Bool",
"JsonbArray",
"TextArray",
"Varchar"
]
},
"nullable": []
},
"hash": "8efd06387ded837d7849adafe5bc93acb882ef90fc58b023650c875e0fd17047"
}

View File

@@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM dependency_map\n WHERE importer_path = $1 AND importer_kind = $3::text::IMPORTER_KIND\n AND workspace_id = $2 AND ($4::text IS NULL OR importer_node_id = $4::text)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "91da4514dfee9a2a5c7c633bc28f8445eef286bd69368bf302d3279494610780"
}

View File

@@ -1,16 +1,18 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE worker_ping SET ping_at = now(), current_job_id = $1, current_job_workspace_id = $2 WHERE worker = $3",
"query": "UPDATE worker_ping SET ping_at = now(), current_job_id = $1, current_job_workspace_id = $2, memory_usage = $3, wm_memory_usage = $4 WHERE worker = $5",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Int8",
"Int8",
"Text"
]
},
"nullable": []
},
"hash": "8c62e3bb264c7336b3b3a68677993ba3b729c7358cc3da14513d8b447ce65aaf"
"hash": "95cb1fe8658f98fb736d899fa21cd7378b0c9d3b5f3d6bd6cafcba273f8277d4"
}

View File

@@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS(SELECT 1 FROM app WHERE id = $1 AND workspace_id = $2)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Int8",
"Text"
]
},
"nullable": [
null
]
},
"hash": "98c11a7d870a997c74e533a75bb48f39b0ec43816f05ac1d1eb39ea1903138f9"
}

View File

@@ -0,0 +1,20 @@
{
"db_name": "PostgreSQL",
"query": "SELECT created_at FROM metrics WHERE id = 'license_key_renewal' ORDER BY created_at DESC LIMIT 1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "created_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": []
},
"nullable": [
false
]
},
"hash": "9ed77e78e6295c62745ac3ac3b7e5f544f654d7cddc13acb5d3f4fdc12a8875f"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO global_settings (name, value) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET value = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Jsonb"
]
},
"nullable": []
},
"hash": "a00e61e770e20157bbd9e4cdedf7fb5f9de7c8c9e50282e3ecf2e3ce917ec37a"
}

View File

@@ -1,22 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT CAST(ROUND(AVG(duration_ms) / 1000, 0) AS BIGINT) AS avg_duration_s FROM\n (SELECT duration_ms FROM completed_job WHERE script_path = $1\n ORDER BY started_at\n DESC LIMIT 10) AS t",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "avg_duration_s",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "a0ce703def7e976947513029874fb571893c75730e0a8feeb609852423404cf0"
}

View File

@@ -1,42 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT substr(concat(coalesce(completed_job.logs, ''), job_logs.logs), greatest($1 - job_logs.log_offset, 0)) as logs, mem_peak, \n CASE WHEN is_flow_step is true then NULL else flow_status END as flow_status,\n job_logs.log_offset + char_length(job_logs.logs) + 1 as log_offset\n FROM completed_job \n LEFT JOIN job_logs ON job_logs.job_id = completed_job.id \n WHERE completed_job.workspace_id = $2 AND id = $3",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "logs",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "mem_peak",
"type_info": "Int4"
},
{
"ordinal": 2,
"name": "flow_status",
"type_info": "Jsonb"
},
{
"ordinal": 3,
"name": "log_offset",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Int4",
"Text",
"Uuid"
]
},
"nullable": [
null,
true,
null,
null
]
},
"hash": "a73b57229602d68cc25a8d963753271619e74df9fd7fc6cb05fc0614b10e6001"
}

View File

@@ -1,23 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT importer_path FROM dependency_map\n WHERE imported_path = $1 AND importer_kind = 'script'\n AND workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "importer_path",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "aa44311f9bae8253c6c483d122597ce7e470c6ba1905e7e877dca35d9d68968f"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE queue SET canceled = true, canceled_by = $1, canceled_reason = $2, scheduled_for = now(), suspend = 0 WHERE id = $3 AND workspace_id = $4 RETURNING id",
"query": "UPDATE queue SET canceled = true, canceled_by = $1, canceled_reason = $2, scheduled_for = now(), suspend = 0 WHERE id = $3 AND workspace_id = $4 AND canceled = false RETURNING id",
"describe": {
"columns": [
{
@@ -21,5 +21,5 @@
false
]
},
"hash": "f1f7a27738deae46de6acc10cbff701ff0c3872cc5b387e304bd9a058bb0c8a8"
"hash": "aa923ddc251f5daf4bf075cb251dfddf87877f12fbbc8fbf3cfd08f43bbad8a0"
}

View File

@@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT self_wait_time_ms, aggregate_wait_time_ms FROM outstanding_wait_time WHERE job_id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "self_wait_time_ms",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "aggregate_wait_time_ms",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
true,
true
]
},
"hash": "b2ce29f663cfe1f10dd506dd28b8ce31c58bd40dc130e05df6ef804b2800d6cb"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO outstanding_wait_time(job_id, aggregate_wait_time_ms) VALUES ($1, $2)\n ON CONFLICT (job_id) DO UPDATE SET aggregate_wait_time_ms =\n COALESCE(outstanding_wait_time.aggregate_wait_time_ms, 0) + EXCLUDED.aggregate_wait_time_ms",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Int8"
]
},
"nullable": []
},
"hash": "b3d13bdc40c19d0f94937633053a213057f09e853ea48dc8034a4a586c44ee55"
}

View File

@@ -0,0 +1,41 @@
{
"db_name": "PostgreSQL",
"query": "SELECT created_by, CONCAT(coalesce(completed_job.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM completed_job \n LEFT JOIN job_logs ON job_logs.job_id = completed_job.id \n WHERE completed_job.id = $1 AND completed_job.workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "created_by",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "logs",
"type_info": "Text"
},
{
"ordinal": 2,
"name": "log_offset",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "log_file_index",
"type_info": "TextArray"
}
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
},
"nullable": [
false,
null,
false,
true
]
},
"hash": "b4c4b1aa4bcf7e5f49ce3bd93fff3b7c49e812271e4888d33eb73dd638486488"
}

View File

@@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT CAST(ROUND(AVG(duration_ms), 0) AS BIGINT) AS avg_duration_s FROM\n (SELECT duration_ms FROM concurrency_key LEFT JOIN completed_job ON completed_job.id = concurrency_key.job_id WHERE key = $1 AND ended_at IS NOT NULL\n ORDER BY ended_at\n DESC LIMIT 10) AS t",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "avg_duration_s",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "c845c06aa46b52a1e3672fd379dbcec167f4044e45e932aeeefd3d9237e5042c"
}

View File

@@ -1,35 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT CONCAT(coalesce(completed_job.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM completed_job \n LEFT JOIN job_logs ON job_logs.job_id = completed_job.id \n WHERE completed_job.id = $1 AND completed_job.workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "logs",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "log_offset",
"type_info": "Int4"
},
{
"ordinal": 2,
"name": "log_file_index",
"type_info": "TextArray"
}
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
},
"nullable": [
null,
false,
true
]
},
"hash": "d0ce6a8ff7b89a0e99902989e57e7cae736e346c067261de34100f4fb97ca6db"
}

View File

@@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO metrics (id, value) VALUES ('license_key_renewal', $1)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Jsonb"
]
},
"nullable": []
},
"hash": "d113bc301f2f094c3a2a4c6ed385da65edde2fbfee0fac5103ba7bd18c64563d"
}

View File

@@ -0,0 +1,71 @@
{
"db_name": "PostgreSQL",
"query": "SELECT * FROM job_perms WHERE job_id = $1 AND workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "job_id",
"type_info": "Uuid"
},
{
"ordinal": 1,
"name": "email",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "username",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "is_admin",
"type_info": "Bool"
},
{
"ordinal": 4,
"name": "is_operator",
"type_info": "Bool"
},
{
"ordinal": 5,
"name": "created_at",
"type_info": "Timestamp"
},
{
"ordinal": 6,
"name": "workspace_id",
"type_info": "Varchar"
},
{
"ordinal": 7,
"name": "groups",
"type_info": "TextArray"
},
{
"ordinal": 8,
"name": "folders",
"type_info": "JsonbArray"
}
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "d2def87d7f7901eebc65082f7df5e0a33e5702b25c3db3affa06155e90480e42"
}

View File

@@ -1,23 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT username FROM usr WHERE workspace_id = $1 AND email = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "username",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "da5da57ea48ddc6ab271b6c18baa5f7360008e082e2fb8d58faff4461e18c83a"
}

View File

@@ -1,16 +1,18 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO dependency_map (workspace_id, importer_path, importer_kind, imported_path)\n VALUES ($1, $2, 'script', $3)",
"query": "INSERT INTO dependency_map (workspace_id, importer_path, importer_kind, imported_path, importer_node_id)\n VALUES ($1, $2, $4::text::IMPORTER_KIND, $3, $5)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Varchar",
"Text",
"Varchar"
]
},
"nullable": []
},
"hash": "5fbd5dfb8df9aecce023c5d482ee58efcbc23c8682a3f0ec94977eb56023ed72"
"hash": "e87c317550af671e4b65752a9c0b659cedf430fb7242faee4379b4a13e5fd763"
}

View File

@@ -0,0 +1,35 @@
{
"db_name": "PostgreSQL",
"query": "SELECT importer_path, importer_kind::text, array_agg(importer_node_id) as importer_node_ids FROM dependency_map\n WHERE imported_path = $1\n AND workspace_id = $2\n GROUP BY importer_path, importer_kind",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "importer_path",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "importer_kind",
"type_info": "Text"
},
{
"ordinal": 2,
"name": "importer_node_ids",
"type_info": "VarcharArray"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false,
null,
null
]
},
"hash": "ec3359bbc309c2b893e9f68c09c9f61501068f4b027f58279e0c8508839607f4"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "SELECT flow_status FROM queue WHERE id = $1 AND workspace_id = $2",
"query": "SELECT parent_job FROM queue WHERE id = $1 AND workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "flow_status",
"type_info": "Jsonb"
"name": "parent_job",
"type_info": "Uuid"
}
],
"parameters": {
@@ -19,5 +19,5 @@
true
]
},
"hash": "0a7212dd507ed8f7a311724185e39ecc1809abb208a681ad711614c27baadd83"
"hash": "f33dd637181439ba7fa441dbd7d7430c1ccc0f410c377cde71c70c9211f9c1df"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO outstanding_wait_time(job_id, self_wait_time_ms) VALUES ($1, $2)\n ON CONFLICT (job_id) DO UPDATE SET self_wait_time_ms = EXCLUDED.self_wait_time_ms",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Int8"
]
},
"nullable": []
},
"hash": "f367a1c8f80dd414dcbcd949374eeb5770796f00b5b3d547163bcfdaed65d8ae"
}

View File

@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO concurrency_key (job_id, key) SELECT id, $1 FROM unnest($2::uuid[]) as id",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"UuidArray"
]
},
"nullable": []
},
"hash": "f5a0346034f3bef54260962f7783b3fde7b1aa1f37a72058e292eebbcae08d74"
}

2688
backend/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "windmill"
version = "1.335.0"
version = "1.350.3"
authors.workspace = true
edition.workspace = true
@@ -24,7 +24,7 @@ members = [
]
[workspace.package]
version = "1.335.0"
version = "1.350.3"
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
edition = "2021"
@@ -50,8 +50,8 @@ parquet = ["windmill-api/parquet", "windmill-common/parquet", "windmill-worker/p
prometheus = ["windmill-common/prometheus", "windmill-api/prometheus", "windmill-worker/prometheus", "windmill-queue/prometheus"]
flow_testing = ["windmill-worker/flow_testing"]
openidconnect = ["windmill-api/openidconnect"]
cloud = ["windmill-queue/cloud"]
jemalloc = ["dep:tikv-jemallocator", "dep:tikv-jemalloc-sys", "dep:tikv-jemalloc-ctl"]
cloud = ["windmill-queue/cloud", "windmill-worker/cloud"]
jemalloc = ["windmill-common/jemalloc", "dep:tikv-jemallocator", "dep:tikv-jemalloc-sys", "dep:tikv-jemalloc-ctl"]
[dependencies]
anyhow.workspace = true
@@ -65,7 +65,6 @@ windmill-worker.workspace = true
futures.workspace = true
tracing.workspace = true
sqlx.workspace = true
tokio-metrics.workspace = true
rand.workspace = true
chrono.workspace = true
git-version.workspace = true
@@ -84,9 +83,9 @@ deno_core.workspace = true
pg-embed = {git = "https://github.com/faokunega/pg-embed", optional = true, default-features = false, features = ['rt_tokio']}
[target.'cfg(not(target_env = "msvc"))'.dependencies]
tikv-jemallocator = { optional = true, version = "0.5", features = ["profiling"] }
tikv-jemalloc-sys = { optional = true, version = "^0.5", features = ["profiling"] }
tikv-jemalloc-ctl = { optional = true, version = "^0.5" }
tikv-jemallocator = { optional = true, workspace = true }
tikv-jemalloc-sys = { optional = true, workspace = true }
tikv-jemalloc-ctl = { optional = true, workspace = true }
[dev-dependencies]
serde_json.workspace = true
@@ -160,19 +159,20 @@ tokio-util = { version = "^0", features = ["io"] }
json-pointer = "^0"
itertools = "^0"
regex = "^1"
deno_fetch = "0.162.0"
deno_tls = "0.125.0"
deno_console = "0.138.0"
deno_url = "0.138.0"
deno_webidl = "0.138.0"
deno_web = "0.169.0"
deno_core = "0.262.0"
deno_ast = { version = "0.33.3", features = ["transpiling"] }
deno_fetch = "0.179.0"
deno_tls = "0.142.0"
deno_console = "0.155.0"
deno_url = "0.155.0"
deno_webidl = "0.155.0"
deno_web = "0.186.0"
deno_net = "0.147.0"
deno_core = "0.284.0"
deno_ast = { version = "0.39.0", features = ["transpiling"] }
async-recursion = "^1"
swc_common = "=0.33.17"
swc_ecma_parser = "=0.143.3"
swc_ecma_ast = "=0.112.2"
swc_ecma_visit = "=0.98.2"
swc_common = "=0.33.26"
swc_ecma_parser = "=0.144.1"
swc_ecma_ast = "=0.113.4"
swc_ecma_visit = "=0.99.1"
base64 = "0.21.0"
hmac = "0.12.1"
sha2 = "0.10.6"
@@ -191,7 +191,6 @@ dotenv = "^0"
ulid = { version = "^1", features = ["uuid"] }
futures = "^0"
futures-core = "^0"
tokio-metrics = "0.1.0"
lazy_static = "1.4.0"
serde_derive = "1.0.147"
const_format = { version = "0.2", features = ["rust_1_64", "rust_1_51"] }
@@ -236,11 +235,10 @@ tiberius = { git = "https://github.com/prisma/tiberius", rev = "8f66a699dfa041e7
pin-project = "1"
indexmap = { version = "2.2.5", features = ["serde"]}
polars = { version = "0.38.3", features = ["lazy", "parquet", "aws", "azure", "csv", "dtype-full", "serde", "strings", "extract_groups"] }
polars-io = { version = "0.38.3", features = ["csv"] }
object_store = { version = "0.9.1", features = ["aws", "azure"] }
datafusion = "39.0.0"
object_store = { version = "0.10.0", features = ["aws", "azure"] }
openidconnect = { version = "3.4.0" }
zstd = "=0.12.4"
aws-config = "^1"
aws-sdk-sts = "^1"
@@ -248,3 +246,10 @@ crc = "^3"
tar = "^0"
http = "^1"
async-stream = "^0"
tikv-jemallocator = { version = "0.5" }
tikv-jemalloc-sys = { version = "^0.5" }
tikv-jemalloc-ctl = { version = "^0.5" }
# 0.1.12 broken (nested dependency of swc_common)
triomphe = "<0.1.12"

View File

@@ -2,4 +2,4 @@
fn main() {
// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
}
}

View File

@@ -1 +1 @@
229b7acc60691f7e6577c44f782676d6871defdd
6aa8832322866e9f6ff90979db9b2b8f4bf6d4ce

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,2 @@
-- Add up migration script here
ALTER TABLE token ALTER COLUMN label TYPE VARCHAR(1000)

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,2 @@
-- Add up migration script here
ALTER TABLE worker_ping ADD COLUMN memory_usage BIGINT;

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,2 @@
-- Add up migration script here
ALTER TABLE worker_ping ADD COLUMN wm_memory_usage BIGINT;

View File

@@ -0,0 +1,2 @@
-- Add down migration script here
DROP TABLE outstanding_wait_time;

View File

@@ -0,0 +1,6 @@
-- Add up migration script here
CREATE TABLE outstanding_wait_time (
job_id UUID PRIMARY KEY,
self_wait_time_ms BIGINT DEFAULT NULL,
aggregate_wait_time_ms BIGINT DEFAULT NULL
);

View File

@@ -0,0 +1,2 @@
-- Add down migration script here
DROP POLICY "schedule_audit" on audit;

View File

@@ -0,0 +1,4 @@
-- Add up migration script here
CREATE POLICY "schedule_audit" on audit FOR INSERT
TO windmill_user
WITH CHECK (((parameters->>'end_user')::text ~~ 'schedule-%'::text));

View File

@@ -0,0 +1,2 @@
-- Add down migration script here
ALTER TABLE dependency_map DROP COLUMN importer_node_id;

View File

@@ -0,0 +1,4 @@
-- Add up migration script here
ALTER TABLE dependency_map ADD COLUMN importer_node_id VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE dependency_map DROP constraint dependency_map_pkey;
ALTER TABLE dependency_map ADD PRIMARY KEY (workspace_id, importer_node_id, importer_kind, importer_path, imported_path);

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,3 @@
-- Add up migration script here
GRANT ALL ON outstanding_wait_time TO windmill_admin;
GRANT ALL ON outstanding_wait_time TO windmill_user;

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,13 @@
-- Add up migration script here
CREATE TABLE public.job_perms (
job_id uuid NOT NULL,
email varchar(255) NOT NULL,
username varchar(50) NOT NULL,
is_admin bool NOT NULL,
is_operator bool NOT NULL,
created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
workspace_id varchar(50) NOT NULL,
groups _text NOT NULL,
folders _jsonb NOT NULL,
CONSTRAINT job_perms_pk PRIMARY KEY (job_id)
);

View File

@@ -0,0 +1 @@
-- Add down migration script here

View File

@@ -0,0 +1,5 @@
-- Add up migration script here
GRANT ALL ON job_perms TO windmill_admin;
GRANT ALL ON job_perms TO windmill_user;
GRANT ALL ON job_logs TO windmill_admin;
GRANT ALL ON job_logs TO windmill_user;

View File

@@ -11,7 +11,7 @@ pub fn parse_bash_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_bash_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing bash script".to_string()))
}
@@ -21,7 +21,7 @@ pub fn parse_powershell_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_powershell_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing powershell script".to_string()))
}
@@ -160,7 +160,8 @@ non_required="${5:-}"
default: Some(json!("")),
has_default: true
}
]
],
no_main_func: None
}
);

View File

@@ -30,9 +30,19 @@ pub fn parse_go_sig(code: &str) -> anyhow::Result<MainArgSignature> {
Arg { name: get_name(param), otyp, typ, default: None, has_default: false }
})
.collect_vec();
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args,
no_main_func: Some(false),
})
} else {
Err(anyhow::anyhow!("no main function found".to_string(),))
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args: vec![],
no_main_func: Some(true),
})
}
}
@@ -216,7 +226,8 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
default: None,
has_default: false
},
]
],
no_main_func: Some(false)
}
);

View File

@@ -10,7 +10,7 @@ pub fn parse_graphql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_graphql_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -101,7 +101,8 @@ query($s: String, $arr: [String]) {
default: None,
has_default: false
},
]
],
no_main_func: None
}
);

View File

@@ -89,11 +89,19 @@ pub fn parse_php_signature(
})
.collect();
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args,
no_main_func: Some(false),
})
} else {
Err(anyhow::anyhow!(
"main function was not findable".to_string(),
))
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args: vec![],
no_main_func: Some(true),
})
}
}
@@ -157,7 +165,8 @@ function main(string $input1 = \"hey\", bool $input2 = false, int $input3 = 3, f
has_default: false,
default: None
}
]
],
no_main_func: Some(false)
}
);

View File

@@ -53,6 +53,10 @@ static PYTHON_IMPORTS_REPLACEMENT: phf::Map<&'static str, &'static str> = phf_ma
"pymsql" => "PyMySQL",
"haystack" => "haystack-ai",
"github" => "PyGithub",
"ldap" => "python-ldap",
"opensearchpy" => "opensearch-py",
"lokalise" => "python-lokalise-api",
"msgraph" => "msgraph-sdk",
};
fn replace_import(x: String) -> String {
@@ -108,9 +112,25 @@ pub fn parse_relative_imports(code: &str, path: &str) -> error::Result<Vec<Strin
}
fn parse_code_for_imports(code: &str, path: &str) -> error::Result<Vec<String>> {
let code = code.split(DEF_MAIN).next().unwrap_or("");
let ast = Suite::parse(code, "main.py").map_err(|e| {
error::Error::ExecutionErr(format!("Error parsing code: {}", e.to_string()))
let mut code = code.split(DEF_MAIN).next().unwrap_or("").to_string();
// remove main function decorator from end of file if it exists
if code
.lines()
.last()
.map(|x| x.starts_with("@"))
.unwrap_or(false)
{
code = code
.lines()
.take(code.lines().count() - 1)
.collect::<Vec<&str>>()
.join("\n")
+ "\n";
}
let ast = Suite::parse(&code, "main.py").map_err(|e| {
error::Error::ExecutionErr(format!("Error parsing code for imports: {}", e.to_string()))
})?;
let nimports: Vec<String> = ast
.into_iter()

View File

@@ -117,11 +117,15 @@ pub fn parse_python_signature(
}
})
.collect(),
no_main_func: Some(false),
})
} else {
Err(anyhow::anyhow!(
"main function was not findable".to_string(),
))
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args: vec![],
no_main_func: Some(true),
})
}
}
@@ -308,7 +312,8 @@ def main(test1: str, name: datetime.datetime = datetime.now(), byte: bytes = byt
default: Some(json!(true)),
has_default: true
},
]
],
no_main_func: Some(false),
}
);
@@ -367,7 +372,8 @@ def main(test1: str,
default: Some(json!("$res:g/all/resource")),
has_default: true
}
]
],
no_main_func: Some(false),
}
);
@@ -421,7 +427,8 @@ def main(test1: str,
default: Some(json!("<function call>")),
has_default: true
}
]
],
no_main_func: Some(false),
}
);
@@ -461,7 +468,8 @@ def main(test1: Literal["foo", "bar"], test2: List[Literal["foo", "bar"]]): retu
default: None,
has_default: false
}
]
],
no_main_func: Some(false),
}
);

View File

@@ -11,7 +11,7 @@ pub fn parse_mysql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_mysql_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -21,7 +21,7 @@ pub fn parse_pgsql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_pg_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -31,7 +31,7 @@ pub fn parse_bigquery_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_bigquery_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -41,7 +41,7 @@ pub fn parse_snowflake_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_snowflake_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -51,7 +51,7 @@ pub fn parse_mssql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_mssql_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
Ok(MainArgSignature { star_args: false, star_kwargs: false, args, no_main_func: None })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
@@ -316,6 +316,7 @@ pub fn parse_pg_typ(typ: &str) -> Typ {
| "timestamptz"
| "timestamp with time zone"
| "timestamp without time zone" => Typ::Datetime,
"bytea" => Typ::Bytes,
_ => Typ::Str(None),
}
}
@@ -396,7 +397,8 @@ SELECT * FROM table WHERE token=$1::TEXT AND image=$2::BIGINT
default: None,
has_default: false
},
]
],
no_main_func: None
}
);
@@ -431,7 +433,8 @@ SELECT * FROM table WHERE token=@token AND image=@image
default: None,
has_default: false
},
]
],
no_main_func: None
}
);

View File

@@ -16,6 +16,7 @@ serde-wasm-bindgen.workspace = true
[dependencies]
windmill-parser.workspace = true
swc_common.workspace = true
triomphe.workspace = true
swc_ecma_parser.workspace = true
swc_ecma_ast.workspace = true
swc_ecma_visit.workspace = true

View File

@@ -11,7 +11,7 @@ use regex::Regex;
use serde_json::Value;
use std::collections::HashSet;
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use windmill_parser::{json_to_typ, Arg, MainArgSignature, ObjectProperty, Typ};
use windmill_parser::{json_to_typ, Arg, MainArgSignature, ObjectProperty, OneOfVariant, Typ};
use swc_common::{sync::Lrc, FileName, SourceMap, SourceMapper, Span, Spanned};
use swc_ecma_ast::{
@@ -176,13 +176,16 @@ pub fn parse_deno_signature(
.into_iter()
.map(|x| parse_param(x, &cm, skip_dflt, &mut c))
.collect::<anyhow::Result<Vec<Arg>>>()?,
no_main_func: Some(false),
};
Ok(r)
} else {
Err(anyhow::anyhow!(
"main function was not findable (expected to find 'export function main(...)'"
.to_string(),
))
Ok(MainArgSignature {
star_args: false,
star_kwargs: false,
args: vec![],
no_main_func: Some(true),
})
}
}
@@ -398,6 +401,79 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
};
(tstype_to_typ(&types[other_p]).0, true)
} else {
if types.len() > 1 {
let one_of_values: Vec<OneOfVariant> = types
.into_iter()
.map_while(|x| match &**x {
TsType::TsTypeLit(TsTypeLit { members, .. }) => {
let label = members
.iter()
.find_map(|y| match y {
TsTypeElement::TsPropertySignature(
TsPropertySignature { key, type_ann, .. },
) => match (&**key, type_ann) {
(Expr::Ident(Ident { sym, .. }), type_ann) => {
if sym.to_string() == "label" {
type_ann.as_ref().map(|z| match &*z.type_ann {
TsType::TsLitType(TsLitType {
lit: TsLit::Str(Str { value, .. }),
..
}) => Some(value.to_string()),
_ => None,
})
} else {
None
}
}
_ => None,
},
_ => None,
})
.flatten();
match label {
Some(label) => {
let properties: Vec<ObjectProperty> = members
.into_iter()
.filter_map(|x| match x {
TsTypeElement::TsPropertySignature(
TsPropertySignature { key, type_ann, .. },
) => match (*key.to_owned(), type_ann) {
(Expr::Ident(Ident { sym, .. }), type_ann) => {
Some(ObjectProperty {
key: sym.to_string(),
typ: type_ann
.as_ref()
.map(|typ| {
Box::new(
tstype_to_typ(
&*typ.type_ann,
)
.0,
)
})
.unwrap_or(Box::new(Typ::Unknown)),
})
}
_ => None,
},
_ => None,
})
.collect();
Some(OneOfVariant { label, properties })
}
_ => None,
}
}
_ => None,
})
.collect();
if one_of_values.len() == types.len() {
return (Typ::OneOf(one_of_values), false);
}
}
let literals = types
.into_iter()
.filter(|x| match ***x {

View File

@@ -3,7 +3,7 @@
"collaborators": [
"Ruben Fiszel <ruben@windmill.dev>"
],
"version": "1.327.0",
"version": "1.347.1",
"files": [
"windmill_parser_wasm_bg.wasm",
"windmill_parser_wasm.js",

View File

@@ -97,6 +97,15 @@ function getInt32Memory0() {
return cachedInt32Memory0;
}
let cachedFloat64Memory0 = null;
function getFloat64Memory0() {
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
}
return cachedFloat64Memory0;
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
@@ -115,15 +124,6 @@ function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
let cachedFloat64Memory0 = null;
function getFloat64Memory0() {
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
}
return cachedFloat64Memory0;
}
let cachedBigInt64Memory0 = null;
function getBigInt64Memory0() {
@@ -587,10 +587,6 @@ function __wbg_get_imports() {
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_eval_f2b8ae7add53626d = function(arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'string' ? obj : undefined;
@@ -608,6 +604,21 @@ function __wbg_get_imports() {
const ret = typeof(getObject(arg0)) === 'bigint';
return ret;
};
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'number' ? obj : undefined;
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
};
imports.wbg.__wbindgen_is_object = function(arg0) {
const val = getObject(arg0);
const ret = typeof(val) === 'object' && val !== null;
return ret;
};
imports.wbg.__wbindgen_in = function(arg0, arg1) {
const ret = getObject(arg0) in getObject(arg1);
return ret;
};
imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) {
const ret = arg0;
return addHeapObject(ret);
@@ -624,20 +635,9 @@ function __wbg_get_imports() {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'number' ? obj : undefined;
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
};
imports.wbg.__wbindgen_is_object = function(arg0) {
const val = getObject(arg0);
const ret = typeof(val) === 'object' && val !== null;
return ret;
};
imports.wbg.__wbindgen_in = function(arg0, arg1) {
const ret = getObject(arg0) in getObject(arg1);
return ret;
imports.wbg.__wbg_eval_83a1cdd46625140c = function(arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
const ret = getObject(arg0) == getObject(arg1);

View File

@@ -116,7 +116,8 @@ export function main(test1?: string, test2: string = \"burkina\",
default: None,
has_default: true
}
]
],
no_main_func: Some(false)
}
);
@@ -185,7 +186,8 @@ export function main(test2 = \"burkina\",
default: Some(json!({"a": "test", "b": 42})),
has_default: true
}
]
],
no_main_func: Some(false)
}
);
@@ -230,7 +232,8 @@ export function main(foo: FooBar, {a, b}: FooBar, {c, d}: FooBar = {a: \"foo\",
default: Some(json!({"a": "foo", "b": 42})),
has_default: true
}
]
],
no_main_func: Some(false)
}
);
@@ -258,7 +261,8 @@ export function main(foo: (\"foo\" | \"bar\")[]) {
])))),
default: None,
has_default: false
}]
}],
no_main_func: Some(false)
}
);
@@ -388,7 +392,8 @@ Write-Output 'Testing...'
default: None,
has_default: false
}
]
],
no_main_func: None,
}
);

View File

@@ -14,6 +14,7 @@ pub struct MainArgSignature {
pub star_args: bool,
pub star_kwargs: bool,
pub args: Vec<Arg>,
pub no_main_func: Option<bool>,
}
#[derive(Serialize, Clone, Debug, PartialEq)]
@@ -23,6 +24,13 @@ pub struct ObjectProperty {
pub typ: Box<Typ>,
}
#[derive(Serialize, Clone, Debug, PartialEq)]
#[serde(rename_all(serialize = "lowercase"))]
pub struct OneOfVariant {
pub label: String,
pub properties: Vec<ObjectProperty>,
}
#[derive(Serialize, Clone, Debug, PartialEq)]
#[serde(rename_all(serialize = "lowercase"))]
pub enum Typ {
@@ -37,6 +45,7 @@ pub enum Typ {
Email,
Sql,
Object(Vec<ObjectProperty>),
OneOf(Vec<OneOfVariant>),
Unknown,
}

View File

@@ -16,15 +16,20 @@ use std::{
};
use tokio::fs::DirBuilder;
use windmill_api::HTTP_CLIENT;
#[cfg(feature = "enterprise")]
use windmill_common::ee::schedule_key_renewal;
use windmill_common::{
global_settings::{
BASE_URL_SETTING, BUNFIG_INSTALL_SCOPES_SETTING, CRITICAL_ERROR_CHANNELS_SETTING,
CUSTOM_TAGS_SETTING, DEFAULT_TAGS_PER_WORKSPACE_SETTING, ENV_SETTINGS,
EXPOSE_DEBUG_METRICS_SETTING, EXPOSE_METRICS_SETTING, EXTRA_PIP_INDEX_URL_SETTING,
HUB_BASE_URL_SETTING, JOB_DEFAULT_TIMEOUT_SECS_SETTING, KEEP_JOB_DIR_SETTING,
LICENSE_KEY_SETTING, NPM_CONFIG_REGISTRY_SETTING, OAUTH_SETTING, PIP_INDEX_URL_SETTING,
REQUEST_SIZE_LIMIT_SETTING, REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING,
RETENTION_PERIOD_SECS_SETTING, SAML_METADATA_SETTING, SCIM_TOKEN_SETTING,
HUB_BASE_URL_SETTING, JOB_DEFAULT_TIMEOUT_SECS_SETTING, JWT_SECRET_SETTING,
KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING, NPM_CONFIG_REGISTRY_SETTING, OAUTH_SETTING,
PIP_INDEX_URL_SETTING, REQUEST_SIZE_LIMIT_SETTING,
REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING, RETENTION_PERIOD_SECS_SETTING,
SAML_METADATA_SETTING, SCIM_TOKEN_SETTING,
},
stats_ee::schedule_stats,
utils::{rd_string, Mode},
@@ -49,9 +54,9 @@ use windmill_common::METRICS_ADDR;
use windmill_common::global_settings::OBJECT_STORE_CACHE_CONFIG_SETTING;
use windmill_worker::{
BUN_CACHE_DIR, DENO_CACHE_DIR, DENO_CACHE_DIR_DEPS, DENO_CACHE_DIR_NPM, GO_BIN_CACHE_DIR,
GO_CACHE_DIR, HUB_CACHE_DIR, LOCK_CACHE_DIR, PIP_CACHE_DIR, POWERSHELL_CACHE_DIR,
TAR_PIP_CACHE_DIR, TMP_LOGS_DIR,
BUN_CACHE_DIR, BUN_TAR_CACHE_DIR, DENO_CACHE_DIR, DENO_CACHE_DIR_DEPS, DENO_CACHE_DIR_NPM,
GO_BIN_CACHE_DIR, GO_CACHE_DIR, HUB_CACHE_DIR, LOCK_CACHE_DIR, PIP_CACHE_DIR,
POWERSHELL_CACHE_DIR, TAR_PIP_CACHE_DIR, TMP_LOGS_DIR,
};
use crate::monitor::{
@@ -59,9 +64,10 @@ use crate::monitor::{
load_tag_per_workspace_enabled, monitor_db, monitor_pool, reload_base_url_setting,
reload_bunfig_install_scopes_setting, reload_critical_error_channels_setting,
reload_extra_pip_index_url_setting, reload_hub_base_url_setting,
reload_job_default_timeout_setting, reload_license_key, reload_npm_config_registry_setting,
reload_pip_index_url_setting, reload_retention_period_setting, reload_scim_token_setting,
reload_server_config, reload_worker_config,
reload_job_default_timeout_setting, reload_jwt_secret_setting, reload_license_key,
reload_npm_config_registry_setting, reload_pip_index_url_setting,
reload_retention_period_setting, reload_scim_token_setting, reload_server_config,
reload_worker_config,
};
#[cfg(feature = "parquet")]
@@ -159,7 +165,7 @@ async fn windmill_main() -> anyhow::Result<()> {
panic!("BASE_INTERNAL_URL is required in agent mode")
}
if std::env::var("JOB_TOKEN").is_err() {
tracing::warn!("JOB_TOKEN is not passed, hence workers will still create one ephemeral token per job and the DATABASE_URL need to be of a role that can INSERT into the token table")
tracing::warn!("JOB_TOKEN is not passed, hence workers will still need to create permissions for each job and the DATABASE_URL needs to be of a role that can INSERT into the job_perms table")
}
#[cfg(not(feature = "enterprise"))]
@@ -325,7 +331,9 @@ Windmill Community Edition {GIT_VERSION}
monitor_pool(&db).await;
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
monitor_mem().await;
if !worker_mode {
monitor_mem().await;
}
let addr = SocketAddr::from((server_bind_address, port));
@@ -353,7 +361,7 @@ Windmill Community Edition {GIT_VERSION}
base_internal_tx
.send(base_internal_url.clone())
.map_err(|e| {
anyhow::anyhow!("Could not send base_internal_url to agent: {e}")
anyhow::anyhow!("Could not send base_internal_url to agent: {e:#}")
})?;
}
Ok(()) as anyhow::Result<()>
@@ -453,7 +461,7 @@ Windmill Community Edition {GIT_VERSION}
},
DEFAULT_TAGS_PER_WORKSPACE_SETTING => {
if let Err(e) = load_tag_per_workspace_enabled(&db).await {
tracing::error!("Error loading default tag per workpsace: {e}");
tracing::error!("Error loading default tag per workpsace: {e:#}");
}
},
RETENTION_PERIOD_SECS_SETTING => {
@@ -530,6 +538,11 @@ Windmill Community Edition {GIT_VERSION}
tracing::error!(error = %e, "Could not reload critical error emails setting");
}
},
JWT_SECRET_SETTING => {
if let Err(e) = reload_jwt_secret_setting(&db).await {
tracing::error!(error = %e, "Could not reload jwt secret setting");
}
},
a @_ => {
tracing::info!("Unrecognized Global Setting Change Payload: {:?}", a);
}
@@ -557,7 +570,7 @@ Windmill Community Edition {GIT_VERSION}
});
if let Err(e) = h.await {
tracing::error!("Error waiting for monitor handle:{e}")
tracing::error!("Error waiting for monitor handle:{e:#}")
}
Ok(()) as anyhow::Result<()>
};
@@ -579,6 +592,11 @@ Windmill Community Edition {GIT_VERSION}
schedule_stats(instance_name, &db, &HTTP_CLIENT).await;
}
#[cfg(feature = "enterprise")]
if mode == Mode::Server || mode == Mode::Standalone {
schedule_key_renewal(&HTTP_CLIENT, &db).await;
}
futures::try_join!(shutdown_signal, workers_f, monitor_f, server_f, metrics_f)?;
} else {
tracing::info!("Nothing to do, exiting.");
@@ -664,20 +682,21 @@ pub async fn run_workers<R: rsmq_async::RsmqConnection + Send + Sync + Clone + '
tracing::info!("Received killpill, exiting");
return Ok(());
}
let instance_name = gethostname()
let hostname = gethostname()
.to_str()
.map(|x| {
x.replace(" ", "")
.split("-")
.last()
.unwrap()
.to_ascii_lowercase()
.to_string()
})
.map(|x| x.to_string())
.unwrap_or_else(|| rd_string(5));
let instance_name = hostname
.clone()
.replace(" ", "")
.split("-")
.last()
.unwrap()
.to_ascii_lowercase()
.to_string();
#[cfg(tokio_unstable)]
let monitor = tokio_metrics::TaskMonitor::new();
// #[cfg(tokio_unstable)]
// let monitor = tokio_metrics::TaskMonitor::new();
let ip = windmill_common::external_ip::get_ip()
.await
@@ -697,6 +716,7 @@ pub async fn run_workers<R: rsmq_async::RsmqConnection + Send + Sync + Clone + '
DENO_CACHE_DIR_DEPS,
DENO_CACHE_DIR_NPM,
BUN_CACHE_DIR,
BUN_TAR_CACHE_DIR,
GO_CACHE_DIR,
GO_BIN_CACHE_DIR,
HUB_CACHE_DIR,
@@ -718,13 +738,14 @@ pub async fn run_workers<R: rsmq_async::RsmqConnection + Send + Sync + Clone + '
let tx = tx.clone();
let base_internal_url = base_internal_url.clone();
let rsmq2 = rsmq.clone();
let hostname = hostname.clone();
handles.push(tokio::spawn(async move {
tracing::info!(worker = %worker_name, "starting worker");
let f = windmill_worker::run_worker(
&db1,
&instance_name,
&hostname,
worker_name,
i as u64,
num_workers as u32,
@@ -736,15 +757,15 @@ pub async fn run_workers<R: rsmq_async::RsmqConnection + Send + Sync + Clone + '
agent_mode,
);
#[cfg(tokio_unstable)]
{
monitor.monitor(f, "worker").await
}
// #[cfg(tokio_unstable)]
// {
// monitor.monitor(f, "worker").await
// }
#[cfg(not(tokio_unstable))]
{
f.await
}
// #[cfg(not(tokio_unstable))]
// {
f.await
// }
}));
}

View File

@@ -22,18 +22,31 @@ use windmill_api::{
DEFAULT_BODY_LIMIT, IS_SECURE, OAUTH_CLIENTS, REQUEST_SIZE_LIMIT, SAML_METADATA, SCIM_TOKEN,
};
use windmill_common::{
ee::CriticalErrorChannel, error, flow_status::FlowStatusModule, global_settings::{
auth::JWT_SECRET,
ee::CriticalErrorChannel,
error,
flow_status::FlowStatusModule,
global_settings::{
BASE_URL_SETTING, BUNFIG_INSTALL_SCOPES_SETTING, CRITICAL_ERROR_CHANNELS_SETTING,
DEFAULT_TAGS_PER_WORKSPACE_SETTING, EXPOSE_DEBUG_METRICS_SETTING, EXPOSE_METRICS_SETTING,
EXTRA_PIP_INDEX_URL_SETTING, HUB_BASE_URL_SETTING, JOB_DEFAULT_TIMEOUT_SECS_SETTING,
KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING, NPM_CONFIG_REGISTRY_SETTING, OAUTH_SETTING,
PIP_INDEX_URL_SETTING, REQUEST_SIZE_LIMIT_SETTING,
JWT_SECRET_SETTING, KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING, NPM_CONFIG_REGISTRY_SETTING,
OAUTH_SETTING, PIP_INDEX_URL_SETTING, REQUEST_SIZE_LIMIT_SETTING,
REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING, RETENTION_PERIOD_SECS_SETTING,
SAML_METADATA_SETTING, SCIM_TOKEN_SETTING,
}, jobs::QueuedJob, oauth2::REQUIRE_PREEXISTING_USER_FOR_OAUTH, server::load_server_config, stats_ee::get_user_usage, users::truncate_token, worker::{
},
jobs::QueuedJob,
oauth2::REQUIRE_PREEXISTING_USER_FOR_OAUTH,
server::load_server_config,
stats_ee::get_user_usage,
users::truncate_token,
utils::{now_from_db, rd_string},
worker::{
load_worker_config, reload_custom_tags_setting, DEFAULT_TAGS_PER_WORKSPACE, SERVER_CONFIG,
WORKER_CONFIG,
}, BASE_URL, CRITICAL_ERROR_CHANNELS, DB, DEFAULT_HUB_BASE_URL, HUB_BASE_URL, METRICS_DEBUG_ENABLED, METRICS_ENABLED
},
BASE_URL, CRITICAL_ERROR_CHANNELS, DB, DEFAULT_HUB_BASE_URL, HUB_BASE_URL,
METRICS_DEBUG_ENABLED, METRICS_ENABLED,
};
use windmill_queue::cancel_job;
use windmill_worker::{
@@ -104,15 +117,15 @@ pub async fn initial_load(
_is_agent: bool,
) {
if let Err(e) = load_metrics_enabled(db).await {
tracing::error!("Error loading expose metrics: {e}");
tracing::error!("Error loading expose metrics: {e:#}");
}
if let Err(e) = load_metrics_debug_enabled(db).await {
tracing::error!("Error loading expose debug metrics: {e}");
tracing::error!("Error loading expose debug metrics: {e:#}");
}
if let Err(e) = load_tag_per_workspace_enabled(db).await {
tracing::error!("Error loading default tag per workpsace: {e}");
tracing::error!("Error loading default tag per workpsace: {e:#}");
}
if server_mode {
@@ -140,6 +153,10 @@ pub async fn initial_load(
tracing::error!("Could not reload critical error emails setting: {:?}", e);
}
if let Err(e) = reload_jwt_secret_setting(&db).await {
tracing::error!("Could not reload jwt secret setting: {:?}", e);
}
#[cfg(feature = "parquet")]
if !_is_agent {
reload_s3_cache_setting(&db).await;
@@ -200,7 +217,7 @@ pub async fn load_metrics_debug_enabled(db: &DB) -> error::Result<()> {
tracing::error!("Error setting jemalloc prof_active: {e:?}");
}
}
},
}
_ => (),
};
Ok(())
@@ -208,7 +225,9 @@ pub async fn load_metrics_debug_enabled(db: &DB) -> error::Result<()> {
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
#[derive(Debug, Clone)]
pub struct MallctlError { pub code: i32 }
pub struct MallctlError {
pub code: i32,
}
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
fn set_prof_active(new_value: bool) -> Result<(), MallctlError> {
@@ -216,13 +235,12 @@ fn set_prof_active(new_value: bool) -> Result<(), MallctlError> {
tracing::info!("Setting jemalloc prof_active to {}", new_value);
let result = unsafe {
tikv_jemalloc_sys::mallctl(
option_name.as_ptr(), // const char *name
std::ptr::null_mut(), // void *oldp
std::ptr::null_mut(), // size_t *oldlenp
&new_value as *const _ as *mut _, // void *newp
std::mem::size_of_val(&new_value) // size_t newlen
option_name.as_ptr(), // const char *name
std::ptr::null_mut(), // void *oldp
std::ptr::null_mut(), // size_t *oldlenp
&new_value as *const _ as *mut _, // void *newp
std::mem::size_of_val(&new_value), // size_t newlen
)
};
@@ -239,31 +257,55 @@ pub fn bytes_to_mb(bytes: u64) -> f64 {
bytes as f64 / BYTES_PER_MB
}
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
pub async fn monitor_mem() {
use std::time::Duration;
use tikv_jemalloc_ctl::{stats, epoch};
use tikv_jemalloc_ctl::{epoch, stats};
tokio::spawn(async move {
// Obtain a MIB for the `epoch`, `stats.allocated`, and
// `atats.resident` keys:
let e = epoch::mib().unwrap();
let allocated = stats::allocated::mib().unwrap();
let resident = stats::resident::mib().unwrap();
let e = match epoch::mib() {
Ok(mib) => mib,
Err(e) => {
tracing::error!("Error getting jemalloc epoch mib: {:?}", e);
return;
}
};
let allocated = match stats::allocated::mib() {
Ok(mib) => mib,
Err(e) => {
tracing::error!("Error getting jemalloc allocated mib: {:?}", e);
return;
}
};
let resident = match stats::resident::mib() {
Ok(mib) => mib,
Err(e) => {
tracing::error!("Error getting jemalloc resident mib: {:?}", e);
return;
}
};
loop {
// Many statistics are cached and only updated
// Many statistics are cached and only updated
// when the epoch is advanced:
e.advance().unwrap();
// Read statistics using MIB key:
let allocated = allocated.read().unwrap();
let resident = resident.read().unwrap();
tracing::info!("{} mb allocated/{} mb resident", bytes_to_mb(allocated as u64), bytes_to_mb(resident as u64));
tokio::time::sleep(Duration::from_secs(10)).await;
match e.advance() {
Ok(_) => {
// Read statistics using MIB key:
let allocated = allocated.read().unwrap_or_default();
let resident = resident.read().unwrap_or_default();
tracing::info!(
"{} mb allocated/{} mb resident",
bytes_to_mb(allocated as u64),
bytes_to_mb(resident as u64)
);
}
Err(e) => {
tracing::error!("Error advancing jemalloc epoch: {:?}", e);
}
}
tokio::time::sleep(Duration::from_secs(30)).await;
}
});
}
@@ -273,7 +315,7 @@ pub async fn load_keep_job_dir(db: &DB) {
match value {
Ok(Some(serde_json::Value::Bool(t))) => KEEP_JOB_DIR.store(t, Ordering::Relaxed),
Err(e) => {
tracing::error!("Error loading keep job dir metrics: {e}");
tracing::error!("Error loading keep job dir metrics: {e:#}");
}
_ => (),
};
@@ -287,7 +329,7 @@ pub async fn load_require_preexisting_user(db: &DB) {
REQUIRE_PREEXISTING_USER_FOR_OAUTH.store(t, Ordering::Relaxed)
}
Err(e) => {
tracing::error!("Error loading keep job dir metrics: {e}");
tracing::error!("Error loading keep job dir metrics: {e:#}");
}
_ => (),
};
@@ -775,7 +817,6 @@ pub async fn expose_queue_metrics(db: &Pool<Postgres>) {
.unwrap_or(true);
if metrics_enabled || save_metrics {
let queue_counts = sqlx::query!(
"SELECT tag, count(*) as count FROM queue WHERE
scheduled_for <= now() - ('3 seconds')::interval AND running = false
@@ -821,20 +862,21 @@ pub async fn expose_queue_metrics(db: &Pool<Postgres>) {
// clean queue metrics older than 14 days
sqlx::query!(
"DELETE FROM metrics WHERE id LIKE 'queue_%' AND created_at < NOW() - INTERVAL '14 day'"
).execute(&mut *tx).await.ok();
)
.execute(&mut *tx)
.await
.ok();
tx.commit().await.ok();
}
}
#[derive(Serialize)]
struct WorkerUsage {
worker: String,
worker_instance: String,
vcpus: Option<i64>,
memory: Option<i64>,
}
pub async fn save_usage_metrics(db: &Pool<Postgres>) {
@@ -852,7 +894,10 @@ pub async fn save_usage_metrics(db: &Pool<Postgres>) {
// save author and operator count every ~24 hours
if last_check
.map(|last_check| chrono::Utc::now() - last_check > chrono::Duration::hours(24) - chrono::Duration::minutes(random_nb % 60))
.map(|last_check| {
chrono::Utc::now() - last_check
> chrono::Duration::hours(24) - chrono::Duration::minutes(random_nb % 60)
})
.unwrap_or(true)
{
let user_usage = get_user_usage(&mut *tx).await.ok();
@@ -860,7 +905,7 @@ pub async fn save_usage_metrics(db: &Pool<Postgres>) {
if let Some(user_usage) = user_usage {
sqlx::query!(
"INSERT INTO metrics (id, value) VALUES ('author_count', $1), ('operator_count', $2)",
serde_json::json!(user_usage.author_count.unwrap_or(0)),
serde_json::json!(user_usage.author_count.unwrap_or(0)),
serde_json::json!(user_usage.operator_count.unwrap_or(0))
)
.execute(&mut *tx)
@@ -868,7 +913,6 @@ pub async fn save_usage_metrics(db: &Pool<Postgres>) {
.ok();
}
// clean metrics older than 6 months (including worker usage)
sqlx::query!(
"DELETE FROM metrics
@@ -881,7 +925,10 @@ pub async fn save_usage_metrics(db: &Pool<Postgres>) {
// save worker usage every ~60 minutes
if last_check
.map(|last_check| chrono::Utc::now() - last_check > chrono::Duration::minutes(60) - chrono::Duration::seconds(random_nb % 300))
.map(|last_check| {
chrono::Utc::now() - last_check
> chrono::Duration::minutes(60) - chrono::Duration::seconds(random_nb % 300)
})
.unwrap_or(true)
{
let worker_usage = sqlx::query_as!(
@@ -905,7 +952,6 @@ pub async fn save_usage_metrics(db: &Pool<Postgres>) {
tx.commit().await.ok();
}
}
pub async fn reload_server_config(db: &Pool<Postgres>) {
@@ -950,7 +996,7 @@ pub async fn reload_worker_config(
tracing::info!("Waiting 5 seconds to allow others workers to start potential jobs that depend on a potential shared cache volume");
tokio::time::sleep(Duration::from_secs(5)).await;
if let Err(e) = windmill_worker::common::clean_cache().await {
tracing::error!("Error cleaning the cache: {e}");
tracing::error!("Error cleaning the cache: {e:#}");
}
}
}
@@ -1079,11 +1125,18 @@ async fn handle_zombie_jobs<R: rsmq_async::RsmqConnection + Send + Sync + Clone>
mpsc::channel::<SameWorkerPayload>(1);
let (send_result_never_used, _send_result_rx_never_used) = mpsc::channel::<SendResult>(1);
let label = if job.permissioned_as != format!("u/{}", job.created_by)
&& job.permissioned_as != job.created_by
{
format!("ephemeral-script-end-user-{}", job.created_by)
} else {
"ephemeral-script".to_string()
};
let token = create_token_for_owner(
&db,
&job.workspace_id,
&job.permissioned_as,
"ephemeral-script",
&label,
*SCRIPT_TOKEN_EXPIRY,
&job.email,
&job.id,
@@ -1132,7 +1185,7 @@ async fn handle_zombie_flows(
SELECT *
FROM queue
WHERE running = true AND suspend = 0 AND suspend_until IS null AND scheduled_for <= now() AND (job_kind = 'flow' OR job_kind = 'flowpreview')
AND last_ping IS NOT NULL AND last_ping < NOW() - ($1 || ' seconds')::interval
AND last_ping IS NOT NULL AND last_ping < NOW() - ($1 || ' seconds')::interval AND canceled = false
"#,
).bind(FLOW_ZOMBIE_TRANSITION_TIMEOUT.as_str())
.fetch_all(db)
@@ -1152,18 +1205,20 @@ async fn handle_zombie_flows(
);
// if the flow hasn't started and is a zombie, we can simply restart it
sqlx::query!(
"UPDATE queue SET running = false, started_at = null WHERE id = $1",
"UPDATE queue SET running = false, started_at = null WHERE id = $1 AND canceled = false",
flow.id
)
.execute(db)
.await?;
} else {
let id = flow.id.clone();
let last_ping = flow.last_ping.clone();
let now = now_from_db(db).await?;
cancel_zombie_flow_job(
db,
flow,
&rsmq,
format!("Flow {} cancelled as it was hanging in between 2 steps", id),
format!("Flow {} cancelled as it was hanging in between 2 steps. Last ping: {last_ping:?} (now: {now})", id),
)
.await?;
}
@@ -1182,11 +1237,12 @@ async fn handle_zombie_flows(
.await?;
for flow in flows2 {
let in_queue =
sqlx::query_as::<_, QueuedJob>("SELECT * FROM queue WHERE id = $1 AND running = true")
.bind(flow.parent_flow_id)
.fetch_optional(db)
.await?;
let in_queue = sqlx::query_as::<_, QueuedJob>(
"SELECT * FROM queue WHERE id = $1 AND running = true AND canceled = false",
)
.bind(flow.parent_flow_id)
.fetch_optional(db)
.await?;
if let Some(job) = in_queue {
tracing::error!(
"parallel Zombie flow detected: {} in workspace {}. Last ping was: {:?}.",
@@ -1216,7 +1272,7 @@ async fn cancel_zombie_flow_job(
flow.id,
flow.workspace_id
);
let (mut ntx, _) = cancel_job(
let (ntx, _) = cancel_job(
"monitor",
Some(message),
flow.id,
@@ -1225,14 +1281,9 @@ async fn cancel_zombie_flow_job(
db,
rsmq.clone(),
false,
false,
)
.await?;
sqlx::query!(
"UPDATE queue SET running = false, started_at = null WHERE id = $1",
flow.id
)
.execute(&mut *ntx)
.await?;
ntx.commit().await?;
Ok(())
}
@@ -1302,3 +1353,35 @@ pub async fn reload_critical_error_channels_setting(db: &DB) -> error::Result<()
Ok(())
}
async fn generate_and_save_jwt_secret(db: &DB) -> error::Result<String> {
let secret = rd_string(32);
sqlx::query!(
"INSERT INTO global_settings (name, value) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET value = $2",
JWT_SECRET_SETTING,
serde_json::to_value(&secret).unwrap()
).execute(db).await?;
Ok(secret)
}
pub async fn reload_jwt_secret_setting(db: &DB) -> error::Result<()> {
let jwt_secret = load_value_from_global_settings(db, JWT_SECRET_SETTING).await?;
let jwt_secret = if let Some(q) = jwt_secret {
if let Ok(v) = serde_json::from_value::<String>(q.clone()) {
v
} else {
tracing::error!("Could not parse jwt_secret setting, generating new one");
generate_and_save_jwt_secret(db).await?
}
} else {
tracing::info!("Not jwt secret found, generating one");
generate_and_save_jwt_secret(db).await?
};
let mut l = JWT_SECRET.write().await;
*l = jwt_secret;
Ok(())
}

View File

@@ -71,7 +71,7 @@ if [ "$REVERT" == "YES" ]; then
ce_file="${ee_file/${EE_CODE_DIR}/.}"
ce_file="${root_dirpath}/backend/${ce_file}"
if [ "$REVERT_PREVIOUS" == "YES" ]; then
git checkout HEAD@{5} ${ce_file} || true
git checkout HEAD@{3} ${ce_file} || true
else
git restore --staged ${ce_file} || true
git restore ${ce_file} || true

View File

@@ -1,5 +1,5 @@
use windmill_api_client::types::{NewScript, NewScriptLanguage};
use std::str::FromStr;
use windmill_api_client::types::{NewScript, NewScriptLanguage};
#[cfg(feature = "enterprise")]
use chrono::Timelike;
@@ -13,26 +13,23 @@ use sqlx::{postgres::PgListener, types::Uuid, Pool, Postgres};
#[cfg(feature = "enterprise")]
use tokio::time::{timeout, Duration};
use windmill_api_client::types::{
CreateFlowBody, RawScript
};
use windmill_api_client::types::{CreateFlowBody, RawScript};
use sqlx::query;
#[cfg(feature = "enterprise")]
use windmill_api_client::types::{EditSchedule, NewSchedule, ScriptArgs};
use windmill_common::worker::{WORKER_CONFIG, PriorityTags};
use serde::Serialize;
use windmill_common::auth::JWT_SECRET;
use windmill_common::worker::{PriorityTags, WORKER_CONFIG};
use windmill_common::{
flow_status::{FlowStatus, FlowStatusModule, RestartedFrom},
flows::{FlowModule, FlowModuleValue, FlowValue, InputTransform},
jobs::{JobPayload, RawCode, JobKind},
scripts::{ScriptLang, ScriptHash}
jobs::{JobKind, JobPayload, RawCode},
scripts::{ScriptHash, ScriptLang},
};
use windmill_queue::PushIsolationLevel;
use serde::Serialize;
#[derive(Debug, sqlx::FromRow, Serialize)]
pub struct CompletedJob {
@@ -66,7 +63,6 @@ pub struct CompletedJob {
pub script_hash: Option<ScriptHash>,
pub language: Option<ScriptLang>,
pub job_kind: JobKind,
}
impl CompletedJob {
@@ -168,6 +164,12 @@ fn find_module_in_vec(modules: Vec<FlowStatusModule>, id: &str) -> Option<FlowSt
modules.into_iter().find(|s| s.id() == id)
}
async fn set_jwt_secret() -> () {
let secret = "mytestsecret".to_string();
let mut l = JWT_SECRET.write().await;
*l = secret;
}
mod suspend_resume {
use serde_json::json;
@@ -272,11 +274,12 @@ mod suspend_resume {
let server = ApiServer::start(db.clone()).await;
let port = server.addr.port();
let flow = RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("port", json!(port))
.push(&db)
.await;
let flow =
RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("port", json!(port))
.push(&db)
.await;
let mut completed = listen_for_completed_jobs(&db).await;
let queue = listen_for_queue(&db).await;
@@ -353,14 +356,15 @@ mod suspend_resume {
let server = ApiServer::start(db.clone()).await;
let port = server.addr.port();
let result = RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("op", json!("cancel"))
.arg("port", json!(port))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("op", json!("cancel"))
.arg("port", json!(port))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
server.close().await.unwrap();
@@ -377,11 +381,12 @@ mod suspend_resume {
let server = ApiServer::start(db.clone()).await;
let port = server.addr.port();
let flow = RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("port", json!(port))
.push(&db)
.await;
let flow =
RunJob::from(JobPayload::RawFlow { value: flow(), path: None, restarted_from: None })
.arg("n", json!(1))
.arg("port", json!(port))
.push(&db)
.await;
let mut completed = listen_for_completed_jobs(&db).await;
let queue = listen_for_queue(&db).await;
@@ -571,13 +576,17 @@ def main(last, port):
.into_iter()
.unzip::<_, _, Vec<_>, Vec<_>>();
let server = Server::start(responses).await;
let result = RunJob::from(JobPayload::RawFlow { value: flow_forloop_retry(), path: None, restarted_from: None })
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result = RunJob::from(JobPayload::RawFlow {
value: flow_forloop_retry(),
path: None,
restarted_from: None,
})
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert_eq!(server.close().await, attempts);
assert_eq!(json!([3, 5, 7, 9]), result);
@@ -600,13 +609,17 @@ def main(last, port):
.into_iter()
.unzip::<_, _, Vec<_>, Vec<_>>();
let server = Server::start(responses).await;
let result = RunJob::from(JobPayload::RawFlow { value: flow_forloop_retry(), path: None, restarted_from: None })
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result = RunJob::from(JobPayload::RawFlow {
value: flow_forloop_retry(),
path: None,
restarted_from: None,
})
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert_eq!(server.close().await, attempts);
@@ -641,11 +654,15 @@ def main(last, port):
.into_iter()
.unzip::<_, _, Vec<_>, Vec<_>>();
let server = Server::start(responses).await;
let job = RunJob::from(JobPayload::RawFlow { value: flow_forloop_retry(), path: None, restarted_from: None })
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await;
let job = RunJob::from(JobPayload::RawFlow {
value: flow_forloop_retry(),
path: None,
restarted_from: None,
})
.arg("items", json!(["unused", "unused", "unused"]))
.arg("port", json!(server.addr.port()))
.run_until_complete(&db, server.addr.port())
.await;
let result = job.json_result().unwrap();
assert_eq!(server.close().await, attempts);
@@ -765,21 +782,23 @@ async fn test_iteration(db: Pool<Postgres>) {
}))
.unwrap();
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!([]))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!([]))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert_eq!(result, serde_json::json!([]));
/* Don't actually test that this does 257 jobs or that will take forever. */
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!((0..257).collect::<Vec<_>>()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!((0..257).collect::<Vec<_>>()))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert!(matches!(result, serde_json::Value::Array(_)));
assert!(result[2]["error"]
.as_object()
@@ -822,19 +841,21 @@ async fn test_iteration_parallel(db: Pool<Postgres>) {
}))
.unwrap();
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!([]))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!([]))
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert_eq!(result, serde_json::json!([]));
/* Don't actually test that this does 257 jobs or that will take forever. */
let job = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!((0..50).collect::<Vec<_>>()))
.run_until_complete(&db, server.addr.port())
.await;
let job =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("items", json!((0..50).collect::<Vec<_>>()))
.run_until_complete(&db, server.addr.port())
.await;
// println!("{:#?}", job);
let result = job.json_result().unwrap();
assert!(matches!(result, serde_json::Value::Array(_)));
@@ -870,7 +891,8 @@ impl RunJob {
let mut hm_args = std::collections::HashMap::new();
for (k, v) in args {
hm_args.insert(k, windmill_common::worker::to_raw_value(&v));
}
}
let tx = PushIsolationLevel::IsolatedRoot(db.clone(), None);
let (uuid, tx) = windmill_queue::push::<rsmq_async::MultiplexedRsmq>(
&db,
@@ -894,6 +916,7 @@ impl RunJob {
None,
None,
None,
None,
)
.await
.expect("push has to succeed");
@@ -928,6 +951,7 @@ async fn in_test_worker<Fut: std::future::Future>(
inner: Fut,
port: u16,
) -> <Fut as std::future::Future>::Output {
set_jwt_secret().await;
let (quit, worker) = spawn_test_worker(db, port);
let worker = tokio::time::timeout(std::time::Duration::from_secs(60), worker);
tokio::pin!(worker);
@@ -959,7 +983,10 @@ fn spawn_test_worker(
tokio::sync::broadcast::Sender<()>,
tokio::task::JoinHandle<()>,
) {
for x in [windmill_worker::LOCK_CACHE_DIR, windmill_worker::GO_BIN_CACHE_DIR] {
for x in [
windmill_worker::LOCK_CACHE_DIR,
windmill_worker::GO_BIN_CACHE_DIR,
] {
std::fs::DirBuilder::new()
.recursive(true)
.create(x)
@@ -976,9 +1003,10 @@ fn spawn_test_worker(
let future = async move {
let base_internal_url = format!("http://localhost:{}", port);
{
let mut wc = WORKER_CONFIG.write().await;
(*wc).worker_tags = windmill_common::worker::DEFAULT_TAGS.clone();
(*wc).priority_tags_sorted = vec![PriorityTags { priority: 0, tags: (*wc).worker_tags.clone()} ]
let mut wc = WORKER_CONFIG.write().await;
(*wc).worker_tags = windmill_common::worker::DEFAULT_TAGS.clone();
(*wc).priority_tags_sorted =
vec![PriorityTags { priority: 0, tags: (*wc).worker_tags.clone() }]
}
windmill_worker::run_worker::<rsmq_async::MultiplexedRsmq>(
&db,
@@ -1028,11 +1056,13 @@ async fn listen_for_uuid_on(
}
async fn completed_job(uuid: Uuid, db: &Pool<Postgres>) -> CompletedJob {
sqlx::query_as::<_, CompletedJob>("SELECT *, result->'wm_labels' as labels FROM completed_job WHERE id = $1").bind(uuid)
.fetch_one(db)
.await
.unwrap()
sqlx::query_as::<_, CompletedJob>(
"SELECT *, result->'wm_labels' as labels FROM completed_job WHERE id = $1",
)
.bind(uuid)
.fetch_one(db)
.await
.unwrap()
}
#[axum::async_trait(?Send)]
@@ -1073,7 +1103,8 @@ async fn test_deno_flow(db: Pool<Postgres>) {
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
}.into(),
}
.into(),
stop_after_if: Default::default(),
summary: Default::default(),
suspend: Default::default(),
@@ -1111,7 +1142,8 @@ async fn test_deno_flow(db: Pool<Postgres>) {
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
}.into(),
}
.into(),
stop_after_if: Default::default(),
summary: Default::default(),
suspend: Default::default(),
@@ -1124,7 +1156,8 @@ async fn test_deno_flow(db: Pool<Postgres>) {
delete_after_use: None,
continue_on_error: None,
}],
}.into(),
}
.into(),
stop_after_if: Default::default(),
summary: Default::default(),
suspend: Default::default(),
@@ -1183,11 +1216,12 @@ async fn test_identity(db: Pool<Postgres>) {
}))
.unwrap();
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.run_until_complete(&db, server.addr.port())
.await
.json_result()
.unwrap();
assert_eq!(result, serde_json::json!(42));
}
@@ -1681,7 +1715,7 @@ func main(derp string) (string, error) {
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
dedicated_worker: None,
}))
.arg("derp", json!("world"))
.run_until_complete(&db, port)
@@ -1714,7 +1748,7 @@ echo "hello $msg"
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
dedicated_worker: None,
}))
.arg("msg", json!("world"))
.run_until_complete(&db, port)
@@ -1744,7 +1778,7 @@ def main():
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
dedicated_worker: None,
});
let result = run_job_in_new_worker_until_complete(&db, job, port)
@@ -1780,7 +1814,7 @@ def main():
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
dedicated_worker: None,
});
let result = run_job_in_new_worker_until_complete(&db, job, port)
@@ -1815,7 +1849,7 @@ def main():
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
dedicated_worker: None,
});
let result = run_job_in_new_worker_until_complete(&db, job, port)
@@ -1915,9 +1949,8 @@ async fn test_invalid_first_step(db: Pool<Postgres>) {
let flow = JobPayload::RawFlow { value: flow, path: None, restarted_from: None };
let job = run_job_in_new_worker_until_complete(&db, flow, port).await;
assert_eq!(
job.json_result().unwrap(),
serde_json::json!( {"error": {"name": "InternalErr", "message": "Expected an array value in the iterator expression, found: invalid type: map, expected a sequence at line 1 column 0"}})
assert!(
serde_json::to_string(&job.json_result().unwrap()).unwrap().contains("Expected an array value in the iterator expression, found: invalid type: map, expected a sequence at line 1 column 0")
);
}
@@ -2457,12 +2490,13 @@ async fn test_failure_module(db: Pool<Postgres>) {
}))
.unwrap();
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(0))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(0))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
assert!(result["from failure module"]["error"]
.as_object()
@@ -2473,12 +2507,13 @@ async fn test_failure_module(db: Pool<Postgres>) {
.unwrap()
.contains("[]"));
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(1))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(1))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
assert!(result["from failure module"]["error"]
.as_object()
@@ -2489,12 +2524,13 @@ async fn test_failure_module(db: Pool<Postgres>) {
.unwrap()
.contains("[0]"));
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(2))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(2))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
assert!(result["from failure module"]["error"]
.as_object()
@@ -2505,12 +2541,13 @@ async fn test_failure_module(db: Pool<Postgres>) {
.unwrap()
.contains("[0,1]"));
let result = RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(3))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
let result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.arg("n", json!(3))
.run_until_complete(&db, port)
.await
.json_result()
.unwrap();
assert_eq!(json!({ "l": [0, 1, 2] }), result);
}
@@ -2819,11 +2856,10 @@ async fn test_complex_flow_restart(db: Pool<Postgres>) {
}))
.unwrap();
let first_run_result = RunJob::from(JobPayload::RawFlow {
value: flow.clone(),
path: None,
restarted_from: None
}).run_until_complete(&db, port).await;
let first_run_result =
RunJob::from(JobPayload::RawFlow { value: flow.clone(), path: None, restarted_from: None })
.run_until_complete(&db, port)
.await;
let restarted_flow_result = RunJob::from(JobPayload::RawFlow {
value: flow.clone(),
@@ -2833,10 +2869,16 @@ async fn test_complex_flow_restart(db: Pool<Postgres>) {
step_id: "h".to_owned(),
branch_or_iteration_n: None,
}),
}).run_until_complete(&db, port).await;
})
.run_until_complete(&db, port)
.await;
let first_run_result_int = serde_json::from_value::<i32>(first_run_result.json_result().unwrap()).expect("first_run_result was not an int");
let restarted_flow_result_int = serde_json::from_value::<i32>(restarted_flow_result.json_result().unwrap()).expect("restarted_flow_result was not an int");
let first_run_result_int =
serde_json::from_value::<i32>(first_run_result.json_result().unwrap())
.expect("first_run_result was not an int");
let restarted_flow_result_int =
serde_json::from_value::<i32>(restarted_flow_result.json_result().unwrap())
.expect("restarted_flow_result was not an int");
assert_eq!(first_run_result_int, restarted_flow_result_int);
}
@@ -2855,7 +2897,6 @@ async fn test_rust_client(db: Pool<Postgres>) {
.unwrap();
}
#[cfg(feature = "enterprise")]
#[sqlx::test(fixtures("base", "schedule"))]
async fn test_script_schedule_handlers(db: Pool<Postgres>) {
@@ -2980,7 +3021,7 @@ async fn test_script_schedule_handlers(db: Pool<Postgres>) {
}
let uuid = uuid.unwrap().unwrap();
let completed_job =
query!("SELECT script_path FROM completed_job WHERE id = $1", uuid)
.fetch_one(&db2)
@@ -2999,7 +3040,6 @@ async fn test_script_schedule_handlers(db: Pool<Postgres>) {
.await;
}
#[cfg(feature = "enterprise")]
#[sqlx::test(fixtures("base", "schedule"))]
async fn test_flow_schedule_handlers(db: Pool<Postgres>) {
@@ -3126,7 +3166,7 @@ async fn test_flow_schedule_handlers(db: Pool<Postgres>) {
}
let uuid = uuid.unwrap().unwrap();
let completed_job =
query!("SELECT script_path FROM completed_job WHERE id = $1", uuid)
.fetch_one(&db2)
@@ -3145,8 +3185,11 @@ async fn test_flow_schedule_handlers(db: Pool<Postgres>) {
.await;
}
async fn run_deployed_relative_imports(db: &Pool<Postgres>, script_content: String, language: ScriptLang) {
async fn run_deployed_relative_imports(
db: &Pool<Postgres>,
script_content: String,
language: ScriptLang,
) {
initialize_tracing().await;
let server = ApiServer::start(db.clone()).await;
let port = server.addr.port();
@@ -3155,109 +3198,138 @@ async fn run_deployed_relative_imports(db: &Pool<Postgres>, script_content: Stri
"SECRET_TOKEN".to_string(),
);
client.create_script(
"test-workspace",
&NewScript {
language: NewScriptLanguage::from_str(language.as_str()).unwrap(),
content: script_content,
path: "f/system/test_import".to_string(),
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None,
description: "".to_string(),
draft_only: None,
envs: vec![],
is_template: None,
kind: None,
parent_hash: None,
lock: None,
summary: "".to_string(),
tag: None,
schema: std::collections::HashMap::new(),
ws_error_handler_muted: Some(false),
priority: None,
delete_after_use: None,
timeout: None,
restart_unless_cancelled: None,
deployment_message: None,
concurrency_key: None,
visible_to_runner_only: None,
no_main_func: None,
codebase: None
},
).await.unwrap();
client
.create_script(
"test-workspace",
&NewScript {
language: NewScriptLanguage::from_str(language.as_str()).unwrap(),
content: script_content,
path: "f/system/test_import".to_string(),
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None,
description: "".to_string(),
draft_only: None,
envs: vec![],
is_template: None,
kind: None,
parent_hash: None,
lock: None,
summary: "".to_string(),
tag: None,
schema: std::collections::HashMap::new(),
ws_error_handler_muted: Some(false),
priority: None,
delete_after_use: None,
timeout: None,
restart_unless_cancelled: None,
deployment_message: None,
concurrency_key: None,
visible_to_runner_only: None,
no_main_func: None,
codebase: None,
},
)
.await
.unwrap();
let mut completed = listen_for_completed_jobs(&db).await;
let db2 = db.clone();
in_test_worker(&db, async move {
completed.next().await; // deployed script
in_test_worker(
&db,
async move {
completed.next().await; // deployed script
let script =
query!("SELECT hash FROM script WHERE path = $1", "f/system/test_import".to_string())
.fetch_one(&db2)
.await
.unwrap();
let script = query!(
"SELECT hash FROM script WHERE path = $1",
"f/system/test_import".to_string()
)
.fetch_one(&db2)
.await
.unwrap();
let job = RunJob::from(JobPayload::ScriptHash {
path: "f/system/test_import".to_string(),
hash: ScriptHash(script.hash),
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None,
language,
priority: None,
}).push(&db2).await;
let job = RunJob::from(JobPayload::ScriptHash {
path: "f/system/test_import".to_string(),
hash: ScriptHash(script.hash),
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None,
language,
priority: None,
})
.push(&db2)
.await;
completed.next().await; // completed job
completed.next().await; // completed job
let result = completed_job(job, &db2).await.json_result().unwrap();
let result = completed_job(job, &db2).await.json_result().unwrap();
assert_eq!(result, serde_json::json!(["f/system/same_folder_script", "f/system/same_folder_script", "f/system_relative/different_folder_script", "f/system_relative/different_folder_script"]));
}, port).await;
assert_eq!(
result,
serde_json::json!([
"f/system/same_folder_script",
"f/system/same_folder_script",
"f/system_relative/different_folder_script",
"f/system_relative/different_folder_script"
])
);
},
port,
)
.await;
}
async fn run_preview_relative_imports(db: &Pool<Postgres>, script_content: String, language: ScriptLang) {
async fn run_preview_relative_imports(
db: &Pool<Postgres>,
script_content: String,
language: ScriptLang,
) {
initialize_tracing().await;
let server = ApiServer::start(db.clone()).await;
let port = server.addr.port();
let mut completed = listen_for_completed_jobs(&db).await;
let db2 = db.clone();
in_test_worker(&db, async move {
let job = RunJob::from(JobPayload::Code(RawCode {
hash: None,
content: script_content,
path: Some("f/system/test_import".to_string()),
language,
lock: None,
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None
})).push(&db2).await;
in_test_worker(
&db,
async move {
let job = RunJob::from(JobPayload::Code(RawCode {
hash: None,
content: script_content,
path: Some("f/system/test_import".to_string()),
language,
lock: None,
custom_concurrency_key: None,
concurrent_limit: None,
concurrency_time_window_s: None,
cache_ttl: None,
dedicated_worker: None,
}))
.push(&db2)
.await;
completed.next().await; // completed job
completed.next().await; // completed job
let result = completed_job(job, &db2).await.json_result().unwrap();
let result = completed_job(job, &db2).await.json_result().unwrap();
assert_eq!(result, serde_json::json!(["f/system/same_folder_script", "f/system/same_folder_script", "f/system_relative/different_folder_script", "f/system_relative/different_folder_script"]));
}, port).await;
assert_eq!(
result,
serde_json::json!([
"f/system/same_folder_script",
"f/system/same_folder_script",
"f/system_relative/different_folder_script",
"f/system_relative/different_folder_script"
])
);
},
port,
)
.await;
}
#[sqlx::test(fixtures("base", "relative_bun"))]
async fn test_relative_imports_bun(db: Pool<Postgres>) {
let content = r#"
@@ -3269,29 +3341,28 @@ import { main as test4 } from "../system_relative/different_folder_script.ts";
export async function main() {
return [test1(), test2(), test3(), test4()];
}
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Bun).await;
run_preview_relative_imports(&db, content, ScriptLang::Bun).await;
}
#[sqlx::test(fixtures("base", "relative_bun"))]
async fn test_nested_imports_bun(db: Pool<Postgres>) {
let content = r#"
import { main as test } from "/f/system_relative/nested_script.ts";
export async function main() {
return test();
}
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Bun).await;
run_preview_relative_imports(&db, content, ScriptLang::Bun).await;
}
#[sqlx::test(fixtures("base", "relative_deno"))]
async fn test_relative_imports_deno(db: Pool<Postgres>) {
let content = r#"
@@ -3303,30 +3374,28 @@ import { main as test4 } from "../system_relative/different_folder_script.ts";
export async function main() {
return [test1(), test2(), test3(), test4()];
}
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Deno).await;
run_preview_relative_imports(&db, content, ScriptLang::Deno).await;
}
#[sqlx::test(fixtures("base", "relative_deno"))]
async fn test_nested_imports_deno(db: Pool<Postgres>) {
let content = r#"
import { main as test } from "/f/system_relative/nested_script.ts";
export async function main() {
return test();
}
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Deno).await;
run_preview_relative_imports(&db, content, ScriptLang::Deno).await;
}
#[sqlx::test(fixtures("base", "relative_python"))]
async fn test_relative_imports_python(db: Pool<Postgres>) {
let content = r#"
@@ -3337,24 +3406,23 @@ from ..system_relative.different_folder_script import main as test4
def main():
return [test1(), test2(), test3(), test4()]
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Python3).await;
run_preview_relative_imports(&db, content, ScriptLang::Python3).await;
}
#[sqlx::test(fixtures("base", "relative_python"))]
async fn test_nested_imports_python(db: Pool<Postgres>) {
let content = r#"
from f.system_relative.nested_script import main as test
def main():
return test()
"#.to_string();
"#
.to_string();
run_deployed_relative_imports(&db, content.clone(), ScriptLang::Python3).await;
run_preview_relative_imports(&db, content, ScriptLang::Python3).await;

View File

@@ -15,7 +15,7 @@ stripe = ["dep:async-stripe"]
enterprise_saml = ["dep:samael"]
benchmark = []
embedding = ["dep:tinyvector", "dep:hf-hub", "dep:tokenizers", "dep:candle-core", "dep:candle-transformers", "dep:candle-nn"]
parquet = ["dep:polars", "dep:polars-io", "dep:object_store", "windmill-common/parquet"]
parquet = ["dep:datafusion", "dep:object_store", "dep:url", "windmill-common/parquet"]
prometheus = ["windmill-common/prometheus", "windmill-queue/prometheus", "dep:prometheus"]
openidconnect = ["dep:openidconnect"]
@@ -82,11 +82,14 @@ tokenizers = { workspace = true, optional = true}
candle-core = { workspace = true, optional = true}
candle-transformers = { workspace = true, optional = true}
candle-nn = { workspace = true, optional = true}
polars = { workspace = true, optional = true}
polars-io = { workspace = true, optional = true}
datafusion = { workspace = true, optional = true}
object_store = { workspace = true, optional = true}
openidconnect = { workspace = true, optional = true}
url = { workspace = true, optional = true}
jsonwebtoken = { workspace = true }
pin-project.workspace = true
crc.workspace = true
http.workspace = true
async-stream.workspace = true
async-stream.workspace = true
ulid.workspace = true

View File

@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.335.0
version: 1.350.3
title: Windmill API
contact:
@@ -766,6 +766,59 @@ paths:
schema:
type: string
/settings/latest_key_renewal_attempt:
get:
summary: get latest key renewal attempt
operationId: getLatestKeyRenewalAttempt
tags:
- setting
responses:
"200":
description: status
content:
application/json:
schema:
type: object
properties:
result:
type: string
attempted_at:
type: string
format: date-time
required:
- result
- attempted_at
nullable: true
/settings/renew_license_key:
post:
summary: renew license key
operationId: renewLicenseKey
tags:
- setting
responses:
"200":
description: status
content:
text/plain:
schema:
type: string
/settings/customer_portal:
post:
summary: create customer portal session
operationId: createCustomerPortalSession
tags:
- setting
responses:
"200":
description: url to portal
content:
text/plain:
schema:
type: string
/saml/test_metadata:
post:
summary: test metadata
@@ -2025,6 +2078,27 @@ paths:
items:
type: string
/w/{workspace}/users/username_to_email/{username}:
get:
summary: get email from username
operationId: usernameToEmail
tags:
- user
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- name: username
in: path
required: true
schema:
type: string
responses:
"200":
description: email
content:
text/plain:
schema:
type: string
/users/tokens/create:
post:
summary: create token
@@ -2098,6 +2172,8 @@ paths:
in: query
schema:
type: boolean
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PerPage"
responses:
"200":
description: truncated token
@@ -2557,16 +2633,40 @@ paths:
content:
application/json:
schema:
additionalProperties:
type: object
properties:
extra_params:
additionalProperties:
type: string
scopes:
type: array
items:
type: string
type: array
items:
type: string
/oauth/get_connect/{client}:
get:
summary: get oauth connect
operationId: getOAuthConnect
tags:
- oauth
parameters:
- name: client
description: client name
in: path
required: true
schema:
type: string
responses:
"200":
description: get
content:
application/json:
schema:
type: object
properties:
extra_params:
type: object
scopes:
type: array
items:
type: string
/w/{workspace}/resources/create:
post:
@@ -4900,6 +5000,8 @@ paths:
type: string
path:
type: string
lock:
type: string
cache_ttl:
type: integer
required:
@@ -4909,6 +5011,10 @@ paths:
type: object
force_viewer_one_of_fields:
type: object
force_viewer_allow_user_resources:
type: array
items:
type: string
required:
- args
- component
@@ -5312,14 +5418,75 @@ paths:
required:
- database_length
/w/{workspace}/jobs/queue/cancel_all:
post:
summary: cancel all jobs
operationId: cancelAll
/w/{workspace}/jobs/queue/list_filtered_uuids:
get:
summary: get the ids of all jobs matching the given filters
operationId: listFilteredUuids
tags:
- job
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/OrderDesc"
- $ref: "#/components/parameters/CreatedBy"
- $ref: "#/components/parameters/ParentJob"
- $ref: "#/components/parameters/ScriptExactPath"
- $ref: "#/components/parameters/ScriptStartPath"
- $ref: "#/components/parameters/SchedulePath"
- $ref: "#/components/parameters/ScriptExactHash"
- $ref: "#/components/parameters/StartedBefore"
- $ref: "#/components/parameters/StartedAfter"
- $ref: "#/components/parameters/Success"
- $ref: "#/components/parameters/ScheduledForBeforeNow"
- $ref: "#/components/parameters/JobKinds"
- $ref: "#/components/parameters/Suspended"
- $ref: "#/components/parameters/Running"
- $ref: "#/components/parameters/ArgsFilter"
- $ref: "#/components/parameters/ResultFilter"
- $ref: "#/components/parameters/Tag"
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PerPage"
- name: concurrency_key
in: query
required: false
schema:
type: string
- name: all_workspaces
description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
in: query
schema:
type: boolean
- name: is_not_schedule
description: is not a scheduled job
in: query
schema:
type: boolean
responses:
"200":
description: uuids of jobs
content:
application/json:
schema:
type: array
items:
type: string
/w/{workspace}/jobs/queue/cancel_selection:
post:
summary: cancel jobs based on the given uuids
operationId: cancelSelection
tags:
- job
parameters:
- $ref: "#/components/parameters/WorkspaceId"
requestBody:
description: uuids of the jobs to cancel
required: true
content:
application/json:
schema:
type: array
items:
type: string
responses:
"200":
description: uuids of canceled jobs
@@ -5622,6 +5789,22 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/JobId"
- name: suspended_job
in: query
schema:
type: string
- name: resume_id
in: query
schema:
type: integer
- name: secret
in: query
schema:
type: string
- name: approver
in: query
schema:
type: string
responses:
"200":
description: result
@@ -5639,6 +5822,7 @@ paths:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/JobId"
- $ref: "#/components/parameters/GetStarted"
responses:
"200":
description: result
@@ -7626,12 +7810,16 @@ paths:
/w/{workspace}/job_helpers/test_connection:
get:
summary: Test connection to the workspace datasets storage
summary: Test connection to the workspace object storage
operationId: datasetStorageTestConnection
tags:
- helpers
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- name: storage
in: query
schema:
type: string
responses:
"200":
description: Connection settings
@@ -7641,7 +7829,7 @@ paths:
/w/{workspace}/job_helpers/list_stored_files:
get:
summary: List the file keys available in the workspace files storage (S3)
summary: List the file keys available in a workspace object storage
operationId: listStoredFiles
tags:
- helpers
@@ -7660,6 +7848,10 @@ paths:
in: query
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: List of file keys
@@ -7692,6 +7884,10 @@ paths:
required: true
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: FileMetadata
@@ -7737,6 +7933,10 @@ paths:
in: query
schema:
type: integer
- name: storage
in: query
schema:
type: string
responses:
"200":
description: FilePreview
@@ -7778,7 +7978,10 @@ paths:
in: query
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: Parquet Preview
@@ -7786,6 +7989,54 @@ paths:
application/json:
schema: {}
/w/{workspace}/job_helpers/load_csv_preview/{path}:
get:
summary: Load a preview of a csv file
operationId: loadCsvPreview
tags:
- helpers
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- name: offset
in: query
schema:
type: number
- name: limit
in: query
schema:
type: number
- name: sort_col
in: query
schema:
type: string
- name: sort_desc
in: query
schema:
type: boolean
- name: search_col
in: query
schema:
type: string
- name: search_term
in: query
schema:
type: string
- name: storage
in: query
schema:
type: string
- name: csv_separator
in: query
schema:
type: string
responses:
"200":
description: Csv Preview
content:
application/json:
schema: {}
/w/{workspace}/job_helpers/delete_s3_file:
delete:
summary: Permanently delete file from S3
@@ -7799,6 +8050,10 @@ paths:
required: true
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: Confirmation
@@ -7824,6 +8079,10 @@ paths:
required: true
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: Confirmation
@@ -7859,6 +8118,10 @@ paths:
required: false
schema:
type: string
- name: storage
in: query
schema:
type: string
requestBody:
description: File content
required: true
@@ -7903,6 +8166,10 @@ paths:
required: false
schema:
type: string
- name: storage
in: query
schema:
type: string
responses:
"200":
description: Chunk of the downloaded file
@@ -7912,6 +8179,37 @@ paths:
type: string
format: binary
/w/{workspace}/job_helpers/download_s3_parquet_file_as_csv:
get:
summary: Download file to S3 bucket
operationId: fileDownloadParquetAsCsv
tags:
- helpers
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- name: file_key
in: query
required: true
schema:
type: string
- name: s3_resource_path
in: query
required: false
schema:
type: string
- name: resource_type
in: query
required: false
schema:
type: string
responses:
"200":
description: The downloaded file
content:
text/csv:
schema:
type: string
/w/{workspace}/job_metrics/get/{id}:
post:
summary: get job metrics
@@ -8825,6 +9123,10 @@ components:
type: string
priority:
type: integer
self_wait_time_ms:
type: number
aggregate_wait_time_ms:
type: number
required:
- id
- running
@@ -8942,6 +9244,10 @@ components:
type: array
items:
type: string
self_wait_time_ms:
type: number
aggregate_wait_time_ms:
type: number
required:
- id
- created_by
@@ -9416,12 +9722,16 @@ components:
required:
- name
- typ
no_main_func:
type: boolean
nullable: true
required:
- star_args
- start_kwargs
- args
- type
- error
- no_main_func
Preview:
type: object
@@ -9851,6 +10161,14 @@ components:
type: string
occupancy_rate:
type: number
memory:
type: number
vcpus:
type: number
memory_usage:
type: number
wm_memory_usage:
type: number
required:
- worker
- worker_instance
@@ -10270,6 +10588,26 @@ components:
type: string
public_resource:
type: boolean
secondary_storage:
type: object
additionalProperties:
type: object
properties:
type:
type: string
enum:
[
"S3Storage",
"AzureBlobStorage",
"AzureWorkloadIdentity",
"S3AwsOidc",
]
s3_resource_path:
type: string
azure_blob_resource_path:
type: string
public_resource:
type: boolean
WindmillLargeFile:
type: object

View File

@@ -9,7 +9,9 @@ use std::collections::HashMap;
*/
use crate::{
db::{ApiAuthed, DB},
resources::get_resource_value_interpolated_internal,
users::{require_owner_of_path, OptAuthed},
variables::encrypt,
webhook_util::{WebhookMessage, WebhookShared},
HTTP_CLIENT,
};
@@ -38,7 +40,7 @@ use windmill_common::{
utils::{
http_get_from_hub, not_found_if_none, paginate, query_elems_from_hub, Pagination, StripPath,
},
variables::build_crypt,
variables::{build_crypt, build_crypt_with_key_suffix},
worker::to_raw_value,
HUB_BASE_URL,
};
@@ -145,6 +147,7 @@ pub struct AppHistoryUpdate {
pub type StaticFields = HashMap<String, Box<RawValue>>;
pub type OneOfFields = HashMap<String, Vec<Box<RawValue>>>;
pub type AllowUserResources = Vec<String>;
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "lowercase")]
@@ -158,6 +161,8 @@ pub enum ExecutionMode {
pub struct PolicyTriggerableInputs {
static_inputs: StaticFields,
one_of_inputs: OneOfFields,
#[serde(default)]
allow_user_resources: AllowUserResources,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -421,12 +426,12 @@ async fn get_app_by_id(
}
async fn get_public_app_by_secret(
OptAuthed(opt_authed): OptAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, secret)): Path<(String, String)>,
) -> JsonResult<AppWithLastVersion> {
let mut tx = db.begin().await?;
let mc = build_crypt(&mut tx, &w_id).await?;
let mc = build_crypt(&db, &w_id).await?;
let decrypted = mc
.decrypt_bytes_to_bytes(&(hex::decode(secret)?))
@@ -442,18 +447,39 @@ async fn get_public_app_by_secret(
WHERE app.id = $1 AND app.workspace_id = $2 AND app_version.id = app.versions[array_upper(app.versions, 1)]")
.bind(&id)
.bind(&w_id)
.fetch_optional(&mut *tx)
.fetch_optional(&db)
.await?;
tx.commit().await?;
let app = not_found_if_none(app_o, "App", id.to_string())?;
let policy = serde_json::from_str::<Policy>(app.policy.0.get()).map_err(to_anyhow)?;
if !matches!(policy.execution_mode, ExecutionMode::Anonymous) {
return Err(Error::NotAuthorized(
"App visibility does not allow public access".to_string(),
));
if matches!(policy.execution_mode, ExecutionMode::Anonymous) {
return Ok(Json(app));
}
if opt_authed.is_none() {
{
return Err(Error::NotAuthorized(
"App visibility does not allow public access and you are not logged in".to_string(),
));
}
} else {
let authed = opt_authed.unwrap();
let mut tx = user_db.begin(&authed).await?;
let is_visible = sqlx::query_scalar!(
"SELECT EXISTS(SELECT 1 FROM app WHERE id = $1 AND workspace_id = $2)",
id,
&w_id
)
.fetch_one(&mut *tx)
.await?;
tx.commit().await?;
if !is_visible.unwrap_or(false) {
return Err(Error::NotAuthorized(
"App visibility does not allow public access and you are logged in but you have no read-access to that app".to_string(),
));
}
}
Ok(Json(app))
@@ -483,6 +509,7 @@ async fn get_public_resource(
async fn get_secret_id(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, path)): Path<(String, StripPath)>,
) -> Result<String> {
let path = path.to_path();
@@ -496,15 +523,14 @@ async fn get_secret_id(
)
.fetch_optional(&mut *tx)
.await?;
tx.commit().await?;
let id = not_found_if_none(id_o, "App", path.to_string())?;
let mc = build_crypt(&mut tx, &w_id).await?;
let mc = build_crypt(&db, &w_id).await?;
let hx = hex::encode(mc.encrypt_str_to_bytes(id.to_string()));
tx.commit().await?;
Ok(hx)
}
@@ -585,7 +611,7 @@ async fn create_app(
audit_log(
&mut tx,
&authed.username,
&authed,
"apps.create",
ActionKind::Create,
&w_id,
@@ -622,6 +648,7 @@ async fn create_app(
None,
None,
None,
Some(&authed.clone().into()),
)
.await?;
tracing::info!("Pushed app dependency job {}", dependency_job_uuid);
@@ -701,7 +728,7 @@ async fn delete_app(
audit_log(
&mut *tx,
&authed.username,
&authed,
"apps.delete",
ActionKind::Delete,
&w_id,
@@ -736,7 +763,7 @@ async fn delete_app(
.await
.map_err(|e| {
Error::InternalErr(format!(
"error deleting deployment metadata for script with path {path} in workspace {w_id}: {e}"
"error deleting deployment metadata for script with path {path} in workspace {w_id}: {e:#}"
))
})?;
@@ -873,7 +900,7 @@ async fn update_app(
audit_log(
&mut tx,
&authed.username,
&authed,
"apps.update",
ActionKind::Update,
&w_id,
@@ -912,6 +939,7 @@ async fn update_app(
None,
None,
None,
Some(&authed.clone().into()),
)
.await?;
tracing::info!("Pushed app dependency job {}", dependency_job_uuid);
@@ -940,6 +968,7 @@ pub struct ExecuteApp {
// if set, the app is executed as viewer with the given static fields
pub force_viewer_static_fields: Option<StaticFields>,
pub force_viewer_one_of_fields: Option<OneOfFields>,
pub force_viewer_allow_user_resources: Option<AllowUserResources>,
}
fn digest(code: &str) -> String {
@@ -952,6 +981,7 @@ fn digest(code: &str) -> String {
async fn execute_component(
OptAuthed(opt_authed): OptAuthed,
Extension(db): Extension<DB>,
Extension(user_db): Extension<UserDB>,
Extension(rsmq): Extension<Option<rsmq_async::MultiplexedRsmq>>,
Path((w_id, path)): Path<(String, StripPath)>,
Json(payload): Json<ExecuteApp>,
@@ -976,6 +1006,7 @@ async fn execute_component(
ExecuteApp {
force_viewer_static_fields: Some(static_fields),
force_viewer_one_of_fields: Some(one_of_fields),
force_viewer_allow_user_resources: Some(allow_user_resources),
..
} => {
let mut hm = HashMap::new();
@@ -986,6 +1017,7 @@ async fn execute_component(
PolicyTriggerableInputs {
static_inputs: static_fields,
one_of_inputs: one_of_fields,
allow_user_resources,
},
);
} else {
@@ -998,6 +1030,7 @@ async fn execute_component(
PolicyTriggerableInputs {
static_inputs: static_fields,
one_of_inputs: one_of_fields,
allow_user_resources,
},
);
}
@@ -1027,22 +1060,31 @@ async fn execute_component(
let (username, permissioned_as, email) = match policy.execution_mode {
ExecutionMode::Anonymous => {
let username = opt_authed
.map(|a| a.username)
.as_ref()
.map(|a| a.username.clone())
.unwrap_or_else(|| "anonymous".to_string());
let (permissioned_as, email) = get_on_behalf_of(&policy)?;
(username, permissioned_as, email)
}
ExecutionMode::Publisher => {
let username = opt_authed.map(|a| a.username).ok_or_else(|| {
Error::BadRequest("publisher execution mode requires authentication".to_string())
})?;
let username = opt_authed
.as_ref()
.map(|a| a.username.clone())
.ok_or_else(|| {
Error::BadRequest(
"publisher execution mode requires authentication".to_string(),
)
})?;
let (permissioned_as, email) = get_on_behalf_of(&policy)?;
(username, permissioned_as, email)
}
ExecutionMode::Viewer => {
let (username, email) = opt_authed.map(|a| (a.username, a.email)).ok_or_else(|| {
Error::BadRequest("Required to be authed in viewer mode".to_string())
})?;
let (username, email) = opt_authed
.as_ref()
.map(|a| (a.username.clone(), a.email.clone()))
.ok_or_else(|| {
Error::BadRequest("Required to be authed in viewer mode".to_string())
})?;
(
username.clone(),
username_to_permissioned_as(&username),
@@ -1051,17 +1093,37 @@ async fn execute_component(
}
};
let (job_payload, args, tag) = match payload {
let (job_payload, (args, job_id), tag) = match payload {
ExecuteApp { args, component, raw_code: Some(raw_code), path: None, .. } => {
let content = &raw_code.content;
let payload = JobPayload::Code(raw_code.clone());
let path = digest(content);
let args = build_args(policy, &component, path, args)?;
let args = build_args(
policy,
&component,
path,
args,
opt_authed.as_ref(),
&user_db,
&db,
&w_id,
)
.await?;
(payload, args, None)
}
ExecuteApp { args, component, raw_code: None, path: Some(path), .. } => {
let (payload, tag) = get_payload_tag_from_prefixed_path(&path, &db, &w_id).await?;
let args = build_args(policy, &component, path.to_string(), args)?;
let args = build_args(
policy,
&component,
path.to_string(),
args,
opt_authed.as_ref(),
&user_db,
&db,
&w_id,
)
.await?;
(payload, args, tag)
}
_ => unreachable!(),
@@ -1081,7 +1143,7 @@ async fn execute_component(
None,
None,
None,
None,
job_id,
false,
false,
None,
@@ -1090,6 +1152,7 @@ async fn execute_component(
None,
None,
None,
None,
)
.await?;
tx.commit().await?;
@@ -1150,16 +1213,21 @@ async fn exists_app(
Ok(Json(exists))
}
fn build_args(
async fn build_args(
policy: Policy,
component: &str,
path: String,
args: HashMap<String, Box<RawValue>>,
) -> Result<PushArgs> {
authed: Option<&ApiAuthed>,
user_db: &UserDB,
db: &DB,
w_id: &str,
) -> Result<(PushArgs, Option<Uuid>)> {
let mut job_id: Option<Uuid> = None;
let key = format!("{}:{}", component, &path);
let (static_inputs, one_of_inputs) = match policy {
let (static_inputs, one_of_inputs, allow_user_resources) = match policy {
Policy { triggerables_v2: Some(t), .. } => {
let PolicyTriggerableInputs { static_inputs, one_of_inputs } = t
let PolicyTriggerableInputs { static_inputs, one_of_inputs, allow_user_resources } = t
.get(&key)
.or_else(|| t.get(&path))
.map(|x| x.clone())
@@ -1168,6 +1236,7 @@ fn build_args(
Some(PolicyTriggerableInputs {
static_inputs: HashMap::new(),
one_of_inputs: HashMap::new(),
allow_user_resources: Vec::new(),
})
} else {
None
@@ -1177,7 +1246,7 @@ fn build_args(
Error::BadRequest(format!("path {} is not allowed in the app policy", path))
})?;
(static_inputs, one_of_inputs)
(static_inputs, one_of_inputs, allow_user_resources)
}
Policy { triggerables: Some(t), .. } => {
let static_inputs = t
@@ -1195,7 +1264,7 @@ fn build_args(
Error::BadRequest(format!("path {} is not allowed in the app policy", path))
})?;
(static_inputs, HashMap::new())
(static_inputs, HashMap::new(), Vec::new())
}
_ => Err(Error::BadRequest(format!(
"Policy is missing triggerables for {}",
@@ -1206,7 +1275,55 @@ fn build_args(
let mut args = args.clone();
let mut safe_args = HashMap::<String, Box<RawValue>>::new();
// tracing::error!("{:?}", allow_user_resources);
for k in allow_user_resources.iter() {
if let Some(arg_val) = args.get(k) {
let key = serde_json::from_str::<String>(arg_val.get()).ok();
if let Some(path) =
key.and_then(|x| x.clone().strip_prefix("$res:").map(|x| x.to_string()))
{
if let Some(authed) = authed {
let res = get_resource_value_interpolated_internal(
authed,
Some(user_db.clone()),
db,
w_id,
&path,
None,
"",
)
.await?;
if res.is_none() {
return Err(Error::BadRequest(format!(
"Resource {} not found or not allowed for viewer",
path
)));
}
let job_id = if let Some(job_id) = job_id {
job_id
} else {
job_id = Some(ulid::Ulid::new().into());
job_id.unwrap()
};
let mc = build_crypt_with_key_suffix(&db, &w_id, &job_id.to_string()).await?;
let encrypted = encrypt(&mc, to_raw_value(&res.unwrap()).get());
safe_args.insert(
k.to_string(),
to_raw_value(&format!("$encrypted:{encrypted}")),
);
} else {
return Err(Error::BadRequest(
"User resources are not allowed without being logged in".to_string(),
));
}
}
}
}
for (k, v) in one_of_inputs {
if safe_args.contains_key(&k) {
continue;
}
if let Some(arg_val) = args.get(&k) {
let arg_str = arg_val.get();
@@ -1239,9 +1356,13 @@ fn build_args(
}
for (k, v) in args {
let arg_str = serde_json::to_string(&v).unwrap_or_else(|_| "".to_string());
if safe_args.contains_key(&k) {
continue;
}
if !arg_str.contains("$var:") && !arg_str.contains("$res:") {
let arg_str = v.get();
if !arg_str.contains("\"$var:") && !arg_str.contains("\"$res:") {
safe_args.insert(k.to_string(), v);
} else {
safe_args.insert(
@@ -1254,7 +1375,7 @@ fn build_args(
)
.replace(
"$res:",
"The following resource has been omitted for security reasons: ",
"The following resource has been omitted for security reasons, to allow it, toggle: 'Allow resources from users' on that field input: ",
),
)
.map_err(|e| {
@@ -1270,5 +1391,5 @@ fn build_args(
for (k, v) in static_inputs {
extra.insert(k.to_string(), v.to_owned());
}
Ok(PushArgs { extra, args: safe_args })
Ok((PushArgs { extra, args: safe_args }, job_id))
}

View File

@@ -120,14 +120,13 @@ struct ObscuredJob {
}
#[derive(Deserialize)]
struct ExtendedJobsParams {
concurrency_key: Option<String>,
row_limit: Option<i64>,
}
fn join_concurrency_key<'c>(concurrency_key: Option<&String>, mut sqlb: SqlBuilder) -> SqlBuilder {
pub fn join_concurrency_key<'c>(concurrency_key: Option<&String>, mut sqlb: SqlBuilder) -> SqlBuilder {
if let Some(key) = concurrency_key {
sqlb.join("concurrency_key")
.on_eq("id", "job_id")
.on_eq("id", "concurrency_key.job_id")
.and_where_eq("key", "?".bind(key));
}
@@ -151,7 +150,6 @@ async fn get_concurrent_intervals(
}
let row_limit = iq.row_limit.unwrap_or(1000);
let concurrency_key = iq.concurrency_key;
let lq = ListCompletedQuery { order_desc: Some(true), ..lq };
let lqc = lq.clone();
@@ -177,10 +175,10 @@ async fn get_concurrent_intervals(
.limit(row_limit)
.clone();
sqlb_q = join_concurrency_key(concurrency_key.as_ref(), sqlb_q);
sqlb_c = join_concurrency_key(concurrency_key.as_ref(), sqlb_c);
sqlb_q_user = join_concurrency_key(concurrency_key.as_ref(), sqlb_q_user);
sqlb_c_user = join_concurrency_key(concurrency_key.as_ref(), sqlb_c_user);
sqlb_q = join_concurrency_key(lq.concurrency_key.as_ref(), sqlb_q);
sqlb_c = join_concurrency_key(lq.concurrency_key.as_ref(), sqlb_c);
sqlb_q_user = join_concurrency_key(lq.concurrency_key.as_ref(), sqlb_q_user);
sqlb_c_user = join_concurrency_key(lq.concurrency_key.as_ref(), sqlb_c_user);
let should_fetch_obscured_jobs = match lq {
ListCompletedQuery {
@@ -197,10 +195,10 @@ async fn get_concurrent_intervals(
args: None,
result: None,
tag: None,
scheduled_for_before_now: None,
has_null_parent: None,
label: None,
is_not_schedule: None,
scheduled_for_before_now: _,
is_not_schedule: _,
started_before: _,
started_after: _,
created_before: _,
@@ -211,7 +209,8 @@ async fn get_concurrent_intervals(
job_kinds: _,
is_flow_step: _,
all_workspaces: _,
} => concurrency_key.is_some(),
concurrency_key: Some(_),
} => true,
_ => false,
};
@@ -221,31 +220,25 @@ async fn get_concurrent_intervals(
// the workspace.
// To avoid infering information through filtering, don't return obscured
// jobs if the filters are too specific
if should_fetch_obscured_jobs {
let (sqlb_q, sqlb_c) = if w_id != "admin" {
// By default get obscured jobs from all workspaces, unless in
// admin workspace where admins can select to get all or not
(
filter_list_queue_query(
sqlb_q,
&ListQueueQuery { all_workspaces: Some(true), ..lqq.clone() },
"admins",
),
filter_list_completed_query(
sqlb_c,
&ListCompletedQuery { all_workspaces: Some(true), ..lq.clone() },
"admins",
),
)
} else {
(
filter_list_queue_query(sqlb_q, &lqq, w_id.as_str()),
filter_list_completed_query(sqlb_c, &lq, w_id.as_str()),
)
};
if should_fetch_obscured_jobs && w_id != "admins" {
// Get the obscured jobs from all workspaces (concurrency key could be global)
let (sqlb_q, sqlb_c) = (
filter_list_queue_query(
sqlb_q,
&ListQueueQuery { all_workspaces: Some(true), ..lqq.clone() },
"admins",
true,
),
filter_list_completed_query(
sqlb_c,
&ListCompletedQuery { all_workspaces: Some(true), ..lq.clone() },
"admins",
true,
),
);
sqlb_q_user = filter_list_queue_query(sqlb_q_user, &lqq, w_id.as_str());
sqlb_c_user = filter_list_completed_query(sqlb_c_user, &lq, w_id.as_str());
sqlb_q_user = filter_list_queue_query(sqlb_q_user, &lqq, w_id.as_str(), true);
sqlb_c_user = filter_list_completed_query(sqlb_c_user, &lq, w_id.as_str(), true);
let sql_q_user = sqlb_q_user.query()?;
let sql_c_user = sqlb_c_user.query()?;
@@ -311,6 +304,8 @@ async fn get_concurrent_intervals(
omitted_obscured_jobs: !should_fetch_obscured_jobs,
}))
} else {
sqlb_q = filter_list_queue_query(sqlb_q, &lqq, w_id.as_str(), true);
sqlb_c = filter_list_completed_query(sqlb_c, &lq, w_id.as_str(), true);
let sql_q = sqlb_q.query()?;
let sql_c = sqlb_c.query()?;

View File

@@ -122,7 +122,7 @@ async fn update_config(
audit_log(
&mut *tx,
&authed.username,
&authed,
"worker_config.update",
ActionKind::Update,
"global",
@@ -149,7 +149,7 @@ async fn delete_config(
audit_log(
&mut *tx,
&authed.username,
&authed,
"worker_config.delete",
ActionKind::Delete,
"global",

View File

@@ -15,6 +15,7 @@ use sqlx::{
pool::PoolConnection,
PgConnection, Pool, Postgres,
};
use windmill_audit::audit_ee::{AuditAuthor, AuditAuthorable};
use windmill_common::{
db::{Authable, Authed},
error::Error,
@@ -85,7 +86,7 @@ impl Migrate for CustomMigrator {
.fetch_one(&mut *self.inner)
.await
.map_err(|e| {
tracing::error!("Error acquiring lock: {e}");
tracing::error!("Error acquiring lock: {e:#}");
sqlx::migrate::MigrateError::Execute(e)
})?
.unwrap_or(false);
@@ -174,7 +175,7 @@ pub async fn migrate(db: &DB) -> Result<(), Error> {
Err(sqlx::migrate::MigrateError::VersionMissing(e)) => {
tracing::error!("Database had been applied more migrations than this container.
This usually mean than another container on a more recent version migrated the database and this one is on an earlier version.
Please update the container to latest. Not critical, but may cause issues if migration introduced a breaking change. Version missing: {e}");
Please update the container to latest. Not critical, but may cause issues if migration introduced a breaking change. Version missing: {e:#}");
custom_migrator.unlock().await?;
Ok(())
}
@@ -183,7 +184,7 @@ pub async fn migrate(db: &DB) -> Result<(), Error> {
#[cfg(feature = "enterprise")]
if let Err(e) = windmill_migrations(&mut custom_migrator, db).await {
tracing::error!("Could not apply windmill custom migrations: {e}")
tracing::error!("Could not apply windmill custom migrations: {e:#}")
}
Ok(())
@@ -246,12 +247,34 @@ impl From<ApiAuthed> for Authed {
}
}
impl From<&ApiAuthed> for AuditAuthor {
fn from(value: &ApiAuthed) -> Self {
Self {
email: value.email.clone(),
username: value.username.clone(),
username_override: value.username_override.clone(),
}
}
}
impl ApiAuthed {
pub fn display_username(&self) -> &str {
self.username_override.as_ref().unwrap_or(&self.username)
}
}
impl AuditAuthorable for ApiAuthed {
fn username(&self) -> &str {
self.username.as_str()
}
fn email(&self) -> &str {
self.email.as_str()
}
fn username_override(&self) -> Option<&str> {
self.username_override.as_deref()
}
}
impl Authable for ApiAuthed {
fn is_admin(&self) -> bool {
self.is_admin

View File

@@ -4,3 +4,13 @@ pub async fn validate_license_key(_license_key: String) -> anyhow::Result<String
// Implementation is not open source
Err(anyhow!("License can't be validated in Windmill CE"))
}
#[cfg(feature = "enterprise")]
pub async fn jwt_ext_auth(
_w_id: Option<&String>,
_token: &str,
) -> Option<(crate::db::ApiAuthed, usize)> {
// Implementation is not open source
None
}

View File

@@ -27,6 +27,7 @@ use candle_transformers::models::bert::{BertModel, Config, DTYPE};
use hf_hub::{api::sync::Api, Cache, Repo};
#[cfg(feature = "embedding")]
use serde::Deserialize;
#[cfg(feature = "embedding")]
use serde::Serialize;
#[cfg(feature = "embedding")]
use sqlx::{Pool, Postgres};
@@ -63,6 +64,7 @@ struct HubScriptsQuery {
app: Option<String>,
}
#[cfg(feature = "embedding")]
#[derive(Serialize)]
pub struct HubScriptResult {
ask_id: i64,
@@ -100,6 +102,7 @@ struct ResourceTypesQuery {
limit: Option<i64>,
}
#[cfg(feature = "embedding")]
#[derive(Serialize)]
pub struct ResourceTypeResult {
name: String,

View File

@@ -348,7 +348,7 @@ async fn create_flow(
audit_log(
&mut tx,
&authed.username,
&authed,
"flows.create",
ActionKind::Create,
&w_id,
@@ -393,6 +393,7 @@ async fn create_flow(
None,
None,
None,
Some(&authed.clone().into()),
)
.await?;
@@ -504,7 +505,7 @@ async fn update_flow(
nf.visible_to_runner_only.unwrap_or(false),
)
.execute(&mut tx)
.await?;
.await.map_err(|e| error::Error::InternalErr(format!("Error updating flow due to flow update: {e:#}")))?;
if nf.path != flow_path {
check_schedule_conflict(tx.transaction_mut(), &w_id, &nf.path).await?;
@@ -520,7 +521,7 @@ async fn update_flow(
.bind(&flow_path)
.bind(&w_id)
.fetch_all(&mut tx)
.await?;
.await.map_err(|e| error::Error::InternalErr(format!("Error updating flow due to related schedules update: {e:#}")))?;
let schedule = sqlx::query_as::<_, Schedule>(
"UPDATE schedule SET path = $1, script_path = $1 WHERE path = $2 AND workspace_id = $3 AND is_flow IS true RETURNING *")
@@ -528,7 +529,7 @@ async fn update_flow(
.bind(&flow_path)
.bind(&w_id)
.fetch_optional(&mut tx)
.await?;
.await.map_err(|e| error::Error::InternalErr(format!("Error updating flow due to related schedule update: {e:#}")))?;
if let Some(schedule) = schedule {
clear_schedule(tx.transaction_mut(), &flow_path, &w_id).await?;
@@ -539,7 +540,7 @@ async fn update_flow(
clear_schedule(tx.transaction_mut(), &schedule.path, &w_id).await?;
if schedule.enabled {
tx = push_scheduled_job(&db, tx, &schedule).await?;
tx = push_scheduled_job(&db, tx, &schedule, None).await?;
}
}
@@ -553,7 +554,7 @@ async fn update_flow(
audit_log(
&mut tx,
&authed.username,
&authed,
"flows.update",
ActionKind::Create,
&w_id,
@@ -609,6 +610,7 @@ async fn update_flow(
None,
None,
None,
Some(&authed.clone().into()),
)
.await?;
sqlx::query!(
@@ -618,14 +620,24 @@ async fn update_flow(
w_id
)
.execute(&mut new_tx)
.await?;
.await
.map_err(|e| {
error::Error::InternalErr(format!(
"Error updating flow due to updating dependency job field: {e:#}"
))
})?;
if let Some(old_dep_job) = old_dep_job {
sqlx::query!(
"UPDATE queue SET canceled = true WHERE id = $1",
old_dep_job
)
.execute(&mut new_tx)
.await?;
.await
.map_err(|e| {
error::Error::InternalErr(format!(
"Error updating flow due to cancelling dependency job: {e:#}"
))
})?;
}
new_tx.commit().await?;
@@ -746,7 +758,7 @@ async fn archive_flow_by_path(
audit_log(
&mut *tx,
&authed.username,
&authed,
"flows.archive",
ActionKind::Delete,
&w_id,
@@ -813,7 +825,7 @@ async fn delete_flow_by_path(
audit_log(
&mut *tx,
&authed.username,
&authed,
"flows.delete",
ActionKind::Delete,
&w_id,
@@ -844,7 +856,7 @@ async fn delete_flow_by_path(
.await
.map_err(|e| {
Error::InternalErr(format!(
"error deleting deployment metadata for script with path {path} in workspace {w_id}: {e}"
"error deleting deployment metadata for script with path {path} in workspace {w_id}: {e:#}"
))
})?;
@@ -1120,7 +1132,7 @@ mod tests {
None
],
(0..4)
.map(|previous_attempts| retry.interval(previous_attempts))
.map(|previous_attempts| retry.interval(previous_attempts, false))
.collect::<Vec<_>>()
);
@@ -1147,7 +1159,7 @@ mod tests {
None,
],
(0..5)
.map(|previous_attempts| retry.interval(previous_attempts))
.map(|previous_attempts| retry.interval(previous_attempts, false))
.collect::<Vec<_>>()
);

View File

@@ -223,7 +223,7 @@ async fn create_folder(
audit_log(
&mut *tx,
&authed.username,
&authed,
"folder.create",
ActionKind::Create,
&w_id,
@@ -356,7 +356,7 @@ async fn update_folder(
audit_log(
&mut *tx,
&authed.username,
&authed,
"folder.update",
ActionKind::Update,
&w_id,
@@ -522,7 +522,7 @@ async fn delete_folder(
audit_log(
&mut *tx,
&authed.username,
&authed,
"folder.delete",
ActionKind::Delete,
&w_id,
@@ -585,7 +585,7 @@ async fn add_owner(
audit_log(
&mut *tx,
&authed.username,
&authed,
"folder.add_owner",
ActionKind::Update,
&w_id,
@@ -603,32 +603,6 @@ async fn add_owner(
Ok(format!("Added {} to folder {}", owner, name))
}
pub async fn get_folders_for_user(
w_id: &str,
username: &str,
groups: &[String],
db: &DB,
) -> Result<Vec<(String, bool, bool)>> {
let mut perms = groups
.into_iter()
.map(|x| format!("g/{}", x))
.collect::<Vec<_>>();
perms.insert(0, format!("u/{}", username));
let folders = sqlx::query!(
"SELECT name, (EXISTS (SELECT 1 FROM (SELECT key, value FROM jsonb_each_text(extra_perms) WHERE key = ANY($1)) t WHERE value::boolean IS true)) as write, $1 && owners::text[] as owner FROM folder
WHERE extra_perms ?| $1 AND workspace_id = $2",
&perms[..],
w_id,
)
.fetch_all(db)
.await?
.into_iter()
.map(|x| (x.name, x.write.unwrap_or(false), x.owner.unwrap_or(false)))
.collect();
Ok(folders)
}
async fn remove_owner(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
@@ -664,7 +638,7 @@ async fn remove_owner(
audit_log(
&mut *tx,
&authed.username,
&authed,
"folder.remove_owner",
ActionKind::Update,
&w_id,

View File

@@ -7,7 +7,7 @@
*/
use crate::db::ApiAuthed;
use crate::{db::DB, users::get_groups_for_user, utils::require_super_admin};
use crate::{db::DB, utils::require_super_admin};
use axum::{
extract::{Extension, Path, Query},
@@ -17,11 +17,12 @@ use axum::{
use windmill_audit::audit_ee::audit_log;
use windmill_audit::ActionKind;
use windmill_common::worker::CLOUD_HOSTED;
use windmill_common::{db::UserDB, users::username_to_permissioned_as};
use windmill_common::{
auth::get_groups_for_user,
error::{Error, JsonResult, Result},
utils::{not_found_if_none, paginate, Pagination},
};
use windmill_common::{db::UserDB, users::username_to_permissioned_as};
use serde::{Deserialize, Serialize};
use sqlx::{query_scalar, FromRow, Postgres, Transaction};
@@ -252,7 +253,7 @@ async fn create_group(
audit_log(
&mut *tx,
&authed.username,
&authed,
"group.create",
ActionKind::Create,
&w_id,
@@ -296,7 +297,7 @@ async fn create_igroup(
audit_log(
&mut *tx,
&authed.username,
&authed,
"igroup.create",
ActionKind::Create,
"global",
@@ -337,7 +338,7 @@ async fn update_igroup(
audit_log(
&mut *tx,
&authed.username,
&authed,
"igroup.updated",
ActionKind::Delete,
"global",
@@ -367,7 +368,7 @@ async fn delete_igroup(
audit_log(
&mut *tx,
&authed.username,
&authed,
"igroup.delete",
ActionKind::Delete,
"global",
@@ -472,7 +473,7 @@ async fn delete_group(
.await?;
audit_log(
&mut *tx,
&authed.username,
&authed,
"group.delete",
ActionKind::Delete,
&w_id,
@@ -522,7 +523,7 @@ async fn update_group(
audit_log(
&mut *tx,
&authed.username,
&authed,
"group.edit",
ActionKind::Update,
&w_id,
@@ -573,7 +574,7 @@ async fn add_user(
audit_log(
&mut *tx,
&authed.username,
&authed,
"group.adduser",
ActionKind::Update,
&w_id,
@@ -624,7 +625,7 @@ async fn add_user_igroup(
audit_log(
&mut *tx,
&authed.username,
&authed,
"igroup.adduser",
ActionKind::Update,
"global",
@@ -693,7 +694,7 @@ async fn remove_user_igroup(
audit_log(
&mut *tx,
&authed.username,
&authed,
"igroup.removeuser",
ActionKind::Update,
"global",
@@ -733,7 +734,7 @@ async fn remove_user(
audit_log(
&mut *tx,
&authed.username,
&authed,
"group.removeuser",
ActionKind::Update,
&w_id,

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,7 @@ use axum::extract::DefaultBodyLimit;
use axum::{middleware::from_extractor, routing::get, Extension, Router};
use db::DB;
use git_version::git_version;
use http::HeaderValue;
use reqwest::Client;
use std::collections::HashMap;
use std::time::Duration;
@@ -117,6 +118,28 @@ lazy_static::lazy_static! {
}));
}
// Compliance with cloud events spec.
pub async fn add_webhook_allowed_origin(
req: axum::extract::Request,
next: axum::middleware::Next,
) -> axum::response::Response {
if req.method() == http::Method::OPTIONS {
if let Some(webhook_request_origin) = req.headers().get("Webhook-Request-Origin") {
let webhook_request_origin = webhook_request_origin.clone();
let mut response = next.run(req).await;
response
.headers_mut()
.insert("Webhook-Allowed-Origin", webhook_request_origin);
response
.headers_mut()
.insert("Webhook-Allowed-Rate", HeaderValue::from_static("*"));
return response;
}
}
next.run(req).await
}
pub async fn run_server(
db: DB,
rsmq: Option<rsmq_async::MultiplexedRsmq>,
@@ -130,7 +153,7 @@ pub async fn run_server(
let r =
rsmq_async::RsmqConnection::create_queue(&mut rsmq, &tag, None, None, None).await;
if let Err(e) = r {
tracing::info!("Redis queue {tag} could not be created: {e}");
tracing::info!("Redis queue {tag} could not be created: {e:#}");
} else {
tracing::info!("Redis queue {tag} created");
}
@@ -197,7 +220,10 @@ pub async fn run_server(
.nest("/apps", apps::workspaced_service())
.nest("/audit", audit::workspaced_service())
.nest("/capture", capture::workspaced_service())
.nest("/concurrency_groups", concurrency_groups::workspaced_service())
.nest(
"/concurrency_groups",
concurrency_groups::workspaced_service(),
)
.nest("/embeddings", embeddings::workspaced_service())
.nest("/drafts", drafts::workspaced_service())
.nest("/favorites", favorite::workspaced_service())

Some files were not shown because too many files have changed in this diff Show More