Compare commits

...

611 Commits

Author SHA1 Message Date
Loïc Mathieu
04ba7363c2 fix(ci): workflow build artifact doesn't need the plugin version 2025-07-31 14:32:57 +02:00
Loïc Mathieu
281a987944 chore(version): upgrade version to 0.24.0-rc1-SNAPSHOT 2025-07-31 14:20:07 +02:00
github-actions[bot]
c9ce54b0be chore(core): localize to languages other than english (#10494)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 14:19:14 +02:00
github-actions[bot]
ccd9baef3c chore(core): localize to languages other than english (#10489)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 14:19:04 +02:00
Barthélémy Ledoux
97869b9c75 fix(flows): forget all old taskRunId when a new execution (#10487) 2025-07-31 14:17:14 +02:00
Barthélémy Ledoux
1c681c1492 fix(flows): wait longer for widgets to be rendered (#10485) 2025-07-31 14:17:06 +02:00
Barthélémy Ledoux
de2a446f93 fix(flows): load flows documentation when coming back to no-code root (#10374) 2025-07-31 14:17:00 +02:00
Barthélémy Ledoux
d778947017 fix(flows): add the load errors to the flow errors (#10483) 2025-07-31 14:16:47 +02:00
Barthélémy Ledoux
3f97845fdd fix(flows): hide executionkind meta in the logs (#10482) 2025-07-31 14:16:41 +02:00
Barthélémy Ledoux
631cd169a1 fix(executions): do not rely on monaco to get value (#10467) 2025-07-31 14:16:33 +02:00
Barthélémy Ledoux
1648fa076c fix(flows): playground - implement new designs (#10459)
Co-authored-by: brian.mulier <bmmulier@hotmail.fr>
2025-07-31 14:16:26 +02:00
Barthélémy Ledoux
474806882e fix(flows): playground align restart button button (#10415) 2025-07-31 14:16:17 +02:00
Barthélémy Ledoux
65467bd118 fix(flows): playground clear current execution when clearExecutions() (#10414) 2025-07-31 14:16:04 +02:00
YannC
387bbb80ac feat(ui): added http method autocompletion (#10492) 2025-07-31 13:29:22 +02:00
Loïc Mathieu
19d4c64f19 fix(executions): Don't create outputs from the Subflow task when we didn't wait
As, well, if we didn't wait for the subflow execution, we cannot have access to its outputs.
2025-07-31 13:07:26 +02:00
Loïc Mathieu
809c0a228c feat(system): improve performance of computeSchedulable
- Store flowIds in a list to avoid computing the multiple times
- Storeg triggers by ID in a map to avoid iterating the list of triggers for each flow
2025-07-31 12:34:30 +02:00
Piyush Bhaskar
6a045900fb fix(core): remove top spacing from no execution page and removing the redundant code (#10445)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-31 13:28:08 +05:30
Piyush Bhaskar
4ada5fe8f3 fix(executions): make columns that are not links normal text (#10460)
* fix(executions): make it normal text

* fix(executions): use monospace font only
2025-07-31 13:27:45 +05:30
github-actions[bot]
998087ca30 chore(core): localize to languages other than english (#10471)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 08:25:16 +02:00
Malaydewangan09
146338e48f feat(plugins): add script plugins 2025-07-30 23:34:55 +05:30
brian.mulier
de177b925e chore(deps): hardcode vue override version 2025-07-30 19:26:31 +02:00
brian.mulier
04bfb19095 fix(core): avoid follow execution from being discarded too early
closes #10472
closes #7623
2025-07-30 19:26:31 +02:00
brian-mulier-p
c913c48785 fix(core): redesign playground run task button (#10423)
closes #10389
2025-07-30 15:27:49 +02:00
François Delbrayelle
0d5b593d42 fix(): fix icons 2025-07-30 14:55:33 +02:00
weibo1
83f92535c5 feat: Trigger Initialization Method Performance Optimization 2025-07-30 14:54:08 +02:00
Loïc Mathieu
fd6a0a6c11 fix(ci): bad SNAPSHOT repo URL 2025-07-30 12:57:28 +02:00
Loïc Mathieu
104c4c97b4 fix(ci): don't publish docker in build-artifact 2025-07-30 12:05:30 +02:00
Loïc Mathieu
21cd21269f fix(ci): add missing build artifact job 2025-07-30 11:50:26 +02:00
Loïc Mathieu
679befa2fe build(ci): allow downloading the exe from the workflow and not the release
This would allow running the workflow even if the release step fail
2025-07-30 11:24:21 +02:00
YannC
8a0ecdeb8a fix(dashboard): pageSize & pageNumber is now correctly pass when fetching a chart (#10413) 2025-07-30 08:45:51 +02:00
YannC.
ee8762e138 fix(ci): correctly pass GH token to release workflow 2025-07-29 15:04:18 +02:00
github-actions[bot]
d16324f265 chore(version): update to version 'v0.24.0-rc0-SNAPSHOT'. 2025-07-29 12:14:49 +00:00
François Delbrayelle
a518fefecd feat(plugins): add plugin-deepseek 2025-07-29 13:58:11 +02:00
Barthélémy Ledoux
1d3210fd7d fix(flows): remove text from warning button (#10370) 2025-07-29 11:27:37 +02:00
brian-mulier-p
597f84ecb7 fix(core): topology was no longer working on new flows (#10411)
closes #10354
2025-07-29 11:19:05 +02:00
Barthélémy Ledoux
5f3c7ac9f0 fix(core): allow icons api call to take longer than local call (#10412) 2025-07-29 11:13:12 +02:00
Nicolas K.
77c4691b04 fix(tests): rework basic auth service test (#10409)
* fix(tests): rework basic auth service test

* fix(tests): clean basic auth service test

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-29 10:59:43 +02:00
github-actions[bot]
6d34416529 chore(core): localize to languages other than english (#10410)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-29 13:55:25 +05:30
Piyush Bhaskar
40a67d5dcd feat(flows): add webhook curl and json field (#10392) 2025-07-29 13:48:28 +05:30
Loïc Mathieu
2c68c704f6 fix(test): flaky test JdbcQueueTest.withGroupAndType() 2025-07-29 09:35:28 +02:00
Miloš Paunović
e59d9f622c chore(namespaces): properly handle file name field on flow run dialog if set from defaults (#10390)
Closes https://github.com/kestra-io/kestra/issues/10365.
2025-07-29 08:29:08 +02:00
Piyush Bhaskar
c951ba39a7 fix(core): make validation less aggressive (#10406) 2025-07-29 11:41:38 +05:30
github-actions[bot]
a0200cfacb chore(core): localize to languages other than english (#10405)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-28 20:50:23 +02:00
dependabot[bot]
c6310f0697 build(deps): bump com.github.ben-manes.caffeine:caffeine
Bumps [com.github.ben-manes.caffeine:caffeine](https://github.com/ben-manes/caffeine) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.2.1...v3.2.2)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-version: 3.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 17:28:31 +02:00
dependabot[bot]
21ba59a525 build(deps): bump org.postgresql:postgresql in the gradle group
Bumps the gradle group with 1 update: [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc).


Updates `org.postgresql:postgresql` from 42.7.6 to 42.7.7
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.7.6...REL42.7.7)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-version: 42.7.7
  dependency-type: direct:production
  dependency-group: gradle
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 17:26:23 +02:00
Barthélémy Ledoux
4f9e3cd06c fix(flows): bring back alignment on overview (#10369) 2025-07-28 17:22:55 +02:00
Barthélémy Ledoux
e74010d1a4 fix(flows): playground - use all tasks as breakpoints (#10399) 2025-07-28 17:22:23 +02:00
Barthélémy Ledoux
465e6467e9 chore: update ui-libs (#10391) 2025-07-28 17:12:56 +02:00
YannC
c68c1b16d9 fix: set postgres and mysql queue offset as a bigint (#10344) 2025-07-28 16:28:09 +02:00
YannC
468c32156e chore: enforce micronaut open api version until Micronaut Platform works (#10393) 2025-07-28 16:27:59 +02:00
Loïc Mathieu
6e0a1c61ef fix(tests): increase the sleep inside ExecutionControllerRunnerTest.triggerExecutionAndFollowDependencies()
I'm not happy with that but I ran 3x 100 repetitions and all passed
2025-07-28 16:23:40 +02:00
Loïc Mathieu
552d55ef6b fix(test): RestactCaseTest.restartFailedWithFinally() should use executionService.isTerminated() 2025-07-28 16:23:40 +02:00
skayliu
08b0b682bf refactor(pebble): add more timestamp data time format 2025-07-28 16:17:55 +02:00
ben8t
cff90c93bb feat(plugin): add Notion plugin (#10049) 2025-07-28 16:09:01 +02:00
Roman Acevedo
ea465056d0 fix(triggers): bulk action on triggers did not take into account this is async (#10307) 2025-07-28 15:21:03 +02:00
Piyush Bhaskar
02f150f0b0 fix(core): animation on ai agent button (#10379)
* fix(core): animation on ai agent button

* reafctor(ai): add AITriggerButton component.
2025-07-28 18:48:34 +05:30
Loïc Mathieu
95d95d3d3c fix(tests): fix assertions in DateFilterTest.now() 2025-07-28 14:51:41 +02:00
Nicolas K.
6b8d3d6928 fix(tests): flaky test with wire mock not staring fast enough (#10383)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-28 14:07:48 +02:00
Piyush Bhaskar
1e347073ca fix(plugins): go to list of plugins from sidebar (#10385)
* fix(plugins): go to list of plugins from sidebar

* fix: update route to use path.
2025-07-28 17:24:09 +05:30
Loïc Mathieu
ac09dcecd9 fix(flows): wrong warning in FILE input
As we deprecate the `extension` property but still have a default for it, the warning is always disaply.
Removing the default and applying only when needed fixes the issue.

Fixes #10361
2025-07-28 13:40:11 +02:00
Miloš Paunović
40b337cd22 fix(namespaces): make sure the namespace parameter is properly passed when reading a file (#10384)
Relates to https://github.com/kestra-io/kestra/issues/10363.
Relates to https://github.com/kestra-io/kestra-ee/issues/4514.
2025-07-28 12:35:44 +02:00
Karthik D
5377d16036 chore(plugins): simplify the plugins search field (#10373)
Closes https://github.com/kestra-io/kestra/issues/10300.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-28 12:15:08 +02:00
Barthélémy Ledoux
f717bc413f tests: update frontend-tests (#10380) 2025-07-28 12:02:32 +02:00
Loïc Mathieu
d6bed2d235 fix(flows): file watching flow should delete the flow when the file is deleted while reading for update
When you use flow watching, a file can be updated then deleted, if it occurs quickly you could have a modified event, read the file then have a file not found exception as it has been deleted.
We should delete the flow in this case.

This has been detected because the related tests are flaky, doing that reduce falkiness of the related tests
2025-07-28 12:00:30 +02:00
Loïc Mathieu
07fd74b238 fix(test): flaky ExecutionControllerRunnerTest.triggerExecutionAndFollowDependencies() 2025-07-28 11:50:57 +02:00
Loïc Mathieu
60eef29de2 fix(tests): await for terminated execution instead of sleep in ExecutionControllerRunnerTest.killByIdShouldFailed() 2025-07-28 11:50:57 +02:00
Loïc Mathieu
20ca7b6380 fix(tests): increase wait time to 10 in LogConsumerTests.logs()
This  should reduce flakiness
2025-07-28 11:50:57 +02:00
Piyush Bhaskar
9d82df61c6 Revert "fix(core): fixes cumbersome operator selection (#10322)" (#10377)
This reverts commit e78210b5eb.
2025-07-28 14:52:58 +05:30
Piyush Bhaskar
e78210b5eb fix(core): fixes cumbersome operator selection (#10322) 2025-07-28 14:29:42 +05:30
Miloš Paunović
83143fae83 fix(executions): add default icons to execution dependency view (#10375)
Closes https://github.com/kestra-io/kestra/issues/10327.
2025-07-28 10:58:12 +02:00
Malay Dewangan
25f5ccc6b5 fix(runner): support floating-point CPU values in Docker runner (#10366) 2025-07-28 14:21:23 +05:30
Piyush Bhaskar
cf3e49a284 fix(core): give height to tooltip and use ks tokens (#10372) 2025-07-28 13:49:42 +05:30
JAGADEESH E
9a72d378df chore(core): amend missing property causing console warning in the settings page (#9788)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-28 09:49:14 +02:00
Loïc Mathieu
752a927fac feat(logs): allow LogShipper to filters on flowId and executionId
Closes https://github.com/kestra-io/kestra-ee/issues/4468
2025-07-28 09:40:36 +02:00
yuri
4053392921 fix(core): amend misc label-related issues (#10044)
* fix(core): amend misc label-related issues

* re-enabled bulk update of label value
* re-enabled merging flow-execution labels by key
* made duplicated keys rejection readable
* forced multiple validations within `RequestUtils`
* ensured existing labels can be overriden
* added multiple tests validating complex scenarios

BREAKING CHANGE: switched from first to last label value override
BREAKING CHANGE: preventing empty key/value labels
BREAKING CHANGE: preventing whitespace in key

* fix(core): reflect feedback

* Deduplicated a list inside the `Labels` task.
* Worked around label mutation at `Worker`.
* Attempted to deduplicate labels within `Execution` as possible.

* fix(core): remove irrelevant changes
2025-07-28 09:38:38 +02:00
Barthélémy Ledoux
8b0483643a feat(flows): code editor can launch playground (#10359) 2025-07-28 09:15:39 +02:00
Piyush Bhaskar
5feeb41c7a fix(core): update state count emission and filter table executions. (#10367) 2025-07-28 12:42:20 +05:30
github-actions[bot]
d7f5e5c05d chore(core): localize to languages other than english (#10368)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-28 09:09:32 +02:00
Aditya
4840f723fc chore(core): properly handle environment name set either via config and through the settings page (#10151)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-28 09:06:34 +02:00
Devesh Kumar
8cf159b281 fix(namespaces): prevent namespace folder highlighting when containing file is selected (#10364)
Closes https://github.com/kestra-io/kestra/issues/10360.
2025-07-28 08:47:25 +02:00
Loïc Mathieu
4c79576113 fix(tests): improve JdbcQueueTest flaky tests 2025-07-25 12:50:27 +02:00
Florian Hussonnois
f87f2ed753 fix(system): avoid potential NPE in ServiceLivenessManager (#10338)
Avoid a potential NPE in ServiceLivenessManager when
a local service is unregistered during shutdown before the liveness probe completes

Fix: #10338
2025-07-25 12:33:18 +02:00
Florian Hussonnois
298a6c7ca8 fix(system): ignore state transition failure for indexer
Fix: kestra-io/kestra-ee#4474
2025-07-25 11:35:09 +02:00
Loïc Mathieu
ab464fff6e fix(executions): flow concurrency limit not honors when executions are created at a high rate
This is due to the fact that we now process the execution queue concurrently so there is a race when counting currently running executions. This can be seen easily using a ForEachItem as it could create tens or hundreds of executions almost instantly leading to almost all those executions started as they would all see 0 executions running...

Using a dedicated execution running queue, as done in EE, would serialize the messages and fix the issue.

However, if using multiple executor instances and concurrency limit = 1, there is a theoretical race as no locks will be done if no execution is running. A max surge of executions could be as high as the number of executor but this race is less probable to happen in real world scenario.

Fixes #10167
2025-07-25 11:35:00 +02:00
Florian Hussonnois
6dcba16314 chore(core): clean QueryFilter class 2025-07-25 11:34:09 +02:00
Barthélémy Ledoux
80a328e87e fix(flows): better loading pattern (#10345) 2025-07-25 10:14:07 +02:00
Loïc Mathieu
f2034f4975 fix(executions): race condition inside nested ForEach with concurrency
Fixes #10167
2025-07-25 09:45:29 +02:00
github-actions[bot]
edca56d168 chore(core): localize to languages other than english (#10341)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-24 23:21:03 +02:00
Roman Acevedo
076434cc7c chore: remove frontend codecov in CI 2025-07-24 18:44:44 +02:00
Barthélémy Ledoux
69d2b97416 feat(flows): playground (#10042)
Co-authored-by: Loïc Mathieu <loikeseke@gmail.com>
2025-07-24 18:00:13 +02:00
Roman Acevedo
a7b07e5556 chore: update utility scripts still referencing old maven repo 2025-07-24 16:16:41 +02:00
Barthélémy Ledoux
ee6a2ae9a3 fix(flows): parse JSON when switching from string to object (#10255) 2025-07-24 15:48:52 +02:00
Florian Hussonnois
e36925c879 fix(system): fix and cleanup StorageInterface (kestra-io/kestra-ee#4488)
Allow tenantId to be null in storage for cluster-wide
operations on object storage

Related-to: kestra-io/kestra-ee#4488
2025-07-24 15:40:00 +02:00
Piyush Bhaskar
df63fc56fc fix(ai): shortcut to submit and for newline (#10325) 2025-07-24 19:01:18 +05:30
Loïc Mathieu
eb22d3f6ee feat(logs): allow purging log by execution ID
Part-of: https://github.com/kestra-io/kestra-ee/issues/4468
2025-07-24 15:12:27 +02:00
Roman Acevedo
150145692f fix(cli): tenantService was injected directly, this is not working in cli 2025-07-24 13:56:04 +02:00
Roman Acevedo
a900d8f5bb fix(cli): when picoli was throwing InitializationException the java process was not stopped 2025-07-24 13:56:04 +02:00
Loïc Mathieu
3e70aacb9c fix(executions): breakpoint on ForEach
We should be able to put a breakpoint without value, easier for the playground
2025-07-24 13:46:51 +02:00
Piyush Bhaskar
31658a1862 fix(core): prevent default if suggestion is active (#10320) 2025-07-24 16:18:25 +05:30
Miloš Paunović
694ee7ed86 chore(deps): regular dependency update (#10314)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-07-24 12:09:22 +02:00
Piyush Bhaskar
83fb225577 fix(executions): update query parameter for state filtering (#10315) 2025-07-24 14:40:24 +05:30
Miloš Paunović
1d89f53526 chore(flows): show small execution charts on flow listing (#10054)
Co-authored-by: YannC. <ycoornaert@kestra.io>
2025-07-24 10:18:27 +02:00
Roman Acevedo
6d72804a54 fix(filters): left menu current page disabling was not working
- fixes https://github.com/kestra-io/kestra/issues/9476
2025-07-24 10:01:52 +02:00
Piyush Bhaskar
26bd7dab97 fix(core): check null uri (#10309) 2025-07-24 12:46:15 +05:30
dependabot[bot]
1925d7832c build(deps): bump axios in /ui in the npm_and_yarn group (#10305)
Bumps the npm_and_yarn group in /ui with 1 update: [axios](https://github.com/axios/axios).


Updates `axios` from 1.10.0 to 1.11.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.10.0...v1.11.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.11.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 08:42:03 +02:00
Piyush Bhaskar
379649785d fix(secrets): show namespace column (#10222)
* fix(secrets): show namespace column

* fix(secrets): update condition
2025-07-24 11:02:41 +05:30
Roman Acevedo
302ec94bee feat(tests): testsuite run persistence 2025-07-23 20:16:03 +02:00
Malaydewangan09
02f97dfd88 feat(*): add new plugins 2025-07-23 19:52:51 +05:30
dependabot[bot]
ac9f44b766 build(deps): bump flyingSaucerVersion from 9.13.0 to 9.13.1
---
updated-dependencies:
- dependency-name: org.xhtmlrenderer:flying-saucer-core
  dependency-version: 9.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.xhtmlrenderer:flying-saucer-pdf
  dependency-version: 9.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 16:18:32 +02:00
dependabot[bot]
c287304264 build(deps): bump com.google.cloud:libraries-bom from 26.63.0 to 26.64.0
---
updated-dependencies:
- dependency-name: com.google.cloud:libraries-bom
  dependency-version: 26.64.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 16:17:37 +02:00
Loïc Mathieu
6510cdfbdc fix(core): revert unwanted changes
These changes should not have been added to https://github.com/kestra-io/kestra/pull/10230.

They have not been properly tested even if they seem to be meaningful
2025-07-23 16:16:39 +02:00
dependabot[bot]
298e9f3ab7 build(deps): bump com.microsoft.playwright:playwright
---
updated-dependencies:
- dependency-name: com.microsoft.playwright:playwright
  dependency-version: 1.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 15:37:11 +02:00
Nicolas K.
45291eb2c4 fix(cli): #10062 add tenant to load flows properly at the startup (#10290)
* fix(cli): #10062 add tenant to load flows properly at the startup

* fix(cli): #10062 add fallback tenant to ee service

* fix(cli): #10062 use tenant id in all cli

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-23 15:36:10 +02:00
dependabot[bot]
ebd47b31b1 build(deps): bump software.amazon.awssdk:bom from 2.32.1 to 2.32.6
Bumps software.amazon.awssdk:bom from 2.32.1 to 2.32.6.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.32.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 15:35:36 +02:00
dependabot[bot]
48a3a3cbbf build(deps): bump jacksonVersion from 2.19.1 to 2.19.2
Bumps `jacksonVersion` from 2.19.1 to 2.19.2.

Updates `com.fasterxml.jackson:jackson-bom` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.19.1...jackson-bom-2.19.2)

Updates `com.fasterxml.jackson.core:jackson-core` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.19.1...jackson-core-2.19.2)

Updates `com.fasterxml.jackson.core:jackson-databind` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.core:jackson-annotations` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.module:jackson-module-parameter-names` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-modules-java8/compare/jackson-modules-java8-2.19.1...jackson-modules-java8-2.19.2)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.19.1...jackson-dataformats-text-2.19.2)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-smile` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-dataformats-binary/compare/jackson-dataformats-binary-2.19.1...jackson-dataformats-binary-2.19.2)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-cbor` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-dataformats-binary/compare/jackson-dataformats-binary-2.19.1...jackson-dataformats-binary-2.19.2)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-ion` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-dataformat-ion/commits)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-xml` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-dataformat-xml/compare/jackson-dataformat-xml-2.19.1...jackson-dataformat-xml-2.19.2)

Updates `com.fasterxml.jackson.datatype:jackson-datatype-guava` from 2.19.1 to 2.19.2
- [Commits](https://github.com/FasterXML/jackson-datatypes-collections/compare/jackson-datatypes-collections-2.19.1...jackson-datatypes-collections-2.19.2)

Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.19.1 to 2.19.2

Updates `com.fasterxml.jackson.datatype:jackson-datatype-jdk8` from 2.19.1 to 2.19.2

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-core
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-annotations
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.module:jackson-module-parameter-names
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-smile
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-cbor
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-ion
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-xml
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-guava
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jdk8
  dependency-version: 2.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 15:34:08 +02:00
dependabot[bot]
fc7b7738bd build(deps): bump com.mysql:mysql-connector-j from 8.0.33 to 9.3.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.0.33 to 9.3.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/9.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.33...9.3.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 15:33:48 +02:00
dependabot[bot]
06ffa6602b build(deps): bump commons-io:commons-io from 2.19.0 to 2.20.0
---
updated-dependencies:
- dependency-name: commons-io:commons-io
  dependency-version: 2.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 15:33:10 +02:00
Piyush Bhaskar
1336cca81a refactor(template): migrate template module to pinia (#10226) 2025-07-23 18:33:38 +05:30
Loïc Mathieu
f0ab8a3067 fix(system)*: don't mix constructor injection with field injection
Field injection are resolved after constructor injection so setting threadCount was never used.
2025-07-23 13:31:06 +02:00
github-actions[bot]
3cfd5ebe4d chore(core): localize to languages other than english (#10291)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-23 16:39:21 +05:30
Piyush Bhaskar
f97ad45cef feat(execution): "Debug Expression" for Trigger Variables (#10242)
* feat(execution): "Debug Expression" for Trigger Variables

* fix(ui): improve layout and text.

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-23 16:00:33 +05:30
Piyush Bhaskar
2a9a0c7484 fix(executions): fixes file preview (#10252)
* fix(executions): fixes file preview

* fix: remove stored file preview

---------

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-23 15:49:17 +05:30
Piyush Bhaskar
9eeffa089c chore(version): bump ui-libs to version 0.0.222 (#10285) 2025-07-23 12:46:03 +05:30
YannC
19df58c6da feat: hide community button on EE edition (#10251) 2025-07-23 08:57:19 +02:00
Piyush Bhaskar
d190522bfd fix(executions): fixes execution selection action button (#10257) 2025-07-23 12:00:17 +05:30
Loïc Mathieu
cbd48b0075 chore(plugins): rename Langchain4j plugin to AI 2025-07-22 16:07:27 +02:00
YannC
ea1603f051 feat(pebble): create a in expression to look for a string in a list (#9817)
* feat(pebble): create a in expression to look for a string in a list

close #9813
2025-07-22 15:43:25 +02:00
YannC
d24f6059d9 chore(test): Improved TestsUtils and added more tests for coverage in… (#9776)
* chore(test): Improved TestsUtils and added more tests for coverage in ExecutionControllerRunnerTest

* fix: revert testUtils + reduce sleep time

* fix: replace 2s sleep to 250ms
2025-07-22 15:08:49 +02:00
YannC.
12c8db40ae feat: action to check if tag is latest in github release 2025-07-22 14:45:38 +02:00
Piyush Bhaskar
3660e1a990 fix(logs): update query filter to show logs ns and flowwise (#10248) 2025-07-22 17:54:20 +05:30
Miloš Paunović
ca96c7b5dc fix(namespaces)*: prevent overwriting namespace file content with undefined string (#10247) 2025-07-22 14:23:44 +02:00
bishalbera
d9bdcc5b20 feat(cli): added skip-deprecated flag in plugindoc command 2025-07-22 13:38:48 +02:00
Piyush Bhaskar
c31fae4cc9 fix(triggers): ensure clearing the selection. (#10245) 2025-07-22 15:58:49 +05:30
Miloš Paunović
87480d81b8 chore(core): add missing translation key/value pairs (#10243) 2025-07-22 11:44:53 +02:00
Nicolas K.
251a821322 fix(repositories): make filter service protected (#10241)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-22 11:36:57 +02:00
dependabot[bot]
3d0b2b7f01 build(deps): bump the npm_and_yarn group in /ui with 3 updates (#10236)
---
updated-dependencies:
- dependency-name: vue-i18n
  dependency-version: 11.1.10
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@intlify/core-base"
  dependency-version: 11.1.10
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 10:37:07 +02:00
Miloš Paunović
0811258d2e fix(executions): make sure outputs do not overflow over right drawer (#10238)
Closes https://github.com/kestra-io/kestra/issues/10232.
2025-07-22 10:12:02 +02:00
Loïc Mathieu
aecd4cc5dd fix(tests): strengthen awaitExecution predicate
In some test situation, awaitExecution may receive old messages so we strenghten the predicate to be sure to wait for the correct execution: the one that ends successfully
2025-07-22 10:08:00 +02:00
YannC.
b1d41f6f47 fix: handle label filter with and instead or for flow
close #4390
2025-07-22 09:42:45 +02:00
Piyush Bhaskar
a9d215996b fix(core): do not show release notes button for ee specific plugins (#10235)
* fix(core): do not show button for ee specific plugins

* fix(core): refactor for improved readability
2025-07-22 12:16:49 +05:30
Emil Shakirov
812c8b5718 feat(core): add a Pebble function to generate KSUID 2025-07-21 18:17:58 +02:00
Nicolas K.
bc3d534ba6 fix(pebble): #8953 add more flexible day number conversion method (#10205)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-21 15:25:09 +02:00
Roman Acevedo
ef4f1bdd1f fix(flows): remove flows date filters UI, they do not exist
- fixes https://github.com/kestra-io/kestra/issues/10201
2025-07-21 12:46:35 +02:00
Loïc Mathieu
6bc1e3ec4d fix(executions)*: restart with finally or afterExecution
When a flow fail and is restarted and contains either a finally or an afterExecution block, those are not resetted so the restart will skip all task and terminate the flow.
The fix will reset the status of those tasks so they are restarted.

Fixes #10155
2025-07-21 12:21:25 +02:00
skayliu
80d394fd6a fix(pebble): fix typo 2025-07-21 12:17:18 +02:00
skayliu
30c4f11b8a fix(pebble): fix typo 2025-07-21 12:17:18 +02:00
skayliu
7bd21887d1 feat(pebble): add millisecond date time format 2025-07-21 12:17:18 +02:00
Roman Acevedo
770438eb66 feat(tests): use Flow YAML autocompletion
- fixes https://github.com/kestra-io/kestra-ee/issues/3900
2025-07-21 11:50:42 +02:00
github-actions[bot]
a8838102ec chore(core): localize to languages other than english (#10221)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-21 11:15:10 +02:00
Piyush Bhaskar
19161cc078 feat(core): update titles , add button slot for license (#10218) 2025-07-21 13:31:45 +05:30
Piyush Bhaskar
6c48571101 feat(core): implement backend validation for login for configs and also fixes PH event (#10196)
* feat(core): implement backend validation for login for configs

* fix(auth): simplify authentication check  and api route

* fix: access auth properly

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>

* fix(ui): improve  auth validation handling and routing

* fix(core): fixes PH event  and initialization for setup process.

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-07-21 13:21:17 +05:30
Loïc Mathieu
c09dafca01 fix(executions): support unicode file name inside the internal storage
Fixes #9550
2025-07-21 09:51:07 +02:00
yuri1969
3a3dadd8e9 fix(tests): timezone issue
Test failed at certain moments when runnin in a non-`Europe/Lisbon` TZ.
2025-07-21 09:03:21 +02:00
skayliu
68c1abb6f2 chore(deps): relocate mysql driver 2025-07-18 12:29:43 +02:00
skayliu
cfea378104 refactor(pebble): Stronger the uuid function from v4 to v7 2025-07-18 12:29:43 +02:00
Barthélémy Ledoux
d1badab05b fix(core): check if logged in before requesting usages (#10194)
* fix(core): check if logged in before requesting usages

* fix: avoid calls to get resources when auth not initialized yet
2025-07-18 15:37:49 +05:30
Nicolas K.
581442c427 feat(security) #10180 open basic auth validation endpoint (#10190)
* feat(security) #10180 open basic auth validation endpoint

* feat(security) #10180 add unit test

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-18 11:23:30 +02:00
MilosPaunovic
02430a00b5 feat: introduce ui changes for keeping filename on file input 2025-07-18 11:16:25 +02:00
Loïc Mathieu
f7c5fd3984 feat(executions): use the uploaded file name for inputs of type FILE
Use the part name for the input ID, this is a BC.
Use the filename attribute of the part for creating the file inside the internal storage.
Detect previous usage of part name and filename and emit a deprecation warning.
2025-07-18 11:16:25 +02:00
Piyush Bhaskar
3f4b39ec4f feat(core): add troubleshooting button and doc (#10191)
* feat(core): add troubleshooting button and doc

* fix: add ?

* fix: type warn

* chore(core): localize to languages other than english (#10193)

Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <actions@github.com>
2025-07-18 14:42:28 +05:30
Piyush Bhaskar
ddfe637828 fix(core): adjust word wrap and prevent newlines in input (#10176)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-18 13:58:16 +05:30
Piyush Bhaskar
e09a89ac03 fix(core): update text from user to account. (#10187)
* fix(core): update text from user to account.

* chore(core): localize to languages other than english (#10188)

Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-18 13:47:37 +05:30
github-actions[bot]
bbb5c2a6e0 chore(core): localize to languages other than english (#10189)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-18 10:07:50 +02:00
Piyush Bhaskar
bbf22d8813 fix(ai): show prompt window only if ai is enabled in configs (#10172) 2025-07-18 13:19:47 +05:30
Piyush Bhaskar
243522372d refactor(ai): migrate ai store from Vuex to Pinia (#10174) 2025-07-18 13:14:15 +05:30
Roman Acevedo
2a24e29bd9 feat(filters): prevent saving a search with duplicated label
- fixes https://github.com/kestra-io/kestra/issues/9026
2025-07-18 09:19:55 +02:00
Miloš Paunović
d7d52cba5a chore(core): move expand all buttons to the left side (#10186)
Closes https://github.com/kestra-io/kestra-ee/issues/4394.
2025-07-18 08:46:44 +02:00
MilosPaunovic
8319ad7439 feat(executions): work on the ui for execution dependencies 2025-07-17 17:45:15 +02:00
Loïc Mathieu
4996ccdefd feat(system): add a between-items timeout on all our SSE connections
This avoid potential connection leak by closing them if nothing happen inside it.
These is very unlickly to happen but as some follow endpoint may have races, for ex an execution ends between the time we fetch it and start listening to its event, this is better to add this as a safety net.
2025-07-17 17:45:15 +02:00
Loïc Mathieu
66889a3d92 feat(executions): execution dependencies
Part-of: https://github.com/kestra-io/kestra-ee/issues/4230
2025-07-17 17:45:15 +02:00
Loïc Mathieu
fc0b52dbd0 feat(executions): add execution outputs inside the expression context
Closes https://github.com/kestra-io/kestra-ee/issues/3999
2025-07-17 17:44:55 +02:00
Piyush Bhaskar
c7b9e1846e fix(core): improve handling of setup completion and display values (#10141) 2025-07-17 16:30:39 +02:00
Nicolas K.
fe485243f7 fix(security) #10133 add password validation and save error in database for the front to use (#10177)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-17 16:29:57 +02:00
Anna Geller
8637bb847f fix(docker-compose): add info about password policy to docker compose example 2025-07-17 16:12:08 +02:00
Nicolas K.
c8d89dbdd4 fix(security) #10133 server error when no basic auth configuration persisted (#10175)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-17 15:28:15 +02:00
Miloš Paunović
71e3b19f02 chore(core): add back the missing translation keys (#10170) 2025-07-17 13:04:33 +02:00
Miloš Paunović
5457c216c8 chore(core): remove non-matching translation keys (#10169) 2025-07-17 13:01:10 +02:00
github-actions[bot]
aa2d88fcbb chore(core): localize to languages other than english (#10160)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-17 12:31:16 +02:00
Piyush Bhaskar
393faed512 fix(plugins): adjust font sizes for collapsible body (#10164) 2025-07-17 15:29:20 +05:30
Barthélémy Ledoux
0e8e65af7c feat(flows): add setting to disable hovers in editor (#10159) 2025-07-17 10:54:04 +02:00
Piyush Bhaskar
133151377f fix(triggers): only updates the trigger that matches both flow and trigger Id (#10158) 2025-07-17 14:19:21 +05:30
Loïc Mathieu
fa2bf8fc5c feat(execution): allow to wait for execution completion into a Webhook
Closes #10147
2025-07-17 10:47:53 +02:00
Piyush Bhaskar
614c7b2226 fix(core): fixes some design tweaks for Ai Agent (#9875)
* fix(core): fixes some design tweaks for Ai Agent

* minor tweaks

* fix: show prompt only  when AI is enabled.

* fix: dark button

* remove

* fix(core): repair GlobalSearch

* fix(ai): swap shortcut to CTRL + ALT + SHIFT + K to avoid collisions

* fix: add key shortcuts in dropdown

* fix(ui): update AI width , toggle shortcut and editor top spacing

* fix: en.json

---------

Co-authored-by: brian.mulier <bmmulier@hotmail.fr>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-17 12:48:45 +05:30
Loïc Mathieu
05cb79f4b6 feat(executions): provide a task run caching mechanism
Closes https://github.com/kestra-io/kestra-ee/issues/3580
2025-07-17 09:16:55 +02:00
Nicolas K.
278dbd8b82 fix(security) #10133 ignore enable=true flag from basic auth config (#10148)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-16 17:28:48 +02:00
Loïc Mathieu
98d1ab57cc feat(execution): add execution ID to the latest execution
Needed for the new playground functionality.
2025-07-16 16:54:45 +02:00
Nicolas K.
f2fd9f398d fix(security) #10133 basic auth config always takes priority (#10145)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-16 15:27:34 +02:00
Piyush Bhaskar
b72381e2cb fix(ai): refine card styles; add button disabled state colors across UI. (#10142) 2025-07-16 18:40:20 +05:30
Piyush Bhaskar
14e853ce40 refactor(store): remove unused graph store module (#10144) 2025-07-16 18:39:21 +05:30
Loïc Mathieu
7ebf5989a5 feat(flows): add an API endpoint for listing flow properties
Closes #9524

The new endpoint allow for properties only JSON schema for all base types.
2025-07-16 14:36:19 +02:00
Barthélémy Ledoux
b70faea505 refactor: migrate executions store from vuex to pinia (#10093)
Co-authored-by: Piyush-r-bhaskar <impiyush0012@gmail.com>
2025-07-16 14:14:38 +02:00
dependabot[bot]
f54ed8a488 build(deps): bump io.micrometer:micrometer-core from 1.15.1 to 1.15.2
Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.15.1 to 1.15.2.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.15.1...v1.15.2)

---
updated-dependencies:
- dependency-name: io.micrometer:micrometer-core
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 12:48:13 +02:00
dependabot[bot]
6a796b0a25 build(deps): bump com.gorylenko.gradle-git-properties
Bumps com.gorylenko.gradle-git-properties from 2.5.0 to 2.5.2.

---
updated-dependencies:
- dependency-name: com.gorylenko.gradle-git-properties
  dependency-version: 2.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 12:14:00 +02:00
Loïc Mathieu
ec7e65d794 fix(system): possible NPE when computing flowable task outputs 2025-07-16 11:22:38 +02:00
Piyush Bhaskar
0c5e190350 fix(ui): reorder collapse items and refine connection properties to show only non required in collapsed (#9673) 2025-07-16 14:49:13 +05:30
Piyush Bhaskar
1014cdefeb refactor(service): migrate service.js to pinia (#9760)
* refactor(service): migrate service.js to pinia

* fix scope of i18n

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-07-16 14:48:51 +05:30
Loïc Mathieu
efdc29f30a feat(executions): add preview for local files and namespace fles
Closes #9740
2025-07-16 11:05:13 +02:00
dependabot[bot]
a44b7f78fb build(deps): bump org.opensearch.client:opensearch-java
---
updated-dependencies:
- dependency-name: org.opensearch.client:opensearch-java
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 10:57:57 +02:00
Bart Ledoux
90eb0ffa4f fix: basePath is now a function 2025-07-16 10:27:33 +02:00
dependabot[bot]
85b5002acf build(deps): bump org.apache.logging.log4j:log4j-to-slf4j
Bumps org.apache.logging.log4j:log4j-to-slf4j from 2.25.0 to 2.25.1.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-to-slf4j
  dependency-version: 2.25.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 09:54:02 +02:00
dependabot[bot]
4fd66d7781 build(deps): bump com.vanniktech.maven.publish from 0.33.0 to 0.34.0
Bumps [com.vanniktech.maven.publish](https://github.com/vanniktech/gradle-maven-publish-plugin) from 0.33.0 to 0.34.0.
- [Release notes](https://github.com/vanniktech/gradle-maven-publish-plugin/releases)
- [Changelog](https://github.com/vanniktech/gradle-maven-publish-plugin/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vanniktech/gradle-maven-publish-plugin/compare/0.33.0...0.34.0)

---
updated-dependencies:
- dependency-name: com.vanniktech.maven.publish
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 09:53:25 +02:00
dependabot[bot]
362858e4d7 build(deps): bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0
Bumps org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0.

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-lang3
  dependency-version: 3.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 09:52:56 +02:00
dependabot[bot]
06e4c9f110 build(deps): bump software.amazon.awssdk:bom from 2.31.77 to 2.32.1
Bumps software.amazon.awssdk:bom from 2.31.77 to 2.32.1.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.32.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 09:52:09 +02:00
dependabot[bot]
a71e46169f build(deps): bump software.amazon.awssdk.crt:aws-crt
---
updated-dependencies:
- dependency-name: software.amazon.awssdk.crt:aws-crt
  dependency-version: 0.38.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 09:51:23 +02:00
Barthélémy Ledoux
4e1c4b7708 fix: curl feature needs baseUrl as a function (#10092) 2025-07-15 18:43:12 +02:00
Barthélémy Ledoux
75f5348db1 fix(executions): restore taskruns store (#10090) 2025-07-15 15:37:34 +02:00
Piyush Bhaskar
5b5b616def fix(secrets): circle masked input to replace squarefont. (#10088) 2025-07-15 19:05:24 +05:30
Miloš Paunović
ec360bd658 fix(core): remove icons from no code input selector (#10080)
Closes https://github.com/kestra-io/kestra/issues/10075.

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-15 15:05:48 +02:00
Piyush Bhaskar
4f2a37c31f fix(core): fixes user with no rights is able to access the dashboard route (#9361)
* fix(core): allow custom logo slot in sidebar.

* fix: use boolean prop instead of slot
2025-07-15 18:11:35 +05:30
Barthélémy Ledoux
90d572ef33 fix(flow): autocomplete output values in pebble editor (#10083) 2025-07-15 14:25:56 +02:00
Biplab Bera
ceecab1811 chore(executions): improve the file input dialog (#9894)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-15 13:35:25 +02:00
Miloš Paunović
25592ec203 refactor(dashboards): minor improvements of dashboard components code (#10085) 2025-07-15 13:24:35 +02:00
github-actions[bot]
d935333c5b chore(core): localize to languages other than english (#10086)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-15 13:11:07 +02:00
Malay Dewangan
e2571ba523 feat(executions): Allow unqueuing to states other than RUNNING #5939 (#8381)
* feat(executions): added the ui part for being able to unqueue exeution to different state

---------

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-07-15 16:18:35 +05:30
Loïc Mathieu
94dc1cea25 feat(tenants): provide an endpoint that list all tenants dependencies
Part-of: https://github.com/kestra-io/kestra-ee/issues/3515
2025-07-15 12:39:17 +02:00
Piyush Bhaskar
87bb87bbbc fix(ai): update styling for Accept/Decline (#10082) 2025-07-15 16:04:30 +05:30
Miloš Paunović
47955fc3c3 fix(core): remove deprecated properties from no code task selector (#10079)
Closes https://github.com/kestra-io/kestra/issues/10077.
Closes https://github.com/kestra-io/kestra-ee/issues/4355.
2025-07-15 11:33:14 +02:00
Anusha G H
be23ac591c chore(executions): remove cancel button from resume dialog (#10051)
Co-authored-by: Anusha G H <anushah@sahaj.ai>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-15 10:56:36 +02:00
Miloš Paunović
578e34ee17 chore(deps): update the element-plus package and remove patch file for it (#10069) 2025-07-15 10:41:06 +02:00
skayliu
05959ee28c feat(pebble): add a timestampMilli pebble function (#10064)
* feat(pebble): add a timestampMilli pebble function

* feat(test): add a timestampMilli pebble function test

* fix(docs): fix typo

* feat(docs): add a timestampMilli pebble function docs

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-15 10:32:44 +02:00
Piyush Bhaskar
ae2ce394c9 fix(core): secrets as a tab. (#10072) 2025-07-15 13:30:44 +05:30
Miloš Paunović
a3fa2051ce fix(executions): add missing uuid property (#10078) 2025-07-15 08:50:46 +02:00
Anna Geller
6fb0858710 fix: basic auth commented out by default to load setup page first 2025-07-14 14:19:49 +02:00
Anna Geller
df94a248e2 fix(docker-compose): cut the removed enabled flag 2025-07-14 14:08:30 +02:00
Piyush Bhaskar
f826d9ac8e fix(ui): update label styles for better visual (#10070)
* fix(ui): update label styles for better visual

* fix: remove light color
2025-07-14 16:35:20 +05:30
Piyush Bhaskar
8d652d5185 fix(core): show plugin toc properly (#10068) 2025-07-14 12:13:01 +05:30
Piyush Bhaskar
c4680836a6 fix(ui): properly update theme switching (#10065) 2025-07-12 19:15:15 +05:30
brian-mulier-p
77f0f5bb87 fix(core): add an exception to avoid popping challenge in case of wrong credentials on login page (#10061) 2025-07-11 17:22:07 +02:00
brian-mulier-p
c68808582b fix(core): add proxy so that origin is the same as request url for workers (#10053) 2025-07-11 16:44:03 +02:00
brian-mulier-p
3a10a52320 feat(core): hide deprecated elements in doc, autocompletion (only types), nocode (#10020)
closes #7206
closes #8786
closes #9322
2025-07-11 16:41:45 +02:00
François Delbrayelle
0a6bfd1389 fix(gradle): be able to use publishToMavenLocal (#10047) 2025-07-11 16:20:20 +02:00
Piyush Bhaskar
b7201055a8 refactor(core): migrate misc store module to pinia (#10048) 2025-07-11 19:13:38 +05:30
Roman Acevedo
710f9a3373 test(e2e): include E2E tests in PR CI (#10036)
* test(e2e): include E2E tests in PR CI

* Update e2e.yml to fix report

* tests(e2e): video and trace on failure

* tests(e2e): unflaky assertion exec

* tests(e2e): slowMo 100ms
2025-07-11 14:31:10 +02:00
brian.mulier
0402362499 fix(core): strict samesite for basic auth cookie 2025-07-11 12:07:49 +02:00
brian-mulier-p
15d3caf62c fix(core): basic auth is now handled through cookies, header then challenge so that SSE sends it (#10043) 2025-07-11 10:56:12 +02:00
Loïc Mathieu
4dc1e52b08 chore(system): avoid calling allTaskWithChild when computing plugin defaults 2025-07-11 09:38:34 +02:00
Roman Acevedo
6f62988135 build: remove codecov for ui #10038
As discussed with Bart it is not helping us, it is often red and the conf is not right, and anyway he believes codecov on frontend is not easy and perfect

from Bart: Nuance: I believe that having code coverage on Frontend is a great tool to see where we should track more, but having it as a metric is very unproductive.

The only thing I care about being tested are:

if a component renders at all
what it looks like
... interactions
None of this is covered by code lines.

We could have a demand for 10% coverage of every patch and that's it.
2025-07-11 09:09:27 +02:00
Roman Acevedo
8080bbf964 test(storage): unflaky StorageTestSuite.filesByPrefix 2025-07-11 09:06:32 +02:00
Barthélémy Ledoux
565bee96c9 fix(core): login setup failures when baseUrl is empty (#10041)
Co-authored-by: Piyush-r-bhaskar <impiyush0012@gmail.com>
2025-07-10 16:29:45 +02:00
Piyush Bhaskar
44f93c0b13 fix(core): streamlining base URL creation (#10039)
* refactor(core): streamlining base URL creation

* fix: less changes

---------

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-10 19:50:04 +05:30
Loïc Mathieu
51f831586a chore(system): avoid calling TaskRun.toStringState() when not needed
This methods do a lot of potentialy big String concatenation so it's better to not call it unless necessary.
2025-07-10 16:06:39 +02:00
Loïc Mathieu
93b9932469 test(executions): improve reliability of the ExecutionControllerRunnerTest 2025-07-10 16:06:26 +02:00
Loïc Mathieu
d10b11ed1f fix(system): merge flowable outputs when terminated
A flowable may compute its outputs before it is terminated. In this case, they can be wiped out when we compute the outputs when terminated.
So we need to merge the maps.
2025-07-10 16:06:26 +02:00
Roman Acevedo
f57ab7a828 feat(tests): impl disabling testcase 2025-07-10 15:32:47 +02:00
Loïc Mathieu
b97f93f2f9 feat(system): use available processor count number of executor threads 2025-07-10 14:59:48 +02:00
Nicolas K.
8094756601 fix(security): use the login/pass of basicAuth for all api urls (#10027)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-10 13:51:27 +02:00
Loïc Mathieu
0de5236f8a fix(flows): possible NPE at flow validation 2025-07-10 12:40:45 +02:00
Piyush Bhaskar
1b7034d154 fix(ui): fixes color for icon and label in light theme (#10032) 2025-07-10 15:50:59 +05:30
Barthélémy Ledoux
732f1d95d7 fix: patch element plus for tabs (#10034) 2025-07-10 11:49:11 +02:00
Miloš Paunović
aa3b118cb5 feat(dashboards): implement the table data export functionality (#9911)
Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>
2025-07-10 10:13:25 +02:00
Piyush Bhaskar
2543ad7216 fix(triggers): disable backfill execution based on yaml definition (#10026) 2025-07-10 13:35:33 +05:30
Nicolas K.
98463335aa fix(security): remove the authorization header (#10025)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-10 09:49:07 +02:00
Nicolas K.
d46ebe2b4a fix(security): add back www-authenticate header (#10018)
* fix(security): add back www-authenticate header

* fix basic auth again

* fix: if setup is not done go to setup

* fix(security): don't persist basic auth config if already persisted

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-10 09:27:42 +02:00
Roman Acevedo
fb96fc2f05 chore(tests): add validation on assertions 2025-07-09 18:25:36 +02:00
Roman Acevedo
910bceb900 fix(webserver): server exceptions were not logged when no message
some libraries or even java code throw Exceptions with a 'null' message (but with a stacktrace), in this case our logger was not logging anything
2025-07-09 17:18:58 +02:00
Roman Acevedo
b6475d8552 feat(tests): allow disabling a TestSuite preventing it to run 2025-07-09 17:08:08 +02:00
brian-mulier-p
e136e1ca9a fix(core): trim expressions in select & multiselect to be able to use '|' instead of '>-' (#10017)
closes #10016
2025-07-09 16:36:24 +02:00
Piyush Bhaskar
0f6ae24b8e fix(ui): fixes basic auth handling (#10010)
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-07-09 15:18:39 +02:00
brian-mulier-p
cc7f1e25e3 feat(kv): add an optional description (#9886)
closes #9606
2025-07-09 15:08:12 +02:00
Miloš Paunović
63dbff1e7a chore(dashboards): improve chart data loading and uniform look on preview tab (#10014) 2025-07-09 14:53:23 +02:00
YannC
9c6b59c362 fix: bring back lastexecution endpoint (#9973) 2025-07-09 13:48:47 +02:00
Miloš Paunović
72341b8090 chore(core): allow displaying topology horizontally (#10012)
Closes https://github.com/kestra-io/kestra/issues/9980.
2025-07-09 13:11:17 +02:00
yuri
0c730843c6 docs(schedule): mention Sunday day-of-the-week alias (#9961) 2025-07-09 11:39:28 +02:00
Loïc Mathieu
05b50c22e3 feat(executions): allow suspending an execution at a breakpoint
- When creating an execution, you can pass a breakpoint of the form `taskId.value` and an execution kind.
- An execution with a breakpoint will be suspended in the `BREAKPOINT` state when arriving at the point where the breakpoint task should be executed
- You can resume an execution from a breakpoint, this would resume the execution and remove the existing breakpoint. At this time a new breakpoint can be passed.
- You can pass a breakpoint when replaying an execution.

Part-of: https://github.com/kestra-io/kestra-ee/issues/1547
2025-07-09 10:56:00 +02:00
dependabot[bot]
cf4f6554e6 build(deps): bump software.amazon.awssdk:bom from 2.31.75 to 2.31.77
Bumps software.amazon.awssdk:bom from 2.31.75 to 2.31.77.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.77
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-09 10:55:39 +02:00
Roman Acevedo
7ec1439bb7 chore: add useful scripts for RC 2025-07-09 10:19:05 +02:00
Miloš Paunović
d1b025253a chore(deps): regular dependency update (#10011)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-07-09 10:02:12 +02:00
dependabot[bot]
aa272418cf build(deps): bump com.github.docker-java:docker-java from 3.5.2 to 3.5.3
---
updated-dependencies:
- dependency-name: com.github.docker-java:docker-java
  dependency-version: 3.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-09 09:22:56 +02:00
dependabot[bot]
ef098c2489 build(deps): bump aquasecurity/trivy-action from 0.31.0 to 0.32.0
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.31.0 to 0.32.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](https://github.com/aquasecurity/trivy-action/compare/0.31.0...0.32.0)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-09 09:21:47 +02:00
Devesh Kumar
c671414958 fix(flows): issue where flows with task IDs longer than the supported database column length would cause the application to shut down. 2025-07-08 17:28:06 +02:00
github-actions[bot]
6bb42641a1 chore(core): localize to languages other than english (#9975)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-08 16:24:28 +02:00
Loïc Mathieu
acca4ddd55 fix(system): EE compilation 2025-07-08 15:40:32 +02:00
Piyush Bhaskar
e75a4a7500 feat(ui): introducing OSS auth (#9972)
Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-07-08 15:29:58 +02:00
Nicolas K.
4afa7dc969 fix(security) #4311 filter only kestra endpoints (#9971)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-08 15:13:33 +02:00
github-actions[bot]
c953e24931 chore(core): localize to languages other than english (#9969)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-08 18:19:14 +05:30
nKwiatkowski
b70545967e Merge remote-tracking branch 'origin/develop' into develop 2025-07-08 14:15:31 +02:00
Barthélémy Ledoux
02302fa54c fix(flows): autocomplete nocode outputs in pebble (#9955) 2025-07-08 14:10:11 +02:00
Nicolas K.
ff8c224554 fix(security) #4311 add basic auth whitelist for config and add new c… (#9968)
* chore(core): localize to languages other than english (#9966)

Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>

* fix(security) #4311 add basic auth whitelist for config and add new config parameter for basic auth initialized

* fix(security) #4311 failing unit tests

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-08 14:02:17 +02:00
Piyush-r-bhaskar
f54c46e238 Revert "feat(core): introducing OSS authentication user creation and login logout (#9683)"
This reverts commit 97b01ab6a4.
2025-07-08 16:51:43 +05:30
github-actions[bot]
750fa4cc8c chore(core): localize to languages other than english (#9966)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-08 11:40:44 +02:00
Piyush Bhaskar
97b01ab6a4 feat(core): introducing OSS authentication user creation and login logout (#9683)
* feat(core): introducing OSS authentication

* use pinia

* fix: error message

* fix logo

* fix import

* fix: i18n

* feat: show dialog fter 30days and send to login page if basicauth is true

* fix: minor tweaks

* fix(ui): ensure email and password are required.
2025-07-08 14:12:32 +05:30
Nicolas K.
eafaf32938 feat(security)!: make basic auth required on OSS (#9688)
* feat(security)!: make basic auth required on OSS

* clean(security)!: put the auth filter code into a publisher

* clean(security)!: add unit tests

* fix(core): merge

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-08 10:41:47 +02:00
Loïc Mathieu
6a4397fdfd fix(system): avoid creating multiple worker job queue
We created miltiple worker job queue because the bean was in the prototype scope.
This was needed only for tests as they are closing it.
Switching to singleton and rebuilding the context of the test that needs it fixes the issue.
2025-07-08 10:35:50 +02:00
YannC.
2109fa8116 fix(ci): Avoid retag latest docker image being true by default 2025-07-08 10:19:34 +02:00
Piyush Bhaskar
7de415e54f refactor(core): migrating doc store module to pinia (#9882) 2025-07-08 13:37:01 +05:30
Piyush Bhaskar
a7307b6a0c fix(ui): openGroup to directly open the first plugin element (#9964) 2025-07-08 13:36:19 +05:30
Barthélémy Ledoux
63613572a5 chore: update ui-libs for documentation collapsible warns (#9954) 2025-07-08 09:08:07 +02:00
Piyush Bhaskar
157e942499 refactor(core): migrate taskrun to Pinia (#9953)
* refactor(core): migrate taskrun to Pinia

* refactor(core): migrate taskrun to Pinia
2025-07-08 12:33:34 +05:30
Piyush Bhaskar
27d1069acd fix(ui): fixes merge snafu and warning lastExecutionByFlowReady (#9962) 2025-07-08 11:54:37 +05:30
brian-mulier-p
4a8b3d4d7d fix(plugins): plugin search is now searching in all element types (#9899) 2025-07-07 20:05:27 +02:00
Loïc Mathieu
475c8d3ce2 fix(webserver)*: bulk set labels remove existing labels
FIxes #9764
2025-07-07 15:21:47 +02:00
AJ Emerich
093ae3ae39 docs(dashboard-data): fix indentations for dashboard data plugins (#9918)
Closes https://github.com/kestra-io/kestra-ee/issues/3646
2025-07-07 15:10:17 +02:00
Piyush Bhaskar
6585d2446a fix(dashboards): include required prop to amend pages using dashboard sections component (#9949)
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-07-07 13:36:04 +02:00
Loïc Mathieu
2a53f55c3d fix(system): force running after execution tasks even if the execution is killed
Fixes #9852
2025-07-07 12:38:08 +02:00
Ludovic DEHON
f9b10407f0 chore(build): try to remove the noise for code coverage 2025-07-07 12:34:05 +02:00
Miloš Paunović
d63039f7f9 fix(core): introduce the missing translation key/value pairs for certain languages (#9943) 2025-07-07 12:23:31 +02:00
Miloš Paunović
3c4c1ed275 refactor(core): improve translation pull request description (#9938) 2025-07-07 12:05:09 +02:00
Miloš Paunović
ce1f8a5cc3 refactor(core): remove default reviewers on translation pull requests and add frontend team mention (#9935) 2025-07-07 12:00:17 +02:00
Miloš Paunović
c4581d1442 refactor(core): change default reviewers on translation pull requests to frontend team (#9931) 2025-07-07 11:47:32 +02:00
Miloš Paunović
5c9bb7a110 refactor(core): change default reviewers on translation pull requests (#9929) 2025-07-07 11:42:33 +02:00
Miloš Paunović
c145a0224b refactor(core): open translation pull request on the selected branch instead of develop (#9924) 2025-07-07 11:37:53 +02:00
Miloš Paunović
64121eb24d refactor(core): open translation pull request on the selected branch instead of develop (#9922) 2025-07-07 11:33:21 +02:00
Piyush Bhaskar
fdd7906412 fix(core): fix icon size and handle long title (#9916) 2025-07-07 14:58:27 +05:30
Miloš Paunović
ad87583939 refactor(dashboards): strengthen types for dashboard store module (#9917) 2025-07-07 11:24:21 +02:00
Miloš Paunović
250ada9689 refactor(core): open translation pull request on the selected branch instead of develop (#9919) 2025-07-07 11:22:58 +02:00
github-actions[bot]
e814c68703 chore(core): localize to languages other than english (#9915)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-07 10:58:44 +02:00
Miloš Paunović
932be71d47 chore(dashboards): improve the chart editing functionality (#9914) 2025-07-07 10:56:55 +02:00
Roman Acevedo
0c9b5222d6 fix(iam): tenant deletion raised error about mandatory tenantID in request context 2025-07-07 10:41:52 +02:00
github-actions[bot]
ad52c59f2e chore(core): localize to languages other than english (#9910)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-07 10:39:56 +02:00
Miloš Paunović
2e9a1478e8 chore(dashboards): add the button tooltip for dashboard edition link (#9909) 2025-07-07 10:38:06 +02:00
Florian Hussonnois
833fa56270 fix(webserver): fix reason in ErrorController (#9897)
The exception message is already included in the payload returned from the response, so we don't have to include it in the HTTP Reason phrase. This leads to a wrong error message format in the UI which is in the form {Reason}: {Error Message}. With the current code Reason=Error Message
2025-07-07 10:12:06 +02:00
Miloš Paunović
34af565257 feat(dashboards): introduce the edit icon on hover for each separate dashboard chart (#9908)
Closes https://github.com/kestra-io/kestra-ee/issues/3419.
2025-07-07 10:07:36 +02:00
Piyush Bhaskar
d61d697665 chore(flows): remove breadcrumbs (#9877)
* chore(core): remove Breadcrumbs

* chore(core): remove no code breadcrumbs related code and logic

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-07 13:29:54 +05:30
yuri1969
d698ef56bf fix(cli): prevent NPE on commands defaulting to help 2025-07-07 09:22:47 +02:00
Nicolas K.
b544e257c3 feat(cicd): migrate fetching plugins to maven central (#9902)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-04 17:15:14 +02:00
brian.mulier
2b49c88eab fix(ai): move AI popup button to right + gray placeholder
closes #9890
2025-07-04 17:05:27 +02:00
Miloš Paunović
82a8a118c0 refactor(core): simlify code in plugin documentation (#9900) 2025-07-04 16:24:32 +02:00
yuri
6d9ef2bb38 fix(cli): enforce server command validator (#7418)
With addition of the eagerly initialized BasicAuth bean the validator's order needed to be enforced.
2025-07-04 16:20:56 +02:00
Daniel Rivas
2b3324797b test(processor): add edge-case tests for ServicesFiles utility (#8828) 2025-07-04 16:17:22 +02:00
github-actions[bot]
281e1ef979 chore(core): localize to languages other than english (#9901)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-04 16:09:40 +02:00
Barthélémy Ledoux
3637f4f646 perf(ui): only load the schemaType once per page (#9619) 2025-07-04 15:56:20 +02:00
Barthélémy Ledoux
dfc0bcbb45 fix(ui): fix types of axios (#9676) 2025-07-04 15:40:53 +02:00
Barthélémy Ledoux
c6e01a7ecd fix(flows): bring back clear selection (#9893) 2025-07-04 15:39:13 +02:00
Piyush Bhaskar
f60cc48230 refactor(core): migrates trigger module to pinia (#9896) 2025-07-04 17:17:59 +05:30
Miloš Paunović
abc4e16372 feat(dashboards): initial work on adding buttons to chart cards (#9892)
Relates to https://github.com/kestra-io/kestra/issues/9148.
Relates to https://github.com/kestra-io/kestra/issues/9368.
Relates to https://github.com/kestra-io/kestra-ee/issues/3419.
2025-07-04 09:43:22 +02:00
Miloš Paunović
0e2d5376b7 refactor(dashboards): move the dashboard selector to proper place and clean up the code (#9883)
Relates to https://github.com/kestra-io/kestra/issues/9149.
Closes https://github.com/kestra-io/kestra/issues/9872.
2025-07-04 08:29:47 +02:00
brian.mulier
eb8c5ec494 fix(tests): move back wiremock port due to hardcoded in application.yml 2025-07-03 17:52:41 +02:00
nKwiatkowski
5d92300849 feat(cicd): #4006 add javadoc and sources to cli release 2025-07-03 14:58:40 +02:00
brian.mulier
75df4be0ef fix(core): avoid crashing AI Agent when having multiple versions of same plugin
closes #9871
2025-07-03 14:55:24 +02:00
Barthélémy Ledoux
739a873cb2 fix(flows): make sure expression can accept null values (#9876) 2025-07-03 11:55:23 +02:00
Bart Ledoux
046dc6cac8 fix(core): update some broken translations 2025-07-03 11:26:36 +02:00
Barthélémy Ledoux
ae442632a9 tests: run all tests (#9868) 2025-07-03 10:30:00 +02:00
github-actions[bot]
70622ca176 chore(core): localize to languages other than english (#9645)
Co-authored-by: GitHub Action <actions@github.com>
2025-07-03 10:15:19 +02:00
Loïc Mathieu
0c90d6d548 feat(triggers): add failOnTriggerError to create a failed execution on trigger error
Closes #7856
2025-07-03 09:55:23 +02:00
MilosPaunovic
2d27386c77 feat(flows): allow expanding all flow dependencies at once 2025-07-03 09:54:22 +02:00
Loïc Mathieu
e2c629a0d7 feat(flows): allow expanding flow dependencies
Part-of: https://github.com/kestra-io/kestra-ee/issues/4229
2025-07-03 09:54:22 +02:00
Loïc Mathieu
96163d4e6f fix(flows): Kill on cascade on SLA violation
FIxes #9801
2025-07-03 09:16:36 +02:00
YannC
6ec08bd9c8 fix!: Remove stats controllers (#9861)
* fix: Remove stats controllers

* fix: clean frontend + tests
2025-07-02 17:02:22 +02:00
brian.mulier
8691c90c9c fix(ai): short-circuit cases where relevant plugin identifier fails to identify ones 2025-07-02 16:37:48 +02:00
brian.mulier
b57e9ae7a0 fix(core): typo 2025-07-02 15:25:39 +02:00
github-actions[bot]
a61853332d chore(core): localize to languages other than english (#9862)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-02 18:30:18 +05:30
Piyush Bhaskar
796be656fa fix(flows): include flow count in export success message. (#9860) 2025-07-02 18:22:49 +05:30
brian.mulier
6e7f3a681a fix(tests): avoid wiremock port collision 2025-07-02 14:06:58 +02:00
Barthélémy Ledoux
665a413d84 fix(flows): open subtask from topology (#9804) 2025-07-02 13:33:30 +02:00
Piyush Bhaskar
c8e61ba3e1 refactor(core): migrates core.js to pinia (#9858)
* refactor(core): migrates core.js to pinia

* fix: remove declaration

* fix: message in axios
2025-07-02 16:44:30 +05:30
Loïc Mathieu
bf8d47f19d feat(flows): remove worker grou validation
No longer invalidate a flow if a task or a trigger set a worker group.

Closes #9808
2025-07-02 13:02:49 +02:00
Roman Acevedo
dcc5c34493 docs(tests,flows): set loosely types fields like input and variable as additional properties
this make the generated openapi spec match batter the existing API
2025-07-02 12:31:15 +02:00
dependabot[bot]
882ac34768 build(deps): bump software.amazon.awssdk:bom from 2.31.70 to 2.31.75
Bumps software.amazon.awssdk:bom from 2.31.70 to 2.31.75.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.75
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 12:16:21 +02:00
dependabot[bot]
e236909e33 build(deps): bump com.azure:azure-sdk-bom from 1.2.35 to 1.2.36
Bumps [com.azure:azure-sdk-bom](https://github.com/azure/azure-sdk-for-java) from 1.2.35 to 1.2.36.
- [Release notes](https://github.com/azure/azure-sdk-for-java/releases)
- [Commits](https://github.com/azure/azure-sdk-for-java/compare/azure-sdk-bom_1.2.35...azure-sdk-bom_1.2.36)

---
updated-dependencies:
- dependency-name: com.azure:azure-sdk-bom
  dependency-version: 1.2.36
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:59:51 +02:00
dependabot[bot]
67518bc2cb build(deps): bump com.gradleup.shadow from 8.3.7 to 8.3.8
Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 8.3.7 to 8.3.8.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](https://github.com/GradleUp/shadow/compare/8.3.7...8.3.8)

---
updated-dependencies:
- dependency-name: com.gradleup.shadow
  dependency-version: 8.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:58:27 +02:00
Miloš Paunović
05787efd90 fix(namespaces)*: take pagination into account when browsing namespace flows (#9849)
Closes https://github.com/kestra-io/kestra/issues/9805.
2025-07-02 11:47:48 +02:00
Miloš Paunović
90c74fceb2 chore(deps): regular dependency update (#9855)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-07-02 11:46:42 +02:00
dependabot[bot]
b1cad2fd93 build(deps): bump org.testcontainers:testcontainers
Bumps [org.testcontainers:testcontainers](https://github.com/testcontainers/testcontainers-java) from 1.21.2 to 1.21.3.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.2...1.21.3)

---
updated-dependencies:
- dependency-name: org.testcontainers:testcontainers
  dependency-version: 1.21.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:44:30 +02:00
dependabot[bot]
0687808430 build(deps): bump com.google.cloud:libraries-bom from 26.62.0 to 26.63.0
---
updated-dependencies:
- dependency-name: com.google.cloud:libraries-bom
  dependency-version: 26.63.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:42:20 +02:00
dependabot[bot]
90d30bb920 build(deps): bump com.github.docker-java:docker-java from 3.5.1 to 3.5.2
Bumps [com.github.docker-java:docker-java](https://github.com/docker-java/docker-java) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/docker-java/docker-java/releases)
- [Changelog](https://github.com/docker-java/docker-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/docker-java/docker-java/compare/3.5.1...3.5.2)

---
updated-dependencies:
- dependency-name: com.github.docker-java:docker-java
  dependency-version: 3.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:41:39 +02:00
dependabot[bot]
fcf5215ccc build(deps): bump flyingSaucerVersion from 9.12.1 to 9.13.0
---
updated-dependencies:
- dependency-name: org.xhtmlrenderer:flying-saucer-core
  dependency-version: 9.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.xhtmlrenderer:flying-saucer-pdf
  dependency-version: 9.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:40:10 +02:00
dependabot[bot]
856db91609 build(deps): bump com.google.adk:google-adk from 0.1.0 to 0.2.0
---
updated-dependencies:
- dependency-name: com.google.adk:google-adk
  dependency-version: 0.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:39:44 +02:00
Nicolas K.
2b83fc7d4d feat(cicd): #4006 change signing method (#9854)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-02 11:13:23 +02:00
Loïc Mathieu
d22b7e9b98 fix(system): fix ExecutionControllerRunnerTest.resumeExecutionPaused() 2025-07-02 11:00:26 +02:00
brian-mulier-p
515dbdbf54 fix(core): remove prerendering + restrict only secret function in debug expression (#9816) 2025-07-02 10:52:14 +02:00
github-actions[bot]
2735986c57 chore(core): localize to languages other than english (#9812)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-01 18:25:58 +02:00
brian.mulier
deb2fdcd9e fix(core): add config from backend that sends whether the AI feature is configured or not 2025-07-01 16:30:08 +02:00
brian-mulier-p
5677a6bdbe feat(core): add Pebble HTTP function (#9786)
closes kestra-io/kestra-ee#4218
2025-07-01 16:27:13 +02:00
Nicolas K.
6a8225d2fb feat(cicd): #4006 migrate to maven central (#9807)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-01 16:17:08 +02:00
brian-mulier-p
f402aa7643 feat(core): introduce AI agent (#9733)
closes kestra-io/kestra-ee#3458
2025-07-01 15:43:54 +02:00
Miloš Paunović
65316da4e8 fix(dashboards): properly show default charts on logs page (#9800)
Closes https://github.com/kestra-io/kestra/issues/9612.
2025-07-01 15:28:43 +02:00
AJ Emerich
a152204f55 docs(dashboards): fix example indentations (#9802)
Closes https://github.com/kestra-io/kestra/issues/9790
2025-07-01 15:21:23 +02:00
Nicolas K.
c6e5cdfd93 feat(cicd): #4006 migrate sonatype to maven central (#9803)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-07-01 15:00:34 +02:00
Barthélémy Ledoux
7fcf94f12a fix(flows): finish YAML_UTILS refactoring (#9795) 2025-07-01 14:29:37 +02:00
YannC.
c4082dbc1b feat(triggers): avoid clearing selection when refreshing in triggers list 2025-07-01 14:20:55 +02:00
YannC.
1d7574b155 fix(triggers): correctly replace the update triggers when disabling 2025-07-01 14:18:13 +02:00
Miloš Paunović
436b770d21 chore(dashboards): move store module from vuex to pinia (#9796) 2025-07-01 14:07:23 +02:00
Piyush Bhaskar
0e382b2492 chore(logs): remove double scrollbar on the logs page (#9670)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-01 13:21:41 +02:00
Loïc Mathieu
47b10b4a79 feat(system): repoll immediatly when a poll returns resutls in the queue 2025-07-01 12:11:52 +02:00
Loïc Mathieu
30792302aa chore(flows): rename retry maxAttempt to maxAttemps
Keep maxAttempt as deprecated to avoid any breaking changes.

Closes #9729
2025-07-01 11:25:46 +02:00
Barthélémy Ledoux
6bcfbaa1df fix(flows): restore dag open tabs after hard refresh (#9792) 2025-07-01 10:16:02 +02:00
Barthélémy Ledoux
8d6547865d fix(flow): avoid calling icons api more than once (#9784) 2025-07-01 10:15:49 +02:00
Piyush Bhaskar
7ba0780b4f feat(core): add useDataTableActions composable (#9777)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-01 12:40:55 +05:30
Roman Acevedo
5493f53892 fix(system): revert Property type changed to string in openapi spec
this may cause issue with jsonSchema generation. So, to not take any risk I reverted it and will do a hack in SDK
2025-06-30 18:46:35 +02:00
Roman Acevedo
39e08abf26 fix(tests): deleted db serialization was broken in recent commit 2025-06-30 18:43:22 +02:00
François Delbrayelle
ff66471f37 feat(gemini): add the plugin to .plugins 2025-06-30 17:00:02 +02:00
Loïc Mathieu
8109493f19 feat(flows): add resumed information to the Pause task
Add who resume the Pause task and when.
Part-of: https://github.com/kestra-io/kestra-ee/issues/2806
2025-06-30 16:22:34 +02:00
Barthélémy Ledoux
2b59d9ec21 refactor(ui): migrate bookmarks store to pinia (#9685) 2025-06-30 16:15:10 +02:00
brian-mulier-p
0beac5e9f2 fix(core): increase max encode size to avoid icons fetch timeout (#9782) 2025-06-30 15:40:10 +02:00
Loïc Mathieu
5f7ecba4c7 feat(flows): allow setting worker group at the flow level
Part-of: https://github.com/kestra-io/kestra-ee/issues/4141
2025-06-30 14:58:45 +02:00
Loïc Mathieu
c56f377019 fix(system)*: mitigate possible deadlock for execution delay and SLA
In case multiple instances of the executor are started, the execution delay loop and the monitoring SLA loop have a risk of duplicate execution resume or execution SLA violation computation.
This could create some race conditions and duplicate execution update.
But this may also risk to create some deadlocks as two instances of the executor may try to lock the same exection to restart it (or fail it due to SLA).
2025-06-30 14:33:06 +02:00
Miloš Paunović
9530e820e8 chore(deps): regular dependency update (#9779)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-06-30 13:21:27 +02:00
Sjoerd Smink
09adee6017 Update Request.java multiline JSON example 2025-06-30 11:21:22 +02:00
yashmurthy98
12f3e2ea68 fix(guides): crawl into sub-folders 2025-06-30 11:05:21 +02:00
rajatsingh23
8c32ff74c9 chore(dashboards): always updating chart previews on dashboard creation (#9536)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-06-30 10:23:06 +02:00
François Delbrayelle
023d005e63 fix(taskrunner): abstract task runner (#9769) 2025-06-30 09:19:32 +02:00
Piyush Bhaskar
9a86bb1125 feat(core): add button to copy all logs to clipboard (#9763) 2025-06-30 11:24:48 +05:30
Piyush Bhaskar
99fca84e31 fix(ui): adjust logo in collapsed state (#9761) 2025-06-30 11:22:51 +05:30
Roman Acevedo
bfe4d7b983 fix(tests): TestSuite fields were almost all required in openapi spec 2025-06-27 17:37:58 +02:00
Roman Acevedo
31d372df55 feat(system): make Property a string in openapi spec generation
we already return Serialize as a string, we need to indicated to openapi generator that it is in fact Serialized as such
2025-06-27 17:30:20 +02:00
Roman Acevedo
70b9ddee28 fix(tests): testcases were not fully validated 2025-06-27 15:52:40 +02:00
Loïc Mathieu
d44a203bed feat(flows): supports the nsfile:// protocol
Automatically fetch namespace files from URI with the 'nsfile' scheme.
The authority allow to fetch file from another namespace.

The following has been done:
- Supports using nsfile inside `from`
- Supports using nsfile inside input files
- Supports using nsfile as a FILE input defaults
- Supports using nsfile inside the Pebble files functions

Closes: #9741
2025-06-27 15:26:38 +02:00
Roman Acevedo
2cb361a7c6 build: lower codecev default targets to make it more pertinent 2025-06-27 11:07:52 +02:00
brian.mulier
b19737f20a fix(core): remove tenant from plugins URLs 2025-06-27 10:52:28 +02:00
Nicolas K.
7373f3ee5b feat(namespaces): #3568 add new folderPerNamespace attribute to namespaceFiles (#9752)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-27 10:46:14 +02:00
Nicolas K.
f8670ef216 feat(api): #4108 remove tenant id from trigger body and plugin URL (#9749)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-27 10:42:17 +02:00
Barthélémy Ledoux
c9debbd869 remove unused constant (#9751) 2025-06-27 10:32:03 +02:00
Loïc Mathieu
4149ef4f3e feat(flows): allow reading local files inside the file functions
Supports the 'file://' protocol inside the read(), isFileEmpty(), fileExists() and fileSize() Pebble functions.

Closes #9739
2025-06-27 09:45:34 +02:00
Piyush Bhaskar
8e50da83c3 refactor(stat): migrate stat store from Vuex to Pinia (#9750) 2025-06-26 16:39:40 +02:00
Barthélémy Ledoux
00b1e320b9 fix(plugins): finish pinia migration of plugins store (#9746) 2025-06-26 16:39:18 +02:00
Loïc Mathieu
c4e762506c feat(cluster): persist maintenance mode in the database
Part-of: https://github.com/kestra-io/kestra-ee/issues/3735
2025-06-26 14:31:05 +02:00
Barthélémy Ledoux
d7f6addb79 fix(flows): make autocomplete work in pebble (#9742) 2025-06-26 11:00:55 +02:00
Piyush Bhaskar
b2f8c89e02 refactor(layout): migrate layout.js from vuex to Pinia. (#9687)
* refactor(layout): migrate layout.js from vuex to Pinia.

* refactor(layout): replace getters with direct state access.
2025-06-26 13:37:43 +05:30
Piyush Bhaskar
83e1d77230 refactor(store): migrate Blueprints to Pinia (#9735)
* refactor(store): migrate Blueprints to Pinia

* fix: remove blueprints from declaration
2025-06-26 13:32:02 +05:30
Piyush Bhaskar
dafebc76a3 feat(tenant): all routes on /main tenant (#9664)
* feat(tenant): all  routes on /main tenant

* fix: remove params

* fix: setup tenant router in main
2025-06-26 11:35:44 +05:30
Malaydewangan09
a1e53443a5 feat(scripts): enable script/cli plugins to override final task state 2025-06-25 23:17:44 +05:30
brian.mulier
076ae2e933 fix(core): use namespace prefix instead of equals
On the namespace/flows, namespace/executions pages and when having a default namespace on Logs page

closes kestra-io/kestra-ee#4200
2025-06-25 17:48:21 +02:00
François Delbrayelle
bb7b9edaf2 feat(devtools): copy plugin jars to plugins dir (#9738) 2025-06-25 17:01:31 +02:00
Loïc Mathieu
5aa1b20138 chore(system): call the close runnable later 2025-06-25 14:34:14 +02:00
Loïc Mathieu
cf01f4f0e8 feat(flows): support local files as FILE input default value
Closes #9681
2025-06-25 13:55:49 +02:00
Loïc Mathieu
201912fa22 feat(flows): support local files in input files
Closes https://github.com/kestra-io/plugin-scripts/issues/268
2025-06-25 10:49:10 +02:00
dependabot[bot]
d4891d1c11 build(deps): bump opensearchRestVersion from 3.0.0 to 3.1.0
Bumps `opensearchRestVersion` from 3.0.0 to 3.1.0.

Updates `org.opensearch.client:opensearch-rest-client` from 3.0.0 to 3.1.0
- [Release notes](https://github.com/opensearch-project/OpenSearch/releases)
- [Changelog](https://github.com/opensearch-project/OpenSearch/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/OpenSearch/compare/3.0.0...3.1.0)

Updates `org.opensearch.client:opensearch-rest-high-level-client` from 3.0.0 to 3.1.0
- [Release notes](https://github.com/opensearch-project/OpenSearch/releases)
- [Changelog](https://github.com/opensearch-project/OpenSearch/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/OpenSearch/compare/3.0.0...3.1.0)

---
updated-dependencies:
- dependency-name: org.opensearch.client:opensearch-rest-client
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.opensearch.client:opensearch-rest-high-level-client
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:30:40 +02:00
dependabot[bot]
bff6865806 build(deps): bump software.amazon.awssdk:bom from 2.31.65 to 2.31.70
Bumps software.amazon.awssdk:bom from 2.31.65 to 2.31.70.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.70
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:30:25 +02:00
dependabot[bot]
ebc887908c build(deps): bump org.jsoup:jsoup from 1.20.1 to 1.21.1
Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.20.1 to 1.21.1.
- [Release notes](https://github.com/jhy/jsoup/releases)
- [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md)
- [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.20.1...jsoup-1.21.1)

---
updated-dependencies:
- dependency-name: org.jsoup:jsoup
  dependency-version: 1.21.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:30:07 +02:00
dependabot[bot]
710d2f6c2b build(deps): bump com.gradleup.shadow from 8.3.6 to 8.3.7
Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 8.3.6 to 8.3.7.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](https://github.com/GradleUp/shadow/compare/8.3.6...8.3.7)

---
updated-dependencies:
- dependency-name: com.gradleup.shadow
  dependency-version: 8.3.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:29:48 +02:00
dependabot[bot]
48de33d04b build(deps): bump org.testcontainers:testcontainers
Bumps [org.testcontainers:testcontainers](https://github.com/testcontainers/testcontainers-java) from 1.21.1 to 1.21.2.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.1...1.21.2)

---
updated-dependencies:
- dependency-name: org.testcontainers:testcontainers
  dependency-version: 1.21.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:29:24 +02:00
dependabot[bot]
59b837e873 build(deps): bump com.microsoft.playwright:playwright
Bumps [com.microsoft.playwright:playwright](https://github.com/microsoft/playwright-java) from 1.52.0 to 1.53.0.
- [Release notes](https://github.com/microsoft/playwright-java/releases)
- [Commits](https://github.com/microsoft/playwright-java/compare/v1.52.0...v1.53.0)

---
updated-dependencies:
- dependency-name: com.microsoft.playwright:playwright
  dependency-version: 1.53.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 10:29:02 +02:00
brian-mulier-p
7463be3496 fix(variables): put fixtures files with arbitrary key and extract it back as root level "files" variable (#9689) 2025-06-24 17:29:39 +02:00
Rishi Jat
aedfbdc46a fix(ui): remove Close Task button in NoCode editor (#9661)
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-06-24 15:22:02 +02:00
Anna Geller
9a8363ce69 fix(api-docs): tenant info in API docs (#9675)
* fix(api-docs): tenant info in API docs

* fix: descriptions
2025-06-23 19:26:16 +02:00
Ludovic DEHON
d08d345719 test(core): fix falling test on schedule 2025-06-23 18:52:51 +02:00
Loïc Mathieu
9813d60954 fix(system): possible NPE on trigger when computing variables 2025-06-23 18:12:09 +02:00
Barthélémy Ledoux
4257168818 fix(ui): deletion of namespace files depend on node not data (#9666) 2025-06-23 14:02:40 +02:00
Loïc Mathieu
d22aedaaa5 feat(flows): add a log into the Subflow task when a flow it fail (#9652) 2025-06-23 12:40:09 +02:00
brian-mulier-p
094ab828e7 fix: avoid failure to deserialize json objects that have unknown fields with http client (#9668)
closes #9667
2025-06-23 12:21:42 +02:00
Satvik Kushwaha
1d9b5d26ce Fix(UI) execution charts values (#9669)
* added steps in bar chart

* date issue fixed

* cohre: minor tweak

* added stepsize for Bar.ue as well

---------

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-06-23 11:47:12 +02:00
Barthélémy Ledoux
d9371c1fd2 refactor: integrate vuex & axios with pinia (#9626) 2025-06-23 10:56:07 +02:00
Loïc Mathieu
9fa5f6df56 feat(executions)*: add tasks to set and unset execution variables
Closes #9555
2025-06-23 10:43:03 +02:00
Loïc Mathieu
97b89d3a38 fix(core): retry flaky runner test restartForEachItem as it's flaky on CI but always pass locally 2025-06-23 10:27:49 +02:00
github-actions[bot]
ab286a1ec1 chore(core): localize to languages other than english (#9659)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-06-20 18:58:59 +02:00
Loïc Mathieu
9c702d3186 fix(execution): parent flow never ends when subflow fail due to SLA
This is because the executor didn't have the flow inside it so the execution is not correctly terminated.
It may fix other issues (like flow triggers, purge, ...)

Fixes #9618
2025-06-20 16:44:23 +02:00
Piyush-r-bhaskar
a2bbd53502 chore: update ui-libs 2025-06-20 19:25:09 +05:30
Piyush Bhaskar
fc2f89bb53 feat(ui): Add connection properties group sorting (#9644) 2025-06-20 18:35:51 +05:30
Loïc Mathieu
ebe1f3f189 fix(system): flow graph fail to be created while editting a flow
Fixes #9551

It is not the validation per se that fail, it's the graph dependency computation that is also done while editing a flow that fail.
2025-06-20 12:07:41 +02:00
Loïc Mathieu
a623b4c478 fix(system)*: runIf inside a WorkingDirectory can crash the Worker
Fixes #9639
2025-06-20 12:07:25 +02:00
Nicolas K.
1d66f7e1cc Fix/failing backup unit test (#9642)
* test(core): fix failing unit tests

* test(core): fix failing unit tests

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-20 11:32:18 +02:00
Loïc Mathieu
b9f224ca91 fix(system): SettingRepository test 2025-06-20 11:31:04 +02:00
Tijn Koppert
1c3049a881 feat(ui): Add support for bulk-select and bulk-delete (#8281)
Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-06-20 11:18:01 +02:00
Barthélémy Ledoux
651fdc1322 fix(ui): default value for expression cannot be null (#9636) 2025-06-20 11:11:54 +02:00
Loïc Mathieu
bb6c480046 feat(flows): allow to pass a typed object in Data.from()
This would facilitate dev experience as he would be able to directly use a typed object not a Map.
This will not be used inside a Kestra instance as deserialization would always deserialize to a Map as the `from` attribute is an Object.
2025-06-20 10:43:54 +02:00
Nicolas K.
5b5cca33f0 fix(triggers): #4110 NPE when disable trigger with empty body (#9635)
* fix(triggers): #4110 NPE when disable trigger with empty body

* fix(triggers): #4110 unit tests

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-20 10:27:33 +02:00
Piyush Bhaskar
bafc3047d9 feat(namespaces): show ns description (#9610)
* feat(namespaces): show ns description

* add slot and data for description
2025-06-20 13:55:20 +05:30
Barthélémy Ledoux
cbd0b8a74a style: fix font-size of label (#9634) 2025-06-20 09:32:01 +02:00
François Delbrayelle
76fc55bbd9 fix(plugin-versioning): replace current JAR if more recent (#9629) 2025-06-19 18:43:41 +02:00
Loïc Mathieu
d7c54809e9 chore(system): relax again some test on AbstractSettingRepositoryTest
Again because in ES there is the version settings and not in JDBC.
2025-06-19 17:53:29 +02:00
YannC.
e015a94c95 fix(ci): modify job id for end task 2025-06-19 17:19:54 +02:00
Loïc Mathieu
5e97e25658 chore(system): relax AbstractSettingRepositoryTest assertion
There is a discrepiancy between JDBC and ES, as it's not important and I dind't find a quik way to fix the test I relax the assertion.
2025-06-19 16:44:32 +02:00
Loïc Mathieu
c8aa678ef8 feat(executions): allow using local host files in tasks
Closes https://github.com/kestra-io/kestra-ee/issues/3469
2025-06-19 15:48:57 +02:00
Loïc Mathieu
695f684613 fix(system): support allowFailure and allowWarning for the Pause task
Fixes #9416
2025-06-19 14:56:42 +02:00
Florian Hussonnois
f59def2c7d chore(core): add top-level exception ConflictException 2025-06-19 14:35:49 +02:00
Barthélémy Ledoux
1139a16d17 tests: nocode editor (#9624) 2025-06-19 14:20:45 +02:00
Bart Ledoux
1e55003e3f Revert "refactor: start replacing vuex with pinia (#8430)"
This reverts commit 9c052c0a41.
2025-06-19 13:24:42 +02:00
Loïc Mathieu
c047e37c01 feat(system): store version in the settings 2025-06-19 12:22:08 +02:00
Barthélémy Ledoux
bc8c8d4ee1 perf(ui): load a sample schema while waiting (#9558) 2025-06-19 11:33:18 +02:00
YannC.
de8c3fd0b7 feat: trigger EE CI when OSS develop branch succeed 2025-06-19 10:55:58 +02:00
Nicolas K.
7fc274fe1a Fix/tutorial flows with migration (#9620)
* fix(core): #9609 delete tutorial flows and triggers before migrating the database

* fix(core): #9609 delete tutorial flows and triggers before migrating the database for EE version

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-19 10:53:18 +02:00
Barthélémy Ledoux
9c052c0a41 refactor: start replacing vuex with pinia (#8430) 2025-06-19 10:52:55 +02:00
YannC
5682d12ee8 fix: correctly use default tenant when synchronizing file with local (#9605)
close #9568
2025-06-19 10:04:39 +02:00
YannC
b160361f9e feat(ui): Allows ContextInfoBar.vue to have dynamic buttons from props (#9613) 2025-06-19 09:46:19 +02:00
François Delbrayelle
a981a309d6 fix(podman): do not pass the tag directly to pullImageCmd (withTag) (#9607) 2025-06-18 18:05:16 +02:00
Nicolas K.
185fa80058 Feat/clean query filters (#9569)
* feat(repositories): clean and fix query filters

* fix(core): #4106 Clean and add unit tests to query filters

* clean(core): format string more cleanly

* fix(core): unit test failing on mysql flow repository

* feat(core): #4106 update ui filters

* fix(ui): add date filter on flows back

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-18 17:40:56 +02:00
Florian Hussonnois
d6047fea96 chore(core): add top-level exception NotFoundException 2025-06-18 16:32:15 +02:00
dependabot[bot]
37bd6e16a1 build(deps): bump jacksonVersion from 2.19.0 to 2.19.1
Bumps `jacksonVersion` from 2.19.0 to 2.19.1.

Updates `com.fasterxml.jackson:jackson-bom` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.19.0...jackson-bom-2.19.1)

Updates `com.fasterxml.jackson.core:jackson-core` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.19.0...jackson-core-2.19.1)

Updates `com.fasterxml.jackson.core:jackson-databind` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.core:jackson-annotations` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson/commits)

Updates `com.fasterxml.jackson.module:jackson-module-parameter-names` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-modules-java8/compare/jackson-modules-java8-2.19.0...jackson-modules-java8-2.19.1)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.19.0...jackson-dataformats-text-2.19.1)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-smile` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-dataformats-binary/compare/jackson-dataformats-binary-2.19.0...jackson-dataformats-binary-2.19.1)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-cbor` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-dataformats-binary/compare/jackson-dataformats-binary-2.19.0...jackson-dataformats-binary-2.19.1)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-ion` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-dataformat-ion/commits)

Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-xml` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-dataformat-xml/compare/jackson-dataformat-xml-2.19.0...jackson-dataformat-xml-2.19.1)

Updates `com.fasterxml.jackson.datatype:jackson-datatype-guava` from 2.19.0 to 2.19.1
- [Commits](https://github.com/FasterXML/jackson-datatypes-collections/compare/jackson-datatypes-collections-2.19.0...jackson-datatypes-collections-2.19.1)

Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.19.0 to 2.19.1

Updates `com.fasterxml.jackson.datatype:jackson-datatype-jdk8` from 2.19.0 to 2.19.1

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-core
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-annotations
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.module:jackson-module-parameter-names
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-smile
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-cbor
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-ion
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-xml
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-guava
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jdk8
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 13:44:14 +02:00
dependabot[bot]
a514500244 build(deps): bump org.apache.logging.log4j:log4j-to-slf4j
Bumps org.apache.logging.log4j:log4j-to-slf4j from 2.24.3 to 2.25.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-to-slf4j
  dependency-version: 2.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 13:42:32 +02:00
François Delbrayelle
25adcc492a fix(plugin): FileSystems.newFileSystem caused a Path component should be / in plugins tests (#9570) 2025-06-18 13:07:56 +02:00
dependabot[bot]
39d31f4a1a build(deps): bump nl.basjes.gitignore:gitignore-reader
Bumps [nl.basjes.gitignore:gitignore-reader](https://github.com/nielsbasjes/codeowners) from 1.11.3 to 1.12.0.
- [Release notes](https://github.com/nielsbasjes/codeowners/releases)
- [Changelog](https://github.com/nielsbasjes/codeowners/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nielsbasjes/codeowners/compare/v1.11.3...v1.12.0)

---
updated-dependencies:
- dependency-name: nl.basjes.gitignore:gitignore-reader
  dependency-version: 1.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 10:44:14 +02:00
dependabot[bot]
35eef54d74 build(deps): bump software.amazon.awssdk:bom from 2.31.61 to 2.31.65
Bumps software.amazon.awssdk:bom from 2.31.61 to 2.31.65.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.65
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 10:07:02 +02:00
dependabot[bot]
f8aa9cc9dd build(deps): bump org.wiremock:wiremock-jetty12 from 3.13.0 to 3.13.1
Bumps [org.wiremock:wiremock-jetty12](https://github.com/wiremock/wiremock) from 3.13.0 to 3.13.1.
- [Release notes](https://github.com/wiremock/wiremock/releases)
- [Commits](https://github.com/wiremock/wiremock/compare/3.13.0...3.13.1)

---
updated-dependencies:
- dependency-name: org.wiremock:wiremock-jetty12
  dependency-version: 3.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 10:06:35 +02:00
dependabot[bot]
0218931596 build(deps): bump flyingSaucerVersion from 9.12.0 to 9.12.1
Bumps `flyingSaucerVersion` from 9.12.0 to 9.12.1.

Updates `org.xhtmlrenderer:flying-saucer-core` from 9.12.0 to 9.12.1
- [Release notes](https://github.com/flyingsaucerproject/flyingsaucer/releases)
- [Changelog](https://github.com/flyingsaucerproject/flyingsaucer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyingsaucerproject/flyingsaucer/compare/v9.12.0...v9.12.1)

Updates `org.xhtmlrenderer:flying-saucer-pdf` from 9.12.0 to 9.12.1
- [Release notes](https://github.com/flyingsaucerproject/flyingsaucer/releases)
- [Changelog](https://github.com/flyingsaucerproject/flyingsaucer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyingsaucerproject/flyingsaucer/compare/v9.12.0...v9.12.1)

---
updated-dependencies:
- dependency-name: org.xhtmlrenderer:flying-saucer-core
  dependency-version: 9.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.xhtmlrenderer:flying-saucer-pdf
  dependency-version: 9.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 10:05:33 +02:00
dependabot[bot]
369d4ba39f build(deps): bump org.jooq:jooq from 3.20.4 to 3.20.5
Bumps org.jooq:jooq from 3.20.4 to 3.20.5.

---
updated-dependencies:
- dependency-name: org.jooq:jooq
  dependency-version: 3.20.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 10:05:05 +02:00
François Delbrayelle
f009263035 Revert "fix(plugin): FileSystems.newFileSystem caused a Path component should be / in plugins tests (#9562)"
This reverts commit 8516557553.
2025-06-17 17:37:38 +02:00
Roman Acevedo
bd576d65f9 refactor: remove package lock json added by mistake 2025-06-17 16:40:07 +02:00
Roman Acevedo
4557bc8f40 tests(flows): add e2e create and execute Flow test
* tests: add e2e create and execute Flow test

* various fixes

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-06-17 16:26:54 +02:00
Piyush Bhaskar
f20f2e7a0e fix(core): save disabled , tab not dirty on save (#9560) 2025-06-17 18:13:01 +05:30
François Delbrayelle
8516557553 fix(plugin): FileSystems.newFileSystem caused a Path component should be / in plugins tests (#9562) 2025-06-17 14:22:47 +02:00
Bart Ledoux
13e1e49ebb chore: update ui-libs 2025-06-17 11:19:46 +02:00
github-actions[bot]
9d989115ad chore(core): localize to languages other than english (#9552)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-06-16 17:20:35 +02:00
Ludovic DEHON
289a26ba87 fix(tasks): sleep example are a full one 2025-06-16 15:01:42 +02:00
Barthélémy Ledoux
105b8ece17 fix(ui): make file panel appear beside main panel in namespace (#9546) 2025-06-16 14:44:40 +02:00
Sarthak Ladhwe
e2b2a1f19f feat(ui): repo star button on right menu (#9526)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-06-16 18:07:04 +05:30
Bart Ledoux
aea8d6e52e tests: fix storybook tests 2025-06-16 13:31:10 +02:00
github-actions[bot]
33404bfa3b chore(core): localize to languages other than english (#9544)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-06-16 13:22:27 +02:00
Prayag
62fc839d64 Fix Sidebar Scrollbar and Version Text Wrapping, Minimize Panel Styles (#9528)
* fix(ui): hide sidebar scrollbar while enabling scrolling and fix version text wrapping

* minor tweak

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-06-16 16:15:25 +05:30
Bart Ledoux
1fa1f0c3d6 fix(ui): make array and KV Pairs work in nocode 2025-06-16 12:19:05 +02:00
rkitamu
bb746e5dad fix(ui): avoid validation API call when Flow editor is empty (#5387) (#9538)
* fix(ui): avoid validation API call when editor is empty

* fix(ui): Replace hardcoded "No data" with translatable message for empty flow validation
2025-06-16 08:56:37 +02:00
Piyush Bhaskar
23db6c60f7 fix(core): route to namespaces' flow and execution (#9517) 2025-06-16 10:44:01 +05:30
Ludovic DEHON
e5b816d723 fix(core): robots.txt was not served
close kestra-io/kestra#9015
2025-06-13 23:00:40 +02:00
Florian Hussonnois
7b44569efc chore(system): remove dedicated JdbcServiceLivenessManager 2025-06-13 17:41:56 +02:00
brian.mulier
8e5c5c97fa fix(core): yaml utils migration 2025-06-13 17:10:02 +02:00
Barthélémy Ledoux
6953e9fa58 fix: cleanup empty metadata to fix variable creation (#9529) 2025-06-13 16:38:54 +02:00
Barthélémy Ledoux
007ace6360 fix(ui): nocode API calls on EE needs tenant (#9527) 2025-06-13 16:38:38 +02:00
Miloš Paunović
4d4f8220ca refactor(dashboards): improve process of dashboard creation (#9530)
Related to https://github.com/kestra-io/kestra/issues/9149.

Companion of https://github.com/kestra-io/kestra-ee/pull/4081.
2025-06-13 16:37:40 +02:00
Florian Hussonnois
d97879f813 fix(executor): delete WorkerJobRunning for any terminated task (#9493)
Make ExecutorService responsible for deleting WorkerJobRunning
when a terminated TaskRun is added to an execution.

Changes:
 - Remove unecessary read before delete on WorkerJobRunning table.

Close: #9493
2025-06-13 16:29:12 +02:00
brian.mulier
7bce99845c fix(core): filters was triggering endless refresh
closes #9508
2025-06-13 16:24:11 +02:00
Miloš Paunović
e8c6a4511b refactor(dashboards): further clean up of the ui code related to dashboards (#9521)
Related to https://github.com/kestra-io/kestra/issues/9149.

Companion of https://github.com/kestra-io/kestra-ee/pull/4079.
2025-06-13 14:32:45 +02:00
Satvik Kushwaha
3a027fef36 chore(dashboards): switch default time series chart scale to integer numbers (#9510)
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-06-13 13:57:10 +02:00
Barthélémy Ledoux
f15919ba2e fix: small tweaks on tabs (#9520) 2025-06-13 13:54:32 +02:00
Miloš Paunović
839836a9e9 refactor(dashboards): add missing translations related to dashboards (#9519) 2025-06-13 13:29:27 +02:00
Barthélémy Ledoux
f700b8a1c5 fix(ui): snafu on duplicate input pair (#9514) 2025-06-13 12:09:33 +02:00
Miloš Paunović
7456440de6 refactor(dashboards): clean up ui code related to dashboards (#9421)
Related to https://github.com/kestra-io/kestra/issues/9149.

Companion of https://github.com/kestra-io/kestra-ee/pull/4023.
2025-06-13 10:15:10 +02:00
Barthélémy Ledoux
576c5cfef9 fix(ui): [nocode] make dag tasks work (#9506) 2025-06-13 09:11:08 +02:00
Miloš Paunović
8678d2d49b fix(core)*: make sure tour always opens with code & topology tabs visible (#9513)
Closes https://github.com/kestra-io/kestra-ee/issues/4073.
2025-06-13 08:53:26 +02:00
Piyush Bhaskar
1149b8e8ac feat(core): variables tab under Multipanel (#9498)
* feat(core): variables tab under Multipanel

* add unstaged changes

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-06-13 11:28:01 +05:30
Barthélémy Ledoux
18fe4e94a9 feat(ui): make version readonly on oss (#9486)
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-12 16:14:05 +02:00
github-actions[bot]
6d0f6c15fe Translations from en.json (#9501)
* fix: move type back to left

* make version field always readonly

* fix: add final touches

* fix: prefill anyof with current value type

* chore(core): localize to languages other than english (#9488)

Co-authored-by: GitHub Action <actions@github.com>

* fix: title of string pebble

* fix translations

* chore(core): localize to languages other than english

Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

---------

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <actions@github.com>
2025-06-12 13:39:32 +02:00
YannC
26df3e98af fix(ui): Better duplicate key management in the pair component (#9431)
* fix(ui): Better duplicate key mananage in the pair component

close #9220

* fix(ui): add a have-error prop on inputText that show a red shadow

* refactor: simplify inputpair component (#9491)

* fix: only show lock if disabled

* alertState define order

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-06-12 13:27:49 +02:00
Roman Acevedo
01ccd0db7b fix(tests): test editor was showing previous shown plugin doc
fixes https://github.com/kestra-io/kestra-ee/issues/4066
2025-06-12 13:20:37 +02:00
brian-mulier-p
06c67f491b feat(core): introduce tasksWithState autocompletion (#9485)
part of #8350
2025-06-12 09:55:21 +02:00
Kelvin Yim
079874e4ca fix(ui): resolve filter display inconsistency between dark and light themes (#9487)
* fix: resolve filter display inconsistency between dark and light themes

Updates KestraFilter.vue styling to ensure search criteria display
consistently across both theme modes.

Fixes #9398

* fix: resolve filter display inconsistency between dark and light themes

Updates KestraFilter.vue styling to ensure search criteria display
consistently across both theme modes.

* fix: resolve filter display inconsistency between dark and light themes

Updates KestraFilter.vue styling to ensure search criteria display
consistently across both theme modes.

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-06-12 13:16:18 +05:30
Barthélémy Ledoux
a5928fd016 fix(ui): nocode updating inputs from yaml (#9430) 2025-06-12 09:44:03 +02:00
Barthélémy Ledoux
efed3cb247 fix(ui): rename namespace field (#9492) 2025-06-12 09:38:41 +02:00
Barthélémy Ledoux
fab1bb0186 fix(ui): prevent cursor change in Editor component when modelValue is updated from outside (#9371) 2025-06-12 09:38:27 +02:00
Nicolas K.
cfa5ba5925 Feat/rework compatibility layer (#9490)
* feat(core): rework compatibility layer

* feat(core): #4062 rework compatibility layer

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-12 09:20:37 +02:00
dependabot[bot]
74720231b8 build(deps-dev): bump brace-expansion in /ui in the npm_and_yarn group (#9496)
Bumps the npm_and_yarn group in /ui with 1 update: [brace-expansion](https://github.com/juliangruber/brace-expansion).


Updates `brace-expansion` from 1.1.11 to 1.1.12
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 08:23:20 +02:00
Tanvir Ahmed
5dafbeee06 build(core): Replaced Microsoft Java with Temurin distribution on dev container 2025-06-11 23:00:37 +02:00
brian.mulier
f76f02952d fix(core): avoid infinite load upon route redirect (#9480)
closes #9479
2025-06-11 17:02:33 +02:00
brian.mulier
527c549522 fix(core): properly map labels filters from query (#9480)
closes #9324
2025-06-11 17:02:33 +02:00
brian.mulier
b6ad8331d4 fix(core): prevent incompatible timeRange & start/endDate filters + prevent multiple scope filters (#9480)
closes #9240
2025-06-11 17:02:33 +02:00
Karuna Tata
ac97e0aa72 feat(ui): drag and convert tabs to panels (#9198)
Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-06-11 16:48:39 +02:00
Barthélémy Ledoux
3309f69ee4 ci: fix frontend storybook tests (#9484) 2025-06-11 15:36:12 +02:00
Bart Ledoux
aaea1e0dd9 fix(ui): restore add button as a button 2025-06-11 14:17:07 +02:00
YannC.
a09fd76105 fix(ui): use type button instead of button 2025-06-11 14:11:13 +02:00
Roman Acevedo
afd4b811d6 feat(tests): add execution url in test result 2025-06-11 14:11:04 +02:00
YannC
a3f0001bca fix(ui): base the required prop on the requiredProperties list (#9433)
close #9377
2025-06-11 13:08:53 +02:00
Loïc Mathieu
075cc07b7a feat(system): don't deepClone maps inside MapUtils.merge 2025-06-11 11:38:20 +02:00
yuri
5b6311a612 fix(ui): amend visiblity of labels (#9475)
Currently labels just blend with the table row's background. This makes selecting labels slightly unpleasant.

This change makes labels a bit more visible, but still not as much visible as in e.g. v0.20.
2025-06-11 14:45:39 +05:30
dependabot[bot]
0d1f7a4db5 build(deps): bump io.micrometer:micrometer-core from 1.15.0 to 1.15.1
Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: io.micrometer:micrometer-core
  dependency-version: 1.15.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 10:36:46 +02:00
Satvik Kushwaha
5eafa90f2f fix(ui): make download and preview visible for text ouputs (#8348)
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-06-11 10:20:49 +02:00
Piyush Bhaskar
59ee76b1c5 fix(flows): importing flows will auto update the table without manual refresh. (#9468) 2025-06-11 13:34:07 +05:30
dependabot[bot]
7e312b8146 build(deps): bump software.amazon.awssdk.crt:aws-crt
Bumps [software.amazon.awssdk.crt:aws-crt](https://github.com/awslabs/aws-crt-java) from 0.38.4 to 0.38.5.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.4...v0.38.5)

---
updated-dependencies:
- dependency-name: software.amazon.awssdk.crt:aws-crt
  dependency-version: 0.38.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 10:00:39 +02:00
Miloš Paunović
266b62db8f fix(core): amend the problem with running storybook tests (#9470) 2025-06-11 09:52:09 +02:00
Barthélémy Ledoux
d31d8dbd55 fix(ui): variables should work with duplicated keys (#9425) 2025-06-11 09:45:34 +02:00
Barthélémy Ledoux
ee3afb575f fix(ui): add datepicker to nocode string field (#9351)
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-11 09:45:17 +02:00
dependabot[bot]
250c219839 build(deps): bump software.amazon.awssdk:bom from 2.31.59 to 2.31.61
Bumps software.amazon.awssdk:bom from 2.31.59 to 2.31.61.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.61
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 09:44:10 +02:00
dependabot[bot]
c1d40e6496 build(deps): bump com.google.cloud:libraries-bom from 26.61.0 to 26.62.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.61.0 to 26.62.0.
- [Release notes](https://github.com/googleapis/java-cloud-bom/releases)
- [Changelog](https://github.com/googleapis/java-cloud-bom/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/java-cloud-bom/compare/v26.61.0...v26.62.0)

---
updated-dependencies:
- dependency-name: com.google.cloud:libraries-bom
  dependency-version: 26.62.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 09:43:45 +02:00
dependabot[bot]
462550d59a build(deps): bump org.owasp.dependencycheck from 12.1.2 to 12.1.3
Bumps org.owasp.dependencycheck from 12.1.2 to 12.1.3.

---
updated-dependencies:
- dependency-name: org.owasp.dependencycheck
  dependency-version: 12.1.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 09:43:26 +02:00
Miloš Paunović
d00f52649a chore(deps): regular dependency update (#9402)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-06-11 09:29:33 +02:00
Piyush Bhaskar
b6603a161d fix(core): plugins docs container background. (#9461) 2025-06-11 12:57:40 +05:30
YannC
2f9c176440 feat(ui): allow to close a tab with mouse middle click like in a navigator/ide (#9434) 2025-06-11 08:44:19 +02:00
YannC
06f31dda33 fix(core): use Min annotation instead of Positive (#9432)
close #9380
2025-06-10 17:14:39 +02:00
Miloš Paunović
edc32f6548 fix(core)*: properly display chart colors for logs (#9429) 2025-06-10 13:51:35 +02:00
YannC.
d299ff77fe feat(): add Kestra plugin in the list 2025-06-10 12:43:26 +02:00
brian-mulier-p
aaf1812764 fix(core): handle properly dot in nested keys & commas in quoted filter values (#9410) 2025-06-10 11:42:29 +02:00
Florian Hussonnois
c67c71213d fix(plugins): check whether plugin registry support versioning (#9122) 2025-06-10 11:10:39 +02:00
Bart Ledoux
31e9323fba refactor: avoid duplicating vite alias 2025-06-10 10:44:18 +02:00
brian.mulier
d0fe252f5c chore(deps): bump vitest to 3.2.3 2025-06-10 10:44:18 +02:00
brian.mulier
e97f4054ac build(tests): replace workspaces with proper storybook config + working aliases 2025-06-10 10:44:18 +02:00
Florian Hussonnois
3dbb1d7c9a fix(system): allow service to move from CREATED to TERMINATING (#9408)
Fix: #9408
2025-06-10 10:11:27 +02:00
YannC.
92cddfc96a fix(): display correctly doc/chart preview when editing custom dashboard
close #9411
2025-06-10 09:46:48 +02:00
Loïc Mathieu
5304630b30 fix(system): avoid starting two queues for WorkerJob and WorkerTriggerResult
We previously starts 2 queues: one for emit, and a specific one for receive wich handle WorkerJobRunning under the cover.

We can replace by using a single queue that will transparently handle WorkerJobRunning. As queues starts thread pools their cost is not negligeable.

Fixes #9007
2025-06-10 09:36:54 +02:00
Ludovic DEHON
69bf11c935 feat(system): add server_type as global metrics tags 2025-06-10 09:22:19 +02:00
Miloš Paunović
574d75c0f1 refactor(core): properly import github icon to be used in template section (#9403) 2025-06-10 08:31:20 +02:00
Roman Acevedo
c39a6a9413 build(ci): fix setversion workflow not making tag push trigger main 2025-06-09 16:27:45 +02:00
Piyush Bhaskar
447ea8088d fix(core): remove deprecated Github icon. (#9401)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-06-09 18:14:18 +05:30
Florian Hussonnois
b0b158c204 chore: add script to update gradle kestraVersion prop on plugins 2025-06-09 14:30:20 +02:00
Loïc Mathieu
1ed60ba87e fix(system): import flow should set the tenantId 2025-06-09 13:51:14 +02:00
github-actions[bot]
c37ffe9c13 chore(core): localize to languages other than english (#9397)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-06-09 13:14:56 +02:00
Miloš Paunović
c5b9aa1f2e fix(namespaces): properly load flows when changing namespace (#9393)
Closes https://github.com/kestra-io/kestra/issues/9352.
2025-06-09 12:33:53 +02:00
Piyush Bhaskar
28d7a0cfa7 feat(core): add release notes for public plugins (#9374)
* feat(core): add release notes for public plugins

* fix(core): use pluginType for url construct from api.
2025-06-09 16:03:36 +05:30
brian-mulier-p
c00f125c16 fix(core): avoid adding invalid keys from query parameters to filter (#9383)
closes #9364
2025-06-09 12:25:13 +02:00
dependabot[bot]
b54705e641 build(deps): bump com.github.ben-manes.caffeine:caffeine
Bumps [com.github.ben-manes.caffeine:caffeine](https://github.com/ben-manes/caffeine) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.2.0...v3.2.1)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-version: 3.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 12:05:07 +02:00
dependabot[bot]
43eee222bf build(deps): bump org.owasp.dependencycheck from 12.1.1 to 12.1.2
Bumps org.owasp.dependencycheck from 12.1.1 to 12.1.2.

---
updated-dependencies:
- dependency-name: org.owasp.dependencycheck
  dependency-version: 12.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 11:26:46 +02:00
dependabot[bot]
eb1fad4193 build(deps): bump com.azure:azure-sdk-bom from 1.2.34 to 1.2.35
Bumps [com.azure:azure-sdk-bom](https://github.com/azure/azure-sdk-for-java) from 1.2.34 to 1.2.35.
- [Release notes](https://github.com/azure/azure-sdk-for-java/releases)
- [Commits](https://github.com/azure/azure-sdk-for-java/compare/azure-sdk-bom_1.2.34...azure-sdk-bom_1.2.35)

---
updated-dependencies:
- dependency-name: com.azure:azure-sdk-bom
  dependency-version: 1.2.35
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:51:31 +02:00
dependabot[bot]
d68a7c6431 build(deps): bump kafkaVersion from 3.9.0 to 4.0.0
Bumps `kafkaVersion` from 3.9.0 to 4.0.0.

Updates `org.apache.kafka:kafka-clients` from 3.9.0 to 4.0.0

Updates `org.apache.kafka:kafka-streams` from 3.9.0 to 4.0.0

Updates `org.apache.kafka:kafka-streams-test-utils` from 3.9.0 to 4.0.0

---
updated-dependencies:
- dependency-name: org.apache.kafka:kafka-clients
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: org.apache.kafka:kafka-streams
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: org.apache.kafka:kafka-streams-test-utils
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:36:42 +02:00
dependabot[bot]
9f327d24b1 build(deps): bump opensearchRestVersion from 2.19.2 to 3.0.0
Bumps `opensearchRestVersion` from 2.19.2 to 3.0.0.

Updates `org.opensearch.client:opensearch-rest-client` from 2.19.2 to 3.0.0
- [Release notes](https://github.com/opensearch-project/OpenSearch/releases)
- [Changelog](https://github.com/opensearch-project/OpenSearch/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/OpenSearch/compare/2.19.2...3.0.0)

Updates `org.opensearch.client:opensearch-rest-high-level-client` from 2.19.2 to 3.0.0
- [Release notes](https://github.com/opensearch-project/OpenSearch/releases)
- [Changelog](https://github.com/opensearch-project/OpenSearch/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/OpenSearch/compare/2.19.2...3.0.0)

---
updated-dependencies:
- dependency-name: org.opensearch.client:opensearch-rest-client
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: org.opensearch.client:opensearch-rest-high-level-client
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:36:26 +02:00
dependabot[bot]
5a3416db62 build(deps): bump org.projectlombok:lombok from 1.18.36 to 1.18.38
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.36 to 1.18.38.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.36...v1.18.38)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-version: 1.18.38
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:06:30 +02:00
dependabot[bot]
f7be8568cd build(deps): bump software.amazon.awssdk.crt:aws-crt
Bumps [software.amazon.awssdk.crt:aws-crt](https://github.com/awslabs/aws-crt-java) from 0.38.3 to 0.38.4.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.3...v0.38.4)

---
updated-dependencies:
- dependency-name: software.amazon.awssdk.crt:aws-crt
  dependency-version: 0.38.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:05:40 +02:00
dependabot[bot]
ced3067646 build(deps): bump aquasecurity/trivy-action from 0.30.0 to 0.31.0
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](https://github.com/aquasecurity/trivy-action/compare/0.30.0...0.31.0)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:05:23 +02:00
dependabot[bot]
32a3d37618 build(deps): bump bouncycastleVersion from 1.80 to 1.81
Bumps `bouncycastleVersion` from 1.80 to 1.81.

Updates `org.bouncycastle:bcprov-jdk18on` from 1.80 to 1.81
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

Updates `org.bouncycastle:bcpg-jdk18on` from 1.80 to 1.81
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

Updates `org.bouncycastle:bcpkix-jdk18on` from 1.80 to 1.81
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

---
updated-dependencies:
- dependency-name: org.bouncycastle:bcprov-jdk18on
  dependency-version: '1.81'
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcpg-jdk18on
  dependency-version: '1.81'
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcpkix-jdk18on
  dependency-version: '1.81'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:05:04 +02:00
dependabot[bot]
3b74190b2c build(deps): bump org.opensearch.client:opensearch-java
Bumps [org.opensearch.client:opensearch-java](https://github.com/opensearch-project/opensearch-java) from 2.23.0 to 3.1.0.
- [Release notes](https://github.com/opensearch-project/opensearch-java/releases)
- [Changelog](https://github.com/opensearch-project/opensearch-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/opensearch-java/compare/v2.23.0...v3.1.0)

---
updated-dependencies:
- dependency-name: org.opensearch.client:opensearch-java
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:04:43 +02:00
dependabot[bot]
e5083e7cab build(deps): bump software.amazon.awssdk:bom from 2.31.50 to 2.31.59
Bumps software.amazon.awssdk:bom from 2.31.50 to 2.31.59.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.31.59
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 10:04:24 +02:00
enumura
6aad4b7023 fix(core): amend core.metric.Publish task icon visibility in dark mode (#9375)
Closes https://github.com/kestra-io/kestra/issues/9226.
2025-06-06 15:27:11 +02:00
Miloš Paunović
5e1b059dee fix(namespaces): reload namespace once the id parameter changes (#9372)
Closes https://github.com/kestra-io/kestra-ee/issues/3630.
2025-06-06 12:14:45 +02:00
Barthélémy Ledoux
91983cbd29 fix: properly detect condition fields (#9353) 2025-06-06 11:23:46 +02:00
Barthélémy Ledoux
1dcccb706d fix(ui): nocode - open onPause in a new tab (#9366) 2025-06-06 11:23:22 +02:00
brian.mulier
4443ee235e chore(deps): add types for storybook tests 2025-06-06 11:20:08 +02:00
Barthélémy Ledoux
d83339dfcb fix(ui): Tabs that are not blueprint should appear only once (#9370) 2025-06-06 10:18:39 +02:00
dependabot[bot]
ef65793cf6 build(deps-dev): bump @vitest/coverage-v8 from 3.1.4 to 3.2.1 in /ui (#9300)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 09:58:49 +02:00
dependabot[bot]
7c44c7694d build(deps-dev): bump typescript-eslint from 8.32.1 to 8.33.1 in /ui (#9309)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 09:58:16 +02:00
dependabot[bot]
005253766c build(deps-dev): bump eslint from 9.27.0 to 9.28.0 in /ui (#9306)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 09:57:36 +02:00
dependabot[bot]
617e425bb0 build(deps-dev): bump @typescript-eslint/parser in /ui (#9301)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 09:57:14 +02:00
Barthélémy Ledoux
0636cc5e6a chore: upgrade storybook (#9326) 2025-06-06 09:54:50 +02:00
Barthélémy Ledoux
367f49d457 fix: initialize array fields without any value (#9367) 2025-06-06 09:42:15 +02:00
Piyush Bhaskar
b4d15494c1 feat(core): custom blueprints now in side menu. (#9349) 2025-06-06 12:07:38 +05:30
Satvik Kushwaha
a92aa030f5 fixed blueprint redirection in namespace (#9330)
* fixed blueprint redirection in namespace

* removed unnecessary changes
2025-06-06 12:06:42 +05:30
brian.mulier
7bcf284497 fix(core): add DefaultFilterLanguage as default in KestraFilter
closes #9365
2025-06-05 17:42:11 +02:00
Roman Acevedo
62e718fc12 tests(e2e): add workflow dispatch to launch manually 2025-06-05 14:39:27 +02:00
Roman Acevedo
762b0ec89c tests(core): add storybook on executions filters (#9354)
* tests(core): add storybook on executions filters

* refactor(core): reformat storybook executions filters

* Update ui/src/components/inputs/MonacoEditor.vue

Co-authored-by: brian-mulier-p <bmmulier@hotmail.fr>

* tests(core): stop using monaco class and expect color is red dominant

* tests(core): monacoFilter const

---------

Co-authored-by: brian-mulier-p <bmmulier@hotmail.fr>
2025-06-05 14:29:33 +02:00
Miloš Paunović
c6604cda32 fix(core): amend positioning of the default tour elements (#9360)
Closes https://github.com/kestra-io/kestra/issues/9356.
2025-06-05 14:22:28 +02:00
Barthélémy Ledoux
2a808be985 refactor: load nocode root form from server schema (#9327) 2025-06-05 14:12:46 +02:00
brian-mulier-p
649d5fee6e fix(core): avoid crashing in case of taskrun having too large value (#9359)
closes #9312
2025-06-05 14:08:20 +02:00
Karuna Tata
51afdfd396 fix(ui): clear selection of retry form radio buttons (#9268)
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
thank you so much for this geat work ! ❤️
2025-06-05 12:19:36 +02:00
Barthélémy Ledoux
ad2eb8a8b8 fix(ui): allow key of sub-tasks to be other than tasks (#9333) 2025-06-05 12:17:52 +02:00
François Delbrayelle
7124b53b7b feat(sifflet): add new plugin-sifflet 2025-06-05 10:54:57 +02:00
github-actions[bot]
d70b572257 chore(core): localize to languages other than english (#9347)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-06-05 10:26:11 +02:00
Piyush Bhaskar
50ca1d7946 feat(core): refactor of welcome and overide for card. (#9341)
* feat(core): refactor of welcome and overide for card.

* fix: remove type ignore
2025-06-05 13:42:48 +05:30
Nicolas K.
be14d818e6 fix(flows): #9319 error when puase with timeout trigger an execution (#9334)
* fix(flows): #9319 error when puase with timeout trigger an execution even after it's terminated

* fix(flows): only skip paused flow when execution is terminated

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-05 10:07:59 +02:00
YannC.
aab3fd408f fix(ci): put back bump helm chart and remove if condition 2025-06-05 08:49:06 +02:00
yuri
6323b0369b fix(core): add missing editor shortcut in the list (#9339)
Closes https://github.com/kestra-io/kestra/issues/9317.
2025-06-05 08:38:38 +02:00
YannC.
c06985cba8 fix(ci): modify actions order 2025-06-04 21:13:46 +02:00
brian.mulier
173cb29f56 fix(core): larger debounce for filter 2025-06-04 17:22:03 +02:00
brian.mulier
cc86b2064e fix(core): handle whitespaces in label key and value 2025-06-04 17:19:37 +02:00
brian.mulier
3e470d7674 fix(core): smarter autocomplete order in editor 2025-06-04 16:24:29 +02:00
brian-mulier-p
168e2e0db4 fix(core): additional plugins are now properly shown in plugin docs (#9329)
closes kestra-io/plugin-langchain4j#61
2025-06-04 15:42:32 +02:00
brian.mulier
51ce2208de fix(core): avoid suggest widget reset upon typing 2025-06-04 15:39:40 +02:00
YannC.
28f58e63d7 fix(ci): remove debug branch for actions checkout step 2025-06-04 14:59:09 +02:00
870 changed files with 53858 additions and 37718 deletions

View File

@@ -37,16 +37,16 @@ ARG OS_ARCHITECTURE
RUN mkdir -p /usr/java
RUN echo "Building on platform: $BUILDPLATFORM"
RUN case "$BUILDPLATFORM" in \
"linux/amd64") OS_ARCHITECTURE="linux-x64" ;; \
"linux/arm64") OS_ARCHITECTURE="linux-aarch64" ;; \
"darwin/amd64") OS_ARCHITECTURE="macos-x64" ;; \
"darwin/arm64") OS_ARCHITECTURE="macos-aarch64" ;; \
"linux/amd64") OS_ARCHITECTURE="x64_linux" ;; \
"linux/arm64") OS_ARCHITECTURE="aarch64_linux" ;; \
"darwin/amd64") OS_ARCHITECTURE="x64_mac" ;; \
"darwin/arm64") OS_ARCHITECTURE="aarch64_mac" ;; \
*) echo "Unsupported BUILDPLATFORM: $BUILDPLATFORM" && exit 1 ;; \
esac && \
wget "https://aka.ms/download-jdk/microsoft-jdk-21.0.6-$OS_ARCHITECTURE.tar.gz" && \
mv "microsoft-jdk-21.0.6-$OS_ARCHITECTURE.tar.gz" microsoft-jdk-21.0.6.tar.gz
RUN tar -xzvf microsoft-jdk-21.0.6.tar.gz && \
mv jdk-21.0.6+7 jdk-21 && \
wget "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.7%2B6/OpenJDK21U-jdk_${OS_ARCHITECTURE}_hotspot_21.0.7_6.tar.gz" && \
mv OpenJDK21U-jdk_${OS_ARCHITECTURE}_hotspot_21.0.7_6.tar.gz openjdk-21.0.7.tar.gz
RUN tar -xzvf openjdk-21.0.7.tar.gz && \
mv jdk-21.0.7+6 jdk-21 && \
mv jdk-21 /usr/java/
ENV JAVA_HOME=/usr/java/jdk-21
ENV PATH="$PATH:$JAVA_HOME/bin"

View File

@@ -27,11 +27,6 @@ In the meantime, you can move onto the next step...
- Create a `.env.development.local` file in the `ui` folder and paste the following:
```bash
# This lets the frontend know what the backend URL is but you are free to change this to your actual server URL e.g. hosted version of Kestra.
VITE_APP_API_URL=http://localhost:8080
```
- Navigate into the `ui` folder and run `npm install` to install the dependencies for the frontend project.
- Now go to the `cli/src/main/resources` folder and create a `application-override.yml` file.
@@ -74,9 +69,6 @@ kestra:
path: /tmp/kestra-wd/tmp
anonymous-usage-report:
enabled: false
server:
basic-auth:
enabled: false
datasources:
postgres:

View File

@@ -39,7 +39,7 @@
"yoavbls.pretty-ts-errors",
"github.vscode-github-actions",
"vscjava.vscode-java-pack",
"ms-azuretools.vscode-docker"
"docker.docker"
]
}
}

View File

@@ -80,7 +80,6 @@ python3 -m pip install virtualenv
The frontend is made with [Vue.js](https://vuejs.org/) and located on the `/ui` folder.
- `npm install`
- create a file `ui/.env.development.local` with content `VITE_APP_API_URL=http://localhost:8080` (or your actual server url)
- `npm run dev` will start the development server with hot reload.
- The server start by default on port 5173 and is reachable on `http://localhost:5173`
- You can run `npm run build` in order to build the front-end that will be delivered from the backend (without running the `npm run dev`) above.

View File

@@ -1,26 +1,31 @@
# See GitHub's docs for more information on this file:
# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
day: "wednesday"
time: "08:00"
timezone: "Europe/Paris"
open-pull-requests-limit: 50
labels:
- "dependency-upgrade"
open-pull-requests-limit: 50
# Maintain dependencies for Gradle modules
- package-ecosystem: "gradle"
directory: "/"
schedule:
# Check for updates to Gradle modules every week
interval: "weekly"
day: "wednesday"
time: "08:00"
timezone: "Europe/Paris"
open-pull-requests-limit: 50
labels:
- "dependency-upgrade"
open-pull-requests-limit: 50
# Maintain dependencies for NPM modules
- package-ecosystem: "npm"
@@ -31,8 +36,15 @@ updates:
time: "08:00"
timezone: "Europe/Paris"
open-pull-requests-limit: 50
labels: ["dependency-upgrade"]
labels:
- "dependency-upgrade"
ignore:
# Ignore updates of version 1.x, as we're using beta of 2.x
# Ignore updates of version 1.x, as we're using the beta of 2.x (still in beta)
- dependency-name: "vue-virtual-scroller"
versions: ["1.x"]
versions:
- "1.x"
# Ignore updates to monaco-yaml, version is pinned to 5.3.1 due to patch-package script additions
- dependency-name: "monaco-yaml"
versions:
- ">=5.3.2"

View File

@@ -43,9 +43,6 @@ jobs:
with:
node-version: "20.x"
- name: Check keys matching
run: node ui/src/translations/check.js
- name: Set up Git
run: |
git config --global user.name "GitHub Action"
@@ -64,4 +61,7 @@ jobs:
fi
git commit -m "chore(core): localize to languages other than english" -m "Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference."
git push -u origin $BRANCH_NAME || (git push origin --delete $BRANCH_NAME && git push -u origin $BRANCH_NAME)
gh pr create --title "Translations from en.json" --body "This PR was created automatically by a GitHub Action." --base develop --head $BRANCH_NAME --assignee anna-geller --reviewer anna-geller
gh pr create --title "Translations from en.json" --body $'This PR was created automatically by a GitHub Action.\n\nSomeone from the @kestra-io/frontend team needs to review and merge.' --base ${{ github.ref_name }} --head $BRANCH_NAME
- name: Check keys matching
run: node ui/src/translations/check.js

View File

@@ -7,7 +7,7 @@ on:
description: 'Retag latest Docker images'
required: true
type: string
default: "true"
default: "false"
options:
- "true"
- "false"
@@ -20,6 +20,15 @@ on:
required: false
type: string
default: "LATEST"
force-download-artifact:
description: 'Force download artifact'
required: false
type: string
default: "true"
options:
- "true"
- "false"
env:
PLUGIN_VERSION: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
jobs:
@@ -38,9 +47,18 @@ jobs:
id: plugins
with:
plugin-version: ${{ env.PLUGIN_VERSION }}
# ********************************************************************************************************************
# Build
# ********************************************************************************************************************
build-artifacts:
name: Build Artifacts
if: ${{ github.event.inputs.force-download-artifact == 'true' }}
uses: ./.github/workflows/workflow-build-artifacts.yml
docker:
name: Publish Docker
needs: [ plugins ]
needs: [ plugins, build-artifacts ]
runs-on: ubuntu-latest
strategy:
matrix:
@@ -69,18 +87,31 @@ jobs:
fi
if [[ "${{ env.PLUGIN_VERSION }}" == *"-SNAPSHOT" ]]; then
echo "plugins=--repositories=https://s01.oss.sonatype.org/content/repositories/snapshots ${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT;
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots ${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT;
else
echo "plugins=${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT
fi
# Download release
- name: Download release
# [workflow_dispatch]
# Download executable from GitHub Release
- name: Artifacts - Download release (workflow_dispatch)
id: download-github-release
if: github.event_name == 'workflow_dispatch' && github.event.inputs.force-download-artifact == 'false'
uses: robinraju/release-downloader@v1.12
with:
tag: ${{steps.vars.outputs.tag}}
fileName: 'kestra-*'
out-file-path: build/executable
# [workflow_call]
# Download executable from artifact
- name: Artifacts - Download executable
if: github.event_name != 'workflow_dispatch' || steps.download-github-release.outcome == 'skipped'
uses: actions/download-artifact@v4
with:
name: exe
path: build/executable
- name: Copy exe to image
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra

View File

@@ -1,42 +1,36 @@
name: 'Reusable Workflow for Running End-to-End Tests'
name: 'E2E tests revival'
description: 'New E2E tests implementation started by Roman. Based on playwright in npm UI project, tests Kestra OSS develop docker image. These tests are written from zero, lets make them unflaky from the start!.'
on:
schedule:
- cron: "0 * * * *" # Every hour
workflow_call:
inputs:
tags:
description: "Tags used for filtering tests to include for QA."
type: string
required: true
docker-artifact-name:
description: "The GitHub artifact containing the Kestra docker image."
type: string
noInputYet:
description: 'not input yet.'
required: false
docker-image-tag:
description: "The Docker image Tag for Kestra"
default: 'kestra/kestra:develop'
type: string
required: true
backend:
description: "The Kestra backend type to be used for E2E tests."
type: string
required: true
default: "postgres"
secrets:
GITHUB_AUTH_TOKEN:
description: "The GitHub Token."
required: true
GOOGLE_SERVICE_ACCOUNT:
description: "The Google Service Account."
default: "no input"
workflow_dispatch:
inputs:
noInputYet:
description: 'not input yet.'
required: false
type: string
default: "no input"
jobs:
check:
timeout-minutes: 60
timeout-minutes: 10
runs-on: ubuntu-latest
env:
GOOGLE_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}
E2E_TEST_DOCKER_DIR: ./kestra/e2e-tests/docker
KESTRA_BASE_URL: http://127.27.27.27:8080/ui/
steps:
# Checkout kestra
- name: Login to DockerHub
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Checkout kestra
uses: actions/checkout@v4
with:
@@ -44,115 +38,49 @@ jobs:
# Setup build
- uses: kestra-io/actions/.github/actions/setup-build@main
name: Setup - Build
id: build
with:
java-enabled: true
node-enabled: true
python-enabled: true
# Get Docker Image
- name: Download Kestra Image
if: inputs.docker-artifact-name != ''
uses: actions/download-artifact@v4
with:
name: ${{ inputs.docker-artifact-name }}
path: /tmp
- name: Load Kestra Image
if: inputs.docker-artifact-name != ''
- name: Install Npm dependencies
run: |
docker load --input /tmp/${{ inputs.docker-artifact-name }}.tar
# Docker Compose
- name: Login to DockerHub
uses: docker/login-action@v3
if: inputs.docker-artifact-name == ''
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
# Build configuration
- name: Create additional application configuration
run: |
touch ${{ env.E2E_TEST_DOCKER_DIR }}/data/application-secrets.yml
- name: Setup additional application configuration
if: env.APPLICATION_SECRETS != null
env:
APPLICATION_SECRETS: ${{ secrets.APPLICATION_SECRETS }}
run: |
echo $APPLICATION_SECRETS | base64 -d > ${{ env.E2E_TEST_DOCKER_DIR }}/data/application-secrets.yml
# Deploy Docker Compose Stack
- name: Run Kestra (${{ inputs.backend }})
env:
KESTRA_DOCKER_IMAGE: ${{ inputs.docker-image-tag }}
run: |
cd ${{ env.E2E_TEST_DOCKER_DIR }}
echo "KESTRA_DOCKER_IMAGE=$KESTRA_DOCKER_IMAGE" >> .env
docker compose -f docker-compose-${{ inputs.backend }}.yml up -d
- name: Install Playwright Deps
run: |
cd kestra
./gradlew playwright --args="install-deps"
# Run E2E Tests
- name: Wait For Kestra UI
run: |
# Start time
START_TIME=$(date +%s)
# Timeout duration in seconds (5 minutes)
TIMEOUT_DURATION=$((5 * 60))
while [ $(curl -s -L -o /dev/null -w %{http_code} $KESTRA_BASE_URL) != 200 ]; do
echo -e $(date) "\tKestra server HTTP state: " $(curl -k -L -s -o /dev/null -w %{http_code} $KESTRA_BASE_URL) " (waiting for 200)";
# Check the elapsed time
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
# Break the loop if the elapsed time exceeds the timeout duration
if [ $ELAPSED_TIME -ge $TIMEOUT_DURATION ]; then
echo "Timeout reached: Exiting after 5 minutes."
exit 1;
fi
sleep 2;
done;
echo "Kestra is running: $KESTRA_BASE_URL 🚀";
continue-on-error: true
- name: Run E2E Tests (${{ inputs.tags }})
if: inputs.tags != ''
run: |
cd kestra
./gradlew e2eTestsCheck -P tags=${{ inputs.tags }}
cd kestra/ui
npm i
npx playwright install --with-deps chromium
- name: Run E2E Tests
if: inputs.tags == ''
run: |
cd kestra
./gradlew e2eTestsCheck
sh build-and-start-e2e-tests.sh
# Allure check
- name: Auth to Google Cloud
id: auth
if: ${{ !cancelled() && env.GOOGLE_SERVICE_ACCOUNT != 0 }}
uses: 'google-github-actions/auth@v2'
- name: Upload Playwright Report as Github artifact
# 'With this report, you can analyze locally the results of the tests. see https://playwright.dev/docs/ci-intro#html-report'
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
credentials_json: '${{ secrets.GOOGLE_SERVICE_ACCOUNT }}'
- uses: rlespinasse/github-slug-action@v5
- name: Publish allure report
uses: andrcuns/allure-publish-action@v2.9.0
if: ${{ !cancelled() && env.GOOGLE_SERVICE_ACCOUNT != 0 }}
env:
GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_AUTH_TOKEN }}
JAVA_HOME: /usr/lib/jvm/default-jvm/
with:
storageType: gcs
resultsGlob: build/allure-results
bucket: internal-kestra-host
baseUrl: "https://internal.dev.kestra.io"
prefix: ${{ format('{0}/{1}/{2}', github.repository, env.GITHUB_HEAD_REF_SLUG != '' && env.GITHUB_HEAD_REF_SLUG || github.ref_name, 'allure/playwright') }}
copyLatest: true
ignoreMissingResults: true
name: playwright-report
path: kestra/ui/playwright-report/
retention-days: 7
# Allure check
# TODO I don't know what it should do
# - uses: rlespinasse/github-slug-action@v5
# name: Allure - Generate slug variables
#
# - name: Allure - Publish report
# uses: andrcuns/allure-publish-action@v2.9.0
# if: always() && env.GOOGLE_SERVICE_ACCOUNT != ''
# continue-on-error: true
# env:
# GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_AUTH_TOKEN }}
# JAVA_HOME: /usr/lib/jvm/default-jvm/
# with:
# storageType: gcs
# resultsGlob: "**/build/allure-results"
# bucket: internal-kestra-host
# baseUrl: "https://internal.dev.kestra.io"
# prefix: ${{ format('{0}/{1}', github.repository, 'allure/java') }}
# copyLatest: true
# ignoreMissingResults: true

View File

@@ -43,6 +43,7 @@ jobs:
SONATYPE_GPG_KEYID: ${{ secrets.SONATYPE_GPG_KEYID }}
SONATYPE_GPG_PASSWORD: ${{ secrets.SONATYPE_GPG_PASSWORD }}
SONATYPE_GPG_FILE: ${{ secrets.SONATYPE_GPG_FILE }}
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
end:
runs-on: ubuntu-latest
@@ -52,15 +53,14 @@ jobs:
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
# Update
- name: Github - Update internal
uses: benc-uk/workflow-dispatch@v1
if: github.ref == 'refs/heads/develop' && needs.docker.result == 'success'
- name: Trigger EE Workflow
uses: peter-evans/repository-dispatch@v3
if: github.ref == 'refs/heads/develop' && needs.release.result == 'success'
with:
workflow: oss-build.yml
repo: kestra-io/infra
ref: master
token: ${{ secrets.GH_PERSONAL_TOKEN }}
repository: kestra-io/kestra-ee
event-type: "oss-updated"
# Slack
- name: Slack - Notification

View File

@@ -56,6 +56,10 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GOOGLE_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}
e2e-tests:
name: E2E - Tests
uses: ./.github/workflows/e2e.yml
end:
name: End
runs-on: ubuntu-latest

View File

@@ -22,11 +22,11 @@ jobs:
echo "Invalid release version. Must match regex: ^[0-9]+(\.[0-9]+)(\.[0-9]+)-(rc[0-9])?(-SNAPSHOT)?$"
exit 1
fi
# Extract the major and minor versions
BASE_VERSION=$(echo "$RELEASE_VERSION" | sed -E 's/^([0-9]+\.[0-9]+)\..*/\1/')
RELEASE_BRANCH="refs/heads/releases/v${BASE_VERSION}.x"
CURRENT_BRANCH="$GITHUB_REF"
if ! [[ "$CURRENT_BRANCH" == "$RELEASE_BRANCH" ]]; then
echo "Invalid release branch. Expected $RELEASE_BRANCH, was $CURRENT_BRANCH"
@@ -54,4 +54,4 @@ jobs:
git commit -m"chore(version): update to version '$RELEASE_VERSION'"
git push
git tag -a "v$RELEASE_VERSION" -m"v$RELEASE_VERSION"
git push origin "v$RELEASE_VERSION"
git push --tags

View File

@@ -87,7 +87,7 @@ jobs:
# Run Trivy image scan for Docker vulnerabilities, see https://github.com/aquasecurity/trivy-action
- name: Docker Vulnerabilities Check
uses: aquasecurity/trivy-action@0.30.0
uses: aquasecurity/trivy-action@0.32.0
with:
image-ref: kestra/kestra:develop
format: 'template'
@@ -132,7 +132,7 @@ jobs:
# Run Trivy image scan for Docker vulnerabilities, see https://github.com/aquasecurity/trivy-action
- name: Docker Vulnerabilities Check
uses: aquasecurity/trivy-action@0.30.0
uses: aquasecurity/trivy-action@0.32.0
with:
image-ref: kestra/kestra:latest
format: table

View File

@@ -1,23 +1,7 @@
name: Build Artifacts
on:
workflow_call:
inputs:
plugin-version:
description: "Kestra version"
default: 'LATEST'
required: true
type: string
outputs:
docker-tag:
value: ${{ jobs.build.outputs.docker-tag }}
description: "The Docker image Tag for Kestra"
docker-artifact-name:
value: ${{ jobs.build.outputs.docker-artifact-name }}
description: "The GitHub artifact containing the Kestra docker image name."
plugins:
value: ${{ jobs.build.outputs.plugins }}
description: "The Kestra plugins list used for the build."
workflow_call: {}
jobs:
build:
@@ -68,7 +52,7 @@ jobs:
if [[ $TAG = "master" || $TAG == v* ]]; then
echo "plugins=$PLUGINS" >> $GITHUB_OUTPUT
else
echo "plugins=--repositories=https://s01.oss.sonatype.org/content/repositories/snapshots $PLUGINS" >> $GITHUB_OUTPUT
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ $PLUGINS" >> $GITHUB_OUTPUT
fi
# Build
@@ -82,55 +66,6 @@ jobs:
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra
# Docker Tag
- name: Setup - Docker vars
id: vars
shell: bash
run: |
TAG=${GITHUB_REF#refs/*/}
if [[ $TAG = "master" ]]
then
TAG="latest";
elif [[ $TAG = "develop" ]]
then
TAG="develop";
elif [[ $TAG = v* ]]
then
TAG="${TAG}";
else
TAG="build-${{ github.run_id }}";
fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "artifact=docker-kestra-${TAG}" >> $GITHUB_OUTPUT
# Docker setup
- name: Docker - Setup QEMU
uses: docker/setup-qemu-action@v3
- name: Docker - Fix Qemu
shell: bash
run: |
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
- name: Docker - Setup Buildx
uses: docker/setup-buildx-action@v3
# Docker Build
- name: Docker - Build & export image
uses: docker/build-push-action@v6
if: "!startsWith(github.ref, 'refs/tags/v')"
with:
context: .
push: false
file: Dockerfile
tags: |
kestra/kestra:${{ steps.vars.outputs.tag }}
build-args: |
KESTRA_PLUGINS=${{ steps.plugins.outputs.plugins }}
APT_PACKAGES=${{ env.DOCKER_APT_PACKAGES }}
PYTHON_LIBRARIES=${{ env.DOCKER_PYTHON_LIBRARIES }}
outputs: type=docker,dest=/tmp/${{ steps.vars.outputs.artifact }}.tar
# Upload artifacts
- name: Artifacts - Upload JAR
uses: actions/upload-artifact@v4
@@ -143,10 +78,3 @@ jobs:
with:
name: exe
path: build/executable/
- name: Artifacts - Upload Docker
uses: actions/upload-artifact@v4
if: "!startsWith(github.ref, 'refs/tags/v')"
with:
name: ${{ steps.vars.outputs.artifact }}
path: /tmp/${{ steps.vars.outputs.artifact }}.tar

View File

@@ -39,7 +39,6 @@ jobs:
key: playwright-${{ hashFiles('ui/package-lock.json') }}
- name: Npm - install
shell: bash
if: steps.cache-node-modules.outputs.cache-hit != 'true'
working-directory: ui
run: npm ci
@@ -52,35 +51,20 @@ jobs:
workdir: ui
- name: Npm - Run build
shell: bash
working-directory: ui
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: npm run build
- name: Run front-end unit tests
working-directory: ui
run: npm run test:unit -- --coverage
- name: Storybook - Install Playwright
shell: bash
working-directory: ui
if: steps.cache-playwright.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
- name: Run front-end unit tests
shell: bash
- name: Run storybook component tests
working-directory: ui
run: npm run test:cicd
- name: Codecov - Upload coverage reports
uses: codecov/codecov-action@v5
if: ${{ !cancelled() && github.event.pull_request.head.repo.full_name == github.repository }}
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: frontend
- name: Codecov - Upload test results
uses: codecov/test-results-action@v1
if: ${{ !cancelled() }}
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN && github.event.pull_request.head.repo.full_name == github.repository }}
flags: frontend
run: npm run test:storybook -- --coverage

View File

@@ -1,6 +1,8 @@
name: Github - Release
on:
workflow_dispatch:
workflow_call:
secrets:
GH_PERSONAL_TOKEN:
@@ -15,14 +17,6 @@ jobs:
name: Github - Release
runs-on: ubuntu-latest
steps:
# Download Exec
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
name: exe
path: build/executable
# Check out
- name: Checkout - Repository
uses: actions/checkout@v4
@@ -36,16 +30,51 @@ jobs:
with:
repository: kestra-io/actions
sparse-checkout-cone-mode: true
ref: fix/core-release
path: actions
sparse-checkout: |
.github/actions
# Download Exec
# Must be done after checkout actions
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
name: exe
path: build/executable
- name: Check if current tag is latest
id: is_latest
run: |
latest_tag=$(git tag | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sed 's/^v//' | sort -V | tail -n1)
current_tag="${GITHUB_REF_NAME#v}"
if [ "$current_tag" = "$latest_tag" ]; then
echo "latest=true" >> $GITHUB_OUTPUT
else
echo "latest=false" >> $GITHUB_OUTPUT
fi
env:
GITHUB_REF_NAME: ${{ github.ref_name }}
# GitHub Release
- name: Create GitHub release
uses: ./actions/.github/actions/github-release
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
MAKE_LATEST: ${{ steps.is_latest.outputs.latest }}
GITHUB_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}
# Trigger gha workflow to bump helm chart version
- name: GitHub - Trigger the Helm chart version bump
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.GH_PERSONAL_TOKEN }}
repository: kestra-io/helm-charts
event-type: update-helm-chart-version
client-payload: |-
{
"new_version": "${{ github.ref_name }}",
"github_repository": "${{ github.repository }}",
"github_actor": "${{ github.actor }}"
}

View File

@@ -41,8 +41,6 @@ jobs:
name: Build Artifacts
if: ${{ github.event.inputs.force-download-artifact == 'true' }}
uses: ./.github/workflows/workflow-build-artifacts.yml
with:
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
# ********************************************************************************************************************
# Docker
# ********************************************************************************************************************
@@ -112,12 +110,12 @@ jobs:
echo "plugins=${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT
elif [[ $TAG = "develop" ]]; then
TAG="develop";
echo "plugins=--repositories=https://s01.oss.sonatype.org/content/repositories/snapshots $PLUGINS" >> $GITHUB_OUTPUT
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ $PLUGINS" >> $GITHUB_OUTPUT
else
TAG="build-${{ github.run_id }}";
echo "plugins=--repositories=https://s01.oss.sonatype.org/content/repositories/snapshots $PLUGINS" >> $GITHUB_OUTPUT
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ $PLUGINS" >> $GITHUB_OUTPUT
fi
echo "tag=${TAG}${{ matrix.image.tag }}" >> $GITHUB_OUTPUT
# Build Docker Image

View File

@@ -39,8 +39,8 @@ jobs:
- name: Publish - Release package to Maven Central
shell: bash
env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USER }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }}
SONATYPE_GPG_KEYID: ${{ secrets.SONATYPE_GPG_KEYID }}
SONATYPE_GPG_PASSWORD: ${{ secrets.SONATYPE_GPG_PASSWORD }}
SONATYPE_GPG_FILE: ${{ secrets.SONATYPE_GPG_FILE}}
@@ -50,7 +50,7 @@ jobs:
echo "signing.password=${SONATYPE_GPG_PASSWORD}" >> ~/.gradle/gradle.properties
echo "signing.secretKeyRingFile=${HOME}/.gradle/secring.gpg" >> ~/.gradle/gradle.properties
echo ${SONATYPE_GPG_FILE} | base64 -d > ~/.gradle/secring.gpg
./gradlew publishToSonatype ${{ startsWith(github.ref, 'refs/tags/v') && 'closeAndReleaseSonatypeStagingRepository' || '' }}
./gradlew publishToMavenCentral
# Gradle dependency
- name: Java - Gradle dependency graph

View File

@@ -42,12 +42,13 @@ on:
SONATYPE_GPG_FILE:
description: "The Sonatype GPG file."
required: true
GH_PERSONAL_TOKEN:
description: "GH personnal Token."
required: true
jobs:
build-artifacts:
name: Build - Artifacts
uses: ./.github/workflows/workflow-build-artifacts.yml
with:
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
Docker:
name: Publish Docker

View File

@@ -3,10 +3,12 @@
# Format: <RepositoryName>:<GroupId>:<ArtifactId>:<Version>
#
# Uncomment the lines corresponding to the plugins to be installed:
#plugin-ai:io.kestra.plugin:plugin-ai:LATEST
#plugin-airbyte:io.kestra.plugin:plugin-airbyte:LATEST
#plugin-airflow:io.kestra.plugin:plugin-airflow:LATEST
#plugin-amqp:io.kestra.plugin:plugin-amqp:LATEST
#plugin-ansible:io.kestra.plugin:plugin-ansible:LATEST
#plugin-anthropic:io.kestra.plugin:plugin-anthropic:LATEST
#plugin-aws:io.kestra.plugin:plugin-aws:LATEST
#plugin-azure:io.kestra.plugin:plugin-azure:LATEST
#plugin-cassandra:io.kestra.plugin:plugin-cassandra:LATEST
@@ -24,11 +26,13 @@
#plugin-debezium:io.kestra.plugin:plugin-debezium-oracle:LATEST
#plugin-debezium:io.kestra.plugin:plugin-debezium-postgres:LATEST
#plugin-debezium:io.kestra.plugin:plugin-debezium-sqlserver:LATEST
#plugin-deepseek:io.kestra.plugin:plugin-deepseek:LATEST
#plugin-docker:io.kestra.plugin:plugin-docker:LATEST
#plugin-elasticsearch:io.kestra.plugin:plugin-elasticsearch:LATEST
#plugin-fivetran:io.kestra.plugin:plugin-fivetran:LATEST
#plugin-fs:io.kestra.plugin:plugin-fs:LATEST
#plugin-gcp:io.kestra.plugin:plugin-gcp:LATEST
#plugin-gemini:io.kestra.plugin:plugin-gemini:LATEST
#plugin-git:io.kestra.plugin:plugin-git:LATEST
#plugin-github:io.kestra.plugin:plugin-github:LATEST
#plugin-googleworkspace:io.kestra.plugin:plugin-googleworkspace:LATEST
@@ -61,32 +65,40 @@
#plugin-jenkins:io.kestra.plugin:plugin-jenkins:LATEST
#plugin-jira:io.kestra.plugin:plugin-jira:LATEST
#plugin-kafka:io.kestra.plugin:plugin-kafka:LATEST
#plugin-kestra:io.kestra.plugin:plugin-kestra:LATEST
#plugin-kubernetes:io.kestra.plugin:plugin-kubernetes:LATEST
#plugin-langchain4j:io.kestra.plugin:plugin-langchain4j:LATEST
#plugin-ldap:io.kestra.plugin:plugin-ldap:LATEST
#plugin-linear:io.kestra.plugin:plugin-linear:LATEST
#plugin-malloy:io.kestra.plugin:plugin-malloy:LATEST
#plugin-meilisearch:io.kestra.plugin:plugin-meilisearch:LATEST
#plugin-minio:io.kestra.plugin:plugin-minio:LATEST
#plugin-mistral:io.kestra.plugin:plugin-mistral:LATEST
#plugin-modal:io.kestra.plugin:plugin-modal:LATEST
#plugin-mongodb:io.kestra.plugin:plugin-mongodb:LATEST
#plugin-mqtt:io.kestra.plugin:plugin-mqtt:LATEST
#plugin-nats:io.kestra.plugin:plugin-nats:LATEST
#plugin-neo4j:io.kestra.plugin:plugin-neo4j:LATEST
#plugin-notifications:io.kestra.plugin:plugin-notifications:LATEST
#plugin-notion:io.kestra.plugin:plugin-notion:LATEST
#plugin-ollama:io.kestra.plugin:plugin-ollama:LATEST
#plugin-openai:io.kestra.plugin:plugin-openai:LATEST
#plugin-opensearch:io.kestra.plugin:plugin-opensearch:LATEST
#plugin-perplexity:io.kestra.plugin:plugin-perplexity:LATEST
#plugin-powerbi:io.kestra.plugin:plugin-powerbi:LATEST
#plugin-pulsar:io.kestra.plugin:plugin-pulsar:LATEST
#plugin-redis:io.kestra.plugin:plugin-redis:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-bun:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-deno:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-go:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-groovy:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-jbang:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-julia:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-jython:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-lua:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-nashorn:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-node:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-perl:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-php:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-powershell:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-python:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-r:LATEST
@@ -94,6 +106,7 @@
#plugin-scripts:io.kestra.plugin:plugin-script-shell:LATEST
#plugin-serdes:io.kestra.plugin:plugin-serdes:LATEST
#plugin-servicenow:io.kestra.plugin:plugin-servicenow:LATEST
#plugin-sifflet:io.kestra.plugin:plugin-sifflet:LATEST
#plugin-singer:io.kestra.plugin:plugin-singer:LATEST
#plugin-soda:io.kestra.plugin:plugin-soda:LATEST
#plugin-solace:io.kestra.plugin:plugin-solace:LATEST

View File

@@ -77,7 +77,7 @@ install-plugins:
else \
${KESTRA_BASEDIR}/bin/kestra plugins install $$CURRENT_PLUGIN \
--plugins ${KESTRA_BASEDIR}/plugins \
--repositories=https://s01.oss.sonatype.org/content/repositories/snapshots || exit 1; \
--repositories=https://central.sonatype.com/repository/maven-snapshots || exit 1; \
fi \
done < $$PLUGIN_LIST
@@ -130,9 +130,6 @@ datasources:
username: kestra
password: k3str4
kestra:
server:
basic-auth:
enabled: false
encryption:
secret-key: 3ywuDa/Ec61VHkOX3RlI9gYq7CaD0mv0Pf3DHtAXA6U=
repository:

46
build-and-start-e2e-tests.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -e
# E2E main script that can be run on a dev computer or in the CI
# it will build the backend of the current git repo and the frontend
# create a docker image out of it
# run tests on this image
LOCAL_IMAGE_VERSION="local-e2e"
echo "Running E2E"
echo "Start time: $(date '+%Y-%m-%d %H:%M:%S')"
start_time=$(date +%s)
echo ""
echo "Building the image for this current repository"
make build-docker VERSION=$LOCAL_IMAGE_VERSION
end_time=$(date +%s)
elapsed=$(( end_time - start_time ))
echo ""
echo "building elapsed time: ${elapsed} seconds"
echo ""
echo "Start time: $(date '+%Y-%m-%d %H:%M:%S')"
start_time2=$(date +%s)
echo "cd ./ui"
cd ./ui
echo "npm i"
npm i
echo 'sh ./run-e2e-tests.sh --kestra-docker-image-to-test "kestra/kestra:$LOCAL_IMAGE_VERSION"'
sh ./run-e2e-tests.sh --kestra-docker-image-to-test "kestra/kestra:$LOCAL_IMAGE_VERSION"
end_time2=$(date +%s)
elapsed2=$(( end_time2 - start_time2 ))
echo ""
echo "Tests elapsed time: ${elapsed2} seconds"
echo ""
total_elapsed=$(( elapsed + elapsed2 ))
echo "Total elapsed time: ${total_elapsed} seconds"
echo ""
exit 0

View File

@@ -16,7 +16,7 @@ plugins {
id "java"
id 'java-library'
id "idea"
id "com.gradleup.shadow" version "8.3.6"
id "com.gradleup.shadow" version "8.3.8"
id "application"
// test
@@ -31,15 +31,13 @@ plugins {
id 'com.github.node-gradle.node' version '7.1.0'
// release
id "io.github.gradle-nexus.publish-plugin" version "2.0.0"
id 'net.researchgate.release' version '3.1.0'
id "com.gorylenko.gradle-git-properties" version "2.5.0"
id "com.gorylenko.gradle-git-properties" version "2.5.2"
id 'signing'
id 'ru.vyarus.pom' version '3.0.0' apply false
id 'ru.vyarus.github-info' version '2.0.0' apply false
id "com.vanniktech.maven.publish" version "0.34.0"
// OWASP dependency check
id "org.owasp.dependencycheck" version "12.1.1" apply false
id "org.owasp.dependencycheck" version "12.1.3" apply false
}
idea {
@@ -73,6 +71,11 @@ dependencies {
* Dependencies
**********************************************************************************************************************/
allprojects {
tasks.withType(GenerateModuleMetadata).configureEach {
suppressedValidationErrors.add('enforced-platform')
}
if (it.name != 'platform') {
group = "io.kestra"
@@ -145,6 +148,7 @@ allprojects {
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-guava'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310'
implementation group: 'com.fasterxml.uuid', name: 'java-uuid-generator'
// kestra
implementation group: 'com.devskiller.friendly-id', name: 'friendly-id'
@@ -414,6 +418,7 @@ distTar.dependsOn shadowJar
startScripts.dependsOn shadowJar
startShadowScripts.dependsOn jar
shadowJar.dependsOn 'ui:assembleFrontend'
shadowJar.dependsOn jar
/**********************************************************************************************************************\
* Executable Jar
@@ -484,24 +489,11 @@ tasks.register('runStandalone', JavaExec) {
/**********************************************************************************************************************\
* Publish
**********************************************************************************************************************/
nexusPublishing {
repositoryDescription = "${project.group}:${rootProject.name}:${project.version}"
useStaging = !project.version.endsWith("-SNAPSHOT")
repositories {
sonatype {
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
}
}
}
subprojects {subProject ->
subprojects {
if (it.name != 'jmh-benchmarks') {
apply plugin: "maven-publish"
if (subProject.name != 'jmh-benchmarks' && subProject.name != rootProject.name) {
apply plugin: 'signing'
apply plugin: 'ru.vyarus.pom'
apply plugin: 'ru.vyarus.github-info'
apply plugin: "com.vanniktech.maven.publish"
javadoc {
options {
@@ -535,66 +527,104 @@ subprojects {
}
}
github {
user 'kestra-io'
license 'Apache'
repository 'kestra'
site 'https://kestra.io'
//These modules should not be published
def unpublishedModules = ["jdbc-mysql", "jdbc-postgres", "webserver"]
if (subProject.name in unpublishedModules){
return
}
maven.pom {
description = 'The modern, scalable orchestrator & scheduler open source platform'
mavenPublishing {
publishToMavenCentral(true)
signAllPublications()
developers {
developer {
id = "tchiotludo"
name = "Ludovic Dehon"
coordinates(
"${rootProject.group}",
subProject.name == "cli" ? rootProject.name : subProject.name,
"${rootProject.version}"
)
pom {
name = project.name
description = "${project.group}:${project.name}:${rootProject.version}"
url = "https://github.com/kestra-io/${rootProject.name}"
licenses {
license {
name = "The Apache License, Version 2.0"
url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
}
}
developers {
developer {
id = "tchiotludo"
name = "Ludovic Dehon"
email = "ldehon@kestra.io"
}
}
scm {
connection = 'scm:git:'
url = "https://github.com/kestra-io/${rootProject.name}"
}
}
}
publishing {
publications {
sonatypePublication(MavenPublication) {
version project.version
afterEvaluate {
publishing {
publications {
withType(MavenPublication).configureEach { publication ->
if (project.name.contains('cli')) {
groupId "io.kestra"
artifactId "kestra"
artifact shadowJar
artifact executableJar
} else if (project.name.contains('platform')){
groupId project.group
artifactId project.name
} else {
from components.java
groupId project.group
artifactId project.name
artifact sourcesJar
artifact javadocJar
artifact testsJar
if (subProject.name == "platform") {
// Clear all artifacts except the BOM
publication.artifacts.clear()
}
}
}
}
}
signing {
// only sign JARs that we publish to Sonatype
required { gradle.taskGraph.hasTask("publishSonatypePublicationPublicationToSonatypeRepository") }
sign publishing.publications.sonatypePublication
}
if (subProject.name == 'cli') {
tasks.withType(GenerateModuleMetadata).configureEach {
// Suppression this validation error as we want to enforce the Kestra platform
suppressedValidationErrors.add('enforced-platform')
/* Make sure the special publication is wired *after* every plugin */
subProject.afterEvaluate {
/* 1. Remove the default java component so Gradle stops expecting
the standard cli-*.jar, sources, javadoc, etc. */
components.removeAll { it.name == "java" }
/* 2. Replace the publications artifacts with shadow + exec */
publishing.publications.withType(MavenPublication).configureEach { pub ->
pub.artifacts.clear()
// main shadow JAR built at root
pub.artifact(rootProject.tasks.named("shadowJar").get()) {
extension = "jar"
}
// executable ZIP built at root
pub.artifact(rootProject.tasks.named("executableJar").get().archiveFile) {
classifier = "exec"
extension = "zip"
}
pub.artifact(tasks.named("sourcesJar").get())
pub.artifact(tasks.named("javadocJar").get())
}
/* 3. Disable Gradle-module metadata for this publication to
avoid the “artifact removed from java component” error. */
tasks.withType(GenerateModuleMetadata).configureEach { it.enabled = false }
/* 4. Make every publish task in :cli wait for the two artifacts */
tasks.matching { it.name.startsWith("publish") }.configureEach {
dependsOn rootProject.tasks.named("shadowJar")
dependsOn rootProject.tasks.named("executableJar")
}
}
}
}
}
/**********************************************************************************************************************\
* Version
**********************************************************************************************************************/

View File

@@ -37,4 +37,4 @@ dependencies {
//test
testImplementation "org.wiremock:wiremock-jetty12"
}
}

View File

@@ -1,7 +1,5 @@
package io.kestra.cli;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.HttpHeaders;
import io.micronaut.http.HttpRequest;
@@ -16,16 +14,15 @@ import io.micronaut.http.netty.body.NettyJsonHandler;
import io.micronaut.json.JsonMapper;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import picocli.CommandLine;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import picocli.CommandLine;
public abstract class AbstractApiCommand extends AbstractCommand {
@CommandLine.Option(names = {"--server"}, description = "Kestra server url", defaultValue = "http://localhost:8080")
@@ -37,7 +34,7 @@ public abstract class AbstractApiCommand extends AbstractCommand {
@CommandLine.Option(names = {"--user"}, paramLabel = "<user:password>", description = "Server user and password")
protected String user;
@CommandLine.Option(names = {"--tenant"}, description = "Tenant identifier (EE only, when multi-tenancy is enabled)")
@CommandLine.Option(names = {"--tenant"}, description = "Tenant identifier (EE only)")
protected String tenantId;
@CommandLine.Option(names = {"--api-token"}, description = "API Token (EE only).")
@@ -87,12 +84,12 @@ public abstract class AbstractApiCommand extends AbstractCommand {
return request;
}
protected String apiUri(String path) {
protected String apiUri(String path, String tenantId) {
if (path == null || !path.startsWith("/")) {
throw new IllegalArgumentException("'path' must be non-null and start with '/'");
}
return tenantId == null ? "/api/v1/" + MAIN_TENANT + path : "/api/v1/" + tenantId + path;
return "/api/v1/" + tenantId + path;
}
@Builder

View File

@@ -40,7 +40,7 @@ import picocli.CommandLine.Option;
)
@Slf4j
@Introspected
abstract public class AbstractCommand implements Callable<Integer> {
public abstract class AbstractCommand implements Callable<Integer> {
@Inject
private ApplicationContext applicationContext;
@@ -93,7 +93,7 @@ abstract public class AbstractCommand implements Callable<Integer> {
this.startupHook.start(this);
}
if (this.pluginsPath != null && loadExternalPlugins()) {
if (pluginRegistryProvider != null && this.pluginsPath != null && loadExternalPlugins()) {
pluginRegistry = pluginRegistryProvider.get();
pluginRegistry.registerIfAbsent(pluginsPath);

View File

@@ -1,5 +1,6 @@
package io.kestra.cli;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.validations.ModelValidator;
import io.kestra.core.models.validations.ValidateConstraintViolation;
import io.kestra.core.serializers.YamlParser;
@@ -9,6 +10,7 @@ import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import picocli.CommandLine;
import java.io.IOException;
@@ -31,6 +33,9 @@ public abstract class AbstractValidateCommand extends AbstractApiCommand {
@CommandLine.Parameters(index = "0", description = "the directory containing files to check")
protected Path directory;
@Inject
private TenantIdSelectorService tenantService;
/** {@inheritDoc} **/
@Override
protected boolean loadExternalPlugins() {
@@ -112,7 +117,7 @@ public abstract class AbstractValidateCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.POST(apiUri("/flows/validate"), body).contentType(MediaType.APPLICATION_YAML);
.POST(apiUri("/flows/validate", tenantService.getTenantId(tenantId)), body).contentType(MediaType.APPLICATION_YAML);
List<ValidateConstraintViolation> validations = client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -66,8 +66,14 @@ public class App implements Callable<Integer> {
ApplicationContext applicationContext = App.applicationContext(cls, args);
// Call Picocli command
int exitCode = new CommandLine(cls, new MicronautFactory(applicationContext)).execute(args);
int exitCode = 0;
try {
exitCode = new CommandLine(cls, new MicronautFactory(applicationContext)).execute(args);
} catch (CommandLine.InitializationException e){
System.err.println("Could not initialize picoli ComandLine, err: " + e.getMessage());
e.printStackTrace();
exitCode = 1;
}
applicationContext.close();
// exit code

View File

@@ -2,11 +2,13 @@ package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -23,6 +25,9 @@ public class FlowCreateCommand extends AbstractApiCommand {
@CommandLine.Parameters(index = "0", description = "The file containing the flow")
public Path flowFile;
@Inject
private TenantIdSelectorService tenantService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
@@ -34,7 +39,7 @@ public class FlowCreateCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.POST(apiUri("/flows"), body).contentType(MediaType.APPLICATION_YAML);
.POST(apiUri("/flows", tenantService.getTenantId(tenantId)), body).contentType(MediaType.APPLICATION_YAML);
client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -2,10 +2,12 @@ package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -23,6 +25,9 @@ public class FlowDeleteCommand extends AbstractApiCommand {
@CommandLine.Parameters(index = "1", description = "The ID of the flow")
public String id;
@Inject
private TenantIdSelectorService tenantService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
@@ -30,7 +35,7 @@ public class FlowDeleteCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.DELETE(apiUri("/flows/" + namespace + "/" + id ));
.DELETE(apiUri("/flows/" + namespace + "/" + id, tenantService.getTenantId(tenantId)));
client.toBlocking().exchange(
this.requestOptions(request)

View File

@@ -2,7 +2,7 @@ package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.micronaut.context.ApplicationContext;
import io.kestra.cli.services.TenantIdSelectorService;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
@@ -25,9 +25,8 @@ import java.nio.file.Path;
public class FlowExportCommand extends AbstractApiCommand {
private static final String DEFAULT_FILE_NAME = "flows.zip";
// @FIXME: Keep it for bug in micronaut that need to have inject on top level command to inject on abstract classe
@Inject
private ApplicationContext applicationContext;
private TenantIdSelectorService tenantService;
@CommandLine.Option(names = {"--namespace"}, description = "The namespace of flows to export")
public String namespace;
@@ -41,7 +40,7 @@ public class FlowExportCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<Object> request = HttpRequest
.GET(apiUri("/flows/export/by-query") + (namespace != null ? "?namespace=" + namespace : ""))
.GET(apiUri("/flows/export/by-query", tenantService.getTenantId(tenantId)) + (namespace != null ? "?namespace=" + namespace : ""))
.accept(MediaType.APPLICATION_OCTET_STREAM);
HttpResponse<byte[]> response = client.toBlocking().exchange(this.requestOptions(request), byte[].class);

View File

@@ -1,7 +1,8 @@
package io.kestra.cli.commands.flows;
import com.google.common.collect.ImmutableMap;
import io.kestra.cli.AbstractCommand;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.repositories.LocalFlowRepositoryLoader;
@@ -30,7 +31,7 @@ import java.util.concurrent.TimeoutException;
description = "Test a flow"
)
@Slf4j
public class FlowTestCommand extends AbstractCommand {
public class FlowTestCommand extends AbstractApiCommand {
@Inject
private ApplicationContext applicationContext;
@@ -76,6 +77,7 @@ public class FlowTestCommand extends AbstractCommand {
FlowRepositoryInterface flowRepository = applicationContext.getBean(FlowRepositoryInterface.class);
FlowInputOutput flowInputOutput = applicationContext.getBean(FlowInputOutput.class);
RunnerUtils runnerUtils = applicationContext.getBean(RunnerUtils.class);
TenantIdSelectorService tenantService = applicationContext.getBean(TenantIdSelectorService.class);
Map<String, Object> inputs = new HashMap<>();
@@ -89,7 +91,7 @@ public class FlowTestCommand extends AbstractCommand {
try {
runner.run();
repositoryLoader.load(file.toFile());
repositoryLoader.load(tenantService.getTenantId(tenantId), file.toFile());
List<Flow> all = flowRepository.findAllForAllTenants();
if (all.size() != 1) {

View File

@@ -2,11 +2,13 @@ package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -29,6 +31,9 @@ public class FlowUpdateCommand extends AbstractApiCommand {
@CommandLine.Parameters(index = "2", description = "The ID of the flow")
public String id;
@Inject
private TenantIdSelectorService tenantService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
@@ -40,7 +45,7 @@ public class FlowUpdateCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.PUT(apiUri("/flows/" + namespace + "/" + id ), body).contentType(MediaType.APPLICATION_YAML);
.PUT(apiUri("/flows/" + namespace + "/" + id, tenantService.getTenantId(tenantId)), body).contentType(MediaType.APPLICATION_YAML);
client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -2,6 +2,7 @@ package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.serializers.YamlParser;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpRequest;
@@ -9,6 +10,7 @@ import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -36,6 +38,9 @@ public class FlowUpdatesCommand extends AbstractApiCommand {
@CommandLine.Option(names = {"--namespace"}, description = "The parent namespace of the flows, if not set, every namespace are allowed.")
public String namespace;
@Inject
private TenantIdSelectorService tenantIdSelectorService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
@@ -66,7 +71,7 @@ public class FlowUpdatesCommand extends AbstractApiCommand {
namespaceQuery = "&namespace=" + namespace;
}
MutableHttpRequest<String> request = HttpRequest
.POST(apiUri("/flows/bulk") + "?allowNamespaceChild=true&delete=" + delete + namespaceQuery, body).contentType(MediaType.APPLICATION_YAML);
.POST(apiUri("/flows/bulk", tenantIdSelectorService.getTenantId(tenantId)) + "?allowNamespaceChild=true&delete=" + delete + namespaceQuery, body).contentType(MediaType.APPLICATION_YAML);
List<UpdateResult> updated = client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -1,6 +1,7 @@
package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.validations.ModelValidator;
import io.kestra.core.services.FlowService;
@@ -22,6 +23,9 @@ public class FlowValidateCommand extends AbstractValidateCommand {
@Inject
private FlowService flowService;
@Inject
private TenantIdSelectorService tenantService;
@Override
public Integer call() throws Exception {
return this.call(
@@ -35,7 +39,7 @@ public class FlowValidateCommand extends AbstractValidateCommand {
FlowWithSource flow = (FlowWithSource) object;
List<String> warnings = new ArrayList<>();
warnings.addAll(flowService.deprecationPaths(flow).stream().map(deprecation -> deprecation + " is deprecated").toList());
warnings.addAll(flowService.warnings(flow, this.tenantId));
warnings.addAll(flowService.warnings(flow, tenantService.getTenantId(tenantId)));
return warnings;
},
(Object object) -> {

View File

@@ -3,6 +3,7 @@ package io.kestra.cli.commands.flows.namespaces;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.commands.AbstractServiceNamespaceUpdateCommand;
import io.kestra.cli.commands.flows.IncludeHelperExpander;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.serializers.YamlParser;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpRequest;
@@ -10,6 +11,7 @@ import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -30,6 +32,9 @@ public class FlowNamespaceUpdateCommand extends AbstractServiceNamespaceUpdateCo
@CommandLine.Option(names = {"--override-namespaces"}, negatable = true, description = "Replace namespace of all flows by the one provided")
public boolean override = false;
@Inject
private TenantIdSelectorService tenantService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
@@ -59,7 +64,7 @@ public class FlowNamespaceUpdateCommand extends AbstractServiceNamespaceUpdateCo
}
try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.POST(apiUri("/flows/") + namespace + "?delete=" + delete, body).contentType(MediaType.APPLICATION_YAML);
.POST(apiUri("/flows/", tenantService.getTenantId(tenantId)) + namespace + "?delete=" + delete, body).contentType(MediaType.APPLICATION_YAML);
List<UpdateResult> updated = client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -2,12 +2,14 @@ package io.kestra.cli.commands.namespaces.files;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.utils.KestraIgnore;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.multipart.MultipartBody;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -34,6 +36,9 @@ public class NamespaceFilesUpdateCommand extends AbstractApiCommand {
@CommandLine.Option(names = {"--delete"}, negatable = true, description = "Whether missing should be deleted")
public boolean delete = false;
@Inject
private TenantIdSelectorService tenantService;
private static final String KESTRA_IGNORE_FILE = ".kestraignore";
@Override
@@ -44,7 +49,7 @@ public class NamespaceFilesUpdateCommand extends AbstractApiCommand {
try (var files = Files.walk(from); DefaultHttpClient client = client()) {
if (delete) {
client.toBlocking().exchange(this.requestOptions(HttpRequest.DELETE(apiUri("/namespaces/") + namespace + "/files?path=" + to, null)));
client.toBlocking().exchange(this.requestOptions(HttpRequest.DELETE(apiUri("/namespaces/", tenantService.getTenantId(tenantId)) + namespace + "/files?path=" + to, null)));
}
KestraIgnore kestraIgnore = new KestraIgnore(from);
@@ -62,7 +67,7 @@ public class NamespaceFilesUpdateCommand extends AbstractApiCommand {
client.toBlocking().exchange(
this.requestOptions(
HttpRequest.POST(
apiUri("/namespaces/") + namespace + "/files?path=" + destination,
apiUri("/namespaces/", tenantService.getTenantId(tenantId)) + namespace + "/files?path=" + destination,
body
).contentType(MediaType.MULTIPART_FORM_DATA)
)

View File

@@ -3,11 +3,13 @@ package io.kestra.cli.commands.namespaces.kv;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.serializers.JacksonMapper;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
import picocli.CommandLine.Option;
@@ -42,6 +44,9 @@ public class KvUpdateCommand extends AbstractApiCommand {
@Option(names = {"-f", "--file-value"}, description = "The file from which to read the value to set. If this is provided, it will take precedence over any specified value.")
public Path fileValue;
@Inject
private TenantIdSelectorService tenantService;
@Override
public Integer call() throws Exception {
super.call();
@@ -56,7 +61,7 @@ public class KvUpdateCommand extends AbstractApiCommand {
Duration ttl = expiration == null ? null : Duration.parse(expiration);
MutableHttpRequest<String> request = HttpRequest
.PUT(apiUri("/namespaces/") + namespace + "/kv/" + key, value)
.PUT(apiUri("/namespaces/", tenantService.getTenantId(tenantId)) + namespace + "/kv/" + key, value)
.contentType(MediaType.APPLICATION_JSON_TYPE);
if (ttl != null) {

View File

@@ -18,6 +18,8 @@ import java.nio.file.Paths;
import java.util.Base64;
import java.util.List;
import static io.kestra.core.models.Plugin.isDeprecated;
@CommandLine.Command(
name = "doc",
description = "Generate documentation for all plugins currently installed"
@@ -38,6 +40,9 @@ public class PluginDocCommand extends AbstractCommand {
@CommandLine.Option(names = {"--schema"}, description = "Also write JSON Schema for each task")
private boolean schema = false;
@CommandLine.Option(names = {"--skip-deprecated"},description = "Skip deprecated plugins when generating documentations")
private boolean skipDeprecated = false;
@Override
public Integer call() throws Exception {
super.call();
@@ -45,6 +50,11 @@ public class PluginDocCommand extends AbstractCommand {
PluginRegistry registry = pluginRegistryProvider.get();
List<RegisteredPlugin> plugins = core ? registry.plugins() : registry.externalPlugins();
if (skipDeprecated) {
plugins = plugins.stream()
.filter(plugin -> !isDeprecated(plugin.getClass()))
.toList();
}
boolean hasFailures = false;
for (RegisteredPlugin registeredPlugin : plugins) {

View File

@@ -2,6 +2,7 @@ package io.kestra.cli.commands.servers;
import com.google.common.collect.ImmutableMap;
import io.kestra.cli.services.FileChangedEventListener;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.repositories.LocalFlowRepositoryLoader;
@@ -44,6 +45,9 @@ public class StandAloneCommand extends AbstractServerCommand {
@CommandLine.Option(names = {"-f", "--flow-path"}, description = "the flow path containing flow to inject at startup (when running with a memory flow repository)")
private File flowPath;
@CommandLine.Option(names = "--tenant", description = "Tenant identifier, Required to load flows from path with the enterprise edition")
private String tenantId;
@CommandLine.Option(names = {"--worker-thread"}, description = "the number of worker threads, defaults to four times the number of available processors. Set it to 0 to avoid starting a worker.")
private int workerThread = defaultWorkerThread();
@@ -98,7 +102,8 @@ public class StandAloneCommand extends AbstractServerCommand {
if (flowPath != null) {
try {
LocalFlowRepositoryLoader localFlowRepositoryLoader = applicationContext.getBean(LocalFlowRepositoryLoader.class);
localFlowRepositoryLoader.load(null, this.flowPath);
TenantIdSelectorService tenantIdSelectorService = applicationContext.getBean(TenantIdSelectorService.class);
localFlowRepositoryLoader.load(tenantIdSelectorService.getTenantId(this.tenantId), this.flowPath);
} catch (IOException e) {
throw new CommandLine.ParameterException(this.spec.commandLine(), "Invalid flow path", e);
}

View File

@@ -2,8 +2,8 @@ package io.kestra.cli.commands.templates;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.templates.TemplateEnabled;
import io.micronaut.context.ApplicationContext;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
@@ -27,9 +27,8 @@ import java.nio.file.Path;
public class TemplateExportCommand extends AbstractApiCommand {
private static final String DEFAULT_FILE_NAME = "templates.zip";
// @FIXME: Keep it for bug in micronaut that need to have inject on top level command to inject on abstract classe
@Inject
private ApplicationContext applicationContext;
private TenantIdSelectorService tenantService;
@CommandLine.Option(names = {"--namespace"}, description = "The namespace of templates to export")
public String namespace;
@@ -43,7 +42,7 @@ public class TemplateExportCommand extends AbstractApiCommand {
try(DefaultHttpClient client = client()) {
MutableHttpRequest<Object> request = HttpRequest
.GET(apiUri("/templates/export/by-query") + (namespace != null ? "?namespace=" + namespace : ""))
.GET(apiUri("/templates/export/by-query", tenantService.getTenantId(tenantId)) + (namespace != null ? "?namespace=" + namespace : ""))
.accept(MediaType.APPLICATION_OCTET_STREAM);
HttpResponse<byte[]> response = client.toBlocking().exchange(this.requestOptions(request), byte[].class);

View File

@@ -2,6 +2,7 @@ package io.kestra.cli.commands.templates.namespaces;
import io.kestra.cli.AbstractValidateCommand;
import io.kestra.cli.commands.AbstractServiceNamespaceUpdateCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.templates.Template;
import io.kestra.core.models.templates.TemplateEnabled;
import io.kestra.core.serializers.YamlParser;
@@ -10,6 +11,7 @@ import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@@ -27,6 +29,9 @@ import jakarta.validation.ConstraintViolationException;
@TemplateEnabled
public class TemplateNamespaceUpdateCommand extends AbstractServiceNamespaceUpdateCommand {
@Inject
private TenantIdSelectorService tenantService;
@Override
public Integer call() throws Exception {
super.call();
@@ -44,7 +49,7 @@ public class TemplateNamespaceUpdateCommand extends AbstractServiceNamespaceUpda
try (DefaultHttpClient client = client()) {
MutableHttpRequest<List<Template>> request = HttpRequest
.POST(apiUri("/templates/") + namespace + "?delete=" + delete, templates);
.POST(apiUri("/templates/", tenantService.getTenantId(tenantId)) + namespace + "?delete=" + delete, templates);
List<UpdateResult> updated = client.toBlocking().retrieve(
this.requestOptions(request),

View File

@@ -12,8 +12,8 @@ import io.kestra.core.services.PluginDefaultService;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.annotation.Value;
import io.micronaut.scheduling.io.watch.FileWatchConfiguration;
import jakarta.inject.Inject;
import jakarta.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
@@ -26,6 +26,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
@Singleton
@Slf4j
@Requires(property = "micronaut.io.watch.enabled", value = "true")
@@ -111,6 +113,8 @@ public class FileChangedEventListener {
}
public void startListening(List<Path> paths) throws IOException, InterruptedException {
String tenantId = this.tenantId != null ? this.tenantId : MAIN_TENANT;
for (Path path : paths) {
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
}
@@ -158,7 +162,15 @@ public class FileChangedEventListener {
}
} catch (NoSuchFileException e) {
log.error("File not found: {}", entry, e);
log.warn("File not found: {}, deleting it", entry, e);
// the file might have been deleted while reading so if not found we try to delete the flow
flows.stream()
.filter(flow -> flow.getPath().equals(filePath.toString()))
.findFirst()
.ifPresent(flowWithPath -> {
flowFilesManager.deleteFlow(flowWithPath.getTenantId(), flowWithPath.getNamespace(), flowWithPath.getId());
this.flows.removeIf(fwp -> fwp.uidWithoutRevision().equals(flowWithPath.uidWithoutRevision()));
});
} catch (IOException e) {
log.error("Error reading file: {}", entry, e);
}
@@ -189,6 +201,8 @@ public class FileChangedEventListener {
}
private void loadFlowsFromFolder(Path folder) {
String tenantId = this.tenantId != null ? this.tenantId : MAIN_TENANT;
try {
Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
@Override
@@ -232,6 +246,8 @@ public class FileChangedEventListener {
}
private Optional<FlowWithSource> parseFlow(String content, Path entry) {
String tenantId = this.tenantId != null ? this.tenantId : MAIN_TENANT;
try {
FlowWithSource flow = pluginDefaultService.parseFlowWithAllDefaults(tenantId, content, false);
modelValidator.validate(flow);

View File

@@ -0,0 +1,19 @@
package io.kestra.cli.services;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import io.kestra.core.exceptions.KestraRuntimeException;
import jakarta.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
@Singleton
public class TenantIdSelectorService {
//For override purpose in Kestra EE
public String getTenantId(String tenantId) {
if (StringUtils.isNotBlank(tenantId) && !MAIN_TENANT.equals(tenantId)){
throw new KestraRuntimeException("Tenant id can only be 'main'");
}
return MAIN_TENANT;
}
}

View File

@@ -15,6 +15,9 @@ micronaut:
static:
paths: classpath:static
mapping: /static/**
root:
paths: classpath:root
mapping: /**
server:
max-request-size: 10GB
multipart:
@@ -24,6 +27,7 @@ micronaut:
write-idle-timeout: 60m
idle-timeout: 60m
netty:
max-zstd-encode-size: 67108864 # increased to 64MB from the default of 32MB
max-chunk-size: 10MB
max-header-size: 32768 # increased from the default of 8k
responses:
@@ -180,7 +184,6 @@ kestra:
server:
basic-auth:
enabled: false
# These URLs will not be authenticated, by default we open some of the Micronaut default endpoints but not all for security reasons
open-urls:
- "/ping"
@@ -225,4 +228,4 @@ otel:
- /health
- /env
- /prometheus
propagators: tracecontext, baggage
propagators: tracecontext, baggage

View File

@@ -108,6 +108,34 @@ class FlowCreateOrUpdateCommandTest {
}
}
@Test
void should_fail_with_incorrect_tenant() {
URL directory = FlowCreateOrUpdateCommandTest.class.getClassLoader().getResource("flows");
ByteArrayOutputStream err = new ByteArrayOutputStream();
System.setErr(new PrintStream(err));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
EmbeddedServer embeddedServer = ctx.getBean(EmbeddedServer.class);
embeddedServer.start();
String[] args = {
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word",
"--tenant", "incorrect",
directory.getPath(),
};
PicocliRunner.call(FlowUpdatesCommand.class, ctx, args);
assertThat(err.toString()).contains("Tenant id can only be 'main'");
err.reset();
}
}
@Test
void helper() {
URL directory = FlowCreateOrUpdateCommandTest.class.getClassLoader().getResource("helper");

View File

@@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class PluginDocCommandTest {
public static final String PLUGIN_TEMPLATE_TEST = "plugin-template-test-0.18.0-SNAPSHOT.jar";
public static final String PLUGIN_TEMPLATE_TEST = "plugin-template-test-0.24.0-SNAPSHOT.jar";
@Test
void run() throws IOException, URISyntaxException {

View File

@@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class PluginListCommandTest {
private static final String PLUGIN_TEMPLATE_TEST = "plugin-template-test-0.18.0-SNAPSHOT.jar";
private static final String PLUGIN_TEMPLATE_TEST = "plugin-template-test-0.24.0-SNAPSHOT.jar";
@Test
void shouldListPluginsInstalledLocally() throws IOException, URISyntaxException {

View File

@@ -0,0 +1,33 @@
package io.kestra.cli.commands.servers;
import static org.assertj.core.api.Assertions.assertThat;
import io.kestra.cli.App;
import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.jupiter.api.Test;
public class TenantIdSelectorServiceTest {
@Test
void should_fail_without_tenant_id() {
ByteArrayOutputStream err = new ByteArrayOutputStream();
System.setErr(new PrintStream(err));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
String[] start = {
"server", "standalone",
"-f", "unused",
"--tenant", "wrong_tenant"
};
PicocliRunner.call(App.class, ctx, start);
assertThat(err.toString()).contains("Tenant id can only be 'main'");
err.reset();
}
}
}

View File

@@ -17,7 +17,7 @@ kestra:
central:
url: https://repo.maven.apache.org/maven2/
sonatype:
url: https://s01.oss.sonatype.org/content/repositories/snapshots/
url: https://central.sonatype.com/repository/maven-snapshots/
server:
liveness:
enabled: false

View File

@@ -56,21 +56,23 @@ component_management:
name: Tests
paths:
- tests/**
- component_id: ui
name: Ui
paths:
- ui/**
- component_id: webserver
name: Webserver
paths:
- webserver/**
ignore:
- ui/**
# we are not mature yet to have a ui code coverage
flag_management:
default_rules:
carryforward: true
statuses:
- type: project
target: 80%
threshold: 1%
target: 70%
threshold: 10%
- type: patch
target: 90%
target: 75%
threshold: 10%

View File

@@ -37,6 +37,7 @@ dependencies {
implementation 'nl.basjes.gitignore:gitignore-reader'
implementation group: 'dev.failsafe', name: 'failsafe'
implementation 'com.github.ben-manes.caffeine:caffeine'
implementation 'com.github.ksuid:ksuid:1.1.3'
api 'org.apache.httpcomponents.client5:httpclient5'
// plugins
@@ -74,7 +75,9 @@ dependencies {
testImplementation "io.micronaut:micronaut-http-server-netty"
testImplementation "io.micronaut:micronaut-management"
testImplementation "org.testcontainers:testcontainers:1.21.1"
testImplementation "org.testcontainers:junit-jupiter:1.21.1"
testImplementation "org.bouncycastle:bcpkix-jdk18on:1.80"
testImplementation "org.testcontainers:testcontainers:1.21.3"
testImplementation "org.testcontainers:junit-jupiter:1.21.3"
testImplementation "org.bouncycastle:bcpkix-jdk18on:1.81"
testImplementation "org.wiremock:wiremock-jetty12"
}

View File

@@ -0,0 +1,26 @@
package io.kestra.core.debug;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class Breakpoint {
@NotNull
private String id;
@Nullable
private String value;
public static Breakpoint of(String breakpoint) {
if (breakpoint.indexOf('.') > 0) {
return new Breakpoint(breakpoint.substring(0, breakpoint.indexOf('.')), breakpoint.substring(breakpoint.indexOf('.') + 1));
} else {
return new Breakpoint(breakpoint, null);
}
}
}

View File

@@ -6,14 +6,17 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
@Getter
@EqualsAndHashCode
@ToString
public class ClassPluginDocumentation<T> extends AbstractClassDocumentation<T> {
private static final Map<PluginDocIdentifier, ClassPluginDocumentation<?>> CACHE = new ConcurrentHashMap<>();
private String icon;
private String group;
protected String docLicense;
@@ -78,8 +81,12 @@ public class ClassPluginDocumentation<T> extends AbstractClassDocumentation<T> {
}
}
public static <T> ClassPluginDocumentation<T> of(JsonSchemaGenerator jsonSchemaGenerator, PluginClassAndMetadata<T> plugin, boolean allProperties) {
return new ClassPluginDocumentation<>(jsonSchemaGenerator, plugin, allProperties);
public static <T> ClassPluginDocumentation<T> of(JsonSchemaGenerator jsonSchemaGenerator, PluginClassAndMetadata<T> plugin, String version, boolean allProperties) {
//noinspection unchecked
return (ClassPluginDocumentation<T>) CACHE.computeIfAbsent(
new PluginDocIdentifier(plugin.type(), version, allProperties),
(key) -> new ClassPluginDocumentation<>(jsonSchemaGenerator, plugin, allProperties)
);
}
@AllArgsConstructor
@@ -90,5 +97,11 @@ public class ClassPluginDocumentation<T> extends AbstractClassDocumentation<T> {
String unit;
String description;
}
private record PluginDocIdentifier(String pluginClassAndVersion, boolean allProperties) {
public PluginDocIdentifier(Class<?> pluginClass, String version, boolean allProperties) {
this(pluginClass.getName() + ":" + version, allProperties);
}
}
}

View File

@@ -227,7 +227,7 @@ public class DocumentationGenerator {
baseCls,
null
);
return ClassPluginDocumentation.of(jsonSchemaGenerator, metadata, true);
return ClassPluginDocumentation.of(jsonSchemaGenerator, metadata, registeredPlugin.version(), true);
})
.map(pluginDocumentation -> {
try {

View File

@@ -24,6 +24,7 @@ public class JsonSchemaCache {
private final JsonSchemaGenerator jsonSchemaGenerator;
private final ConcurrentMap<CacheKey, Map<String, Object>> schemaCache = new ConcurrentHashMap<>();
private final ConcurrentMap<SchemaType, Map<String, Object>> propertiesCache = new ConcurrentHashMap<>();
private final Map<SchemaType, Class<?>> classesBySchemaType = new HashMap<>();
@@ -44,7 +45,7 @@ public class JsonSchemaCache {
public Map<String, Object> getSchemaForType(final SchemaType type,
final boolean arrayOf) {
return schemaCache.computeIfAbsent(new CacheKey(type, arrayOf), (key) -> {
return schemaCache.computeIfAbsent(new CacheKey(type, arrayOf), key -> {
Class<?> cls = Optional.ofNullable(classesBySchemaType.get(type))
.orElseThrow(() -> new IllegalArgumentException("Cannot found schema for type '" + type + "'"));
@@ -52,6 +53,16 @@ public class JsonSchemaCache {
});
}
public Map<String, Object> getPropertiesForType(final SchemaType type) {
return propertiesCache.computeIfAbsent(type, key -> {
Class<?> cls = Optional.ofNullable(classesBySchemaType.get(type))
.orElseThrow(() -> new IllegalArgumentException("Cannot found properties for type '" + type + "'"));
return jsonSchemaGenerator.properties(null, cls);
});
}
// must be public as it's used in EE
public void registerClassForType(final SchemaType type, final Class<?> clazz) {
classesBySchemaType.put(type, clazz);
}

View File

@@ -88,12 +88,16 @@ public class JsonSchemaGenerator {
}
public <T> Map<String, Object> schemas(Class<? extends T> cls, boolean arrayOf) {
return this.schemas(cls, arrayOf, Collections.emptyList());
}
public <T> Map<String, Object> schemas(Class<? extends T> cls, boolean arrayOf, List<String> allowedPluginTypes) {
SchemaGeneratorConfigBuilder builder = new SchemaGeneratorConfigBuilder(
SchemaVersion.DRAFT_7,
OptionPreset.PLAIN_JSON
);
this.build(builder, true);
this.build(builder, true, allowedPluginTypes);
SchemaGeneratorConfig schemaGeneratorConfig = builder.build();
@@ -240,6 +244,10 @@ public class JsonSchemaGenerator {
}
protected void build(SchemaGeneratorConfigBuilder builder, boolean draft7) {
this.build(builder, draft7, Collections.emptyList());
}
protected void build(SchemaGeneratorConfigBuilder builder, boolean draft7, List<String> allowedPluginTypes) {
// builder.withObjectMapper(builder.getObjectMapper().configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false));
builder
.with(new JakartaValidationModule(
@@ -456,7 +464,7 @@ public class JsonSchemaGenerator {
.withSubtypeResolver((declaredType, context) -> {
TypeContext typeContext = context.getTypeContext();
return this.subtypeResolver(declaredType, typeContext);
return this.subtypeResolver(declaredType, typeContext, allowedPluginTypes);
});
// description as Markdown
@@ -533,7 +541,7 @@ public class JsonSchemaGenerator {
return null;
}
return this.subtypeResolver(declaredType, typeContext);
return this.subtypeResolver(declaredType, typeContext, allowedPluginTypes);
});
}
@@ -616,11 +624,12 @@ public class JsonSchemaGenerator {
return false;
}
protected List<ResolvedType> subtypeResolver(ResolvedType declaredType, TypeContext typeContext) {
protected List<ResolvedType> subtypeResolver(ResolvedType declaredType, TypeContext typeContext, List<String> allowedPluginTypes) {
if (declaredType.getErasedType() == Task.class) {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getTasks().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.flatMap(clz -> safelyResolveSubtype(declaredType, clz, typeContext).stream())
.toList();
@@ -628,6 +637,7 @@ public class JsonSchemaGenerator {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getTriggers().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.flatMap(clz -> safelyResolveSubtype(declaredType, clz, typeContext).stream())
.toList();
@@ -635,6 +645,7 @@ public class JsonSchemaGenerator {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getConditions().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.flatMap(clz -> safelyResolveSubtype(declaredType, clz, typeContext).stream())
.toList();
@@ -643,6 +654,7 @@ public class JsonSchemaGenerator {
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getConditions().stream())
.filter(ScheduleCondition.class::isAssignableFrom)
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.flatMap(clz -> safelyResolveSubtype(declaredType, clz, typeContext).stream())
.toList();
@@ -650,6 +662,7 @@ public class JsonSchemaGenerator {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getTaskRunners().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.map(typeContext::resolve)
.toList();
@@ -657,6 +670,7 @@ public class JsonSchemaGenerator {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getLogExporters().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.map(typeContext::resolve)
.toList();
@@ -666,6 +680,7 @@ public class JsonSchemaGenerator {
.flatMap(registeredPlugin -> registeredPlugin.getAdditionalPlugins().stream())
// for additional plugins, we have one subtype by type of additional plugins (for ex: embedding store for Langchain4J), so we need to filter on the correct subtype
.filter(cls -> declaredType.getErasedType().isAssignableFrom(cls))
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(cls -> cls != declaredType.getErasedType())
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.map(typeContext::resolve)
@@ -674,6 +689,7 @@ public class JsonSchemaGenerator {
return getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getCharts().stream())
.filter(p -> allowedPluginTypes.isEmpty() || allowedPluginTypes.contains(p.getName()))
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.<ResolvedType>mapMulti((clz, consumer) -> {
if (DataChart.class.isAssignableFrom(clz)) {
@@ -740,12 +756,16 @@ public class JsonSchemaGenerator {
}
protected <T> Map<String, Object> generate(Class<? extends T> cls, @Nullable Class<T> base) {
return this.generate(cls, base, Collections.emptyList());
}
protected <T> Map<String, Object> generate(Class<? extends T> cls, @Nullable Class<T> base, List<String> allowedPluginTypes) {
SchemaGeneratorConfigBuilder builder = new SchemaGeneratorConfigBuilder(
SchemaVersion.DRAFT_2019_09,
OptionPreset.PLAIN_JSON
);
this.build(builder, false);
this.build(builder, false, allowedPluginTypes);
// we don't return base properties unless specified with @PluginProperty and hidden is false
builder

View File

@@ -23,29 +23,25 @@ public class Plugin {
private String group;
private String version;
private Map<String, String> manifest;
private List<String> tasks;
private List<String> triggers;
private List<String> conditions;
private List<String> controllers;
private List<String> storages;
private List<String> secrets;
private List<String> taskRunners;
private List<String> guides;
private List<String> aliases;
private List<String> apps;
private List<String> appBlocks;
private List<String> charts;
private List<String> dataFilters;
private List<String> logExporters;
private List<String> additionalPlugins;
private List<PluginElementMetadata> tasks;
private List<PluginElementMetadata> triggers;
private List<PluginElementMetadata> conditions;
private List<PluginElementMetadata> controllers;
private List<PluginElementMetadata> storages;
private List<PluginElementMetadata> secrets;
private List<PluginElementMetadata> taskRunners;
private List<PluginElementMetadata> apps;
private List<PluginElementMetadata> appBlocks;
private List<PluginElementMetadata> charts;
private List<PluginElementMetadata> dataFilters;
private List<PluginElementMetadata> logExporters;
private List<PluginElementMetadata> additionalPlugins;
private List<PluginSubGroup.PluginCategory> categories;
private String subGroup;
public static Plugin of(RegisteredPlugin registeredPlugin, @Nullable String subgroup) {
return Plugin.of(registeredPlugin, subgroup, true);
}
public static Plugin of(RegisteredPlugin registeredPlugin, @Nullable String subgroup, boolean includeDeprecated) {
Plugin plugin = new Plugin();
plugin.name = registeredPlugin.name();
PluginSubGroup subGroupInfos = null;
@@ -90,18 +86,18 @@ public class Plugin {
plugin.subGroup = subgroup;
Predicate<Class<?>> packagePredicate = c -> subgroup == null || c.getPackageName().equals(subgroup);
plugin.tasks = filterAndGetClassName(registeredPlugin.getTasks(), includeDeprecated, packagePredicate);
plugin.triggers = filterAndGetClassName(registeredPlugin.getTriggers(), includeDeprecated, packagePredicate);
plugin.conditions = filterAndGetClassName(registeredPlugin.getConditions(), includeDeprecated, packagePredicate);
plugin.storages = filterAndGetClassName(registeredPlugin.getStorages(), includeDeprecated, packagePredicate);
plugin.secrets = filterAndGetClassName(registeredPlugin.getSecrets(), includeDeprecated, packagePredicate);
plugin.taskRunners = filterAndGetClassName(registeredPlugin.getTaskRunners(), includeDeprecated, packagePredicate);
plugin.apps = filterAndGetClassName(registeredPlugin.getApps(), includeDeprecated, packagePredicate);
plugin.appBlocks = filterAndGetClassName(registeredPlugin.getAppBlocks(), includeDeprecated, packagePredicate);
plugin.charts = filterAndGetClassName(registeredPlugin.getCharts(), includeDeprecated, packagePredicate);
plugin.dataFilters = filterAndGetClassName(registeredPlugin.getDataFilters(), includeDeprecated, packagePredicate);
plugin.logExporters = filterAndGetClassName(registeredPlugin.getLogExporters(), includeDeprecated, packagePredicate);
plugin.additionalPlugins = filterAndGetClassName(registeredPlugin.getAdditionalPlugins(), includeDeprecated, packagePredicate);
plugin.tasks = filterAndGetTypeWithMetadata(registeredPlugin.getTasks(), packagePredicate);
plugin.triggers = filterAndGetTypeWithMetadata(registeredPlugin.getTriggers(), packagePredicate);
plugin.conditions = filterAndGetTypeWithMetadata(registeredPlugin.getConditions(), packagePredicate);
plugin.storages = filterAndGetTypeWithMetadata(registeredPlugin.getStorages(), packagePredicate);
plugin.secrets = filterAndGetTypeWithMetadata(registeredPlugin.getSecrets(), packagePredicate);
plugin.taskRunners = filterAndGetTypeWithMetadata(registeredPlugin.getTaskRunners(), packagePredicate);
plugin.apps = filterAndGetTypeWithMetadata(registeredPlugin.getApps(), packagePredicate);
plugin.appBlocks = filterAndGetTypeWithMetadata(registeredPlugin.getAppBlocks(), packagePredicate);
plugin.charts = filterAndGetTypeWithMetadata(registeredPlugin.getCharts(), packagePredicate);
plugin.dataFilters = filterAndGetTypeWithMetadata(registeredPlugin.getDataFilters(), packagePredicate);
plugin.logExporters = filterAndGetTypeWithMetadata(registeredPlugin.getLogExporters(), packagePredicate);
plugin.additionalPlugins = filterAndGetTypeWithMetadata(registeredPlugin.getAdditionalPlugins(), packagePredicate);
return plugin;
}
@@ -111,17 +107,18 @@ public class Plugin {
* Those classes are only filtered from the documentation to ensure backward compatibility.
*
* @param list The list of classes?
* @param includeDeprecated whether to include deprecated plugins or not
* @return a filtered streams.
*/
private static List<String> filterAndGetClassName(final List<? extends Class<?>> list, boolean includeDeprecated, Predicate<Class<?>> clazzFilter) {
private static List<PluginElementMetadata> filterAndGetTypeWithMetadata(final List<? extends Class<?>> list, Predicate<Class<?>> clazzFilter) {
return list
.stream()
.filter(not(io.kestra.core.models.Plugin::isInternal))
.filter(p -> includeDeprecated || !io.kestra.core.models.Plugin.isDeprecated(p))
.filter(clazzFilter)
.map(Class::getName)
.filter(c -> !c.startsWith("org.kestra."))
.filter(c -> !c.getName().startsWith("org.kestra."))
.map(c -> new PluginElementMetadata(c.getName(), io.kestra.core.models.Plugin.isDeprecated(c) ? true : null))
.toList();
}
public record PluginElementMetadata(String cls, Boolean deprecated) {
}
}

View File

@@ -0,0 +1,25 @@
package io.kestra.core.exceptions;
/**
* General exception that can be thrown when an AI service replies with an error.
* When propagated in the context of a REST API call, this exception should
* result in an HTTP 422 UNPROCESSABLE_ENTITY response.
*/
public class AiException extends KestraRuntimeException {
/**
* Creates a new {@link AiException} instance.
*/
public AiException() {
super();
}
/**
* Creates a new {@link AiException} instance.
*
* @param aiErrorMessage the AI error message.
*/
public AiException(final String aiErrorMessage) {
super(aiErrorMessage);
}
}

View File

@@ -0,0 +1,30 @@
package io.kestra.core.exceptions;
/**
* General exception that can be thrown when a Kestra resource or entity conflicts with an existing one.
* <p>
* Typically used in REST API contexts to signal situations such as:
* attempting to create a resource that already exists, or updating a resource
* in a way that causes a conflict.
* <p>
* When propagated in the context of a REST API call, this exception should
* result in an HTTP 409 Conflict response.
*/
public class ConflictException extends KestraRuntimeException {
/**
* Creates a new {@link ConflictException} instance.
*/
public ConflictException() {
super();
}
/**
* Creates a new {@link ConflictException} instance.
*
* @param message the error message.
*/
public ConflictException(final String message) {
super(message);
}
}

View File

@@ -0,0 +1,43 @@
package io.kestra.core.exceptions;
import java.io.Serial;
import java.util.List;
/**
* General exception that can be throws when a Kestra entity field is query, but is not valid or existing.
*/
public class InvalidQueryFiltersException extends KestraRuntimeException {
@Serial
private static final long serialVersionUID = 1L;
private static final String INVALID_QUERY_FILTER_MESSAGE = "Provided query filters are invalid";
private transient final List<String> invalids;
/**
* Creates a new {@link InvalidQueryFiltersException} instance.
*
* @param invalids the invalid filters.
*/
public InvalidQueryFiltersException(final List<String> invalids) {
super(INVALID_QUERY_FILTER_MESSAGE);
this.invalids = invalids;
}
/**
* Creates a new {@link InvalidQueryFiltersException} instance.
*
* @param invalid the invalid filter.
*/
public InvalidQueryFiltersException(final String invalid) {
super(INVALID_QUERY_FILTER_MESSAGE);
this.invalids = List.of(invalid);
}
public String formatedInvalidObjects(){
if (invalids == null || invalids.isEmpty()){
return INVALID_QUERY_FILTER_MESSAGE;
}
return String.join(", ", invalids);
}
}

View File

@@ -0,0 +1,23 @@
package io.kestra.core.exceptions;
/**
* General exception that can be throws when a Kestra resource or entity is not found.
*/
public class NotFoundException extends KestraRuntimeException {
/**
* Creates a new {@link NotFoundException} instance.
*/
public NotFoundException() {
super();
}
/**
* Creates a new {@link NotFoundException} instance.
*
* @param message the error message.
*/
public NotFoundException(final String message) {
super(message);
}
}

View File

@@ -0,0 +1,35 @@
package io.kestra.core.exceptions;
import java.io.Serial;
import java.util.List;
import lombok.Getter;
/**
* General exception that can be throws when a resource fail validation.
*/
public class ValidationErrorException extends KestraRuntimeException {
@Serial
private static final long serialVersionUID = 1L;
private static final String VALIDATION_ERROR_MESSAGE = "Resource fails validation";
@Getter
private transient final List<String> invalids;
/**
* Creates a new {@link ValidationErrorException} instance.
*
* @param invalids the invalid filters.
*/
public ValidationErrorException(final List<String> invalids) {
super(VALIDATION_ERROR_MESSAGE);
this.invalids = invalids;
}
public String formatedInvalidObjects(){
if (invalids == null || invalids.isEmpty()){
return VALIDATION_ERROR_MESSAGE;
}
return String.join(", ", invalids);
}
}

View File

@@ -8,6 +8,7 @@ import io.kestra.core.http.client.apache.*;
import io.kestra.core.http.client.configurations.HttpConfiguration;
import io.kestra.core.runners.RunContext;
import io.kestra.core.serializers.JacksonMapper;
import io.micronaut.http.MediaType;
import jakarta.annotation.Nullable;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
@@ -279,12 +280,14 @@ public class HttpClient implements Closeable {
private <T> T bodyHandler(Class<?> cls, HttpEntity entity) throws IOException, ParseException {
if (entity == null) {
return null;
} else if (cls.isAssignableFrom(String.class)) {
} else if (String.class.isAssignableFrom(cls)) {
return (T) EntityUtils.toString(entity);
} else if (cls.isAssignableFrom(Byte[].class)) {
} else if (Byte[].class.isAssignableFrom(cls)) {
return (T) ArrayUtils.toObject(EntityUtils.toByteArray(entity));
} else if (MediaType.APPLICATION_YAML.equals(entity.getContentType()) || "application/yaml".equals(entity.getContentType())) {
return (T) JacksonMapper.ofYaml().readValue(entity.getContent(), cls);
} else {
return (T) JacksonMapper.ofJson().readValue(entity.getContent(), cls);
return (T) JacksonMapper.ofJson(false).readValue(entity.getContent(), cls);
}
}

View File

@@ -1,11 +1,14 @@
package io.kestra.core.metrics;
import io.kestra.core.models.ServerType;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.micronaut.configuration.metrics.aggregator.MeterRegistryConfigurer;
import io.micronaut.context.annotation.Requires;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
@@ -15,20 +18,26 @@ public class GlobalTagsConfigurer implements MeterRegistryConfigurer<SimpleMeter
@Inject
MetricConfig metricConfig;
@Nullable
@Value("${kestra.server-type}")
ServerType serverType;
@Override
public void configure(SimpleMeterRegistry meterRegistry) {
if (metricConfig.getTags() != null) {
meterRegistry
.config()
.commonTags(
metricConfig.getTags()
.entrySet()
.stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue()))
.toList()
.toArray(String[]::new)
);
}
String[] tags = Stream
.concat(
metricConfig.getTags() != null ? metricConfig.getTags()
.entrySet()
.stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue())) : Stream.empty(),
serverType != null ? Stream.of("server_type", serverType.name()) : Stream.empty()
)
.toList()
.toArray(String[]::new);
meterRegistry
.config()
.commonTags(tags);
}
@Override

View File

@@ -1,11 +1,10 @@
package io.kestra.core.models;
import io.kestra.core.utils.MapUtils;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
public record Label(@NotNull String key, @NotNull String value) {
@@ -29,11 +28,36 @@ public record Label(@NotNull String key, @NotNull String value) {
* @return the nested {@link Map}.
*/
public static Map<String, Object> toNestedMap(List<Label> labels) {
Map<String, Object> asMap = labels.stream()
return MapUtils.flattenToNestedMap(toMap(labels));
}
/**
* Static helper method for converting a list of labels to a flat map.
* Key order is kept.
*
* @param labels The list of {@link Label} to be converted.
* @return the flat {@link Map}.
*/
public static Map<String, String> toMap(@Nullable List<Label> labels) {
if (labels == null || labels.isEmpty()) return Collections.emptyMap();
return labels.stream()
.filter(label -> label.value() != null && label.key() != null)
// using an accumulator in case labels with the same key exists: the first is kept
.collect(Collectors.toMap(Label::key, Label::value, (first, second) -> first));
return MapUtils.flattenToNestedMap(asMap);
// using an accumulator in case labels with the same key exists: the second is kept
.collect(Collectors.toMap(Label::key, Label::value, (first, second) -> second, LinkedHashMap::new));
}
/**
* Static helper method for deduplicating a list of labels by their key.
* Value of the last key occurrence is kept.
*
* @param labels The list of {@link Label} to be deduplicated.
* @return the deduplicated {@link List}.
*/
public static List<Label> deduplicate(@Nullable List<Label> labels) {
if (labels == null || labels.isEmpty()) return Collections.emptyList();
return toMap(labels).entrySet().stream()
.map(entry -> new Label(entry.getKey(), entry.getValue()))
.collect(Collectors.toCollection(ArrayList::new));
}
/**

View File

@@ -3,10 +3,12 @@ package io.kestra.core.models;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import io.kestra.core.exceptions.InvalidQueryFiltersException;
import io.kestra.core.models.dashboards.filters.*;
import io.kestra.core.utils.Enums;
import lombok.Builder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -47,42 +49,27 @@ public record QueryFilter(
PREFIX
}
@SuppressWarnings("unchecked")
private List<Object> asValues(Object value) {
return value instanceof String valueStr ? Arrays.asList(valueStr.split(",")) : (List<Object>) value;
}
@SuppressWarnings("unchecked")
public <T extends Enum<T>> AbstractFilter<T> toDashboardFilterBuilder(T field, Object value) {
switch (this.operation) {
case EQUALS:
return EqualTo.<T>builder().field(field).value(value).build();
case NOT_EQUALS:
return NotEqualTo.<T>builder().field(field).value(value).build();
case GREATER_THAN:
return GreaterThan.<T>builder().field(field).value(value).build();
case LESS_THAN:
return LessThan.<T>builder().field(field).value(value).build();
case GREATER_THAN_OR_EQUAL_TO:
return GreaterThanOrEqualTo.<T>builder().field(field).value(value).build();
case LESS_THAN_OR_EQUAL_TO:
return LessThanOrEqualTo.<T>builder().field(field).value(value).build();
case IN:
return In.<T>builder().field(field).values(asValues(value)).build();
case NOT_IN:
return NotIn.<T>builder().field(field).values(asValues(value)).build();
case STARTS_WITH:
return StartsWith.<T>builder().field(field).value(value.toString()).build();
case ENDS_WITH:
return EndsWith.<T>builder().field(field).value(value.toString()).build();
case CONTAINS:
return Contains.<T>builder().field(field).value(value.toString()).build();
case REGEX:
return Regex.<T>builder().field(field).value(value.toString()).build();
case PREFIX:
return Regex.<T>builder().field(field).value("^" + value.toString().replace(".", "\\.") + "(?:\\..+)?$").build();
default:
throw new IllegalArgumentException("Unsupported operation: " + this.operation);
}
return switch (this.operation) {
case EQUALS -> EqualTo.<T>builder().field(field).value(value).build();
case NOT_EQUALS -> NotEqualTo.<T>builder().field(field).value(value).build();
case GREATER_THAN -> GreaterThan.<T>builder().field(field).value(value).build();
case LESS_THAN -> LessThan.<T>builder().field(field).value(value).build();
case GREATER_THAN_OR_EQUAL_TO -> GreaterThanOrEqualTo.<T>builder().field(field).value(value).build();
case LESS_THAN_OR_EQUAL_TO -> LessThanOrEqualTo.<T>builder().field(field).value(value).build();
case IN -> In.<T>builder().field(field).values(asValues(value)).build();
case NOT_IN -> NotIn.<T>builder().field(field).values(asValues(value)).build();
case STARTS_WITH -> StartsWith.<T>builder().field(field).value(value.toString()).build();
case ENDS_WITH -> EndsWith.<T>builder().field(field).value(value.toString()).build();
case CONTAINS -> Contains.<T>builder().field(field).value(value.toString()).build();
case REGEX -> Regex.<T>builder().field(field).value(value.toString()).build();
case PREFIX -> Regex.<T>builder().field(field).value("^" + value.toString().replace(".", "\\.") + "(?:\\..+)?$").build();
};
}
public enum Field {
@@ -101,7 +88,7 @@ public record QueryFilter(
NAMESPACE("namespace") {
@Override
public List<Op> supportedOp() {
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.STARTS_WITH, Op.ENDS_WITH, Op.REGEX, Op.IN, Op.PREFIX);
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.STARTS_WITH, Op.ENDS_WITH, Op.REGEX, Op.IN, Op.NOT_IN, Op.PREFIX);
}
},
LABELS("labels") {
@@ -113,7 +100,7 @@ public record QueryFilter(
FLOW_ID("flowId") {
@Override
public List<Op> supportedOp() {
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.IN, Op.NOT_IN);
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.STARTS_WITH, Op.ENDS_WITH, Op.REGEX);
}
},
START_DATE("startDate") {
@@ -125,7 +112,7 @@ public record QueryFilter(
END_DATE("endDate") {
@Override
public List<Op> supportedOp() {
return List.of(Op.GREATER_THAN, Op.LESS_THAN, Op.EQUALS, Op.NOT_EQUALS);
return List.of(Op.GREATER_THAN_OR_EQUAL_TO, Op.GREATER_THAN, Op.LESS_THAN_OR_EQUAL_TO, Op.LESS_THAN, Op.EQUALS, Op.NOT_EQUALS);
}
},
STATE("state") {
@@ -137,8 +124,7 @@ public record QueryFilter(
TIME_RANGE("timeRange") {
@Override
public List<Op> supportedOp() {
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.STARTS_WITH,
Op.ENDS_WITH, Op.IN, Op.NOT_IN, Op.REGEX);
return List.of(Op.EQUALS);
}
},
TRIGGER_EXECUTION_ID("triggerExecutionId") {
@@ -217,7 +203,7 @@ public record QueryFilter(
@Override
public List<Field> supportedField() {
return List.of(
Field.QUERY, Field.SCOPE, Field.FLOW_ID, Field.START_DATE, Field.END_DATE, Field.TIME_RANGE,
Field.QUERY, Field.SCOPE, Field.FLOW_ID, Field.START_DATE, Field.END_DATE,
Field.STATE, Field.LABELS, Field.TRIGGER_EXECUTION_ID, Field.CHILD_FILTER,
Field.NAMESPACE
);
@@ -226,8 +212,8 @@ public record QueryFilter(
LOG {
@Override
public List<Field> supportedField() {
return List.of(Field.NAMESPACE, Field.START_DATE, Field.END_DATE,
Field.FLOW_ID, Field.TRIGGER_ID, Field.MIN_LEVEL
return List.of(Field.QUERY, Field.SCOPE, Field.NAMESPACE, Field.START_DATE,
Field.END_DATE, Field.FLOW_ID, Field.TRIGGER_ID, Field.MIN_LEVEL
);
}
},
@@ -248,7 +234,8 @@ public record QueryFilter(
TRIGGER {
@Override
public List<Field> supportedField() {
return List.of(Field.QUERY, Field.NAMESPACE, Field.WORKER_ID, Field.FLOW_ID
return List.of(Field.QUERY, Field.SCOPE, Field.NAMESPACE, Field.WORKER_ID, Field.FLOW_ID,
Field.START_DATE, Field.END_DATE, Field.TRIGGER_ID
);
}
};
@@ -295,4 +282,26 @@ public record QueryFilter(
public record Operation(String name, String value) {
}
public static void validateQueryFilters(List<QueryFilter> filters, Resource resource){
if (filters == null) {
return;
}
List<String> errors = new ArrayList<>();
filters.forEach(filter -> {
if (!filter.field().supportedOp().contains(filter.operation())) {
errors.add("Operation %s is not supported for field %s. Supported operations are %s".formatted(
filter.operation(), filter.field().name(),
filter.field().supportedOp().stream().map(Op::name).collect(Collectors.joining(", "))));
}
if (!resource.supportedField().contains(filter.field())){
errors.add("Field %s is not supported for resource %s. Supported fields are %s".formatted(
filter.field().name(), resource.name(),
resource.supportedField().stream().map(Field::name).collect(Collectors.joining(", "))));
}
});
if (!errors.isEmpty()){
throw new InvalidQueryFiltersException(errors);
}
}
}

View File

@@ -15,6 +15,8 @@ import jakarta.validation.constraints.NotNull;
@NoArgsConstructor
public class Setting {
public static final String INSTANCE_UUID = "instance.uuid";
public static final String INSTANCE_VERSION = "instance.version";
@NotNull
private String key;

View File

@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import io.kestra.core.debug.Breakpoint;
import io.kestra.core.exceptions.InternalException;
import io.kestra.core.models.DeletedInterface;
import io.kestra.core.models.Label;
@@ -24,6 +25,7 @@ import io.kestra.core.serializers.ListOrMapOfLabelSerializer;
import io.kestra.core.services.LabelService;
import io.kestra.core.test.flow.TaskFixture;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.ListUtils;
import io.kestra.core.utils.MapUtils;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.annotation.Nullable;
@@ -120,6 +122,9 @@ public class Execution implements DeletedInterface, TenantInterface {
@Nullable
ExecutionKind kind;
@Nullable
List<Breakpoint> breakpoints;
/**
* Factory method for constructing a new {@link Execution} object for the given {@link Flow}.
*
@@ -132,7 +137,7 @@ public class Execution implements DeletedInterface, TenantInterface {
}
public List<Label> getLabels() {
return Optional.ofNullable(this.labels).orElse(new ArrayList<>());
return ListUtils.emptyOnNull(this.labels);
}
/**
@@ -156,6 +161,7 @@ public class Execution implements DeletedInterface, TenantInterface {
.flowRevision(flow.getRevision())
.state(new State())
.scheduleDate(scheduleDate.map(ChronoZonedDateTime::toInstant).orElse(null))
.variables(flow.getVariables())
.build();
List<Label> executionLabels = new ArrayList<>(LabelService.labelsExcludingSystem(flow));
@@ -176,8 +182,22 @@ public class Execution implements DeletedInterface, TenantInterface {
}
/**
* Customization of Lombok-generated builder.
*/
public static class ExecutionBuilder {
/**
* Enforce unique values of {@link Label} when using the builder.
*
* @param labels The labels.
* @return Deduplicated labels.
*/
public ExecutionBuilder labels(List<Label> labels) {
this.labels = Label.deduplicate(labels);
return this;
}
void prebuild() {
this.originalId = this.id;
this.metadata = ExecutionMetadata.builder()
@@ -220,12 +240,12 @@ public class Execution implements DeletedInterface, TenantInterface {
this.scheduleDate,
this.traceParent,
this.fixtures,
this.kind
this.kind,
this.breakpoints
);
}
public Execution withLabels(List<Label> labels) {
return new Execution(
this.tenantId,
this.id,
@@ -235,7 +255,7 @@ public class Execution implements DeletedInterface, TenantInterface {
this.taskRunList,
this.inputs,
this.outputs,
labels,
Label.deduplicate(labels),
this.variables,
this.state,
this.parentId,
@@ -246,7 +266,8 @@ public class Execution implements DeletedInterface, TenantInterface {
this.scheduleDate,
this.traceParent,
this.fixtures,
this.kind
this.kind,
this.breakpoints
);
}
@@ -285,7 +306,34 @@ public class Execution implements DeletedInterface, TenantInterface {
this.scheduleDate,
this.traceParent,
this.fixtures,
this.kind
this.kind,
this.breakpoints
);
}
public Execution withBreakpoints(List<Breakpoint> newBreakpoints) {
return new Execution(
this.tenantId,
this.id,
this.namespace,
this.flowId,
this.flowRevision,
this.taskRunList,
this.inputs,
this.outputs,
this.labels,
this.variables,
this.state,
this.parentId,
this.originalId,
this.trigger,
this.deleted,
this.metadata,
this.scheduleDate,
this.traceParent,
this.fixtures,
this.kind,
newBreakpoints
);
}
@@ -311,7 +359,8 @@ public class Execution implements DeletedInterface, TenantInterface {
this.scheduleDate,
this.traceParent,
this.fixtures,
this.kind
this.kind,
this.breakpoints
);
}
@@ -365,7 +414,7 @@ public class Execution implements DeletedInterface, TenantInterface {
*
* @param resolvedTasks normal tasks
* @param resolvedErrors errors tasks
* @param resolvedErrors finally tasks
* @param resolvedFinally finally tasks
* @return the flow we need to follow
*/
public List<ResolvedTask> findTaskDependingFlowState(
@@ -823,7 +872,7 @@ public class Execution implements DeletedInterface, TenantInterface {
* @param e the current exception
* @return the {@link ILoggingEvent} waited to generate {@link LogEntry}
*/
public static ILoggingEvent loggingEventFromException(Exception e) {
public static ILoggingEvent loggingEventFromException(Throwable e) {
LoggingEvent loggingEvent = new LoggingEvent();
loggingEvent.setLevel(ch.qos.logback.classic.Level.ERROR);
loggingEvent.setThrowableProxy(new ThrowableProxy(e));

View File

@@ -3,8 +3,9 @@ package io.kestra.core.models.executions;
/**
* Describe the kind of execution:
* - TEST: created by a test
* - PLAYGROUND: created by a playground
* - NORMAL: anything else, for backward compatibility NORMAL is not persisted but null is used instead
*/
public enum ExecutionKind {
NORMAL, TEST
NORMAL, TEST, PLAYGROUND
}

View File

@@ -7,6 +7,7 @@ import io.kestra.core.models.tasks.ResolvedTask;
import io.kestra.core.models.tasks.retrys.AbstractRetry;
import io.kestra.core.utils.IdUtils;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.*;
@@ -62,6 +63,11 @@ public class TaskRun implements TenantInterface {
@With
Boolean dynamic;
// Set it to true to force execution even if the execution is killed
@Nullable
@With
Boolean forceExecution;
@Deprecated
public void setItems(String items) {
// no-op for backward compatibility
@@ -81,7 +87,8 @@ public class TaskRun implements TenantInterface {
this.outputs,
this.state.withState(state),
this.iteration,
this.dynamic
this.dynamic,
this.forceExecution
);
}
@@ -99,7 +106,8 @@ public class TaskRun implements TenantInterface {
this.outputs,
newState,
this.iteration,
this.dynamic
this.dynamic,
this.forceExecution
);
}
@@ -121,7 +129,8 @@ public class TaskRun implements TenantInterface {
this.outputs,
this.state.withState(State.Type.FAILED),
this.iteration,
this.dynamic
this.dynamic,
this.forceExecution
);
}
@@ -245,7 +254,7 @@ public class TaskRun implements TenantInterface {
* @return The next retry date, null if maxAttempt || maxDuration is reached
*/
public Instant nextRetryDate(AbstractRetry retry, Execution execution) {
if (retry.getMaxAttempt() != null && execution.getMetadata().getAttemptNumber() >= retry.getMaxAttempt()) {
if (retry.getMaxAttempts() != null && execution.getMetadata().getAttemptNumber() >= retry.getMaxAttempts()) {
return null;
}
@@ -265,7 +274,7 @@ public class TaskRun implements TenantInterface {
* @return The next retry date, null if maxAttempt || maxDuration is reached
*/
public Instant nextRetryDate(AbstractRetry retry) {
if (this.attempts == null || this.attempts.isEmpty() || (retry.getMaxAttempt() != null && this.attemptNumber() >= retry.getMaxAttempt())) {
if (this.attempts == null || this.attempts.isEmpty() || (retry.getMaxAttempts() != null && this.attemptNumber() >= retry.getMaxAttempts())) {
return null;
}

View File

@@ -3,6 +3,8 @@ package io.kestra.core.models.flows;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.kestra.core.models.Label;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.tasks.WorkerGroup;
import io.kestra.core.serializers.ListOrMapOfLabelDeserializer;
import io.kestra.core.serializers.ListOrMapOfLabelSerializer;
import io.swagger.v3.oas.annotations.Hidden;
@@ -60,6 +62,9 @@ public abstract class AbstractFlow implements FlowInterface {
@Schema(implementation = Object.class, oneOf = {List.class, Map.class})
List<Label> labels;
@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE)
Map<String, Object> variables;
@Valid
private WorkerGroup workerGroup;
}

View File

@@ -1,20 +1,19 @@
package io.kestra.core.models.flows;
import io.micronaut.core.annotation.Introspected;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
@SuperBuilder
@Getter
@NoArgsConstructor
@Introspected
public class Concurrency {
@Positive
@Min(1)
@NotNull
private Integer limit;

View File

@@ -19,7 +19,6 @@ import io.kestra.core.models.tasks.retrys.AbstractRetry;
import io.kestra.core.models.triggers.AbstractTrigger;
import io.kestra.core.models.validations.ManualConstraintViolation;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.services.FlowService;
import io.kestra.core.utils.ListUtils;
import io.kestra.core.validations.FlowValidation;
import io.micronaut.core.annotation.Introspected;
@@ -30,8 +29,6 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Collectors;
@@ -70,6 +67,8 @@ public class Flow extends AbstractFlow implements HasUID {
@Valid
@NotEmpty
@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE)
List<Task> tasks;
@Valid
@@ -187,19 +186,32 @@ public class Flow extends AbstractFlow implements HasUID {
.toList();
}
public List<Task> allErrorsWithChilds() {
public List<Task> allErrorsWithChildren() {
var allErrors = allTasksWithChilds().stream()
.filter(task -> task.isFlowable() && ((FlowableTask<?>) task).getErrors() != null)
.flatMap(task -> ((FlowableTask<?>) task).getErrors().stream())
.collect(Collectors.toCollection(ArrayList::new));
if (this.getErrors() != null && !this.getErrors().isEmpty()) {
if (!ListUtils.isEmpty(this.getErrors())) {
allErrors.addAll(this.getErrors());
}
return allErrors;
}
public List<Task> allFinallyWithChildren() {
var allFinally = allTasksWithChilds().stream()
.filter(task -> task.isFlowable() && ((FlowableTask<?>) task).getFinally() != null)
.flatMap(task -> ((FlowableTask<?>) task).getFinally().stream())
.collect(Collectors.toCollection(ArrayList::new));
if (!ListUtils.isEmpty(this.getFinally())) {
allFinally.addAll(this.getFinally());
}
return allFinally;
}
public Task findParentTasksByTaskId(String taskId) {
return allTasksWithChilds()
.stream()

View File

@@ -11,6 +11,7 @@ import io.kestra.core.models.HasUID;
import io.kestra.core.models.Label;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.sla.SLA;
import io.kestra.core.models.tasks.WorkerGroup;
import io.kestra.core.serializers.JacksonMapper;
import java.util.AbstractMap;
@@ -42,6 +43,8 @@ public interface FlowInterface extends FlowId, DeletedInterface, TenantInterface
Map<String, Object> getVariables();
WorkerGroup getWorkerGroup();
default Concurrency getConcurrency() {
return null;
}

View File

@@ -3,6 +3,7 @@ package io.kestra.core.models.flows;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.kestra.core.models.tasks.Task;
import io.micronaut.core.annotation.Introspected;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
@@ -167,6 +168,11 @@ public class State {
return this.current.isPaused();
}
@JsonIgnore
public boolean isBreakpoint() {
return this.current.isBreakpoint();
}
@JsonIgnore
public boolean isRetrying() {
return this.current.isRetrying();
@@ -215,7 +221,8 @@ public class State {
QUEUED,
RETRYING,
RETRIED,
SKIPPED;
SKIPPED,
BREAKPOINT;
public boolean isTerminated() {
return this == Type.FAILED || this == Type.WARNING || this == Type.SUCCESS || this == Type.KILLED || this == Type.CANCELLED || this == Type.RETRIED || this == Type.SKIPPED;
@@ -241,6 +248,10 @@ public class State {
return this == Type.PAUSED;
}
public boolean isBreakpoint() {
return this == Type.BREAKPOINT;
}
public boolean isRetrying() {
return this == Type.RETRYING || this == Type.RETRIED;
}
@@ -253,9 +264,22 @@ public class State {
return this == Type.KILLED;
}
/**
* @return states that are terminal to an execution
*/
public static List<Type> terminatedTypes() {
return Stream.of(Type.values()).filter(type -> type.isTerminated()).toList();
}
/**
* Compute the final 'failure' of a task depending on <code>allowFailure</code> and <code>allowWarning</code>:
* - if both are true -> SUCCESS
* - if only <code>allowFailure</code> is true -> WARNING
* - if none -> FAILED
*/
public static State.Type fail(Task task) {
return task.isAllowFailure() ? (task.isAllowWarning() ? State.Type.SUCCESS : State.Type.WARNING) : State.Type.FAILED;
}
}
@Value

View File

@@ -20,8 +20,8 @@ public class FileInput extends Input<URI> {
private static final String DEFAULT_EXTENSION = ".upl";
@Builder.Default
public String extension = DEFAULT_EXTENSION;
@Deprecated(since = "0.24", forRemoval = true)
public String extension;
@Override
public void validate(URI input) throws ConstraintViolationException {
@@ -32,6 +32,7 @@ public class FileInput extends Input<URI> {
String res = inputs.stream()
.filter(in -> in instanceof FileInput)
.filter(in -> in.getId().equals(fileName))
.filter(flowInput -> ((FileInput) flowInput).getExtension() != null)
.map(flowInput -> ((FileInput) flowInput).getExtension())
.findFirst()
.orElse(FileInput.DEFAULT_EXTENSION);

View File

@@ -108,7 +108,7 @@ public class MultiselectInput extends Input<List<String>> implements ItemTypeInt
private List<String> renderExpressionValues(final Function<String, Object> renderer) {
Object result;
try {
result = renderer.apply(expression);
result = renderer.apply(expression.trim());
} catch (Exception e) {
throw ManualConstraintViolation.toConstraintViolationException(
"Cannot render 'expression'. Cause: " + e.getMessage(),

View File

@@ -86,7 +86,7 @@ public class SelectInput extends Input<String> implements RenderableInput {
private List<String> renderExpressionValues(final Function<String, Object> renderer) {
Object result;
try {
result = renderer.apply(expression);
result = renderer.apply(expression.trim());
} catch (Exception e) {
throw ManualConstraintViolation.toConstraintViolationException(
"Cannot render 'expression'. Cause: " + e.getMessage(),

View File

@@ -1,12 +1,16 @@
package io.kestra.core.models.property;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.runners.RunContext;
import io.kestra.core.serializers.FileSerde;
import io.kestra.core.validations.DataValidation;
import io.kestra.core.serializers.JacksonMapper;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import jakarta.annotation.Nullable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
@@ -15,140 +19,132 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;
@Getter
@Builder
@DataValidation
@Schema(
title = "A carrier for some data that can comes from either an internal storage URI, an object or an array of objects."
)
public class Data<T> {
@Schema(title = "A Kestra internal storage URI")
private Property<URI> fromURI;
import static io.kestra.core.utils.Rethrow.throwFunction;
@Schema(title = "An object (which is equivalent to a map)")
private Property<Map<String, Object>> fromMap;
/**
* A carrier for structured data items.
*/
public class Data {
@SuppressWarnings("unchecked")
private static final Class<Map<String, Object>> MAP_OF_STRING_OBJECT = (Class<Map<String, Object>>) Map.of().getClass();
@Schema(title = "An array of objects (which is equivalent to a list of maps)")
private Property<List<Map<String, Object>>> fromList;
// this would be used in case 'from' is a String but not a URI to read it as a single item or a list of items
private static final ObjectMapper JSON_MAPPER = JacksonMapper.ofJson()
.copy()
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
/**
* Convenient factory method to create a Data object from a URI, mainly for testing purpose.
*
* @see #ofMap(Map)
* @see #ofList(List)
*/
public static Data<?> ofURI(URI uri) {
return Data.builder().fromURI(Property.ofValue(uri)).build();
@Nullable
private final Object from;
public Data(@Nullable Object from) {
this.from = from;
}
/**
* Convenient factory method to create a Data object from a Map, mainly for testing purpose.
*
* @see #ofURI(URI)
* @see #ofList(List)
* Build a carrier Data object for structured data items.
* The `from` parameter can be either a map, a list of maps, or a String.
*/
public static Data<?> ofMap(Map<String, Object> map) {
return Data.builder().fromMap(Property.ofValue(map)).build();
public static Data from(@Nullable Object from) {
return new Data(from);
}
/**
* Convenient factory method to create a Data object from a List, mainly for testing purpose.
* Generates a <code>Flux</code> of maps for the data items.
* If you want to work with objects, use {@link #readAs(RunContext, Class, Function)} instead.
*
* @see #ofURI(URI)
* @see #ofMap(Map)
* @see #readAs(RunContext, Class, Function)
*/
public static Data<?> ofList(List<Map<String, Object>> list) {
return Data.builder().fromList(Property.ofValue(list)).build();
public Flux<Map<String, Object>> read(RunContext runContext) throws IllegalVariableEvaluationException {
return readAs(runContext, MAP_OF_STRING_OBJECT, it -> it);
}
/**
* Generates a flux of objects for the data property, using either of its three properties.
* The mapper passed to this method will be used to map the map to the desired type when using 'fromMap' or 'fromList',
* it can be omitted when using 'fromURI'.
* Generates a <code>Flux</code> of objects for the data items.
* The mapper passed to this method will be used to map to the desired type when the `from` attribute is a Map or a List of Maps.
* If you want to work with maps, use {@link #read(RunContext)} instead.
*
* @see #read(RunContext)
*/
public Flux<T> flux(RunContext runContext, Class<T> clazz, Function<Map<String, Object>, T> mapper) throws IllegalVariableEvaluationException {
if (isFromURI()) {
URI uri = runContext.render(fromURI).as(URI.class).orElseThrow();
try {
var reader = new BufferedReader(new InputStreamReader(runContext.storage().getFile(uri)));
return FileSerde.readAll(reader, clazz)
.publishOn(Schedulers.boundedElastic())
.doFinally(signalType -> {
try {
reader.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
@SuppressWarnings("unchecked")
public <T> Flux<T> readAs(RunContext runContext, Class<T> clazz, Function<Map<String, Object>, T> mapper) throws IllegalVariableEvaluationException {
Objects.requireNonNull(mapper); // as mapper is not used everywhere, we assert it's not null to cover dev issues
if (from == null) {
return Flux.empty();
}
if (isFromMap()) {
Map<String, Object> map = runContext.render(fromMap).asMap(String.class, Object.class);
if (from instanceof Map<?, ?> fromMap) {
Map<String, Object> map = runContext.render((Map<String, Object>) fromMap);
return Mono.just(map).flux().map(mapper);
}
if (isFromList()) {
List<Map<String, Object>> list = runContext.render(fromList).asList(Map.class);
return Flux.fromIterable(list).map(mapper);
if (clazz.isAssignableFrom(from.getClass())) {
// it could be the case in tests so we handle it for dev experience
return Mono.just((T) from).flux();
}
return Flux.empty();
}
/**
* @return true if fromURI is set
*/
public boolean isFromURI() {
return fromURI != null;
}
/**
* If a fromURI is present, performs the given action with the URI, otherwise does nothing.
*/
public void ifFromURI(RunContext runContext, Consumer<URI> consumer) throws IllegalVariableEvaluationException {
runContext.render(fromURI).as(URI.class).ifPresent(uri -> consumer.accept(uri));
}
/**
* @return true if fromMap is set
*/
public boolean isFromMap() {
return fromMap != null;
}
/**
* If a fromMap is present, performs the given action with the mat, otherwise does nothing.
*/
public void ifFromMap(RunContext runContext, Consumer<Map<String, Object>> consumer) throws IllegalVariableEvaluationException {
if (isFromMap()) {
Map<String, Object> map = runContext.render(fromMap).asMap(String.class, Object.class);
consumer.accept(map);
if (from instanceof List<?> fromList) {
if (!fromList.isEmpty() && clazz.isAssignableFrom(fromList.getFirst().getClass())){
// it could be the case in tests so we handle it for dev experience
return Flux.fromIterable((List<T>) fromList);
}
Stream<Map<String, Object>> stream = fromList.stream().map(throwFunction(it -> runContext.render((Map<String, Object>) it)));
return Flux.fromStream(stream).map(mapper);
}
}
/**
* @return true if fromList is set
*/
public boolean isFromList() {
return fromList != null;
}
/**
* If a fromList is present, performs the given action with the list of maps, otherwise does nothing.
*/
public void ifFromList(RunContext runContext, Consumer<List<Map<String, Object>>> consumer) throws IllegalVariableEvaluationException {
if (isFromList()) {
List<Map<String, Object>> list = runContext.render(fromList).asList(Map.class);
consumer.accept(list);
if (from instanceof String str) {
var renderedString = runContext.render(str);
if (URIFetcher.supports(renderedString)) {
var uri = URIFetcher.of(runContext.render(str));
try {
var reader = new BufferedReader(new InputStreamReader(uri.fetch(runContext)), FileSerde.BUFFER_SIZE);
return FileSerde.readAll(reader, clazz)
.publishOn(Schedulers.boundedElastic())
.doFinally(signalType -> {
try {
reader.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} else {
// Try to parse it as a list of JSON items.
// A single value instead of a list is also supported as we configure the JSON mapper for it.
try {
CollectionType collectionType = JSON_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz);
List<T> list = JSON_MAPPER.readValue(renderedString, collectionType);
return Flux.fromIterable(list);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
throw new IllegalArgumentException("Cannot handle structured data of type: " + from.getClass());
}
public interface From {
String TITLE = "Structured data items, either as a map, a list of map, a URI, or a JSON string.";
String DESCRIPTION = """
Structured data items can be defined in the following ways:
- A single item as a map (a document).
- A list of items as a list of maps (a list of documents).
- A URI, supported schemes are `kestra` for internal storage files, `file` for host local files, and `nsfile` for namespace files.
- A JSON String that will then be serialized either as a single item or a list of items.""";
@Schema(
title = TITLE,
description = DESCRIPTION,
anyOf = {String.class, List.class, Map.class}
)
@PluginProperty(dynamic = true)
Object getFrom();
}
}

View File

@@ -0,0 +1,100 @@
package io.kestra.core.models.property;
import io.kestra.core.runners.LocalPath;
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.StorageContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Path;
import java.util.List;
/**
* Helper class for fetching content from a URI.
* It supports reading from the following schemes: {@link #SUPPORTED_SCHEMES}.
*/
public class URIFetcher {
private static final List<String> SUPPORTED_SCHEMES = List.of(StorageContext.KESTRA_SCHEME, LocalPath.FILE_SCHEME, Namespace.NAMESPACE_FILE_SCHEME);
private final URI uri;
/**
* Build a new URI Fetcher from a String URI.
* WARNING: the URI must be rendered before.
*
* A factory method is also provided for fluent style programming, see {@link #of(String).}
*/
public URIFetcher(String uri) {
this(URI.create(uri));
}
/**
* Build a new URI Fetcher from a URI.
*
* A factory method is also provided for fluent style programming, see {@link #of(URI).}
*/
public URIFetcher(URI uri) {
if (SUPPORTED_SCHEMES.stream().noneMatch(s -> s.equals(uri.getScheme()))) {
throw new IllegalArgumentException("Scheme not supported: " + uri.getScheme() + ". Supported schemes are: " + SUPPORTED_SCHEMES);
}
this.uri = uri;
}
/**
* Build a new URI Fetcher from a String URI.
* WARNING: the URI must be rendered before.
*/
public static URIFetcher of(String uri) {
return new URIFetcher(uri);
}
/**
* Build a new URI Fetcher from a URI.
*/
public static URIFetcher of(URI uri) {
return new URIFetcher(uri);
}
/**
* Whether the URI is supported by the Fetcher.
* A supported URI is a string that starts with one of the {@link #SUPPORTED_SCHEMES}.
*/
public static boolean supports(String uri) {
return SUPPORTED_SCHEMES.stream().anyMatch(scheme -> uri.startsWith(scheme + "://"));
}
/**
* Whether the URI is supported by the Fetcher.
* A supported URI is a URI which scheme is one of the {@link #SUPPORTED_SCHEMES}.
*/
public static boolean supports(URI uri) {
return uri.getScheme() != null && SUPPORTED_SCHEMES.contains(uri.getScheme());
}
/**
* Fetch the resource pointed by this SmartURI
*
* @throws IOException if an IO error occurs
* @throws SecurityException if the URI points to a path that is not allowed
*/
public InputStream fetch(RunContext runContext) throws IOException {
if (uri == null) {
return InputStream.nullInputStream();
}
// we need to first check the protocol, then create one reader by protocol
return switch (uri.getScheme()) {
case StorageContext.KESTRA_SCHEME -> runContext.storage().getFile(uri);
case LocalPath.FILE_SCHEME -> runContext.localPath().get(uri);
case Namespace.NAMESPACE_FILE_SCHEME -> {
var namespace = uri.getAuthority() == null ? runContext.storage().namespace() : runContext.storage().namespace(uri.getAuthority());
var nsFileUri = namespace.get(Path.of(uri.getPath())).uri();
yield runContext.storage().getFile(nsFileUri);
}
default -> throw new IllegalArgumentException("Scheme not supported: " + uri.getScheme());
};
}
}

View File

@@ -0,0 +1,20 @@
package io.kestra.core.models.tasks;
import io.micronaut.core.annotation.Introspected;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.Duration;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Introspected
public class Cache {
@NotNull
private Boolean enabled;
private Duration ttl;
}

View File

@@ -7,7 +7,12 @@ import java.util.Map;
public interface InputFilesInterface {
@Schema(
title = "The files to create on the local filesystem. It can be a map or a JSON object.",
title = "The files to create on the working. It can be a map or a JSON object.",
description = """
Each file can be defined:
- Inline with its content
- As a URI, supported schemes are `kestra` for internal storage files, `file` for host local files, and `nsfile` for namespace files.
""",
oneOf = {Map.class, String.class}
)
@PluginProperty(dynamic = true)

View File

@@ -49,4 +49,10 @@ public class NamespaceFiles {
)
@Builder.Default
private Property<FileExistComportment> ifExists = Property.ofValue(FileExistComportment.OVERWRITE);
@Schema(
title = "Whether to mount file into the root of the working directory, or create a folder per namespace"
)
@Builder.Default
private Property<Boolean> folderPerNamespace = Property.ofValue(false);
}

View File

@@ -11,6 +11,7 @@ import io.kestra.core.models.tasks.retrys.AbstractRetry;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.core.flow.WorkingDirectory;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -28,6 +29,7 @@ import static io.kestra.core.utils.Rethrow.throwFunction;
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@Plugin
abstract public class Task implements TaskInterface {
@Size(max = 256, message = "Task id must be at most 256 characters")
protected String id;
protected String type;
@@ -72,6 +74,10 @@ abstract public class Task implements TaskInterface {
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean allowWarning = false;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
@Valid
private Cache taskCache;
public Optional<Task> findById(String id) {
if (this.getId().equals(id)) {
return Optional.of(this);

View File

@@ -1,6 +1,5 @@
package io.kestra.core.models.tasks;
import io.kestra.core.validations.WorkerGroupValidation;
import io.micronaut.core.annotation.Introspected;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -10,7 +9,6 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Introspected
@WorkerGroupValidation
public class WorkerGroup {
private String key;

View File

@@ -29,8 +29,18 @@ public abstract class AbstractRetry {
private Duration maxDuration;
@Deprecated(forRemoval = true)
public Integer getMaxAttempt() {
return maxAttempts;
}
@Deprecated(forRemoval = true)
public void setMaxAttempt(@Min(1) Integer maxAttempt) {
this.maxAttempts = maxAttempt;
}
@Min(1)
private Integer maxAttempt;
private Integer maxAttempts;
@Builder.Default
private Boolean warningOnRetry = false;
@@ -46,8 +56,8 @@ public abstract class AbstractRetry {
builder.withMaxDuration(maxDuration);
}
if (this.maxAttempt != null) {
builder.withMaxAttempts(this.maxAttempt);
if (this.maxAttempts != null) {
builder.withMaxAttempts(this.maxAttempts);
}
return builder;
}

View File

@@ -100,7 +100,7 @@ abstract public class PluginUtilsService {
@SuppressWarnings("unchecked")
public static Map<String, String> transformInputFiles(RunContext runContext, Map<String, Object> additionalVars, @NotNull Object inputFiles) throws IllegalVariableEvaluationException, JsonProcessingException {
if (inputFiles instanceof Map) {
Map<String, String> castedInputFiles = (Map<String, String>) ((Map<?, ?>) inputFiles);
Map<String, String> castedInputFiles = (Map<String, String>) inputFiles;
Map<String, String> nullFilteredInputFiles = new HashMap<>();
castedInputFiles.forEach((key, val) -> {
if (val != null) {
@@ -110,7 +110,6 @@ abstract public class PluginUtilsService {
return runContext.renderMap(nullFilteredInputFiles, additionalVars);
} else if (inputFiles instanceof String inputFileString) {
return JacksonMapper.ofJson(false).readValue(
runContext.render(inputFileString, additionalVars),
MAP_TYPE_REFERENCE

View File

@@ -30,7 +30,7 @@ import static io.kestra.core.utils.Rethrow.throwFunction;
* Helper class for task runners and script tasks.
*/
public final class ScriptService {
private static final Pattern INTERNAL_STORAGE_PATTERN = Pattern.compile("(kestra:\\/\\/[-a-zA-Z0-9%._\\+~#=/]*)");
private static final Pattern INTERNAL_STORAGE_PATTERN = Pattern.compile("(kestra:\\/\\/[-\\p{Alnum}._\\+~#=/]*)", Pattern.UNICODE_CHARACTER_CLASS);
// These are the three common additional variables task runners must provide for variable rendering.
public static final String VAR_WORKING_DIR = "workingDir";

View File

@@ -1,7 +1,6 @@
package io.kestra.core.models.topologies;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.FlowInterface;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.AllArgsConstructor;
@@ -11,6 +10,8 @@ import lombok.experimental.SuperBuilder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import java.util.Objects;
@Getter
@AllArgsConstructor
@SuperBuilder(toBuilder = true)
@@ -26,6 +27,18 @@ public class FlowNode implements TenantInterface {
String id;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
FlowNode flowNode = (FlowNode) o;
return Objects.equals(uid, flowNode.uid);
}
@Override
public int hashCode() {
return Objects.hash(uid);
}
public static FlowNode of(FlowInterface flow) {
return FlowNode.builder()
.uid(flow.uidWithoutRevision())

View File

@@ -78,6 +78,10 @@ abstract public class AbstractTrigger implements TriggerInterface {
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean logToFile = false;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean failOnTriggerError = false;
/**
* For backward compatibility: we rename minLogLevel to logLevel.
* @deprecated use {@link #logLevel} instead

View File

@@ -8,6 +8,7 @@ import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
@@ -20,6 +21,7 @@ import java.util.List;
@NoArgsConstructor
@Introspected
public class TriggerContext {
@Setter
@Pattern(regexp = "^[a-z0-9][a-z0-9_-]")
private String tenantId;

View File

@@ -119,6 +119,7 @@ public abstract class TriggerService {
.id(id)
.namespace(context.getNamespace())
.flowId(context.getFlowId())
.tenantId(context.getTenantId())
.flowRevision(flowRevision)
.state(new State())
.trigger(executionTrigger)

View File

@@ -329,6 +329,14 @@ public class DefaultPluginRegistry implements PluginRegistry {
pluginClassByIdentifier.clear();
}
/**
* {@inheritDoc}
**/
@Override
public boolean isVersioningSupported() {
return false;
}
public record PluginBundleIdentifier(@Nullable URL location) {
public static PluginBundleIdentifier CORE = new PluginBundleIdentifier(null);

View File

@@ -151,7 +151,7 @@ public class LocalPluginManager implements PluginManager {
* {@inheritDoc}
**/
@Override
public PluginArtifact install(File file, boolean installForRegistration, @Nullable Path localRepositoryPath) {
public PluginArtifact install(File file, boolean installForRegistration, @Nullable Path localRepositoryPath, boolean forceInstallOnExistingVersions) {
try {
PluginArtifact artifact = PluginArtifact.fromFile(file);
log.info("Installing managed plugin artifact '{}'", artifact);

View File

@@ -55,14 +55,16 @@ public interface PluginManager extends AutoCloseable {
/**
* Installs the given plugin artifact.
*
* @param file the plugin JAR file.
* @param installForRegistration specify whether plugin artifacts should be scanned and registered.
* @param localRepositoryPath the optional local repository path to install artifact.
* @param file the plugin JAR file.
* @param installForRegistration specify whether plugin artifacts should be scanned and registered.
* @param localRepositoryPath the optional local repository path to install artifact.
* @param forceInstallOnExistingVersions specify whether plugin should be forced install upon the existing one
* @return The URI of the installed plugin.
*/
PluginArtifact install(final File file,
boolean installForRegistration,
@Nullable Path localRepositoryPath);
@Nullable Path localRepositoryPath,
boolean forceInstallOnExistingVersions);
/**
* Installs the given plugin artifact.

View File

@@ -116,4 +116,11 @@ public interface PluginRegistry {
default void clear() {
}
/**
* Checks whether plugin-versioning is supported by this registry.
*
* @return {@code true} if supported. Otherwise {@code false}.
*/
boolean isVersioningSupported();
}

View File

@@ -18,9 +18,11 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -202,19 +204,13 @@ public class PluginScanner {
var guidesDirectory = classLoader.getResource("doc/guides");
if (guidesDirectory != null) {
try (var fileSystem = FileSystems.newFileSystem(guidesDirectory.toURI(), Collections.emptyMap())) {
var root = fileSystem.getPath("/doc/guides");
try (var stream = Files.walk(root, 1)) {
stream
.skip(1) // first element is the root element
.sorted(Comparator.comparing(path -> path.getName(path.getParent().getNameCount()).toString()))
.forEach(guide -> {
var guideName = guide.getName(guide.getParent().getNameCount()).toString();
guides.add(guideName.substring(0, guideName.lastIndexOf('.')));
});
}
try {
var root = Path.of(guidesDirectory.toURI());
addGuides(root, guides);
} catch (IOException | URISyntaxException e) {
// silently fail
} catch (FileSystemNotFoundException e) {
addGuidesThroughNewFileSystem(guidesDirectory, guides);
}
}
@@ -243,6 +239,27 @@ public class PluginScanner {
.build();
}
private static void addGuidesThroughNewFileSystem(URL guidesDirectory, List<String> guides) {
try (var fileSystem = FileSystems.newFileSystem(guidesDirectory.toURI(), Collections.emptyMap())) {
var root = fileSystem.getPath("doc/guides");
addGuides(root, guides);
} catch (IOException | URISyntaxException e) {
// silently fail
}
}
private static void addGuides(Path root, List<String> guides) throws IOException {
try (var stream = Files.walk(root)) { // remove depth limit to walk recursively
stream
.filter(Files::isRegularFile)
.sorted(Comparator.comparing(path -> path.getName(path.getParent().getNameCount()).toString()))
.forEach(guide -> {
var guideName = guide.getName(guide.getParent().getNameCount()).toString();
guides.add(guideName.substring(0, guideName.lastIndexOf('.')));
});
}
}
public static Manifest getManifest(ClassLoader classLoader) {
try {
URL url = classLoader.getResource(JarFile.MANIFEST_NAME);

View File

@@ -33,6 +33,20 @@ import static io.kestra.core.utils.Rethrow.throwFunction;
@EqualsAndHashCode
@Builder
public class RegisteredPlugin {
public static final String TASKS_GROUP_NAME = "tasks";
public static final String TRIGGERS_GROUP_NAME = "triggers";
public static final String CONDITIONS_GROUP_NAME = "conditions";
public static final String STORAGES_GROUP_NAME = "storages";
public static final String SECRETS_GROUP_NAME = "secrets";
public static final String TASK_RUNNERS_GROUP_NAME = "task-runners";
public static final String APPS_GROUP_NAME = "apps";
public static final String APP_BLOCKS_GROUP_NAME = "app-blocks";
public static final String CHARTS_GROUP_NAME = "charts";
public static final String DATA_FILTERS_GROUP_NAME = "data-filters";
public static final String DATA_FILTERS_KPI_GROUP_NAME = "data-filters-kpi";
public static final String LOG_EXPORTERS_GROUP_NAME = "log-exporters";
public static final String ADDITIONAL_PLUGINS_GROUP_NAME = "additional-plugins";
private final ExternalPlugin externalPlugin;
private final Manifest manifest;
private final ClassLoader classLoader;
@@ -160,19 +174,19 @@ public class RegisteredPlugin {
public Map<String, List<Class>> allClassGrouped() {
Map<String, List<Class>> result = new HashMap<>();
result.put("tasks", Arrays.asList(this.getTasks().toArray(Class[]::new)));
result.put("triggers", Arrays.asList(this.getTriggers().toArray(Class[]::new)));
result.put("conditions", Arrays.asList(this.getConditions().toArray(Class[]::new)));
result.put("storages", Arrays.asList(this.getStorages().toArray(Class[]::new)));
result.put("secrets", Arrays.asList(this.getSecrets().toArray(Class[]::new)));
result.put("task-runners", Arrays.asList(this.getTaskRunners().toArray(Class[]::new)));
result.put("apps", Arrays.asList(this.getApps().toArray(Class[]::new)));
result.put("app-blocks", Arrays.asList(this.getAppBlocks().toArray(Class[]::new)));
result.put("charts", Arrays.asList(this.getCharts().toArray(Class[]::new)));
result.put("data-filters", Arrays.asList(this.getDataFilters().toArray(Class[]::new)));
result.put("data-filters-kpi", Arrays.asList(this.getDataFiltersKPI().toArray(Class[]::new)));
result.put("log-exporters", Arrays.asList(this.getLogExporters().toArray(Class[]::new)));
result.put("additional-plugins", Arrays.asList(this.getAdditionalPlugins().toArray(Class[]::new)));
result.put(TASKS_GROUP_NAME, Arrays.asList(this.getTasks().toArray(Class[]::new)));
result.put(TRIGGERS_GROUP_NAME, Arrays.asList(this.getTriggers().toArray(Class[]::new)));
result.put(CONDITIONS_GROUP_NAME, Arrays.asList(this.getConditions().toArray(Class[]::new)));
result.put(STORAGES_GROUP_NAME, Arrays.asList(this.getStorages().toArray(Class[]::new)));
result.put(SECRETS_GROUP_NAME, Arrays.asList(this.getSecrets().toArray(Class[]::new)));
result.put(TASK_RUNNERS_GROUP_NAME, Arrays.asList(this.getTaskRunners().toArray(Class[]::new)));
result.put(APPS_GROUP_NAME, Arrays.asList(this.getApps().toArray(Class[]::new)));
result.put(APP_BLOCKS_GROUP_NAME, Arrays.asList(this.getAppBlocks().toArray(Class[]::new)));
result.put(CHARTS_GROUP_NAME, Arrays.asList(this.getCharts().toArray(Class[]::new)));
result.put(DATA_FILTERS_GROUP_NAME, Arrays.asList(this.getDataFilters().toArray(Class[]::new)));
result.put(DATA_FILTERS_KPI_GROUP_NAME, Arrays.asList(this.getDataFiltersKPI().toArray(Class[]::new)));
result.put(LOG_EXPORTERS_GROUP_NAME, Arrays.asList(this.getLogExporters().toArray(Class[]::new)));
result.put(ADDITIONAL_PLUGINS_GROUP_NAME, Arrays.asList(this.getAdditionalPlugins().toArray(Class[]::new)));
return result;
}

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