Compare commits

...

638 Commits

Author SHA1 Message Date
Loïc Mathieu
181460e5d2 fix(system): possible NPE on trigger when computing variables 2025-06-23 17:39:03 +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
Loïc Mathieu
f544bc9f85 fix(system)*: don't include yourself as def in the JSONSchema
For AdditionalPlugin, as we resolves subtypes using isAssignable, we will resolve ourself as a subtype which leads to infinite loop while parsing the schema.
2025-06-04 13:18:36 +02:00
Piyush Bhaskar
f06998571d fix(core): update background for plugin-doc in EE Apps and alert-info block styling in plugin doc. (#9323) 2025-06-04 16:10:01 +05:30
Piyush Bhaskar
2a27f031e2 fix(triggers): update link color in triggers (#9257) 2025-06-04 16:09:32 +05:30
YannC.
7e4a030fa3 fix(): add mising checkout in workflow github release 2025-06-04 12:25:32 +02:00
Loïc Mathieu
979b271638 fix(system)*: correctly resolve additional plugin subtypes so autocompletion work
Part-of: https://github.com/kestra-io/plugin-langchain4j/issues/61
2025-06-04 11:06:59 +02:00
Florian Hussonnois
bfc8556024 fix(build): fix deve-tool release-plugins script 2025-06-04 10:20:40 +02:00
Roman Acevedo
ca10215540 fix: langchain4j with wrong repo name in .plugins 2025-06-04 10:16:47 +02:00
Piyush Bhaskar
4bd3a50f9d fix(flow): update flow revision restoration (#9311) 2025-06-04 13:25:28 +05:30
Piyush Bhaskar
cfa239a7df fix(core): improve theme handling in Monaco editor (#9294) 2025-06-04 13:25:15 +05:30
brian.mulier
e163d91122 fix(core): rename NAMESPACE_PREFIX comparator to PREFIX 2025-06-04 09:32:29 +02:00
Miloš Paunović
8980c23895 chore(core): add an extra storage key constant for maintenance mode (#9310)
Related to https://github.com/kestra-io/kestra-ee/issues/3961.
2025-06-04 09:19:08 +02:00
Miloš Paunović
1c1bc18d91 fix(core): if task array has enum options, show select box instead of input (#9270)
Closes https://github.com/kestra-io/kestra/issues/9208.
Closes https://github.com/kestra-io/kestra/issues/9255.
2025-06-04 08:07:32 +02:00
brian.mulier
282cd766e2 fix(core): restore theme colors from Monaco editor 2025-06-03 20:37:55 +02:00
brian.mulier
ea0c3b9b22 fix(core): remove text filter for dashboards 2025-06-03 17:52:39 +02:00
brian.mulier
43ad5aa3fd fix(core): regex is not yet supported for text so we remove it for now 2025-06-03 17:46:31 +02:00
Anna Geller
581d5e4961 docs: clarify log level on the log task (#9277) 2025-06-03 15:58:44 +02:00
Roman Acevedo
8de568e7ac chore(version): update snapshot version 'v0.24.0-SNAPSHOT'. 2025-06-03 15:51:39 +02:00
Roman Acevedo
29eb0eb9c2 chore(version): update to version 'v0.23.0-rc0-SNAPSHOT'. 2025-06-03 15:49:49 +02:00
brian.mulier
83c6333c6f fix(core): change naming from STARTS_WITH_NAMESPACE_PREFIX to NAMESPACE_PREFIX 2025-06-03 15:32:42 +02:00
Florian Hussonnois
ccb871aec5 fix(ci): fix workflow gradle-release 2025-06-03 15:18:04 +02:00
Barthélémy Ledoux
3fe4556dd5 refactor: remove the theme and chartColor from schemes (#7296) 2025-06-03 15:00:35 +02:00
Barthélémy Ledoux
4a0d449106 refactor: remove nocode components registration from global scope (#9211) 2025-06-03 14:58:55 +02:00
Barthélémy Ledoux
c787ce3b4c fix: only load default values when changing type (#9272) 2025-06-03 14:58:41 +02:00
Roman Acevedo
cd9fdcd3d3 tests(system): make restartForEachItem test more deterministic 2025-06-03 14:27:48 +02:00
brian-mulier-p
e580c3590c feat(executions): add filter bar to flow concurrency tab (#9269)
closes #5825
2025-06-03 14:24:51 +02:00
brian.mulier
786be667a2 fix(core): remove REGEX filter for text search 2025-06-03 14:04:06 +02:00
Piyush Bhaskar
e2373448ff fix(core): update save button disabled logic. (#9267) 2025-06-03 17:17:16 +05:30
Miloš Paunović
23499a627a chore(core): remove sort buttons in no code if the block type is plugin defaults (#9265)
Closes https://github.com/kestra-io/kestra/issues/9217.
2025-06-03 12:36:27 +02:00
Miloš Paunović
24c4eebaf4 chore(core): remove margin from blueprints if used in combined view (#9264)
Closes https://github.com/kestra-io/kestra/issues/8503.
2025-06-03 12:28:00 +02:00
Piyush Bhaskar
3606a563f3 feat(flows): add global save functionality (#9262) 2025-06-03 15:55:30 +05:30
Anna Geller
22131f8c49 fix(assertions): fix assertions grammar (#9173) 2025-06-03 12:24:16 +02:00
YannC
c3d5811c86 fix: now correctly handles State filter for executions (#9223) 2025-06-03 12:15:44 +02:00
YannC
317621e7bb fix(ui): allows even embed table to be sorted (#9261)
close #9230
2025-06-03 12:09:16 +02:00
Daniel Rivas
598582fa76 test(cli): add return code and YAML-output tests for ConfigPropertiesCommand (#8827) 2025-06-03 12:00:43 +02:00
Loïc Mathieu
9bd87d7492 feat(flow): allow grouping plugin properties
Closes #7199
2025-06-03 11:59:10 +02:00
Roman Acevedo
712a3753f6 fix(triggers): bulk actions for Triggers with new Filter 2025-06-03 11:34:51 +02:00
Nicolas K.
49bb93b4db feat(tenants): change the tenant migration command name (#9253)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-03 11:32:18 +02:00
Miloš Paunović
f10b289d76 fix(dashboards): include pagination parameters in default dashboard tables (#9251)
Closes https://github.com/kestra-io/kestra/issues/9250.
2025-06-03 11:08:29 +02:00
brian.mulier
7f677211af fix(core): avoid adding incomplete key.{subKey} as text filter
closes #9243
2025-06-03 10:53:08 +02:00
Roman Acevedo
066a5f09fe fix(flows,executions): filtering QUERY NOT_EQUALS was not handled in jdbc 2025-06-03 10:44:32 +02:00
YannC
5145cf0567 fix(secrets): display all namespaces (#9248)
close kestra-io/kestra-ee#3942
2025-06-03 10:00:38 +02:00
Loïc Mathieu
70c1a8671a feat(execution): allow to loop until an unlimited duration or iteration count
But not both as this would means unlimited loops which are a bad practice.

Fixes #9152
2025-06-03 09:32:27 +02:00
Miloš Paunović
fc7df186f6 fix(core): prevent monaco suggestion widget to update its position (#9164)
Closes https://github.com/kestra-io/kestra/issues/9116.
2025-06-03 09:08:27 +02:00
Piyush Bhaskar
76d068fe35 fix(core): same position in center for all modals (#9247) 2025-06-03 12:28:29 +05:30
YannC
5c624579e0 fix(dashboard): make refresh button works (#9238)
close #7083
2025-06-03 08:55:13 +02:00
Piyush Bhaskar
a1db7b5677 chore(version): update @kestra-io/ui-libs to version 0.0.203 for finally block (#9246) 2025-06-03 12:21:36 +05:30
Miloš Paunović
2d36646cac refactor(core): remove unnecessary import (#9245) 2025-06-03 08:50:55 +02:00
Piyush Bhaskar
1c294cf4af fix(triggers): show the url instead of open. (#9244) 2025-06-03 12:13:02 +05:30
brian.mulier
ac19b4a86d fix(core): properly parse IN & NOT_IN values for Dashboards 2025-06-02 20:32:18 +02:00
brian.mulier
3511a8f74e fix(core): skip empty values from filters in query 2025-06-02 20:26:27 +02:00
brian.mulier
30bf32af83 fix(core): better relevance on filter syntax highlighting + IN working
closes #9214
2025-06-02 20:17:54 +02:00
brian.mulier
4d73138152 fix(core): restoreUrl is now scoped to route tab
closes #9235
2025-06-02 18:51:22 +02:00
YannC
fa96ca1f12 fix(core): Valid correctly conditions in triggers (#9228) 2025-06-02 17:39:11 +02:00
Nicolas K.
7fcafce47b feat(tenants): change the tenant migration command name (#9215)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-02 16:53:16 +02:00
Roman Acevedo
d92015cdc6 refactor(system): centralize filters legacy mapping in controllers (#9183) 2025-06-02 16:15:59 +02:00
AJ Emerich
7c0435ffd7 docs(dashboard): fix indentations in examples and add KPI (#9203)
* docs(dashboard): fix indentations in examples and add KPI

Closes https://github.com/kestra-io/kestra/issues/9193

* docs(kpi-chart): update width
2025-06-02 16:10:03 +02:00
Miloš Paunović
8c0c50bff3 chore(core): keep the property name in no code in monospace font (#9216)
Closes https://github.com/kestra-io/kestra/issues/9213.
2025-06-02 15:36:29 +02:00
Miloš Paunović
b55032bd3f chore(triggers): remove column cron from triggers listing and sort out trigger details dialog (#9212)
Closes https://github.com/kestra-io/kestra/issues/8605.
2025-06-02 15:35:26 +02:00
Barthélémy Ledoux
ba5d7e4c1a fix: restore namespace and id when emptying while editing (#9138) 2025-06-02 14:33:40 +02:00
Loïc Mathieu
15937a6565 feat(system): FlowRepository.findByNamespacePrefixWithSource() 2025-06-02 13:48:31 +02:00
Miloš Paunović
c0f66f6dda fix(core): amend positioning of the default tour elements (#9202)
Closes https://github.com/kestra-io/kestra/issues/9172.
2025-06-02 13:38:15 +02:00
Miloš Paunović
8265f6db7a fix(dashboards): use namespace parameter for next execution table to be able to build links (#9195)
Closes https://github.com/kestra-io/kestra/issues/9188.
2025-06-02 12:42:49 +02:00
github-actions[bot]
f55d2e2350 chore(core): localize to languages other than english (#9197)
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-02 12:11:53 +02:00
Miloš Paunović
c8e6e5ad50 feat(tests): add tests preview tab in left menu (#9191)
Closes https://github.com/kestra-io/kestra-ee/issues/3927.
2025-06-02 12:05:07 +02:00
Miloš Paunović
a03721040f chore(secrets): allow deletion of all tags, including the last one (#9187)
Closes https://github.com/kestra-io/kestra-ee/issues/3937.
2025-06-02 11:43:54 +02:00
Miloš Paunović
afe267eeeb chore(secrets): make the key field disabled on secret editing (#9185)
Closes https://github.com/kestra-io/kestra-ee/issues/3936.
2025-06-02 11:43:31 +02:00
Barthélémy Ledoux
a51f4f213b fix(ui): nocode - add clear selected button for anyof (#9136)
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-02 11:23:19 +02:00
Ludovic DEHON
c7986ec986 build(deps): bump org.testcontainers:testcontainers to 1.21.1 2025-06-02 10:58:53 +02:00
Piyush Bhaskar
5205cf24a6 chore(version): update the ui-libs version (#9184) 2025-06-02 14:09:18 +05:30
dependabot[bot]
9ff2df6ae4 build(deps): bump com.github.oshi:oshi-core from 6.8.1 to 6.8.2
Bumps [com.github.oshi:oshi-core](https://github.com/oshi/oshi) from 6.8.1 to 6.8.2.
- [Release notes](https://github.com/oshi/oshi/releases)
- [Changelog](https://github.com/oshi/oshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/oshi/oshi/compare/oshi-parent-6.8.1...oshi-parent-6.8.2)

---
updated-dependencies:
- dependency-name: com.github.oshi:oshi-core
  dependency-version: 6.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 10:19:01 +02:00
dependabot[bot]
f46234a577 build(deps): bump org.postgresql:postgresql from 42.7.5 to 42.7.6
Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.5 to 42.7.6.
- [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.5...REL42.7.6)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-version: 42.7.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 10:18:20 +02:00
dependabot[bot]
97b23a2d91 build(deps): bump org.testcontainers:junit-jupiter from 1.21.0 to 1.21.1
Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.21.0 to 1.21.1.
- [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.0...1.21.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 10:18:00 +02:00
Loïc Mathieu
bf18f671ce fix(system): don't set execution to queued twice 2025-06-02 09:35:08 +02:00
brian.mulier
e3285b1813 fix(core): add red highlighter upon using wrong comparator for a key in filters
closes #9090
closes #9097
2025-05-30 19:50:13 +02:00
brian.mulier
3ffa446c54 feat(core): implement STARTS_WITH_NAMESPACE_PREFIX filter 2025-05-30 19:49:37 +02:00
brian.mulier
87f4143ed4 fix(core): handle text filter properly for dashboards 2025-05-30 19:33:20 +02:00
brian.mulier
c439d08a0e fix(core): implement STARTS_WITH_NAMESPACE_PREFIX global filter using REGEX 2025-05-30 18:04:49 +02:00
Roman Acevedo
81d7588627 feat(system): add STARTS_WITH_NAMESPACE_PREFIX query filter for by namespace query 2025-05-30 17:21:29 +02:00
brian.mulier
f797f87041 fix(core): fixed eslint not to apply to tests 2025-05-30 17:19:10 +02:00
Miloš Paunović
3484074274 fix(core): handle no code inputs type change (#9166)
Closes https://github.com/kestra-io/kestra/issues/9101.
2025-05-30 15:21:56 +02:00
brian.mulier
630e4fd43a fix(core): repair audit logs type filter
closes #9091
2025-05-30 15:20:20 +02:00
brian.mulier
c6bc44ca6c fix(core): better filter comparator detection 2025-05-30 15:19:38 +02:00
Roman Acevedo
9063f61a4c feat(flows): remove JDBC NAMESPACE START_WITH filter specifities 2025-05-30 14:17:10 +02:00
Roman Acevedo
20c229a64f fix(executions): inclusive validation of start and end date 2025-05-30 14:17:10 +02:00
Roman Acevedo
a632c5e81a fix(flows): bulk actions for Flows with new Filter 2025-05-30 14:17:10 +02:00
Roman Acevedo
c8376daa1b refactor(flows): remove old FlowRepositoryInterface.find method not used anymore 2025-05-30 14:17:10 +02:00
Miloš Paunović
e29840de36 fix(core): amend padding on the global error notification container (#9161)
Closes https://github.com/kestra-io/kestra-ee/issues/3924.
2025-05-30 11:46:55 +02:00
Piyush Bhaskar
d8f8cb6244 fix(core): definition now expands from properties. (#9160) 2025-05-30 14:41:04 +05:30
Miloš Paunović
f6095cee99 fix(dashboards): amend line chart values & bar chart stacks sorting (#9158)
Closes https://github.com/kestra-io/kestra/issues/6603.
Closes https://github.com/kestra-io/kestra-ee/issues/3918.
2025-05-30 10:45:39 +02:00
YannC.
3865f90553 ci: moved helm update trigger on EE side 2025-05-30 09:30:28 +02:00
Piyush Bhaskar
f93ecbf741 fix(core): update regex to correctly render the alert for embedded docs. (#9151) 2025-05-29 18:32:39 +05:30
Miloš Paunović
9f03840e21 chore(dashboards): improve date format in dashboard table cells (#9150) 2025-05-29 14:33:26 +02:00
Miloš Paunović
e150384e17 fix(dashboards): change default dashboard yaml to include filtering in progress states (#9146)
States that now will be filtered for the `In Progress` table:

- `CREATED`
- `RESTARTED`
- `QUEUED`
- `RUNNING`
- `PAUSED`
- `RETRYING`
- `KILLING`

Closes https://github.com/kestra-io/kestra/issues/9125.
2025-05-29 14:11:08 +02:00
Miloš Paunović
29006071bb fix(executions): properly guard against the npe error (#9147) 2025-05-29 14:06:19 +02:00
Miloš Paunović
ff2df65b00 fix(dashboards): properly replace namespace and flow variables in flow dashboard yaml (#9145) 2025-05-29 14:03:23 +02:00
Miloš Paunović
e00d1ca0b7 fix(dashboards): show proper value in dashboard table, flow column (#9142) 2025-05-29 10:37:53 +02:00
Miloš Paunović
345a6331ad fix(dashboards): amend line chart values & bar chart stacks sorting (#9141)
Closes https://github.com/kestra-io/kestra/issues/6603.
Closes https://github.com/kestra-io/kestra-ee/issues/3918.
2025-05-29 10:35:15 +02:00
Miloš Paunović
124fcbf87f fix(core): switch filter colors on main theme change (#9140)
Closes https://github.com/kestra-io/kestra/issues/9119.
2025-05-29 08:32:17 +02:00
Piyush Bhaskar
82f617b704 feat(core): 503 Service Unavailable status in error messages. (#9135) 2025-05-29 10:51:24 +05:30
brian.mulier
6e6d4e4d26 fix(core): avoid sending date filters to flow list API call
closes kestra-io/kestra-ee#3911
closes #9132
2025-05-28 23:13:16 +02:00
brian.mulier
31a96fe30b fix(core): properly filter Namespace executions 2025-05-28 23:10:56 +02:00
brian.mulier
dd52bc1d4c fix(core): text search without needing "text" key prefix
closes #9105
2025-05-28 18:29:56 +02:00
brian.mulier
b2cfe1dda3 fix(core): properly remap q parameter to text in filter bar 2025-05-28 17:55:22 +02:00
Nicolas K.
457e4826a8 test(storage): remove null tenant in test suit (#9139)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-28 17:41:13 +02:00
Loïc Mathieu
6a465c1289 feat(system): monitor and close the Scheduler monitoring loop 2025-05-28 16:02:54 +02:00
Miloš Paunović
e93ef87dba chore(dashboards): load more dashboards at once (#9127) 2025-05-28 16:00:15 +02:00
Miloš Paunović
a990155519 chore(dashboards): use displayName property for table headers, if existing (#9129)
Related to https://github.com/kestra-io/kestra-ee/issues/3910.
2025-05-28 15:54:16 +02:00
Miloš Paunović
38a0c7aafb chore(dashboards): make sure save button is disabled again on successful action (#9131)
Related to https://github.com/kestra-io/kestra-ee/issues/3910.
2025-05-28 15:52:46 +02:00
Miloš Paunović
ba793a00a4 chore(dashboards): remove text transformation in chart legend creation (#9130) 2025-05-28 15:52:05 +02:00
Loïc Mathieu
6c7a8be5bd fix(system): use the correct config name for resonse cache 2025-05-28 15:21:05 +02:00
brian.mulier
858f37933e fix(core): avoid sort, page & size from interfering with filter widget 2025-05-28 15:18:27 +02:00
YannC
80061e3fb3 fix: don't use a endDate when not asked (#9056)
* fix: don't use a endDate when not asked

close #9037

* test: fix following change
2025-05-28 15:04:56 +02:00
YannC
59f2674f75 feat: improved new custom dashboard (#9120)
* apply correctly the default filter for namespace and flow pages
* apply a default date on charts if none is set
* add flow_id filter in the global filter
2025-05-28 14:59:00 +02:00
Miloš Paunović
525717a9b8 chore(dashboards): multiple ux improvements of dashboards (#9111)
Closes https://github.com/kestra-io/kestra/issues/9038.
Closes https://github.com/kestra-io/kestra/issues/9057.
Closes https://github.com/kestra-io/kestra-ee/issues/3879.
2025-05-28 14:54:07 +02:00
brian.mulier
30adacaf75 fix(core): log level is not a multi-value filter
closes #9087
2025-05-28 14:48:58 +02:00
brian.mulier
961608fef6 fix(core): remove namespace & flowId keys on Flow -> Executions page filter 2025-05-28 14:48:03 +02:00
brian.mulier
f585264620 fix(core): avoid red-coloured key in filters 2025-05-28 14:31:08 +02:00
Piyush Bhaskar
81a94ec23f fix(core): bring back radio styles. (#9112)
* fix(core): bring back radio styles.

* bring radio back

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

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-05-28 17:55:50 +05:30
Nicolas K.
4f8ea9afb1 feat(storage): refactor getPath (#9104)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-28 14:12:58 +02:00
Roman Acevedo
0523c04be0 fix(executions): by-query not working with new filters (#9058) 2025-05-28 13:15:03 +02:00
Miloš Paunović
63e9bf2672 chore(flows): take default namespace into account on flow creation (#9110)
Closes https://github.com/kestra-io/kestra/issues/9109.
2025-05-28 12:56:41 +02:00
Loïc Mathieu
7cc938c605 feat(test): allow inline files fixtures and render fixture outputs 2025-05-28 12:48:08 +02:00
Florian Hussonnois
3e21e69e85 fix(system): wait for grace period before reemitting tasks for terminated_forced workers
When a worker transitition to the TERMINATED_FORCED, the LivenessCoordinator
should wait for termination grace period to ensure
that all in-flight task-runs had time to be completely processed by the executors

Related-to: #8334
2025-05-28 12:03:48 +02:00
YannC
28417f04d9 feat: replace daily charts by customized charts (#9081) 2025-05-28 11:52:21 +02:00
Nicolas K.
4041ebf340 fix(tests): add tenant id to log repository tests (#9100)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-28 11:45:55 +02:00
brian.mulier
36d79e68dc chore(deps): splitpanes types 2025-05-28 11:23:08 +02:00
Miloš Paunović
6e0516f448 fix(core): prevent cursor in code editor from jumping to top (#9095)
Closes https://github.com/kestra-io/kestra/issues/9013.
2025-05-28 11:10:16 +02:00
Barthélémy Ledoux
a12d5b3eb5 fix: setup anyof forms for taskRunner retry and others (#9049)
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-05-28 11:07:16 +02:00
brian.mulier
c4d9a33987 chore(deps): splitpanes types 2025-05-28 11:04:22 +02:00
brian.mulier
5c33907288 chore(deps): remove @types/splitpanes and add a manual module for it + fix vue version 2025-05-28 10:56:54 +02:00
Nicolas K.
5f0910b54e test(storage): remove all null tenant test (#9054)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-28 09:30:28 +02:00
Piyush Bhaskar
36900cb9ec fix(flow): diff shows as per revision number (#9080) 2025-05-28 12:43:15 +05:30
Miloš Paunović
7047b605f5 fix(core): amend keyboard save shortcut for both flow and namespace files (#9030) 2025-05-28 08:16:33 +02:00
brian.mulier
9e84b12008 fix(core): support REGEX filtering 2025-05-27 20:02:08 +02:00
brian.mulier
7297221e06 fix(core): add REGEX filtering on namespace field in JDBC 2025-05-27 19:24:14 +02:00
brian.mulier
37c001aa56 fix(core): avoid overriding sort, size and page from new filtering 2025-05-27 19:12:39 +02:00
brian.mulier
a12a6ccc2f fix(core): filtering was not working with pagination
closes #9027
2025-05-27 18:58:55 +02:00
brian.mulier
ba2179ed56 fix(core): avoid red-coloured filter keywords
closes #9024
2025-05-27 18:55:02 +02:00
brian.mulier
1a5b1f2b5c fix(core): wrong childFilter naming 2025-05-27 18:52:54 +02:00
brian.mulier
3d26205464 fix(deps): fixed storybook router version to UI one 2025-05-27 17:19:18 +02:00
brian.mulier
9a759e2807 fix(core): avoid undefined due to scope filter addition
closes #9024
2025-05-27 17:19:09 +02:00
brian.mulier
997d71f586 fix(core): scope is a single value filter 2025-05-27 17:17:34 +02:00
Loïc Mathieu
3bc75efbf2 fix(dashboard): Properly cast log level column in Dashboards
Fixes #8128
2025-05-27 16:18:49 +02:00
Loïc Mathieu
5260726daa fix(ui): namespace tab didn't use the pluginDefault translation 2025-05-27 16:18:08 +02:00
brian-mulier-p
79ee64a8a7 fix(core): handle AND by spaces in filters (#9046)
closes kestra-io/kestra-ee#3003
2025-05-27 15:56:01 +02:00
Piyush Bhaskar
69ff5a2365 fix: color of Failed status (#9042) 2025-05-27 18:46:33 +05:30
Anna Geller
387eb9bb33 fix(dashboard): simplify naming for ratio (#9041) 2025-05-27 14:50:00 +02:00
Miloš Paunović
f380501f61 fix(core): properly show custom dashboard card titles (#9035) 2025-05-27 14:16:18 +02:00
brian-mulier-p
217fbcddb8 fix(core): update flow & namespace overview dashboard filters (#9034)
closes #9033
2025-05-27 14:11:56 +02:00
Miloš Paunović
cbc250bb1c fix(core): amend plugin page problems due to npe (#9031)
Closes https://github.com/kestra-io/kestra-ee/issues/3865.
2025-05-27 14:01:06 +02:00
Piyush Bhaskar
c53791435c fix(core): use new color tokens for panes and editor. (#9020) 2025-05-27 16:49:49 +05:30
Satvik Kushwaha
8846da55e8 fixed spacing in demo apps page (#9021)
* fixed spacing in demo apps page

* minor tweak

---------

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-05-27 16:47:40 +05:30
github-actions[bot]
7cefbaccb7 chore(core): localize to languages other than english (#9023)
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-05-27 13:11:48 +02:00
Miloš Paunović
4a5cd1dce7 chore(core): make sure id property is required for sla block (#9022) 2025-05-27 12:55:49 +02:00
Miloš Paunović
4b2e50242b feat(namespaces): allow exporting single namespace files from editor sidebar (#8967) 2025-05-27 12:26:02 +02:00
YannC
f81125ed0b fix: avoid the Kestra Instance to be indexed (#9018)
close #9015
2025-05-27 12:14:15 +02:00
Miloš Paunović
c8f58f842c fix(core): properly check if property is nullish (#9019) 2025-05-27 11:48:54 +02:00
brian.mulier
c25c60d442 chore(build): remove add jmh-benchmarks gradle.properties to gitignore 2025-05-27 11:39:28 +02:00
brian-mulier-p
71a8aea570 feat(core): move KestraFilter to a Monaco-based implementation (#8915)
closes kestra-io/kestra-ee#3004
2025-05-27 11:36:23 +02:00
Barthélémy Ledoux
81da94dfd1 fix(core): avoid inserting empty tasks in flow (#9016) 2025-05-27 11:29:39 +02:00
YannC.
1cc7b3e443 fix: avoid diving by 0 with the KPI chart 2025-05-27 11:23:38 +02:00
Kelvin Yim
f7c2cbec43 fix(ui): improve padding and font sizes on Blueprints tab in Editor (#9002)
* fix/8050 - Improve padding and font sizes on the Blueprints tab in the Editor

fix(ui): improve padding and font sizes on Blueprints tab in Editor

Image 1:
- Added a "Blueprints" tittle
- Added 32px horizontal padding and 16px bottom padding to blueprint container
- Change font tittle
- Reduced blueprint title font size
- Added spacing between Source title and code block
- Changed background to ks-background-input
- Changed editor to ks-background-input

Image 2:
- Changed top spacing
- Changed background to ks-background-input
- Changed "bold" tittle blueprint to "regular"

Fixes #8950

* fix/8050 - Improve padding and font sizes on the Blueprints tab in the Editor

fix(ui): improve padding and font sizes on Blueprints tab in Editor

- FIx padding between tittle "Source" and code block
- changed css &.custom-dark-vs-theme
- Add Community top spacing

Fixes #8950

* fix(ui): improve padding and font sizes on Blueprints tab in Editor

- Updated back button with rounded background and ChevronLeft icon
- Reduced blueprint title font size and improved header layout
- Added proper spacing and alignment for header elements

Fixes #8950

* revert gitignore and application.yml

* fix(ui): minor tweaks.

---------

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-05-27 14:29:42 +05:30
Roman Acevedo
0101f53954 build(ci): require translations to be done (#9014)
at least for the current RC period
2025-05-27 10:54:07 +02:00
Loïc Mathieu
a0ee30916c chore(system): JdbcQueue code refactoring 2025-05-27 10:46:05 +02:00
github-actions[bot]
c30abf40ee chore(core): localize to languages other than english (#9011)
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-05-27 10:28:19 +02:00
Barthélémy Ledoux
17858091a4 fix(ui): clicking on edit/delete in topology opens a nocode (#8993) 2025-05-27 10:25:54 +02:00
Miloš Paunović
09318b7bc2 chore(core): amend labels of task anyof component radio buttons (#9005) 2025-05-27 09:41:47 +02:00
Miloš Paunović
069159f8fd chore(core): add sla block to no code editor (#9004)
Closes https://github.com/kestra-io/kestra/issues/7081.
2025-05-27 09:32:05 +02:00
Loïc Mathieu
6039d100ee feat(system): add metrics for flowable tasks
Part-of: #8341
2025-05-27 09:20:09 +02:00
Loïc Mathieu
6630cf045f fix(system): remove required props in definitions that have a default
Fixes https://github.com/kestra-io/plugin-scripts/issues/243
2025-05-27 08:57:36 +02:00
Loïc Mathieu
270b4d4bc2 feat(system): add metics for concurrency limit
Part_of: #8341
2025-05-27 08:57:10 +02:00
Piyush Bhaskar
3ad13272e5 fix(core): full width for wrapper containing properties. (#9003) 2025-05-27 11:40:44 +05:30
YannC
ea402261d5 Replace the default dashboard with custom dashboard (#8769)
* feat:
- Implement width property
- Replace custom dashboard
- Started to integrate the KPI chart

* feat(ui): introduce dashboard chart layout system

* feat(ui): introduce dashboard chart kpi card

* chore(ui): amend layout widths for sm screen size

* chore(ui): prevent editing of default dashboard

* chore(ui): centering the KPI text inside the box

* chore(ui): dashboard edit preview to respect set layouts

* chore(ui): initial work on setting the default flow & namespace dashboards

* fix(ui): make sure there is no naming clashes

* feat: KPI chart backend implementation

* feat: validation annotations

* chore(ui): make chart legend align to right side

* chore(ui): properly show chart labels

* chore(ui): improve state and ID components inside custom tabels

* chore(ui): add proper link to execution in tables

* feat: implemented Triggers as Datasource for custom dashboards

close kestra-io/kestra-ee#3740

* feat: modified the Markdown chart so now it accept different sources

* feat: rename KPI property to numerator & where

close #3739

* chore(ui): improve markdown component

* chore(ui): markdown charts

* chore(ui): markdown charts

* chore(ui): markdown charts remove padding

* chore(ui): markdown charts

* feat: fixes + define custom dashboard equivalent to current default dashboard with some modification

* fix: round double value

* chore(ui): improve  flows and ns charts

* chore(ui): make sure that table shows execution links only if namespace and flowId exist

* chore(ui): make sure markdown is properly shown on dashboard edititng

* fix: correctly do preview instead of load on homepage

* fix: correctly preview markdown chart and add description in default flow dashboard

* fix: apply review changes

* fix: modify test following classes modifications on charts

* tests: restore package-lock

* remove chromatic tools and a warning

---------

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-05-27 08:02:11 +02:00
yuri
57bafd1240 fix(ui): show proper no results (#8870)
* fix(ui): show proper no result

* Migrated the `SelectTable` component away from `NoData` to the
  placeholder text attribute.
* Enabled `NoData` for logs since their empty result case was also
  not clear.

* fix(core): make selection work and few more tweak.

---------

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-05-27 11:23:26 +05:30
Loïc Mathieu
f90e22a935 fix(tests): improve test robustness by avoiding spinning a new thread for receive timeout 2025-05-26 20:35:28 +02:00
Loïc Mathieu
ec21ef3d32 feat(system): add a metrics for the Executor thread count
Part-of: #8341
2025-05-26 19:37:32 +02:00
Loïc Mathieu
88b88856da feat(system): add metrics to the JDBC queue
Part-of: #8340
2025-05-26 19:37:03 +02:00
github-actions[bot]
96b481348f chore(core): localize to languages other than english (#8999)
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-05-26 18:10:40 +02:00
brian-mulier-p
e3a8c1c086 fix(plugins): resolve subtypes in low code editor (#8957)
closes #8903
2025-05-26 17:49:50 +02:00
Miloš Paunović
87fe3abee5 refactor(core): rename the type in random retry (#8998) 2025-05-26 17:47:56 +02:00
Miloš Paunović
4b7d90faf4 chore(core): add retry block to no code editor (#8996)
Closes https://github.com/kestra-io/kestra/issues/7031.
2025-05-26 17:40:12 +02:00
Barthélémy Ledoux
2f8a844326 fix: save namespace files when clicking ctrl-S (#8994) 2025-05-26 17:09:06 +02:00
Loïc Mathieu
1b4efc51bf feat(system): restore the flow queue after tenant migration
This would lower the risk of trigger/topology not up to date and would make all components having to right set of flows.
2025-05-26 15:37:33 +02:00
YannC
d3c29fcadd fix(logs): Use correct property for filtering logs in kafka (#8812)
* fix(logs): Use correct property for filtering logs in kafka

* test: added a test for date
2025-05-26 15:20:03 +02:00
Barthélémy Ledoux
059323aca0 fix(ci): nocode translate (#8988)
Co-authored-by: GitHub Action <actions@github.com>
2025-05-26 14:35:41 +02:00
YannC
aae752ff3c feat: add a new method "taskWithState" that leverage on the property tasks (#8907)
close #5653
2025-05-26 13:09:13 +02:00
Piyush Bhaskar
ee5c39cbe4 fix(core): remove placeholder on input (#8984)
* fix(core): remove placeholder on input

* fix: remove not required
2025-05-26 16:17:17 +05:30
Roman Acevedo
021357c7a4 feat(tests): validate the Flow exists when create or update Test 2025-05-26 12:35:09 +02:00
Piyush Bhaskar
eff58d96c8 fix(core): few tweaks to align the placeholder and ui as per design. (#8980)
* fix(core): few tweaks to align the placeholder and ui as per design.

* fix: minor tweak

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-05-26 15:27:39 +05:30
Barthélémy Ledoux
3c7ca60188 fix(nocode): reorder subtasks (#8976) 2025-05-26 11:55:46 +02:00
Piyush Bhaskar
06635cdecd fix(core): navigating back to plugins home. (#8972)
* fix(core): navigating back to plugins home.

* fix: keep the scroll to top

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

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-05-26 15:20:53 +05:30
Miloš Paunović
8ada2846bc feat(core): move complex task fields inline in no code editor (#8977)
Closes https://github.com/kestra-io/kestra/issues/8934.
2025-05-26 11:21:49 +02:00
Florian Hussonnois
c2dc1c0b8b fix(cli): properly install all plugins depending on kestra distribution
Related-to: kestra-io/kestra-ee#3806
2025-05-26 10:27:25 +02:00
Miloš Paunović
d66ee28a7a refactor(core): simplify header badge component usage (#8963) 2025-05-26 10:20:34 +02:00
dependabot[bot]
cbe32742f7 build(deps): bump software.amazon.awssdk:bom from 2.31.45 to 2.31.50
Bumps software.amazon.awssdk:bom from 2.31.45 to 2.31.50.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 09:52:36 +02:00
dependabot[bot]
55fb234760 build(deps): bump me.champeau.jmh from 0.7.2 to 0.7.3
Bumps me.champeau.jmh from 0.7.2 to 0.7.3.

---
updated-dependencies:
- dependency-name: me.champeau.jmh
  dependency-version: 0.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 09:52:16 +02:00
dependabot[bot]
6b00ab2623 build(deps): bump com.google.cloud:libraries-bom from 26.60.0 to 26.61.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.60.0 to 26.61.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.60.0...v26.61.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 09:51:55 +02:00
Malaydewangan09
2aa5b1e236 feat(plugins): add plugins InfluxDB, Jenkins, Ollama, GraphQL 2025-05-26 09:31:31 +02:00
Ludovic DEHON
67c2ac8d01 feat(plugins): add allowedResponseCodes on http tasks
close #8973
2025-05-26 09:26:47 +02:00
github-actions[bot]
eb4de0530e chore(core): localize to languages other than english (#8964)
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-05-24 11:55:49 +02:00
Barthélémy Ledoux
d7a420474f feat(ui): make trigger conditions in no-code a form (#8859) 2025-05-24 00:31:22 +02:00
Piyush Bhaskar
3de436cb8b feat(core): improve the ux of no code editor (#8955) 2025-05-23 19:54:15 +02:00
Florian Hussonnois
e46d4ed7ef fix(flows): adjust plugin doc to match the specified plugin version
Related-to: kestra-io/kestra-ee#3528
Related-to: kestra-io/ui-libs#496
2025-05-23 17:46:33 +02:00
github-actions[bot]
5994ffa74c chore(core): localize to languages other than english (#8961)
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-05-23 17:15:50 +02:00
Roman Acevedo
c98911c394 refactor(core): regroup Test and Beta badges with same component 2025-05-23 17:02:09 +02:00
Nicolas K.
29c3bd7dec fix(core): tenant migration scripts now update keys
* chore(core): add keyboard shortcuts icon to flow editor tab (#8925)

fix(core): don't send empty operations when migrating roles (#3807)

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>

* fix(core): migrate key that required tenant id to avoid duplication

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-23 16:44:53 +02:00
Roman Acevedo
2601df3de2 feat(tests): add a contextual Test badge on Execution topbar
fixes https://github.com/kestra-io/kestra-ee/issues/3812
2025-05-23 16:36:16 +02:00
Roman Acevedo
16ea41caa3 feat(tests): add ERROR state and handling
fixes #3804

* feat(tests): display errors in UI test results
2025-05-23 16:09:25 +02:00
Miloš Paunović
246892af29 fix(core): amend autocompletion in multi panel yaml flow editor (#8956)
Closes https://github.com/kestra-io/kestra/issues/8796.
2025-05-23 14:59:09 +02:00
Miloš Paunović
7de5002166 feat(core): save individual namespace files from multi panel editor (#8930)
Closes https://github.com/kestra-io/kestra/issues/8923.
2025-05-23 12:56:12 +02:00
Loïc Mathieu
1a4bb04258 fix(system): rename flyway migrations
They have been renamed in develop due to clashes but one was already backported on 0.22.

Fixes https://github.com/kestra-io/kestra-ee/issues/3819
2025-05-23 11:42:21 +02:00
YannC
88fa884e26 fix(filters): change label filtering to 'and' instead of 'or' (#8661)
* fix(filters): change label filtering to 'and' instead of 'or'

link to #8489

* test(execution): add test to validate and behavior

* test(execution): fix test
2025-05-23 11:26:46 +02:00
Florian Hussonnois
99a6d7533c fix(build): exclude jmh-benchmark module 2025-05-23 11:22:21 +02:00
Miloš Paunović
2c944612f3 fix(core): prevent multiple tabs for adding tasks to create duplicate entries (#8916)
Closes https://github.com/kestra-io/kestra/issues/8781.
Closes https://github.com/kestra-io/kestra/issues/8926.
2025-05-23 09:07:59 +02:00
Miloš Paunović
dc8095b6a2 fix(core): filter the inputs with no id field to prevent breaking of panel (#8944)
Closes https://github.com/kestra-io/kestra/issues/8932.
2025-05-23 08:57:26 +02:00
brian-mulier-p
84310e82e2 fix(system): force a state after kill (#8937)
closes #8936
2025-05-22 19:04:35 +02:00
Loïc Mathieu
ca652a1e96 fix(plugins)*: ForEach executes task in the wrong order when no concurrency limit
Fixes #8904
2025-05-22 17:53:35 +02:00
Miloš Paunović
625478cfb1 chore(core): add keyboard shortcuts icon to flow editor tab (#8925) 2025-05-22 15:37:10 +02:00
YannC
228359c661 test: avoid FileChangedEventListenerTest being flaky (#8810) 2025-05-22 11:38:25 +02:00
Florian Hussonnois
770a703482 feat(system): optimize MapUtils for merge
Optimize merge method by removing use of
java stream
2025-05-22 09:46:54 +02:00
Florian Hussonnois
55740133f0 chore(test): add module for jmh benchmarks 2025-05-22 09:46:54 +02:00
Loïc Mathieu
593aad2aea feat(system): don't compute empty task outputs
The method to compute task output is costly and can be avoided if there are no outputs.
2025-05-22 09:25:11 +02:00
Loïc Mathieu
a179f17dc6 feat(system): don't clone maps when not necessary
This is very cosly as RunVariables are computed each time we create an execution context.
2025-05-22 09:25:11 +02:00
François Delbrayelle
59a6c99fef fix(test): mockTaskRun should be public 2025-05-22 09:20:31 +02:00
Miloš Paunović
769cc28bf0 fix(core): make sure that complex tasks are properly rendered for both inputs and sections (#8902) 2025-05-22 08:30:31 +02:00
Florian Hussonnois
b5aaa6fb38 fix(core): cleanup LogService to always prefix with tenant
Remove use of kestra.ee.tenants.enabled property
2025-05-21 16:18:14 +02:00
brian-mulier-p
1ee60c1075 fix(core): avoid multiple rendering in ForEachItem (#8906)
closes #8905
2025-05-21 16:08:21 +02:00
brian.mulier
a5df187304 fix(plugins): remove "DYNAMIC" log from browser console 2025-05-21 14:53:04 +02:00
YannC
07814abd96 feat(core): added SecurityScheme annotation for openapi spec file generation + add some custom Schema name to avoid duplicated name (#8726) 2025-05-21 14:36:23 +02:00
YannC
2996c885f7 fix(filters): corrected the namespace contains filter (#8653)
close #8498
2025-05-21 14:35:38 +02:00
Loïc Mathieu
0fd8461249 feat(system): use Property.ofValue(T) instead of Property.of(T) 2025-05-21 13:35:35 +02:00
Loïc Mathieu
05d296df34 feat(system): Property.ofValue & Property.ofExpression
Deprecate Property.of(T) in favor of Property.ofValue(T) and new Property(String) in favor of Property.ofExpression(String)
2025-05-21 13:35:35 +02:00
Loïc Mathieu
87d162729e fix(plugins): ForEach must be displayed as a sequential
As the tasks inside each task group are executed sequentially, groups are executed concurrently not tasks inside them.

Part-of: https://github.com/kestra-io/kestra-ee/issues/3722
2025-05-21 13:28:52 +02:00
dependabot[bot]
e4ec427409 build(deps): bump posthog-js from 1.245.0 to 1.245.1 in /ui (#8900)
Bumps [posthog-js](https://github.com/PostHog/posthog-js) from 1.245.0 to 1.245.1.
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/compare/v1.245.0...v1.245.1)

---
updated-dependencies:
- dependency-name: posthog-js
  dependency-version: 1.245.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-21 12:52:17 +02:00
Miloš Paunović
14d6ad5e0d fix(core): filter deprecated properties from optional ones in no code editor (#8896) 2025-05-21 12:51:21 +02:00
Miloš Paunović
341f10a237 chore(deps): regular dependency update (#8895)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-05-21 12:39:43 +02:00
Florian Hussonnois
fb4b1c842a fix(core): fix misc APIs with main tenants
Fix unit-tests
2025-05-21 12:24:09 +02:00
Florian Hussonnois
e3c4f0e502 fix(core): fix rooting to main tenant for configs endpoint 2025-05-21 09:15:24 +02:00
Florian Hussonnois
caf701a1c4 fix(system): remove main tenant from api/v1/configs 2025-05-20 18:57:01 +02:00
Nicolas K.
8821705a06 test(controller): add logs to understand why the test fail (#8858)
* test(controller): add logs to understand why the test fail

* test(controller): add logs to make sure the executions are running

* test(controller): add logs to make sure the executions are running

* test(controller): add logs to make sure the executions are running

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-20 16:55:42 +02:00
Piyush Bhaskar
0723565d99 fix(core): center last step in tour and add Finish animation (#8862)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-05-20 19:09:21 +05:30
github-actions[bot]
15759b8054 chore(core): localize to languages other than english (#8864)
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-05-20 14:15:15 +02:00
Miloš Paunović
bdd0c675b8 chore(core): add group for deprecated properties in the no code editor (#8863)
Closes https://github.com/kestra-io/kestra/issues/7207.
2025-05-20 13:59:14 +02:00
github-actions[bot]
a51e4e240a chore(core): localize to languages other than english (#8861)
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-05-20 13:04:40 +02:00
Piyush Bhaskar
8e8bf8e304 fix(core): tweak product tour flow listing (#8860)
Closes https://github.com/kestra-io/kestra/issues/8366.
2025-05-20 13:02:31 +02:00
Roman Acevedo
d3228b27b7 feat(tests): add fixtures to results 2025-05-20 11:35:15 +02:00
Barthélémy Ledoux
f293f9d849 fix(ui): nocode should allow to delete on click on bin (#8712)
* refactor: remove SECTIONS from local constants

* fix(ui): make delete button work for section, errors & tasks

* fix: allow delete of error, finally and afterexec

* fix: allow deleting fro any section

* use updated YAML_UTILS

* fix keyname usage

* update ui-libs for yaml utils

* fix: delete all tasks and keep order in creation

* chore: update ui-libs
2025-05-20 11:15:35 +02:00
Barthélémy Ledoux
cbf1a9823f fix(ui): update basePath to include 'main' tenant in api urls (#8856) 2025-05-20 10:41:00 +02:00
brian-mulier-p
1a7ccb97bf fix(plugins): show back if property is dynamic (#8846)
closes kestra-io/ui-libs#471
2025-05-20 10:28:11 +02:00
Loïc Mathieu
c9421879c8 fix(system): use a concurrent list to possibly fix the flaky test 2025-05-20 09:43:48 +02:00
Loïc Mathieu
b0f93e1945 chore(system): skip sleep in the JdbcQueue when at max poll size
When a queue is at max poll size, this means that it is at full capacity. In this case skip the sleep and process immediatly the next batch of message.
This improve latency at high thoughput without adding too much load to the database.

We can even go further by skipping sleep each time the poll returns messages but this would imply database cost so for now we balance performance and database cost by only skipping sleep when at max capacity.
2025-05-20 09:43:15 +02:00
Nicolas K.
4b228c966c fix(server): port changed during the redirection when no tenant id in uri (#8854)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-19 19:16:15 +02:00
Daniel Rivas
d755123087 feat(namespaces): Namespace search case insensitivity (#8717)
* Fix: Changed the namespace parsing so that it parses the NAMESPACE_FIELD case-insensitively

* Fix indentation issues
2025-05-19 18:18:34 +02:00
Bala Aparna
5fd9c21ef4 test(plugins): add code coverage to plugin command CLI (#8829)
Added test cases for:

Listing all available subcommands in the PluginCommand CLI help output.
Verifying that external plugins are not loaded by default in PluginCommand.

Updated existing tests for:

Enhanced help output validation to check for the presence of all expected subcommands/ 
Explicitly asserted the behavior of the loadExternalPlugins() method.

Ensured coverage for:

Edge cases where subcommands might be missing from the help output.
Input variants by directly invoking the command and capturing CLI output.
Error handling by confirming correct CLI configuration and plugin loading behavior.
2025-05-19 18:17:30 +02:00
Florian Hussonnois
eede188b38 fix(system): handle storage version in storage interface factory
Related-to: kestra-io/kestra-ee#3302
2025-05-19 18:05:10 +02:00
Anna Geller
f7fbf232cf feat(docker)!: remove non-critical dependencies (#8853) 2025-05-19 17:33:12 +02:00
Nicolas K.
734fcbc45b feat(core): #3427 add OSS tenant migration scripts (#8798)
* feat(core): #3427 add OSS tenant migration scripts

* clean(core): fixes after review

* clean(core): make only one command for oss and EE migration

* fix(core): user synchronisation command and clean PR

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-19 16:42:59 +02:00
Miloš Paunović
9cdc3c54a3 fix(core): make sure that complex tasks are properly rendered (#8848)
Closes https://github.com/kestra-io/kestra/issues/8119.
2025-05-19 15:01:20 +02:00
Karuna Tata
a73c45a802 change label color to white (#8850) 2025-05-19 18:28:34 +05:30
Nicolas K.
11a7e68e93 feat(core)!: make tenant id required (#8460)
* feat(core)!: WIP make tenant id required

* feat(core)!: WIP make tenant id required

* test(core)!: WIP fix storage unit test

* build(deps): bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre

Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.7-jre to 33.4.8-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-version: 33.4.8-jre
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump io.micronaut.platform:micronaut-platform

Bumps [io.micronaut.platform:micronaut-platform](https://github.com/micronaut-projects/micronaut-platform) from 4.8.0 to 4.8.2.
- [Release notes](https://github.com/micronaut-projects/micronaut-platform/releases)
- [Commits](https://github.com/micronaut-projects/micronaut-platform/compare/v4.8.0...v4.8.2)

---
updated-dependencies:
- dependency-name: io.micronaut.platform:micronaut-platform
  dependency-version: 4.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump flyingSaucerVersion from 9.11.6 to 9.12.0

Bumps `flyingSaucerVersion` from 9.11.6 to 9.12.0.

Updates `org.xhtmlrenderer:flying-saucer-core` from 9.11.6 to 9.12.0
- [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.11.6...v9.12.0)

Updates `org.xhtmlrenderer:flying-saucer-pdf` from 9.11.6 to 9.12.0
- [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.11.6...v9.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump software.amazon.awssdk:bom from 2.31.21 to 2.31.25

Bumps software.amazon.awssdk:bom from 2.31.21 to 2.31.25.

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

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump com.github.oshi:oshi-core from 6.8.0 to 6.8.1

Bumps [com.github.oshi:oshi-core](https://github.com/oshi/oshi) from 6.8.0 to 6.8.1.
- [Release notes](https://github.com/oshi/oshi/releases)
- [Changelog](https://github.com/oshi/oshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/oshi/oshi/compare/oshi-parent-6.8.0...oshi-parent-6.8.1)

---
updated-dependencies:
- dependency-name: com.github.oshi:oshi-core
  dependency-version: 6.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump org.opensearch.client:opensearch-java

Bumps [org.opensearch.client:opensearch-java](https://github.com/opensearch-project/opensearch-java) from 2.22.0 to 2.23.0.
- [Release notes](https://github.com/opensearch-project/opensearch-java/releases)
- [Changelog](https://github.com/opensearch-project/opensearch-java/blob/v2.23.0/CHANGELOG.md)
- [Commits](https://github.com/opensearch-project/opensearch-java/compare/v2.22.0...v2.23.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump co.elastic.logging:logback-ecs-encoder

Bumps [co.elastic.logging:logback-ecs-encoder](https://github.com/elastic/ecs-logging-java) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/elastic/ecs-logging-java/releases)
- [Commits](https://github.com/elastic/ecs-logging-java/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: co.elastic.logging:logback-ecs-encoder
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* tests(system): isolate SchedulerScheduleTest tests with tenantId

* Feat/storage outputs (#8361)

* feat(executions): Store outputs inside the internal storage (1/2)

* feat(executions): Store outputs inside the internal storage (2/2)

* feat(test): allow passing tenantId to tests

---------

Co-authored-by: Ludovic DEHON <tchiot.ludo@gmail.com>

* chore(deps): regular dependency update (#8484)

Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.

* fix(ui): full view height for single task logs (#8042)

Co-authored-by: Miloš Paunović <paun992@hotmail.com>

* feat: synchronize task edition with editor (#8433)

* fix(controls): adjust bottom position of contorls in multiPanelsEditor (#8465)

* fix(executions): unqueing execution must remove the execution queued

When an execution is queued in the JDBC backend, a record is inserted inside the execution_queued table, we must remove this record when we unqeue an execution.

Fixes #8448

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

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>

* tests(webserver): fix flaky test which could query previous tests tasks

* tests(system): debug flaky error of shouldPauseExecutionByQueryRunningFlows

* tests(system): debug flaky error of shouldPauseExecutionByQueryRunningFlows

* tests(system): try with different task id

* tests(system): bump sleep-short sleep time to 10s

* fix(execution)*: decode and hide nested inputs of type SECRET

Fixes #7964

* refactor(core): pass the dynamic concurrency schema to no code editor (#8488)

There was an issue with passing hard-coded concurrency schema to be rendered in No Code editor, which is now amended and we're passing down the previously fetched one

* chore(deps): update gradle version

* doc(basic.md): add link to configuration for kestra property variables (#8490)

* fix(flows): properly check average duration for dashboard graphs (#8457)

There was a problem on flows view with the main chart not showing proper data until user clicks on duration toggle.

Closes https://github.com/kestra-io/kestra/issues/8435.
Closes https://github.com/kestra-io/kestra-ee/issues/3499.

* docs(core-pause): update pauseDuration properties, titles, descriptions (#8495)

* fix(system): restrict the JdbcConcurrencyLimitService to the JDBC runner

* fix(core): fix indexer metric description (#8500)

* Add examples with expression and trimmed values (#6154)

* chore(ui): improvement to drilldown for Default and Custom Charts. (#7885)

* chore(ui): improvement to drilldown for Default and Custom Charts.

* minor tweak

* test: fix the Barchart stories to test drilldown

---------

Co-authored-by: Bart Ledoux <bledoux@kestra.io>

* fix(ui): restart trigger position for backfill column (#8246)

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>

* feat(plugin): add a way to provide additional type of plugins

Provide a way for plugins to define a new type of plugins.
To do that, a plugin must provide both an abstract base class that extends AdditionalPlugin and a set of concret classes.
Both the abstract base class and the concrete classes mut be inside the same plugin. This is a limitation that we may work on later by providing, for example, an SPI to add base classes to the application classloader.

* fix(ui): save existing flow after making changes (#8378)

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

* fix(core): failing DocumentationGeneratorTest.returnDoc()

* chore(core): refactor  component to composition API  structure and with some styling (#8504)

* feat(flows): add validation for use of inputs and outputs with '-' in the name (#8379)

* test(core): fix breaking change in local flow repository (#8517)

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>

* feat(system)!: remove the SQLServer runner

Part-of: https://github.com/kestra-io/kestra-ee/issues/3504

* chore(build): add Postgres stat extension

* feat(plugins): add Langchain4J plugins

* chore(system): add warn log when emit logQueue failed (#8432)

* feat(plugins): add Go Script plugin

* fix(jdbc): add service_id index on service_instance table

* chore(flows): improve the blueprints view within the flow editing panels (#7983)

Changes here consist of removing the tags from blueprint view on Multi Panel flow editor, along with couple of other UI improvements.

Closes https://github.com/kestra-io/kestra/issues/7881.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>

* fix(flows): properly load blueprints in multi panel view (#8524)

While using the new Multi Panel view blueprints were not loading properly due to wrong paramtere being sent to action. now that's sorted.

Closes https://github.com/kestra-io/kestra/issues/8523.

* feat(flows): improve the display of array inputs when running an execution (#7953)

This PR is introducing a change of how the `array` inputs are displayed inside the flow run dialog, to be more user-friendly.

Closes https://github.com/kestra-io/kestra/issues/6947.

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>

* fix(system): change default config values for liveness

Change kestra.server.liveness.interval from 5s to 10s
to be less agressive on liveness check. Align
other default liveness configs with kafka implementation.

* fix(ui): amend Absolute date filter's looks (#8501)

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

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>

* docs(flow-trigger): add note about no Pebble in conditions

* fix(ui): remove parts of filter using backspace (#8105)

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

* fix(ui): open link in markdown in other tab. (#8258)

* fix(ui): open link in markdown in other tab.

* chore(core): restrict attribute to external links.

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

---------

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

* fix(system): load OpenTelemetry lib in the app classloader

Without that, as we have it here, plugins may have class loading issue if they use OpenTelemetry internally (like in the Elasticsearch client).

* feat(ui): Add search in internal docs (#8458)

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

* fix(triggers): inject default later inside the Scheduler

Today, as they are injected eagerly, they are done even if no trigger exists.
This is counter-performant, and in case the flow is an error will log each seconds.
Doing it a little later will be better.

* build(deps): bump software.amazon.awssdk:bom from 2.31.25 to 2.31.30

Bumps software.amazon.awssdk:bom from 2.31.25 to 2.31.30.

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

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump org.wiremock:wiremock-jetty12 from 3.12.1 to 3.13.0

Bumps [org.wiremock:wiremock-jetty12](https://github.com/wiremock/wiremock) from 3.12.1 to 3.13.0.
- [Release notes](https://github.com/wiremock/wiremock/releases)
- [Commits](https://github.com/wiremock/wiremock/compare/3.12.1...3.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump jacksonVersion from 2.18.3 to 2.19.0

Bumps `jacksonVersion` from 2.18.3 to 2.19.0.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>

* chore(execution): update display names for executions. (#8527)

* fix(core): change incorrectly used search parameter (#8534)

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>

* fix(ui): set isCreating to false when opening flow edit mode (#8549)

* fix(core): safely access section and identifier query params (#8542)

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

* fix(ui): update storybook editor tests with provided keys (#8550)

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>

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

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(triggers): amend broken filtering on triggers tab (#8553)

There was a problem with both namespace and state filters on Triggers page which is now properly sorted.

Closes https://github.com/kestra-io/kestra/issues/8529.

* chore: attempt to fix flaky tests (#8537)

SingleFlowCommandsTest:

The flow Delete -> Create -> Update sequence is weird - delete got HTTP 404.
Reworked to Create -> Update -> Delete sequence.

PurgeLogsTest:

The log repository contained the prepared single entry but also might
contain additional entries from previously logged messages.

* fix(namespaces): namespaceFiles with same name are wrongly overwritten (#8562)

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>

* feat(core): forward execution labels in Flow Trigger

* chore(triggers)*: properly handle switches for triggers disabled from within flow source (#8106)

It was not clear as to which trigger can not be enabled and why. Now, that is much more clear with the proper tooltips and disabling of switch toggling.

Closes https://github.com/kestra-io/kestra/issues/8011.
Closes https://github.com/kestra-io/kestra/issues/5736.

* fix(executions): fix execution failure due to UnsupportedOperationException (#8563)

Fix: #8563

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

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>

* feat(system): add TestSuite model,taskFixture impl

* fix: redirect to edit when saving new flow (#8560)

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>

* feat(system)*: decrease defaut JDBC queue poll size

Decreasing it from 100 to 50 didn't show any performance hit but should lower the memory consumption now that we process the queue concurrently in the executor.

## BEFORE - pollSize=100
- 10 tx/s: 150ms
- 25 tx/s: 200ms
- 50 tx/s: 300ms
- 75 tx/s: 5.2s
- 100 tx/s: 15s

## AFTER - pollSize=50
- 10 tx/s: 150ms
- 25 tx/s: 200ms
- 50 tx/s: 300ms
- 75 tx/s: 4.8s
- 100 tx/s: 14s

* feat(flows): Allow to define an onPause task on the Pause task

The onPause task will be executed immediatly when the execution is paused.
Part-of: #3601

* feat(core)!: WIP make tenant id required

* feat(core)!: WIP make tenant id required

* Feat/storage outputs (#8361)

* feat(executions): Store outputs inside the internal storage (1/2)

* feat(executions): Store outputs inside the internal storage (2/2)

* feat(test): allow passing tenantId to tests

---------

Co-authored-by: Ludovic DEHON <tchiot.ludo@gmail.com>

* tests(webserver): fix flaky test which could query previous tests tasks

* feat(executions): Add workerId to each worker task attemps

Closes #7799

* Feat/storage outputs (#8361)

* feat(executions): Store outputs inside the internal storage (1/2)

* feat(executions): Store outputs inside the internal storage (2/2)

* feat(test): allow passing tenantId to tests

---------

Co-authored-by: Ludovic DEHON <tchiot.ludo@gmail.com>

* wip(core): fix unit tests

* test(core): fix unit tests

* test(core): fix unit tests

* test(core): fix unit tests

* feat(core): make tenant id required everywhere

* feat(core): make tenant required in create user command

* feat(core): clean the PR

* feat(core): add tenant id to dashboard controller

* fix(core): tests after merging

* clean(core): fixes after review

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>
Co-authored-by: Loïc Mathieu <loikeseke@gmail.com>
Co-authored-by: Ludovic DEHON <tchiot.ludo@gmail.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
Co-authored-by: Barthélémy Ledoux <ledouxb@me.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: AJ Emerich <aemerich@kestra.io>
Co-authored-by: ben8t <46634684+Ben8t@users.noreply.github.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
Co-authored-by: Satvik Kushwaha <59243339+satvik2131@users.noreply.github.com>
Co-authored-by: Karuna Tata <karuna.tata@devrev.ai>
Co-authored-by: Hashim Khalifa <105060840+hashimzs@users.noreply.github.com>
Co-authored-by: lwyang <1670906161@qq.com>
Co-authored-by: 杨利伟 <yangliwei@xiaomi.com>
Co-authored-by: Florian Hussonnois <fhussonnois@kestra.io>
Co-authored-by: yuri <1969yuri1969@gmail.com>
Co-authored-by: AJ Emerich <aj-emerich@proton.me>
Co-authored-by: rajatsingh23 <48049052+rajatsingh23@users.noreply.github.com>
2025-05-19 14:49:10 +02:00
Karuna Tata
05e348370f ui(fix): change namespace hover to white (#8842)
* change namespace hover to white

* fix
2025-05-19 17:24:16 +05:30
Piyush Bhaskar
84a6d09945 chore(core): fix import (#8845) 2025-05-19 15:58:32 +05:30
Roman Acevedo
b5cc011914 build: influxdb and graphql not available yet 2025-05-19 11:34:03 +02:00
dependabot[bot]
174e3f85b1 build(deps): bump org.sonarqube from 6.1.0.5360 to 6.2.0.5505
Bumps org.sonarqube from 6.1.0.5360 to 6.2.0.5505.

---
updated-dependencies:
- dependency-name: org.sonarqube
  dependency-version: 6.2.0.5505
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 10:49:32 +02:00
dependabot[bot]
ba5890f5d0 build(deps): bump io.micrometer:micrometer-core from 1.14.6 to 1.15.0
Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.14.6 to 1.15.0.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.14.6...v1.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 10:47:39 +02:00
Florian Hussonnois
86f0b23cde build: update release-plugin script to set kestra version for plugins
Related-to: kestra-io/kestra-ee#3348
2025-05-19 10:36:50 +02:00
Roman Acevedo
ded5a932e0 chore(tests): add tests icon to tests list view 2025-05-19 10:30:25 +02:00
Roman Acevedo
69037d00c9 feat(tests): improve empty page 2025-05-19 10:30:25 +02:00
Piyush Bhaskar
74b425250c feat(core): change selection to tab and remove display of type and tooltip. (#8805)
* feat(core): replace select with tabs for schema selection.

* feat(core): change selection to tab and remove display of type and tooltip.

* fix: remove obsolete component and add class.

* chore(core): task enclosed under a border.

* fixes enclosed border only for anyOf type

---------

Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-05-19 13:39:52 +05:30
Loïc Mathieu
75ff7d86c5 fix(system): use the minPollInterval when the last poll is beyond all interval
As beyond all interval means it's less than the first interval so we should wait for the minimum not the maximum
2025-05-19 10:07:36 +02:00
dependabot[bot]
1186a8db46 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.2 to 0.38.3.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.2...v0.38.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 09:55:31 +02:00
dependabot[bot]
cc95c4a80b build(deps): bump software.amazon.awssdk:bom from 2.31.40 to 2.31.45
Bumps software.amazon.awssdk:bom from 2.31.40 to 2.31.45.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 09:55:13 +02:00
dependabot[bot]
232194dcba build(deps): bump com.github.docker-java:docker-java from 3.5.0 to 3.5.1
Bumps [com.github.docker-java:docker-java](https://github.com/docker-java/docker-java) from 3.5.0 to 3.5.1.
- [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.0...3.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 09:54:56 +02:00
Barthélémy Ledoux
8a36ddd184 fix: update topology when no-code changes (#8822)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-05-19 09:44:44 +02:00
Barthélémy Ledoux
251802570c fix: restore multipanle bottom of panels (#8823) 2025-05-19 09:44:23 +02:00
Piyush Bhaskar
c90590582e feat(flows): Actions for Flow Navbar (#8838) 2025-05-19 12:44:21 +05:30
Miloš Paunović
3d0c63027a chore(core): remove console warning due to deprecated property (#8819) 2025-05-19 08:55:30 +02:00
brian-mulier-p
2043c81fea fix(plugins): add back metrics to plugin docs (#8826)
closes #8792
2025-05-16 19:55:44 +02:00
brian-mulier-p
5a78cdde12 fix(plugins): type and type-defining properties are now readonly (#8820)
closes #8818
2025-05-16 18:25:06 +02:00
Loïc Mathieu
30b39b2d30 feat(execution): add an execution kind
This allow to differentiate between normal executions and test executions
2025-05-16 17:00:27 +02:00
Miloš Paunović
c9a277d4d5 fix(core): properly handle input creation/updating via no code editor (#8787) 2025-05-16 14:30:28 +02:00
Piyush Bhaskar
bc0f24f22a fix(core): fixes change in theme aligned with selection in setttings. (#8815) 2025-05-16 16:37:58 +05:30
gluttonweb
a856654acb Update core/src/main/java/io/kestra/core/schedulers/AbstractScheduler.java
Co-authored-by: Loïc Mathieu <loikeseke@gmail.com>
2025-05-16 11:43:41 +02:00
weibo1
2c53a210d7 feat: Performance optimization for handle() method: Filter out executions with non-null next_execution_date in the query method, start a separate scheduled thread for scanning, reporting metrics and logging 2025-05-16 11:43:41 +02:00
Loïc Mathieu
476f34e986 feat(system): change the way we concurrently process executor queues
Instead of consuming multiple time the queue, which lead to concurrent queries on the `queues` table, process concurrently via an ExecutorService the messages from the queue.
We dind't process a new batch of messages until the existing one is totally process to be sure we process in FIFO the same execution message.

Also, go back to a poll size of 100 to mitiguate the performance hit due to this change.
2025-05-15 17:03:34 +02:00
Loïc Mathieu
a8e826af7d fix(system)*: reset the trigger into the KafkaScheduler instead of the ExecutorMain 2025-05-15 17:02:44 +02:00
Barthélémy Ledoux
2a9a926ea3 chore: the code is now in ui-libs delete the duplicate yaml-utils test (#8799) 2025-05-15 15:32:10 +02:00
Florian Hussonnois
59e631f048 fix(plugins): properly handle POSIX permissions for Docker task runner
Set POSIX file permissions when uploading/download working-dir files
from and to Docker container
2025-05-15 15:19:40 +02:00
Nicolas K.
09d91034ab test(server): fix time range unit test (#8802)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-05-15 15:00:32 +02:00
Loïc Mathieu
3639abb8bb chore(system): improve performance of IdUtils.fromParts()
Surprisingly, this method appear in some CPU and allocation profile as having a high cost, especially on the scheduler.
Switching to using a StringJoiner brings 4x perf improvements in method execution time (great improvement also on allocation but didn't have a measurement).
2025-05-15 14:07:47 +02:00
Loïc Mathieu
2d5d4b7c1d chore(system): mask Caffeine metrics log
As it's not an error and we cannot do anything if we don't want metrics (which cost) but want to hide that log.
2025-05-15 14:05:25 +02:00
Miloš Paunović
171272ac4b refactor(deps): revert monaco-yaml upgrade due to patch on previous version (#8797) 2025-05-15 11:18:28 +02:00
Malaydewangan09
3c5975f4b3 feat(plugins): add InfluxDB, GraphQL plugins 2025-05-15 09:11:40 +02:00
Loïc Mathieu
f6b7dbd653 fix(core): flaky test ExecutionServiceTest.replayEachSeq or replayEachSeq2
One of the two is failing pretty often, using @ExecuteFlow instead of @LoadFlow seems to make them non-flaky.
We can also remove the second ad those are duplicated test but maybe the person that duplicate it has some reason...
2025-05-14 18:24:50 +02:00
Piyush Bhaskar
ab9551aada feat(core): Embed videos directly on EE-feature teasers. (#8790)
* feat(demo): add video support to various demo components and enhance layout

* update video sources

* feat(core): Embed videos directly on EE-feature teasers.
2025-05-14 19:29:08 +05:30
Miloš Paunović
6642df4756 refactor(deps): revert monaco-yaml upgrade due to patch on previous version (#8791) 2025-05-14 15:53:39 +02:00
Roman Acevedo
e3fa5b7df1 fix(tests): assertions with numbers 2025-05-14 15:36:26 +02:00
Roman Acevedo
fca529a908 feat(tests): rename testsuite to tests in UI,API 2025-05-14 15:36:26 +02:00
YannC
dd29e7521f fix(filters): allows to filter using is not for relative date filter (#8659)
link to #8494
2025-05-14 15:29:49 +02:00
Miloš Paunović
e7129b1024 fix(core): check for schema existence on no code input editing (#8775) 2025-05-14 13:59:53 +02:00
Barthélémy Ledoux
dff9fec74c fix: allow retry edition in no-code (#8770)
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-05-14 13:34:55 +02:00
Miloš Paunović
c898da3aa3 fix(core): make no code breadcrumb clickable only in legacy mode (#8776) 2025-05-14 13:34:08 +02:00
Miloš Paunović
c517985c80 chore(deps): regular dependency update (#8774)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-05-14 11:18:14 +02:00
Miloš Paunović
b8fb39c67e refactor(core): remove obsolete node script (#8773) 2025-05-14 11:06:31 +02:00
Miloš Paunović
32358c787a chore(plugins): hide deprecated plugins from plugin select options (#8744)
Closes https://github.com/kestra-io/kestra/issues/7205.
2025-05-14 10:39:02 +02:00
Piyush Bhaskar
bbcd377257 feat(core): replace task array option selection design (#8699)
Closes https://github.com/kestra-io/kestra/issues/8694.
2025-05-14 09:14:11 +02:00
Loïc Mathieu
df70618b91 feat(system): use the FlowMetaStore instead of the FlowRepository inside the Executor 2025-05-13 17:15:36 +02:00
Roman Acevedo
58fcd0a18d feat(system): add TestSuite run and assertions
feat(system): add assertions for TestSuites

feat(system): allow isNull and other assertion

feat(system): return a default error message
2025-05-13 16:54:31 +02:00
brian.mulier
79242f9e22 tests(executions): remove flakiness on some tests around sleep 2025-05-13 16:07:10 +02:00
brian.mulier
925169c474 fix(executions): avoid to stop following execution too early leading to UI display shifting from actual state (#8718)
part of kestra-io/kestra-ee#3526
2025-05-13 16:07:10 +02:00
Miloš Paunović
cf206e0b08 chore(core): properly handle topology action clicks while using multi panel editor (#8705)
Closes https://github.com/kestra-io/kestra/issues/7804.
Closes https://github.com/kestra-io/kestra/issues/8275.
2025-05-13 15:56:20 +02:00
Miloš Paunović
6156af2969 fix(core): showing properties of any-of tasks (#8748) 2025-05-13 15:51:01 +02:00
Barthélémy Ledoux
9b12079ca4 fix(namespaces): use the right route param to get namespace files (#8747) 2025-05-13 15:45:00 +02:00
Barthélémy Ledoux
dbb7761104 fix(ui): legacy editor iew no-code does not need creatintask flag (#8742) 2025-05-13 13:39:53 +02:00
Miloš Paunović
e616aa525c chore(flows): remove unnecessary section about keyboard shortcuts from flow basic documentation (#8745)
Closes https://github.com/kestra-io/kestra/issues/7065.
2025-05-13 13:27:00 +02:00
Ludovic DEHON
5e4253ec84 fix(core): some logs can emits null message 2025-05-13 07:34:38 +02:00
github-actions[bot]
2bfdca389f Translations from en.json (#8734)
* 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.

* Apply suggestions from code review

---------

Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: Anna Geller <anna.m.geller@gmail.com>
2025-05-12 17:39:49 +02:00
Barthélémy Ledoux
a213a90bbe feat(ui): treat the pluginsdefaults as a section (#8731) 2025-05-12 16:59:12 +02:00
Loïc Mathieu
5c060b5c39 fix(plugins)*: don't cache the condition property inside the If task
Doing that, causes an issue if the If task is used inside a ForEach with a concurrencyLimit > 1.

Fixes #8697
2025-05-12 16:31:44 +02:00
AJ Emerich
ffdebf3f4c docs(docker): update title and description of docker kill grace period property (#8733)
Part of https://github.com/kestra-io/kestra-ee/issues/3625
2025-05-12 14:40:18 +01:00
AJ Emerich
52931769f9 docs(http): update SSL options property with note 2025-05-12 13:46:16 +02:00
dependabot[bot]
625e78375f build(deps): bump com.google.cloud:libraries-bom from 26.59.0 to 26.60.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.59.0 to 26.60.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.59.0...v26.60.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 11:56:16 +02:00
dependabot[bot]
c8c649cb75 build(deps): bump net.thisptr:jackson-jq from 1.2.0 to 1.3.0
Bumps [net.thisptr:jackson-jq](https://github.com/eiiches/jackson-jq) from 1.2.0 to 1.3.0.
- [Release notes](https://github.com/eiiches/jackson-jq/releases)
- [Commits](https://github.com/eiiches/jackson-jq/compare/1.2.0...1.3.0)

---
updated-dependencies:
- dependency-name: net.thisptr:jackson-jq
  dependency-version: 1.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 11:28:57 +02:00
dependabot[bot]
2c1ea4e1c7 build(deps): bump software.amazon.awssdk:bom from 2.31.35 to 2.31.40
Bumps software.amazon.awssdk:bom from 2.31.35 to 2.31.40.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 11:26:13 +02:00
dependabot[bot]
5e08c7dd50 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.1 to 0.38.2.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.1...v0.38.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 11:24:53 +02:00
Loïc Mathieu
13d86c41ea feat(plugins)!: kill the Docker container on kill
And allow configuring a grace period.

Fixes https://github.com/kestra-io/kestra-ee/issues/3625
Part-of: https://github.com/kestra-io/kestra-ee/issues/3526
2025-05-12 11:22:09 +02:00
Loïc Mathieu
a117634348 feat(system): add metrics for Worker Job resubmission
Part-of: https://github.com/kestra-io/kestra/issues/8341
2025-05-12 11:06:16 +02:00
Barthélémy Ledoux
7262ebe616 fix(ui): nocode save /close button is now smaller (#8713) 2025-05-09 22:47:48 +02:00
Florian Hussonnois
2792fa4535 fix(core): allow scalar-to-string concatenation in typed task property
Enable concatenation of arbitrary scalar values (e.g., numbers, booleans)
into a string when setting a typed plugin property expecting a single value:
e.g., the `value` property of the `io.kestra.plugin.core.kv.Set` task.

Fix: kestra-io/kestra-ee#3570
2025-05-09 17:50:52 +02:00
Florian Hussonnois
e6e9803c4a fix(system): avoid catching JVM fatal error on Worker
Re-throw VirtualMachineError when an exception is catched
from a worker task ensuring, for example, that OOM are
correctly propagated.
2025-05-09 17:38:18 +02:00
Barthélémy Ledoux
cf91ca2baf fix(ui): update breadcrumb click behavior in legacy (#8709) 2025-05-09 15:53:31 +02:00
Barthélémy Ledoux
c11af3fa9d fix: make settings menu proper links (#8710)
* fix: make settings menu proper links

* chore(core): remove bg on select's header

---------

Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-05-09 17:34:59 +05:30
Miloš Paunović
f980a6850b fix(namespaces)*: send proper parameter for namespace on file creation/update (#8706)
There was a problem with sending the non-existing parameter to `vuex` action for creation/update of namespace files. Now that's sorted.

Closes https://github.com/kestra-io/kestra-ee/issues/3567.
2025-05-09 13:02:38 +02:00
Miloš Paunović
bc09676a57 chore(flows): make flow validation a bit less aggressive (#8700)
Flow was being validate with a throttle of `500ms`, which was too aggressive. Now it's increased to `2000ms`.

Closes https://github.com/kestra-io/kestra-ee/issues/3627.
2025-05-08 10:37:07 +02:00
github-actions[bot]
faa6f8fc71 chore(core): localize to languages other than english (#8690)
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-05-07 13:10:33 +02:00
Loïc Mathieu
e0af7e824b fix(core): flaky test RunContextLoggerText.logs()
Wait a little longuer by default for logs to avoid too much flakyness.
2025-05-07 12:39:52 +02:00
Loïc Mathieu
e7b72a5d7f feat(system): send task and trigger usage metrics
Fixes https://github.com/kestra-io/kestra-ee/issues/3532
2025-05-07 12:39:14 +02:00
Loïc Mathieu
fcc1fcb799 chore(system): rename FlowExecutorInterface to FlowMetaStoreInterface
Part-of: https://github.com/kestra-io/kestra-ee/issues/3474
2025-05-07 12:36:52 +02:00
Roman Acevedo
ee444bef30 chore(system): prepare TestSuite ui
advance on CRUD UI for Add unit tests for flows — new tab on the Flows page, runnable from the UI, API or from CI/CD (needs CLI and GitHub Action) kestra-ee#3110

linked to feat(system): add TestSuite list and edit pages kestra-ee#3585
2025-05-07 12:30:46 +02:00
Loïc Mathieu
aecf1dbe07 feat(flows)!: evaluate flow trigger on PAUSED by default
This is a breaking change as existing flow trigger wich didn't filter to any states on conditiosn or preconditions was before triggering executions only on terminal states and will now trigger executions on terminated and paused states.

Fixes https://github.com/kestra-io/kestra-ee/issues/3535
2025-05-07 11:43:15 +02:00
Loïc Mathieu
d13a4e70c7 chore(build): gradle runStandalone 2025-05-07 11:43:03 +02:00
Miloš Paunović
5248e95bd9 chore(deps): regular dependency update (#8687)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-05-07 10:03:17 +02:00
YannC
79a6fbbab1 fix(filters): use correct key for timeRange when using multiple filters (#8657)
close #8498
2025-05-07 09:13:34 +02:00
Dhinakaran T
61dcb852e3 chore(triggers): swap the backfill button on triggers page with the one form flow triggers (#8624)
Closes https://github.com/kestra-io/kestra/issues/8606.

---------

Co-authored-by: dhinakaranst <dinastdhinast@.com>
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-05-07 09:05:38 +02:00
Loïc Mathieu
0c93bc6275 chore(core): retry flaky test triggerPaused() 2025-05-06 17:21:50 +02:00
Loïc Mathieu
1754f81e0b feat(system): add NoopCache
To use where we want to be able to disable caching.
2025-05-06 17:21:50 +02:00
Loïc Mathieu
7117ae60f5 feat(system): purge empty service instances
Purge service instance in EMPTY state after a certain duration, 30 days by default, to avoid never ending groth on the service_instances table.

Fixes #8514
2025-05-06 17:17:46 +02:00
Loïc Mathieu
2b015f8d06 fix(tests): flaky test ExecutionServiceTest.deleteExecutionKeepLogs() 2025-05-06 17:06:03 +02:00
github-actions[bot]
8cccd3725d chore(core): localize to languages other than english (#8656)
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-05-06 15:20:07 +02:00
Dhivya G
fdcea57b18 feat(ui): add version property to Frontend API call (#8650) 2025-05-06 14:55:01 +02:00
yuri
3f1d4f8fe0 feat(core): enable filter refresh interval to be changed in settings (#8522)
This change is introducing a new setting for users to choose - the automatic table refresh interval.

---------

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-05-06 14:44:09 +02:00
Loïc Mathieu
fe0a5d287b feat(system): add metrics to the executor
Add metrics to the executor for:
- Execution delays
- Execution killed events
- SLA expirations and violations

Part-of: #8341
2025-05-06 14:20:29 +02:00
Loïc Mathieu
5237bcc90c fix(system): subflow validation can fail when typing 2025-05-06 14:17:39 +02:00
AbdurRahman2004
d7a3e24465 chore(core): update keyboard shortcut for triggering the autocompletion (#8618)
Label for triggering autocompletion was `CMD/CTRL + SPACE`, but on `MacOS`, that was triggering a Spotlight search. As the `CTRL + SPACE` works on `MacOS` also, the label is tweaked.

Closes https://github.com/kestra-io/kestra/issues/8617

---

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-05-06 13:53:04 +02:00
Loïc Mathieu
df5419f9ec fix(flows): ForEach concurrency should not be over the number of values
Fixes #8614
2025-05-06 10:23:09 +02:00
AJ Emerich
9b72ce5a18 docs(http): add mention to check for plugins before using HTTP 2025-05-06 09:24:12 +02:00
Barthélémy Ledoux
e287964416 fix(editor): check isFlow when displaying NoCode in legacy editor (#8645) 2025-05-05 17:29:25 +02:00
dependabot[bot]
5759495216 build(deps): bump software.amazon.awssdk:bom from 2.31.30 to 2.31.35
Bumps software.amazon.awssdk:bom from 2.31.30 to 2.31.35.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 12:08:43 +02:00
Loïc Mathieu
e89e5988ec feat(jdbc): Improve JDBC queue poll duration selection
- By default, switch from quick polling to long polling after 30s of inacitvity on a queue
- By default, configure long polling interval to 500ms
- Use steps to goes from quick polling to long polling (5 steps automatically computed)
2025-05-05 12:07:54 +02:00
github-actions[bot]
51c522976e chore(core): localize to languages other than english (#8641)
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-05-05 11:54:18 +02:00
Miloš Paunović
722d94ba4b fix(core): introduce back the proper translation key (#8639) 2025-05-05 11:51:15 +02:00
Miloš Paunović
e47816c941 fix(core): amend the problem with translation key (#3577) (#8638) 2025-05-05 11:49:18 +02:00
Barthélémy Ledoux
3fdd976b5c fix(ui): conditionally render icon based on save mode (#8636) 2025-05-05 11:26:43 +02:00
Anna Geller
2f8a5903f3 fix(naming): name action file in the same way as name to avoid double display and confusion (#8634) 2025-05-05 11:10:04 +02:00
github-actions[bot]
f3250c0dc9 chore(core): localize to languages other than english (#8635)
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-05-05 11:09:53 +02:00
Barthélémy Ledoux
2c58e97ec3 feat: allow multiple nocode (#8532) 2025-05-05 10:56:56 +02:00
dependabot[bot]
1bd89843ed build(deps): bump org.testcontainers:testcontainers
Bumps [org.testcontainers:testcontainers](https://github.com/testcontainers/testcontainers-java) from 1.20.6 to 1.21.0.
- [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.20.6...1.21.0)

---
updated-dependencies:
- dependency-name: org.testcontainers:testcontainers
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:37:22 +02:00
dependabot[bot]
c565b3b947 build(deps): bump org.jsoup:jsoup from 1.19.1 to 1.20.1
Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.19.1 to 1.20.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.19.1...jsoup-1.20.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:36:59 +02:00
dependabot[bot]
5ce8763ccf build(deps): bump org.jooq:jooq from 3.20.3 to 3.20.4
Bumps org.jooq:jooq from 3.20.3 to 3.20.4.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:36:42 +02:00
dependabot[bot]
d52974de4b build(deps): bump com.azure:azure-sdk-bom from 1.2.33 to 1.2.34
Bumps [com.azure:azure-sdk-bom](https://github.com/azure/azure-sdk-for-java) from 1.2.33 to 1.2.34.
- [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.33...azure-sdk-bom_1.2.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:36:23 +02:00
dependabot[bot]
c9296b657a build(deps): bump com.microsoft.playwright:playwright
Bumps [com.microsoft.playwright:playwright](https://github.com/microsoft/playwright-java) from 1.51.0 to 1.52.0.
- [Release notes](https://github.com/microsoft/playwright-java/releases)
- [Commits](https://github.com/microsoft/playwright-java/compare/v1.51.0...v1.52.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:35:31 +02:00
dependabot[bot]
6f24e31c32 build(deps): bump opensearchRestVersion from 2.19.1 to 2.19.2
Bumps `opensearchRestVersion` from 2.19.1 to 2.19.2.

Updates `org.opensearch.client:opensearch-rest-client` from 2.19.1 to 2.19.2
- [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.1...2.19.2)

Updates `org.opensearch.client:opensearch-rest-high-level-client` from 2.19.1 to 2.19.2
- [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.1...2.19.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:35:12 +02:00
dependabot[bot]
90180cc069 build(deps): bump org.fusesource.jansi:jansi from 2.4.1 to 2.4.2
Bumps [org.fusesource.jansi:jansi](https://github.com/fusesource/jansi) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/fusesource/jansi/releases)
- [Changelog](https://github.com/fusesource/jansi/blob/master/changelog.md)
- [Commits](https://github.com/fusesource/jansi/compare/jansi-2.4.1...jansi-2.4.2)

---
updated-dependencies:
- dependency-name: org.fusesource.jansi:jansi
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 09:34:48 +02:00
Florian Hussonnois
01110c51f6 fix(flows): fix regression on flow validation (#8600)
Fix regression on flow validation when injecting
plugin default values

Fix: #8600
2025-05-02 09:09:02 +02:00
Loïc Mathieu
02723aa3d9 fix(dashboards)*: SQL errors on logs data chart
- PostgreSQL needs a cast from enum to text.
- Missing quotes on the WHERE clause.

Fixes #8128
2025-04-30 18:09:45 +02:00
github-actions[bot]
3d4ebf5f3b chore(core): localize to languages other than english (#8611)
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-04-30 15:44:14 +02:00
Piyush Bhaskar
266c671095 feat(iam): introduce user menu into left sidebar (#8602)
This PR is introducing the new user menu with actions inside the left sidebar.

Relates to https://github.com/kestra-io/kestra-ee/issues/2105.
Relates to https://github.com/kestra-io/kestra-ee/issues/2964.

---------

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-04-30 15:35:20 +02:00
Miloš Paunović
aae1315f74 fix(executions): amend storybook tests for inputs form (#8608) 2025-04-30 14:59:10 +02:00
brian-mulier-p
a9f0cae83f fix(core): Doc search is more relevant (#8601)
closes #6329
2025-04-30 14:35:37 +02:00
Satvik Kushwaha
98cfd32676 feat(executions): use schedule set input values for backfills (#7913)
Made changes to backfilling executions input to fill the default input value by the input value set within a schedule.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-04-30 13:27:31 +02:00
Miloš Paunović
a9a2765521 chore(deps): regular dependency update (#8599)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-04-30 12:21:05 +02:00
github-actions[bot]
c0ba1831bf chore(core): localize to languages other than english (#8576)
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-04-29 21:52:47 +02:00
Florian Hussonnois
a26fabe083 feat(system): add uv to kestra docker image
Use uv to install packages. UV is now required
to manage pythons dependencies for the plugin-script python.

Fix: kestra-io/kestra-ee#3527
2025-04-29 17:27:59 +02:00
Florian Hussonnois
bf41fb4613 fix(core): remove tutorial flows from anonymous report
Fix: kestra-io/kestra-ee#3387
2025-04-29 17:27:28 +02:00
Loïc Mathieu
097336ef28 feat(executions): Add workerId to each worker task attemps
Closes #7799
2025-04-29 16:13:23 +02:00
Loïc Mathieu
7467f1f7fb feat(flows): Allow to define an onPause task on the Pause task
The onPause task will be executed immediatly when the execution is paused.
Part-of: #3601
2025-04-29 15:48:59 +02:00
Loïc Mathieu
4e602021a8 feat(system)*: decrease defaut JDBC queue poll size
Decreasing it from 100 to 50 didn't show any performance hit but should lower the memory consumption now that we process the queue concurrently in the executor.

## BEFORE - pollSize=100
- 10 tx/s: 150ms
- 25 tx/s: 200ms
- 50 tx/s: 300ms
- 75 tx/s: 5.2s
- 100 tx/s: 15s

## AFTER - pollSize=50
- 10 tx/s: 150ms
- 25 tx/s: 200ms
- 50 tx/s: 300ms
- 75 tx/s: 4.8s
- 100 tx/s: 14s
2025-04-29 15:11:24 +02:00
Barthélémy Ledoux
1c23e31b6b fix: redirect to edit when saving new flow (#8560)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-04-29 14:14:36 +02:00
Loïc Mathieu
9beb86bfb5 feat(system): add TestSuite model,taskFixture impl 2025-04-29 11:03:57 +02:00
github-actions[bot]
e0723a94b5 chore(core): localize to languages other than english (#8568)
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-04-29 10:37:01 +02:00
Florian Hussonnois
475a961cec fix(executions): fix execution failure due to UnsupportedOperationException (#8563)
Fix: #8563
2025-04-29 10:34:48 +02:00
Piyush Bhaskar
c5b7c5d483 chore(triggers)*: properly handle switches for triggers disabled from within flow source (#8106)
It was not clear as to which trigger can not be enabled and why. Now, that is much more clear with the proper tooltips and disabling of switch toggling.

Closes https://github.com/kestra-io/kestra/issues/8011.
Closes https://github.com/kestra-io/kestra/issues/5736.
2025-04-29 10:31:55 +02:00
Roman Acevedo
2cf6c54b89 feat(core): forward execution labels in Flow Trigger 2025-04-28 16:55:10 +02:00
Nicolas K.
13d02ee396 fix(namespaces): namespaceFiles with same name are wrongly overwritten (#8562)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-04-28 16:14:31 +02:00
yuri
21dc831f25 chore: attempt to fix flaky tests (#8537)
SingleFlowCommandsTest:

The flow Delete -> Create -> Update sequence is weird - delete got HTTP 404.
Reworked to Create -> Update -> Delete sequence.

PurgeLogsTest:

The log repository contained the prepared single entry but also might
contain additional entries from previously logged messages.
2025-04-28 15:07:28 +02:00
Miloš Paunović
1c9f9af82a fix(triggers): amend broken filtering on triggers tab (#8553)
There was a problem with both namespace and state filters on Triggers page which is now properly sorted.

Closes https://github.com/kestra-io/kestra/issues/8529.
2025-04-28 12:07:50 +02:00
github-actions[bot]
dc5acbc5bb chore(core): localize to languages other than english (#8554)
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-04-28 12:00:37 +02:00
Barthélémy Ledoux
3e23456fb7 fix(ui): update storybook editor tests with provided keys (#8550)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-04-28 11:43:55 +02:00
Piyush Bhaskar
2943e10e7e fix(core): safely access section and identifier query params (#8542)
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-04-28 14:06:39 +05:30
Barthélémy Ledoux
0ec8bd45c8 fix(ui): set isCreating to false when opening flow edit mode (#8549) 2025-04-28 10:34:36 +02:00
Nicolas K.
10e882a54a fix(core): change incorrectly used search parameter (#8534)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-04-28 10:32:57 +02:00
Piyush Bhaskar
4bc7f72fcd chore(execution): update display names for executions. (#8527) 2025-04-28 14:00:21 +05:30
dependabot[bot]
ce6770c574 build(deps): bump jacksonVersion from 2.18.3 to 2.19.0
Bumps `jacksonVersion` from 2.18.3 to 2.19.0.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 09:42:04 +02:00
dependabot[bot]
04f32abb77 build(deps): bump org.wiremock:wiremock-jetty12 from 3.12.1 to 3.13.0
Bumps [org.wiremock:wiremock-jetty12](https://github.com/wiremock/wiremock) from 3.12.1 to 3.13.0.
- [Release notes](https://github.com/wiremock/wiremock/releases)
- [Commits](https://github.com/wiremock/wiremock/compare/3.12.1...3.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 09:41:33 +02:00
dependabot[bot]
d9ab998a03 build(deps): bump software.amazon.awssdk:bom from 2.31.25 to 2.31.30
Bumps software.amazon.awssdk:bom from 2.31.25 to 2.31.30.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 09:41:09 +02:00
Loïc Mathieu
e19056cad3 fix(triggers): inject default later inside the Scheduler
Today, as they are injected eagerly, they are done even if no trigger exists.
This is counter-performant, and in case the flow is an error will log each seconds.
Doing it a little later will be better.
2025-04-28 09:40:33 +02:00
Karuna Tata
897abdd89d feat(ui): Add search in internal docs (#8458)
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-04-28 09:37:25 +02:00
Loïc Mathieu
2571f73811 fix(system): load OpenTelemetry lib in the app classloader
Without that, as we have it here, plugins may have class loading issue if they use OpenTelemetry internally (like in the Elasticsearch client).
2025-04-25 21:26:32 +02:00
Piyush Bhaskar
00cf7863e1 fix(ui): open link in markdown in other tab. (#8258)
* fix(ui): open link in markdown in other tab.

* chore(core): restrict attribute to external links.

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>

---------

Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-04-25 19:09:22 +05:30
rajatsingh23
3c68ff5a2d fix(ui): remove parts of filter using backspace (#8105)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-04-25 14:08:38 +02:00
AJ Emerich
10ce92c0f5 docs(flow-trigger): add note about no Pebble in conditions 2025-04-25 11:54:04 +02:00
github-actions[bot]
6baeba8f63 chore(core): localize to languages other than english (#8528)
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-04-25 11:19:18 +02:00
yuri
efe836874f fix(ui): amend Absolute date filter's looks (#8501) 2025-04-25 14:24:00 +05:30
Florian Hussonnois
8746f2bd15 fix(system): change default config values for liveness
Change kestra.server.liveness.interval from 5s to 10s
to be less agressive on liveness check. Align
other default liveness configs with kafka implementation.
2025-04-25 10:28:30 +02:00
Piyush Bhaskar
34a7316d3f feat(flows): improve the display of array inputs when running an execution (#7953)
This PR is introducing a change of how the `array` inputs are displayed inside the flow run dialog, to be more user-friendly.

Closes https://github.com/kestra-io/kestra/issues/6947.

---------

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-04-25 09:40:24 +02:00
Miloš Paunović
fc452aff94 fix(flows): properly load blueprints in multi panel view (#8524)
While using the new Multi Panel view blueprints were not loading properly due to wrong paramtere being sent to action. now that's sorted.

Closes https://github.com/kestra-io/kestra/issues/8523.
2025-04-25 13:08:45 +05:30
Piyush Bhaskar
77da3fd16c chore(flows): improve the blueprints view within the flow editing panels (#7983)
Changes here consist of removing the tags from blueprint view on Multi Panel flow editor, along with couple of other UI improvements.

Closes https://github.com/kestra-io/kestra/issues/7881.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-04-25 09:10:29 +02:00
杨利伟
03f9aa8e85 fix(jdbc): add service_id index on service_instance table 2025-04-24 18:14:15 +02:00
Loïc Mathieu
3f9f60dd26 feat(plugins): add Go Script plugin 2025-04-24 17:25:16 +02:00
lwyang
8b5f333c02 chore(system): add warn log when emit logQueue failed (#8432) 2025-04-24 16:02:12 +02:00
Loïc Mathieu
d27626fbd1 feat(plugins): add Langchain4J plugins 2025-04-24 15:42:15 +02:00
Loïc Mathieu
08f5ad2710 chore(build): add Postgres stat extension 2025-04-24 14:51:34 +02:00
Loïc Mathieu
56fa97b2e4 feat(system)!: remove the SQLServer runner
Part-of: https://github.com/kestra-io/kestra-ee/issues/3504
2025-04-24 14:50:57 +02:00
Nicolas K.
14210f1661 test(core): fix breaking change in local flow repository (#8517)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-04-24 14:34:10 +02:00
Hashim Khalifa
1fb6958e9e feat(flows): add validation for use of inputs and outputs with '-' in the name (#8379) 2025-04-24 14:31:53 +02:00
Piyush Bhaskar
5e7bc96322 chore(core): refactor component to composition API structure and with some styling (#8504) 2025-04-24 14:29:18 +05:30
Loïc Mathieu
729cf56c54 fix(core): failing DocumentationGeneratorTest.returnDoc() 2025-04-24 10:36:38 +02:00
Karuna Tata
a21cff4ba0 fix(ui): save existing flow after making changes (#8378)
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
2025-04-24 10:31:32 +02:00
Loïc Mathieu
7e590dd603 feat(plugin): add a way to provide additional type of plugins
Provide a way for plugins to define a new type of plugins.
To do that, a plugin must provide both an abstract base class that extends AdditionalPlugin and a set of concret classes.
Both the abstract base class and the concrete classes mut be inside the same plugin. This is a limitation that we may work on later by providing, for example, an SPI to add base classes to the application classloader.
2025-04-24 10:04:51 +02:00
Satvik Kushwaha
ad9f69334c fix(ui): restart trigger position for backfill column (#8246)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Barthélémy Ledoux <ledouxb@me.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-04-24 09:43:59 +02:00
Piyush Bhaskar
c7b448a9f0 chore(ui): improvement to drilldown for Default and Custom Charts. (#7885)
* chore(ui): improvement to drilldown for Default and Custom Charts.

* minor tweak

* test: fix the Barchart stories to test drilldown

---------

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-04-24 10:42:06 +05:30
ben8t
b1a48c17f2 Add examples with expression and trimmed values (#6154) 2025-04-23 19:57:00 +02:00
AJ Emerich
7957b9db12 fix(core): fix indexer metric description (#8500) 2025-04-23 16:48:02 +01:00
Loïc Mathieu
d58898ff34 fix(system): restrict the JdbcConcurrencyLimitService to the JDBC runner 2025-04-23 16:29:10 +02:00
AJ Emerich
1ff2e0355d docs(core-pause): update pauseDuration properties, titles, descriptions (#8495) 2025-04-23 14:34:02 +01:00
Piyush Bhaskar
9cb7cd6453 fix(flows): properly check average duration for dashboard graphs (#8457)
There was a problem on flows view with the main chart not showing proper data until user clicks on duration toggle.

Closes https://github.com/kestra-io/kestra/issues/8435.
Closes https://github.com/kestra-io/kestra-ee/issues/3499.
2025-04-23 14:23:40 +02:00
AJ Emerich
728a6a3af8 doc(basic.md): add link to configuration for kestra property variables (#8490) 2025-04-23 12:04:12 +01:00
Ludovic DEHON
ebd957f00d chore(deps): update gradle version 2025-04-23 12:52:49 +02:00
Miloš Paunović
f24734f5f2 refactor(core): pass the dynamic concurrency schema to no code editor (#8488)
There was an issue with passing hard-coded concurrency schema to be rendered in No Code editor, which is now amended and we're passing down the previously fetched one
2025-04-23 11:54:22 +02:00
Loïc Mathieu
d14ff78fd8 fix(execution)*: decode and hide nested inputs of type SECRET
Fixes #7964
2025-04-23 11:45:57 +02:00
Roman Acevedo
1506d68132 tests(system): bump sleep-short sleep time to 10s 2025-04-23 11:39:50 +02:00
Roman Acevedo
bf4310edc3 tests(system): try with different task id 2025-04-23 11:39:50 +02:00
Roman Acevedo
b4106af12b tests(system): debug flaky error of shouldPauseExecutionByQueryRunningFlows 2025-04-23 11:39:50 +02:00
Roman Acevedo
1974fd15ec tests(system): debug flaky error of shouldPauseExecutionByQueryRunningFlows 2025-04-23 11:39:50 +02:00
Roman Acevedo
ce3eea76f0 tests(webserver): fix flaky test which could query previous tests tasks 2025-04-23 11:39:50 +02:00
github-actions[bot]
636f0f61d7 chore(core): localize to languages other than english (#8485)
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-04-23 11:18:49 +02:00
Loïc Mathieu
3105ddc40b fix(executions): unqueing execution must remove the execution queued
When an execution is queued in the JDBC backend, a record is inserted inside the execution_queued table, we must remove this record when we unqeue an execution.

Fixes #8448
2025-04-23 11:13:31 +02:00
Piyush Bhaskar
b779aa1aed fix(controls): adjust bottom position of contorls in multiPanelsEditor (#8465) 2025-04-23 13:26:36 +05:30
Barthélémy Ledoux
fa5a391103 feat: synchronize task edition with editor (#8433) 2025-04-23 09:43:47 +02:00
Piyush Bhaskar
b947c23402 fix(ui): full view height for single task logs (#8042)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-04-23 09:43:19 +02:00
Miloš Paunović
54b8ff9d0c chore(deps): regular dependency update (#8484)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-04-23 09:38:02 +02:00
Loïc Mathieu
724058a06f Feat/storage outputs (#8361)
* feat(executions): Store outputs inside the internal storage (1/2)

* feat(executions): Store outputs inside the internal storage (2/2)

* feat(test): allow passing tenantId to tests

---------

Co-authored-by: Ludovic DEHON <tchiot.ludo@gmail.com>
2025-04-22 15:46:57 +02:00
Roman Acevedo
d454d133f5 tests(system): isolate SchedulerScheduleTest tests with tenantId 2025-04-22 15:41:54 +02:00
929 changed files with 31561 additions and 19057 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

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

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

@@ -51,7 +51,7 @@ jobs:
python-libs: ""
- name: ""
plugins: ${{needs.plugins.outputs.plugins}}
packages: python3 python3-venv python-is-python3 python3-pip nodejs npm curl zip unzip jattach
packages: python3 python-is-python3 python3-pip curl jattach
python-libs: kestra
steps:
- uses: actions/checkout@v4

View File

@@ -1,158 +1,77 @@
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: Checkout kestra
uses: actions/checkout@v4
with:
path: kestra
# Setup build
- uses: kestra-io/actions/.github/actions/setup-build@main
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 != ''
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: Checkout kestra
uses: actions/checkout@v4
with:
path: kestra
- name: Setup additional application configuration
if: env.APPLICATION_SECRETS != null
env:
APPLICATION_SECRETS: ${{ secrets.APPLICATION_SECRETS }}
- name: Install Npm dependencies
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
cd kestra/ui
npm run test:e2e
# 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/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

@@ -27,7 +27,7 @@ jobs:
echo "Invalid release version. Must match regex: ^[0-9]+(\.[0-9]+)\.0-rc[01](-SNAPSHOT)?$"
exit 1
fi
if ! [[ "$NEXT_VERSION" =~ ^[0-9]+(\.[0-9]+)\.0-SNAPSHOT$ ]]; then
echo "Invalid next version. Must match regex: ^[0-9]+(\.[0-9]+)\.0-SNAPSHOT$"
exit 1;
@@ -36,6 +36,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
path: kestra
# Checkout GitHub Actions
- uses: actions/checkout@v4
@@ -62,18 +63,20 @@ jobs:
- name: Run Gradle Release
env:
GITHUB_PAT: ${{ secrets.GH_PERSONAL_TOKEN }}
run: |
run: |
# Extract the major and minor versions
BASE_VERSION=$(echo "$RELEASE_VERSION" | sed -E 's/^([0-9]+\.[0-9]+)\..*/\1/')
PUSH_RELEASE_BRANCH="releases/v${BASE_VERSION}.x"
cd kestra
# Create and push release branch
git checkout -b "$PUSH_RELEASE_BRANCH";
git push -u origin "$PUSH_RELEASE_BRANCH";
# Run gradle release
git checkout develop;
if [[ "$RELEASE_VERSION" == *"-SNAPSHOT" ]]; then
# -SNAPSHOT qualifier maybe used to test release-candidates
./gradlew release -Prelease.useAutomaticVersion=true \

View File

@@ -52,15 +52,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

@@ -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.31.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.31.0
with:
image-ref: kestra/kestra:latest
format: table

View File

@@ -22,8 +22,25 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Cache Node Modules
id: cache-node-modules
uses: actions/cache@v4
with:
path: |
ui/node_modules
key: modules-${{ hashFiles('ui/package-lock.json') }}
- name: Cache Playwright Binaries
id: cache-playwright
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright
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
@@ -44,6 +61,7 @@ jobs:
- 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

View File

@@ -6,19 +6,21 @@ on:
GH_PERSONAL_TOKEN:
description: "The Github personal token."
required: true
push:
tags:
- '*'
jobs:
publish:
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')
# Check out
- name: Checkout - Repository
uses: actions/checkout@v4
with:
name: exe
path: build/executable
fetch-depth: 0
submodules: true
# Checkout GitHub Actions
- name: Checkout - Actions
@@ -30,18 +32,27 @@ jobs:
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
# GitHub Release
- name: Create GitHub release
uses: ./actions/.github/actions/github-release
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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
if: steps.create_github_release.conclusion == 'success'
with:
token: ${{ secrets.GH_PERSONAL_TOKEN }}
repository: kestra-io/helm-charts

1
.gitignore vendored
View File

@@ -59,3 +59,4 @@ core/src/main/resources/gradle.properties
*storybook.log
storybook-static
/jmh-benchmarks/src/main/resources/gradle.properties

View File

@@ -33,9 +33,11 @@
#plugin-github:io.kestra.plugin:plugin-github:LATEST
#plugin-googleworkspace:io.kestra.plugin:plugin-googleworkspace:LATEST
#plugin-graalvm:io.kestra.plugin:plugin-graalvm:LATEST
#plugin-graphql:io.kestra.plugin:plugin-graphql:LATEST
#plugin-hightouch:io.kestra.plugin:plugin-hightouch:LATEST
#plugin-hubspot:io.kestra.plugin:plugin-hubspot:LATEST
#plugin-huggingface:io.kestra.plugin:plugin-huggingface:LATEST
#plugin-influxdb:io.kestra.plugin:plugin-influxdb:LATEST
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-as400:LATEST
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-clickhouse:LATEST
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-db2:LATEST
@@ -56,9 +58,12 @@
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-arrow-flight:LATEST
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-sqlite:LATEST
#plugin-jdbc:io.kestra.plugin:plugin-jdbc-sybase:LATEST
#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
@@ -70,11 +75,13 @@
#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-ollama:io.kestra.plugin:plugin-ollama:LATEST
#plugin-openai:io.kestra.plugin:plugin-openai:LATEST
#plugin-opensearch:io.kestra.plugin:plugin-opensearch: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-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
@@ -88,6 +95,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

@@ -16,8 +16,9 @@ RUN apt-get update -y && \
if [ -n "${APT_PACKAGES}" ]; then apt-get install -y --no-install-recommends ${APT_PACKAGES}; fi && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/tmp/* /tmp/* && \
curl -LsSf https://astral.sh/uv/0.6.17/install.sh | sh && mv /root/.local/bin/uv /bin && mv /root/.local/bin/uvx /bin && \
if [ -n "${KESTRA_PLUGINS}" ]; then /app/kestra plugins install ${KESTRA_PLUGINS} && rm -rf /tmp/*; fi && \
if [ -n "${PYTHON_LIBRARIES}" ]; then pip install ${PYTHON_LIBRARIES}; fi && \
if [ -n "${PYTHON_LIBRARIES}" ]; then uv pip install --system ${PYTHON_LIBRARIES}; fi && \
chown -R kestra:kestra /app
USER kestra

View File

@@ -21,7 +21,7 @@ plugins {
// test
id "com.adarshr.test-logger" version "4.0.0"
id "org.sonarqube" version "6.1.0.5360"
id "org.sonarqube" version "6.2.0.5505"
id 'jacoco-report-aggregation'
// helper
@@ -39,7 +39,7 @@ plugins {
id 'ru.vyarus.github-info' version '2.0.0' apply false
// OWASP dependency check
id "org.owasp.dependencycheck" version "12.1.1" apply false
id "org.owasp.dependencycheck" version "12.1.3" apply false
}
idea {
@@ -165,7 +165,7 @@ allprojects {
* Test
**********************************************************************************************************************/
subprojects {
if (it.name != 'platform') {
if (it.name != 'platform' && it.name != 'jmh-benchmarks') {
apply plugin: "com.adarshr.test-logger"
java {
@@ -268,7 +268,7 @@ subprojects {
* Allure Reports
**********************************************************************************************************************/
subprojects {
if (it.name != 'platform') {
if (it.name != 'platform' && it.name != 'jmh-benchmarks') {
dependencies {
testImplementation platform("io.qameta.allure:allure-bom")
testImplementation "io.qameta.allure:allure-junit5"
@@ -295,7 +295,7 @@ subprojects {
* Jacoco
**********************************************************************************************************************/
subprojects {
if (it.name != 'platform') {
if (it.name != 'platform' && it.name != 'jmh-benchmarks') {
apply plugin: 'jacoco'
test {
@@ -472,6 +472,15 @@ tasks.register('runLocal', JavaExec) {
args 'server', 'local', '--plugins', 'local/plugins'
}
tasks.register('runStandalone', JavaExec) {
group = "application"
description = "Run Kestra as server local"
classpath = project(":cli").sourceSets.main.runtimeClasspath
mainClass = mainClassName
environment 'MICRONAUT_ENVIRONMENTS', 'override'
args 'server', 'standalone', '--plugins', 'local/plugins'
}
/**********************************************************************************************************************\
* Publish
**********************************************************************************************************************/
@@ -487,98 +496,101 @@ nexusPublishing {
}
subprojects {
apply plugin: "maven-publish"
apply plugin: 'signing'
apply plugin: 'ru.vyarus.pom'
apply plugin: 'ru.vyarus.github-info'
javadoc {
options {
locale = 'en_US'
encoding = 'UTF-8'
addStringOption("Xdoclint:none", "-quiet")
}
}
if (it.name != 'jmh-benchmarks') {
apply plugin: "maven-publish"
apply plugin: 'signing'
apply plugin: 'ru.vyarus.pom'
apply plugin: 'ru.vyarus.github-info'
tasks.register('sourcesJar', Jar) {
dependsOn = [':core:copyGradleProperties']
dependsOn = [':ui:assembleFrontend']
archiveClassifier.set('sources')
from sourceSets.main.allSource
}
sourcesJar.dependsOn ':core:copyGradleProperties'
sourcesJar.dependsOn ':ui:assembleFrontend'
tasks.register('javadocJar', Jar) {
archiveClassifier.set('javadoc')
from javadoc
}
tasks.register('testsJar', Jar) {
group = 'build'
description = 'Build the tests jar'
archiveClassifier.set('tests')
if (sourceSets.matching { it.name == 'test'}) {
from sourceSets.named('test').get().output
}
}
github {
user 'kestra-io'
license 'Apache'
repository 'kestra'
site 'https://kestra.io'
}
maven.pom {
description = 'The modern, scalable orchestrator & scheduler open source platform'
developers {
developer {
id = "tchiotludo"
name = "Ludovic Dehon"
javadoc {
options {
locale = 'en_US'
encoding = 'UTF-8'
addStringOption("Xdoclint:none", "-quiet")
}
}
}
publishing {
publications {
sonatypePublication(MavenPublication) {
version project.version
tasks.register('sourcesJar', Jar) {
dependsOn = [':core:copyGradleProperties']
dependsOn = [':ui:assembleFrontend']
archiveClassifier.set('sources')
from sourceSets.main.allSource
}
sourcesJar.dependsOn ':core:copyGradleProperties'
sourcesJar.dependsOn ':ui:assembleFrontend'
if (project.name.contains('cli')) {
groupId "io.kestra"
artifactId "kestra"
tasks.register('javadocJar', Jar) {
archiveClassifier.set('javadoc')
from javadoc
}
artifact shadowJar
artifact executableJar
} else if (project.name.contains('platform')){
groupId project.group
artifactId project.name
} else {
from components.java
tasks.register('testsJar', Jar) {
group = 'build'
description = 'Build the tests jar'
groupId project.group
artifactId project.name
archiveClassifier.set('tests')
if (sourceSets.matching { it.name == 'test'}) {
from sourceSets.named('test').get().output
}
}
artifact sourcesJar
artifact javadocJar
artifact testsJar
github {
user 'kestra-io'
license 'Apache'
repository 'kestra'
site 'https://kestra.io'
}
maven.pom {
description = 'The modern, scalable orchestrator & scheduler open source platform'
developers {
developer {
id = "tchiotludo"
name = "Ludovic Dehon"
}
}
}
}
signing {
// only sign JARs that we publish to Sonatype
required { gradle.taskGraph.hasTask("publishSonatypePublicationPublicationToSonatypeRepository") }
sign publishing.publications.sonatypePublication
}
publishing {
publications {
sonatypePublication(MavenPublication) {
version project.version
tasks.withType(GenerateModuleMetadata).configureEach {
// Suppression this validation error as we want to enforce the Kestra platform
suppressedValidationErrors.add('enforced-platform')
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
}
}
}
}
signing {
// only sign JARs that we publish to Sonatype
required { gradle.taskGraph.hasTask("publishSonatypePublicationPublicationToSonatypeRepository") }
sign publishing.publications.sonatypePublication
}
tasks.withType(GenerateModuleMetadata).configureEach {
// Suppression this validation error as we want to enforce the Kestra platform
suppressedValidationErrors.add('enforced-platform')
}
}
}

View File

@@ -1,5 +1,7 @@
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;
@@ -90,7 +92,7 @@ public abstract class AbstractApiCommand extends AbstractCommand {
throw new IllegalArgumentException("'path' must be non-null and start with '/'");
}
return tenantId == null ? "/api/v1" + path : "/api/v1/" + tenantId + path;
return tenantId == null ? "/api/v1/" + MAIN_TENANT + path : "/api/v1/" + tenantId + path;
}
@Builder

View File

@@ -2,6 +2,7 @@ package io.kestra.cli;
import io.kestra.cli.commands.configs.sys.ConfigCommand;
import io.kestra.cli.commands.flows.FlowCommand;
import io.kestra.cli.commands.migrations.MigrationCommand;
import io.kestra.cli.commands.namespaces.NamespaceCommand;
import io.kestra.cli.commands.plugins.PluginCommand;
import io.kestra.cli.commands.servers.ServerCommand;
@@ -42,6 +43,7 @@ import java.util.concurrent.Callable;
SysCommand.class,
ConfigCommand.class,
NamespaceCommand.class,
MigrationCommand.class,
}
)
@Introspected

View File

@@ -0,0 +1,29 @@
package io.kestra.cli.commands.migrations;
import io.kestra.cli.AbstractCommand;
import io.kestra.cli.App;
import io.micronaut.configuration.picocli.PicocliRunner;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@CommandLine.Command(
name = "migrate",
description = "handle migrations",
mixinStandardHelpOptions = true,
subcommands = {
TenantMigrationCommand.class,
}
)
@Slf4j
public class MigrationCommand extends AbstractCommand {
@SneakyThrows
@Override
public Integer call() throws Exception {
super.call();
PicocliRunner.call(App.class, "migrate", "--help");
return 0;
}
}

View File

@@ -0,0 +1,49 @@
package io.kestra.cli.commands.migrations;
import io.kestra.cli.AbstractCommand;
import io.kestra.core.repositories.TenantMigrationInterface;
import io.micronaut.context.ApplicationContext;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
import picocli.CommandLine.Option;
@CommandLine.Command(
name = "default-tenant",
description = "migrate every elements from no tenant to the main tenant"
)
@Slf4j
public class TenantMigrationCommand extends AbstractCommand {
@Inject
private ApplicationContext applicationContext;
@Option(names = "--tenant-id", description = "tenant identifier")
String tenantId;
@Option(names = "--tenant-name", description = "tenant name")
String tenantName;
@Option(names = "--dry-run", description = "Preview only, do not update")
boolean dryRun;
@Override
public Integer call() throws Exception {
super.call();
if (dryRun) {
System.out.println("🧪 Dry-run mode enabled. No changes will be applied.");
}
TenantMigrationService migrationService = this.applicationContext.getBean(TenantMigrationService.class);
try {
migrationService.migrateTenant(tenantId, tenantName, dryRun);
System.out.println("✅ Tenant migration complete.");
} catch (Exception e) {
System.err.println("❌ Tenant migration failed: " + e.getMessage());
e.printStackTrace();
return 1;
}
return 0;
}
}

View File

@@ -0,0 +1,56 @@
package io.kestra.cli.commands.migrations;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import com.github.javaparser.utils.Log;
import io.kestra.core.exceptions.KestraRuntimeException;
import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.queues.QueueException;
import io.kestra.core.queues.QueueFactoryInterface;
import io.kestra.core.queues.QueueInterface;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.repositories.TenantMigrationInterface;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@Singleton
@Slf4j
public class TenantMigrationService {
@Inject
private TenantMigrationInterface tenantMigrationInterface;
@Inject
private FlowRepositoryInterface flowRepository;
@Inject
@Named(QueueFactoryInterface.FLOW_NAMED)
private QueueInterface<FlowInterface> flowQueue;
public void migrateTenant(String tenantId, String tenantName, boolean dryRun) {
if (StringUtils.isNotBlank(tenantId) && !MAIN_TENANT.equals(tenantId)){
throw new KestraRuntimeException("Tenant configuration is an enterprise feature. It can only be main in OSS");
}
Log.info("🔁 Starting tenant migration...");
tenantMigrationInterface.migrateTenant(MAIN_TENANT, dryRun);
migrateQueue(dryRun);
}
protected void migrateQueue(boolean dryRun) {
if (!dryRun){
log.info("🔁 Starting restoring queue...");
flowRepository.findAllWithSourceForAllTenants().forEach(flow -> {
try {
flowQueue.emit(flow);
} catch (QueueException e) {
log.warn("Unable to send the flow {} to the queue", flow.uid(), e);
}
});
}
}
}

View File

@@ -1,6 +1,7 @@
package io.kestra.cli.commands.plugins;
import io.kestra.core.contexts.MavenPluginRepositoryConfig;
import io.kestra.core.exceptions.KestraRuntimeException;
import io.kestra.core.plugins.LocalPluginManager;
import io.kestra.core.plugins.MavenPluginDownloader;
import io.kestra.core.plugins.PluginArtifact;
@@ -51,7 +52,7 @@ public class PluginInstallCommand extends AbstractCommand {
Provider<MavenPluginDownloader> mavenPluginRepositoryProvider;
@Inject
@Client("api") HttpClient httpClient;
Provider<PluginCatalogService> pluginCatalogService;
@Override
public Integer call() throws Exception {
@@ -85,7 +86,7 @@ public class PluginInstallCommand extends AbstractCommand {
}
if (all) {
PluginCatalogService service = new PluginCatalogService(httpClient, false, true);
PluginCatalogService service = pluginCatalogService.get();
dependencies = service.get().stream().map(Objects::toString).toList();
}
@@ -103,12 +104,21 @@ public class PluginInstallCommand extends AbstractCommand {
}
try (final PluginManager pluginManager = getPluginManager()) {
List<PluginArtifact> installed = pluginManager.install(
pluginArtifacts,
repositoryConfigs,
false,
pluginsPath
);
List<PluginArtifact> installed;
if (all) {
installed = new ArrayList<>(pluginArtifacts.size());
for (PluginArtifact pluginArtifact : pluginArtifacts) {
try {
installed.add(pluginManager.install(pluginArtifact, repositoryConfigs, false, pluginsPath));
} catch (KestraRuntimeException e) {
String cause = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
stdErr("Failed to install plugin {0}. Cause: {1}", pluginArtifact, cause);
}
}
} else {
installed = pluginManager.install(pluginArtifacts, repositoryConfigs, false, pluginsPath);
}
List<URI> uris = installed.stream().map(PluginArtifact::uri).toList();
stdOut("Successfully installed plugins {0} into {1}", dependencies, uris);

View File

@@ -98,7 +98,7 @@ public class StandAloneCommand extends AbstractServerCommand {
if (flowPath != null) {
try {
LocalFlowRepositoryLoader localFlowRepositoryLoader = applicationContext.getBean(LocalFlowRepositoryLoader.class);
localFlowRepositoryLoader.load(this.flowPath);
localFlowRepositoryLoader.load(null, this.flowPath);
} catch (IOException e) {
throw new CommandLine.ParameterException(this.spec.commandLine(), "Invalid flow path", e);
}

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);
}
@@ -189,6 +193,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 +238,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

@@ -15,7 +15,7 @@ public class LocalFlowFileWatcher implements FlowFilesManager {
@Override
public FlowWithSource createOrUpdateFlow(final GenericFlow flow) {
return flowRepository.findById(null, flow.getNamespace(), flow.getId())
return flowRepository.findById(flow.getTenantId(), flow.getNamespace(), flow.getId())
.map(previous -> flowRepository.update(flow, previous))
.orElseGet(() -> flowRepository.create(flow));
}

View File

@@ -15,6 +15,9 @@ micronaut:
static:
paths: classpath:static
mapping: /static/**
root:
paths: classpath:root
mapping: /**
server:
max-request-size: 10GB
multipart:
@@ -26,11 +29,11 @@ micronaut:
netty:
max-chunk-size: 10MB
max-header-size: 32768 # increased from the default of 8k
responses:
file:
cache-seconds: 86400
cache-control:
public: true
responses:
file:
cache-seconds: 86400
cache-control:
public: true
# Access log configuration, see https://docs.micronaut.io/latest/guide/index.html#accessLogger
access-logger:
@@ -138,8 +141,8 @@ kestra:
jdbc:
queues:
min-poll-interval: 25ms
max-poll-interval: 1000ms
poll-switch-interval: 5s
max-poll-interval: 500ms
poll-switch-interval: 60s
cleaner:
initial-delay: 1h
@@ -195,13 +198,18 @@ kestra:
liveness:
enabled: true
# The expected time between liveness probe.
interval: 5s
interval: 10s
# The timeout used to detect service failures.
timeout: 45s
timeout: 1m
# The time to wait before executing a liveness probe.
initialDelay: 45s
initialDelay: 1m
# The expected time between service heartbeats.
heartbeatInterval: 3s
service:
purge:
initial-delay: 1h
fixed-delay: 1d
retention: 30d
anonymous-usage-report:
enabled: true
uri: https://api.kestra.io/v1/reports/usages

View File

@@ -4,11 +4,14 @@ import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.Yaml;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable;
class ConfigPropertiesCommandTest {
@Test
@@ -23,4 +26,48 @@ class ConfigPropertiesCommandTest {
assertThat(out.toString()).contains("- test");
}
}
@Test
void shouldOutputCustomEnvironment() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, "custom-env")) {
PicocliRunner.call(ConfigPropertiesCommand.class, ctx);
assertThat(out.toString()).contains("activeEnvironments:");
assertThat(out.toString()).contains("- custom-env");
}
}
@Test
void shouldReturnZeroOnSuccess() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
ConfigPropertiesCommand cmd = ctx.createBean(ConfigPropertiesCommand.class);
int result = cmd.call();
assertThat(result).isZero();
}
}
@Test
void shouldOutputValidYaml() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
PicocliRunner.call(ConfigPropertiesCommand.class, ctx);
String output = out.toString();
Yaml yaml = new Yaml();
Throwable thrown = catchThrowable(() -> {
Map<?, ?> parsed = yaml.load(output);
assertThat(parsed).isInstanceOf(Map.class);
});
assertThat(thrown).isNull();
}
}
}

View File

@@ -142,7 +142,7 @@ class FlowUpdatesCommandTest {
};
PicocliRunner.call(FlowUpdatesCommand.class, ctx, args);
assertThat(out.toString()).contains("Invalid entity: flow.namespace: io.kestra.outsider_quattro_-1 - flow namespace is invalid");
assertThat(out.toString()).contains("Invalid entity: flow.namespace: main_io.kestra.outsider_quattro_-1 - flow namespace is invalid");
}
}

View File

@@ -12,12 +12,11 @@ import java.net.URL;
import static org.assertj.core.api.Assertions.assertThat;
public class SingleFlowCommandsTest {
class SingleFlowCommandsTest {
@Test
void all() {
URL flow = SingleFlowCommandsTest.class.getClassLoader().getResource("flows/quattro.yml");
URL flow = SingleFlowCommandsTest.class.getClassLoader().getResource("crudFlow/date.yml");
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
@@ -26,19 +25,6 @@ public class SingleFlowCommandsTest {
EmbeddedServer embeddedServer = ctx.getBean(EmbeddedServer.class);
embeddedServer.start();
String[] deleteArgs = {
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word",
"io.kestra.outsider",
"quattro"
};
PicocliRunner.call(FlowDeleteCommand.class, ctx, deleteArgs);
assertThat(out.toString()).contains("Flow successfully deleted !");
out.reset();
String[] createArgs = {
"--server",
embeddedServer.getURL().toString(),
@@ -50,21 +36,34 @@ public class SingleFlowCommandsTest {
assertThat(out.toString()).contains("Flow successfully created !");
out.reset();
out.reset();String[] updateArgs = {
String[] updateArgs = {
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word",
flow.getPath(),
"io.kestra.outsider",
"quattro"
"io.kestra.cli",
"date"
};
PicocliRunner.call(FlowUpdateCommand.class, ctx, updateArgs);
assertThat(out.toString()).contains("Flow successfully updated !");
out.reset();
String[] deleteArgs = {
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word",
"io.kestra.cli",
"date"
};
PicocliRunner.call(FlowDeleteCommand.class, ctx, deleteArgs);
assertThat(out.toString()).contains("Flow successfully deleted !");
}
}
}

View File

@@ -16,6 +16,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
class KvUpdateCommandTest {
@@ -40,7 +41,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("string").get()).isEqualTo(new KVValue("stringValue"));
assertThat(((InternalKVStore) kvStore).getRawValue("string").get()).isEqualTo("\"stringValue\"");
@@ -68,7 +69,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("int").get()).isEqualTo(new KVValue(1));
assertThat(((InternalKVStore) kvStore).getRawValue("int").get()).isEqualTo("1");
@@ -98,7 +99,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("intStr").get()).isEqualTo(new KVValue("1"));
assertThat(((InternalKVStore) kvStore).getRawValue("intStr").get()).isEqualTo("\"1\"");
@@ -126,7 +127,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("object").get()).isEqualTo(new KVValue(Map.of("some", "json")));
assertThat(((InternalKVStore) kvStore).getRawValue("object").get()).isEqualTo("{some:\"json\"}");
@@ -156,7 +157,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("objectStr").get()).isEqualTo(new KVValue("{\"some\":\"json\"}"));
assertThat(((InternalKVStore) kvStore).getRawValue("objectStr").get()).isEqualTo("\"{\\\"some\\\":\\\"json\\\"}\"");
@@ -190,7 +191,7 @@ class KvUpdateCommandTest {
PicocliRunner.call(KvUpdateCommand.class, ctx, args);
KVStoreService kvStoreService = ctx.getBean(KVStoreService.class);
KVStore kvStore = kvStoreService.get(null, "io.kestra.cli", null);
KVStore kvStore = kvStoreService.get(MAIN_TENANT, "io.kestra.cli", null);
assertThat(kvStore.getValue("objectFromFile").get()).isEqualTo(new KVValue(Map.of("some", "json", "from", "file")));
assertThat(((InternalKVStore) kvStore).getRawValue("objectFromFile").get()).isEqualTo("{some:\"json\",from:\"file\"}");

View File

@@ -23,4 +23,32 @@ class PluginCommandTest {
assertThat(out.toString()).contains("Usage: kestra plugins");
}
}
}
// Additional Coverage:
@Test
void shouldListSubcommandsInHelp() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(out));
try {
PluginCommand cmd = new PluginCommand();
cmd.call();
String output = out.toString();
assertThat(output).contains("install");
assertThat(output).contains("uninstall");
assertThat(output).contains("list");
assertThat(output).contains("doc");
assertThat(output).contains("search");
} finally {
System.setOut(originalOut);
}
}
// Passes
@Test
void shouldNotLoadExternalPlugins() {
PluginCommand cmd = new PluginCommand();
assertThat(cmd.loadExternalPlugins()).isFalse();
}
}

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

@@ -18,6 +18,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static io.kestra.core.utils.Rethrow.throwRunnable;
import static org.assertj.core.api.Assertions.assertThat;
@@ -43,6 +44,7 @@ class FileChangedEventListenerTest {
@AfterAll
static void tearDown() throws IOException {
if (Files.exists(Path.of(FILE_WATCH))) {
FileUtils.cleanDirectory(Path.of(FILE_WATCH).toFile());
FileUtils.deleteDirectory(Path.of(FILE_WATCH).toFile());
}
}
@@ -57,7 +59,7 @@ class FileChangedEventListenerTest {
@RetryingTest(5) // Flaky on CI but always pass locally
void test() throws IOException, TimeoutException {
// remove the flow if it already exists
flowRepository.findByIdWithSource(null, "io.kestra.tests.watch", "myflow").ifPresent(flow -> flowRepository.delete(flow));
flowRepository.findByIdWithSource(MAIN_TENANT, "io.kestra.tests.watch", "myflow").ifPresent(flow -> flowRepository.delete(flow));
// create a basic flow
String flow = """
@@ -71,11 +73,11 @@ class FileChangedEventListenerTest {
""";
Files.write(Path.of(FILE_WATCH + "/myflow.yaml"), flow.getBytes());
Await.until(
() -> flowRepository.findById(null, "io.kestra.tests.watch", "myflow").isPresent(),
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").isPresent(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
Flow myflow = flowRepository.findById(null, "io.kestra.tests.watch", "myflow").orElseThrow();
Flow myflow = flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").orElseThrow();
assertThat(myflow.getTasks()).hasSize(1);
assertThat(myflow.getTasks().getFirst().getId()).isEqualTo("hello");
assertThat(myflow.getTasks().getFirst().getType()).isEqualTo("io.kestra.plugin.core.log.Log");
@@ -83,7 +85,7 @@ class FileChangedEventListenerTest {
// delete the flow
Files.delete(Path.of(FILE_WATCH + "/myflow.yaml"));
Await.until(
() -> flowRepository.findById(null, "io.kestra.tests.watch", "myflow").isEmpty(),
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").isEmpty(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
@@ -92,7 +94,7 @@ class FileChangedEventListenerTest {
@RetryingTest(5) // Flaky on CI but always pass locally
void testWithPluginDefault() throws IOException, TimeoutException {
// remove the flow if it already exists
flowRepository.findByIdWithSource(null, "io.kestra.tests.watch", "pluginDefault").ifPresent(flow -> flowRepository.delete(flow));
flowRepository.findByIdWithSource(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").ifPresent(flow -> flowRepository.delete(flow));
// create a flow with plugin default
String pluginDefault = """
@@ -110,11 +112,11 @@ class FileChangedEventListenerTest {
""";
Files.write(Path.of(FILE_WATCH + "/plugin-default.yaml"), pluginDefault.getBytes());
Await.until(
() -> flowRepository.findById(null, "io.kestra.tests.watch", "pluginDefault").isPresent(),
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").isPresent(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
Flow pluginDefaultFlow = flowRepository.findById(null, "io.kestra.tests.watch", "pluginDefault").orElseThrow();
Flow pluginDefaultFlow = flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").orElseThrow();
assertThat(pluginDefaultFlow.getTasks()).hasSize(1);
assertThat(pluginDefaultFlow.getTasks().getFirst().getId()).isEqualTo("helloWithDefault");
assertThat(pluginDefaultFlow.getTasks().getFirst().getType()).isEqualTo("io.kestra.plugin.core.log.Log");
@@ -122,7 +124,7 @@ class FileChangedEventListenerTest {
// delete both files
Files.delete(Path.of(FILE_WATCH + "/plugin-default.yaml"));
Await.until(
() -> flowRepository.findById(null, "io.kestra.tests.watch", "pluginDefault").isEmpty(),
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").isEmpty(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);

View File

@@ -2,6 +2,7 @@ micronaut:
io:
watch:
enabled: true
tenantId: main
paths:
- build/file-watch

View File

@@ -0,0 +1,7 @@
id: date
namespace: io.kestra.cli
tasks:
- id: date
type: io.kestra.plugin.core.debug.Return
format: "{{taskrun.startDate}}"

View File

@@ -36,6 +36,7 @@ dependencies {
implementation group: 'de.focus-shift', name: 'jollyday-jaxb'
implementation 'nl.basjes.gitignore:gitignore-reader'
implementation group: 'dev.failsafe', name: 'failsafe'
implementation 'com.github.ben-manes.caffeine:caffeine'
api 'org.apache.httpcomponents.client5:httpclient5'
// plugins
@@ -73,7 +74,7 @@ dependencies {
testImplementation "io.micronaut:micronaut-http-server-netty"
testImplementation "io.micronaut:micronaut-management"
testImplementation "org.testcontainers:testcontainers:1.20.6"
testImplementation "org.testcontainers:junit-jupiter:1.20.6"
testImplementation "org.bouncycastle:bcpkix-jdk18on:1.80"
testImplementation "org.testcontainers:testcontainers:1.21.1"
testImplementation "org.testcontainers:junit-jupiter:1.21.1"
testImplementation "org.bouncycastle:bcpkix-jdk18on:1.81"
}

View File

@@ -0,0 +1,92 @@
package io.kestra.core.cache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Policy;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
/**
* A No-Op implementation of a Caffeine Cache.
* Useful to disable caching but still use a cache to avoid if/else chains
*/
public class NoopCache<K, V> implements Cache<K, V> {
private static final ConcurrentMap<?, ?> EMPTY_MAP = new ConcurrentHashMap<>(0);
@Override
public @Nullable V getIfPresent(K key) {
return null;
}
@Override
public V get(K key, Function<? super K, ? extends V> mappingFunction) {
return mappingFunction.apply(key);
}
@Override
public Map<K, @NonNull V> getAllPresent(Iterable<? extends K> keys) {
return Collections.emptyMap();
}
@Override
public Map<K, @NonNull V> getAll(Iterable<? extends K> keys, Function<? super Set<? extends K>, ? extends Map<? extends K, ? extends @NonNull V>> mappingFunction) {
return Collections.emptyMap();
}
@Override
public void put(K key, @NonNull V value) {
// just do nothing
}
@Override
public void putAll(Map<? extends K, ? extends @NonNull V> map) {
// just do nothing
}
@Override
public void invalidate(K key) {
// just do nothing
}
@Override
public void invalidateAll(Iterable<? extends K> keys) {
// just do nothing
}
@Override
public void invalidateAll() {
// just do nothing
}
@Override
public long estimatedSize() {
return 0;
}
@Override
public CacheStats stats() {
return CacheStats.empty();
}
@Override
public ConcurrentMap<K, @NonNull V> asMap() {
return (ConcurrentMap<K, V>) EMPTY_MAP;
}
@Override
public void cleanUp() {
// just do nothing
}
@Override
public Policy<K, @NonNull V> policy() {
throw new UnsupportedOperationException();
}
}

View File

@@ -2,6 +2,7 @@ package io.kestra.core.contexts;
import io.kestra.core.exceptions.KestraRuntimeException;
import io.kestra.core.plugins.DefaultPluginRegistry;
import io.kestra.core.plugins.PluginCatalogService;
import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.storages.StorageInterfaceFactory;
@@ -13,6 +14,8 @@ import io.micronaut.context.annotation.Value;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.convert.format.MapFormat;
import io.micronaut.core.naming.conventions.StringConvention;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.Validator;
@@ -35,6 +38,11 @@ public class KestraBeansFactory {
@Value("${kestra.storage.type}")
protected Optional<String> storageType;
@Singleton
public PluginCatalogService pluginCatalogService(@Client("api") HttpClient httpClient) {
return new PluginCatalogService(httpClient, false, true);
}
@Requires(missingBeans = PluginRegistry.class)
@Singleton
public PluginRegistry pluginRegistry() {

View File

@@ -2,11 +2,13 @@ package io.kestra.core.contexts;
import io.kestra.core.models.ServerType;
import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.VersionProvider;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Context;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.env.Environment;
import io.micronaut.context.env.PropertySource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -80,6 +82,8 @@ public abstract class KestraContext {
*/
public abstract PluginRegistry getPluginRegistry();
public abstract StorageInterface getStorageInterface();
/**
* Shutdowns the Kestra application.
*/
@@ -146,7 +150,7 @@ public abstract class KestraContext {
.ifPresent(val -> configs.put(KESTRA_WORKER_GROUP_KEY, val));
if (!configs.isEmpty()) {
environment.addPropertySource("kestra-runtime", configs);
environment.addPropertySource(PropertySource.of("kestra-runtime", configs));
}
}
@@ -172,5 +176,11 @@ public abstract class KestraContext {
// Lazy init of the PluginRegistry.
return this.applicationContext.getBean(PluginRegistry.class);
}
@Override
public StorageInterface getStorageInterface() {
// Lazy init of the PluginRegistry.
return this.applicationContext.getBean(StorageInterface.class);
}
}
}

View File

@@ -1,9 +1,6 @@
package io.kestra.core.docs;
import com.google.common.base.CaseFormat;
import io.kestra.core.models.Plugin;
import io.kestra.core.models.tasks.retrys.AbstractRetry;
import io.kestra.core.models.tasks.runners.TaskRunner;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -59,7 +56,7 @@ public abstract class AbstractClassDocumentation<T> {
.filter(entry -> (baseCls == null) || !entry.getKey().startsWith("io.kestra.core.models.flows.input."))
.map(entry -> {
Map<String, Object> value = (Map<String, Object>) entry.getValue();
value.put("properties", flatten(properties(value), required(value), isTypeToKeep(entry.getKey())));
value.put("properties", flatten(properties(value), required(value), null));
return new AbstractMap.SimpleEntry<>(
entry.getKey(),
@@ -92,20 +89,13 @@ public abstract class AbstractClassDocumentation<T> {
}
if (this.propertiesSchema.containsKey("properties")) {
this.inputs = flatten(properties(this.propertiesSchema), required(this.propertiesSchema));
this.inputs = flattenWithoutType(properties(this.propertiesSchema), required(this.propertiesSchema));
}
}
protected static Map<String, Object> flatten(Map<String, Object> map, List<String> required) {
protected static Map<String, Object> flattenWithoutType(Map<String, Object> map, List<String> required) {
map.remove("type");
return flatten(map, required, (String) null);
}
protected static Map<String, Object> flatten(Map<String, Object> map, List<String> required, Boolean keepType) {
if (!keepType) {
map.remove("type");
}
return flatten(map, required, (String) null);
return flatten(map, required, null);
}
@SuppressWarnings("unchecked")
@@ -141,23 +131,6 @@ public abstract class AbstractClassDocumentation<T> {
return result;
}
// Some task can have the `type` property but not to represent the task
// so we cant to keep it in the doc
private Boolean isTypeToKeep(String key){
try {
if (AbstractRetry.class.isAssignableFrom(Class.forName(key))) {
return true;
}
if (TaskRunner.class.isAssignableFrom(Class.forName(key))) {
return true;
}
} catch (ClassNotFoundException ignored) {
log.debug(ignored.getMessage(), ignored);
}
return false;
}
protected static String flattenKey(String current, String parent) {
return (parent != null ? parent + "." : "") + current;
}

View File

@@ -1,9 +1,14 @@
package io.kestra.core.docs;
import io.kestra.core.plugins.PluginClassAndMetadata;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@Getter
@EqualsAndHashCode
@@ -50,7 +55,7 @@ public class ClassPluginDocumentation<T> extends AbstractClassDocumentation<T> {
}
if (this.outputsSchema.containsKey("properties")) {
this.outputs = flatten(properties(this.outputsSchema), required(this.outputsSchema));
this.outputs = flattenWithoutType(properties(this.outputsSchema), required(this.outputsSchema));
}
// metrics

View File

@@ -7,6 +7,7 @@ import io.kestra.core.models.tasks.logs.LogExporter;
import io.kestra.core.models.tasks.runners.TaskRunner;
import io.kestra.core.models.tasks.Task;
import io.kestra.core.models.triggers.AbstractTrigger;
import io.kestra.core.plugins.AdditionalPlugin;
import io.kestra.core.plugins.PluginClassAndMetadata;
import io.kestra.core.plugins.RegisteredPlugin;
import io.kestra.core.runners.pebble.Extension;
@@ -75,6 +76,7 @@ public class DocumentationGenerator {
//noinspection unchecked
result.addAll(this.generate(registeredPlugin, registeredPlugin.getTaskRunners(), (Class) TaskRunner.class, "task-runners"));
result.addAll(this.generate(registeredPlugin, registeredPlugin.getLogExporters(), (Class) LogExporter.class, "log-exporters"));
result.addAll(this.generate(registeredPlugin, registeredPlugin.getAdditionalPlugins(), AdditionalPlugin.class, "additional-plugins"));
result.addAll(guides(registeredPlugin));

View File

@@ -2,6 +2,7 @@ package io.kestra.core.docs;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.members.HierarchicType;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -23,8 +24,10 @@ import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.conditions.Condition;
import io.kestra.core.models.conditions.ScheduleCondition;
import io.kestra.core.models.dashboards.DataFilter;
import io.kestra.core.models.dashboards.DataFilterKPI;
import io.kestra.core.models.dashboards.charts.Chart;
import io.kestra.core.models.dashboards.charts.DataChart;
import io.kestra.core.models.dashboards.charts.DataChartKPI;
import io.kestra.core.models.property.Data;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.Output;
@@ -33,6 +36,7 @@ import io.kestra.core.models.tasks.common.EncryptedString;
import io.kestra.core.models.tasks.logs.LogExporter;
import io.kestra.core.models.tasks.runners.TaskRunner;
import io.kestra.core.models.triggers.AbstractTrigger;
import io.kestra.core.plugins.AdditionalPlugin;
import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.plugins.RegisteredPlugin;
import io.kestra.core.serializers.JacksonMapper;
@@ -54,6 +58,7 @@ import static io.kestra.core.serializers.JacksonMapper.MAP_TYPE_REFERENCE;
@Singleton
public class JsonSchemaGenerator {
private static final List<Class<?>> TYPES_RESOLVED_AS_STRING = List.of(Duration.class, LocalTime.class, LocalDate.class, LocalDateTime.class, ZonedDateTime.class, OffsetDateTime.class, OffsetTime.class);
private static final List<Class<?>> SUBTYPE_RESOLUTION_EXCLUSION_FOR_PLUGIN_SCHEMA = List.of(Task.class, AbstractTrigger.class);
private static final ObjectMapper MAPPER = JacksonMapper.ofJson().copy()
.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
@@ -127,6 +132,15 @@ public class JsonSchemaGenerator {
}
}
});
// do the same for all definitions
if (objectNode.get("definitions") instanceof ObjectNode definitions) {
definitions.forEach(jsonNode -> {
if (jsonNode instanceof ObjectNode definition) {
removeRequiredOnPropsWithDefaults(definition);
}
});
}
}
// This hack exists because for Property we generate a anyOf for properties that are not strings.
@@ -237,15 +251,12 @@ public class JsonSchemaGenerator {
.with(Option.DEFINITIONS_FOR_ALL_OBJECTS)
.with(Option.DEFINITION_FOR_MAIN_SCHEMA)
.with(Option.PLAIN_DEFINITION_KEYS)
.with(Option.ALLOF_CLEANUP_AT_THE_END);
.with(Option.ALLOF_CLEANUP_AT_THE_END);;
if (!draft7) {
builder
.with(new JacksonModule(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM))
.with(Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES);
builder.with(new JacksonModule(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM));
} else {
builder
.with(new JacksonModule());
builder.with(new JacksonModule());
}
// default value
@@ -345,6 +356,9 @@ public class JsonSchemaGenerator {
if (pluginPropertyAnnotation.internalStorageURI()) {
memberAttributes.put("$internalStorageURI", true);
}
if (!pluginPropertyAnnotation.group().isEmpty()) {
memberAttributes.put("$group", pluginPropertyAnnotation.group());
}
}
Schema schema = member.getAnnotationConsideringFieldAndGetter(Schema.class);
@@ -436,8 +450,8 @@ public class JsonSchemaGenerator {
return Object.class;
});
// Subtype resolver for all plugins
if (builder.build().getSchemaVersion() != SchemaVersion.DRAFT_2019_09) {
// Subtype resolver for all plugins
builder.forTypesInGeneral()
.withSubtypeResolver((declaredType, context) -> {
TypeContext typeContext = context.getTypeContext();
@@ -510,21 +524,87 @@ public class JsonSchemaGenerator {
collectedTypeAttributes.remove("$examples");
}
});
} else {
builder.forTypesInGeneral()
.withSubtypeResolver((declaredType, context) -> {
TypeContext typeContext = context.getTypeContext();
// Ensure that `type` is defined as a constant in JSON Schema.
// The `const` property is used by editors for auto-completion based on that schema.
builder.forTypesInGeneral().withTypeAttributeOverride((collectedTypeAttributes, scope, context) -> {
final Class<?> pluginType = scope.getType().getErasedType();
if (pluginType.getAnnotation(Plugin.class) != null) {
ObjectNode properties = (ObjectNode) collectedTypeAttributes.get("properties");
if (properties != null) {
properties.set("type", context.getGeneratorConfig().createObjectNode()
.put("const", pluginType.getName())
);
if (SUBTYPE_RESOLUTION_EXCLUSION_FOR_PLUGIN_SCHEMA.contains(declaredType.getErasedType())) {
return null;
}
}
});
return this.subtypeResolver(declaredType, typeContext);
});
}
// Ensure that `type` is defined as a constant in JSON Schema.
// The `const` property is used by editors for auto-completion based on that schema.
builder.forTypesInGeneral().withTypeAttributeOverride((collectedTypeAttributes, scope, context) -> {
final Class<?> pluginType = scope.getType().getErasedType();
if (pluginType.getAnnotation(Plugin.class) != null) {
ObjectNode properties = (ObjectNode) collectedTypeAttributes.get("properties");
if (properties != null) {
properties.set("type", context.getGeneratorConfig().createObjectNode()
.put("const", pluginType.getName())
);
}
}
});
typeDefiningPropertiesToConst(builder);
}
/**
* Properties which are defining an implementation to choose among multiple ones (JsonTypeInfo.property) are simple String with default. We move them to be a "const": "defaultValue" instead
*/
private void typeDefiningPropertiesToConst(SchemaGeneratorConfigBuilder builder) {
builder.forTypesInGeneral().withTypeAttributeOverride((collectedTypeAttributes, scope, context) -> {
final Class<?> targetType = scope.getType().getErasedType();
JsonTypeInfo jsonTypeInfo = Optional.ofNullable(targetType.getSuperclass()).map(c -> c.getAnnotation(JsonTypeInfo.class)).orElse(null);
if (jsonTypeInfo == null) {
return;
}
String property = jsonTypeInfo.property();
if (property == null) {
return;
}
ObjectNode properties = (ObjectNode) collectedTypeAttributes.get("properties");
if (properties == null) {
return;
}
String defaultValue = Optional.ofNullable(properties.get(property))
.flatMap(p -> {
Optional<String> defaultOpt = p.optional("default").map(JsonNode::asText);
if (defaultOpt.isPresent()) {
return defaultOpt;
}
return p.optional("allOf").flatMap(node -> {
if (node.isArray()) {
Iterable<JsonNode> iterable = node::values;
return StreamSupport.stream(
iterable.spliterator(),
false
).filter(subNode -> subNode.has("default"))
.findFirst()
.map(subNode -> subNode.get("default").asText());
}
return Optional.empty();
});
})
.orElse(null);
if (defaultValue == null) {
return;
}
properties.set(property, context.getGeneratorConfig().createObjectNode()
.put("const", defaultValue)
);
});
}
private boolean isAssignableFromResolvedAsString(Class<?> declaredType) {
@@ -580,6 +660,16 @@ public class JsonSchemaGenerator {
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.map(typeContext::resolve)
.toList();
} else if (AdditionalPlugin.class.isAssignableFrom(declaredType.getErasedType())) { // base type for addition plugin is not AdditionalPlugin but a subtype of AdditionalPlugin.
return getRegisteredPlugins()
.stream()
.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(cls -> cls != declaredType.getErasedType())
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.map(typeContext::resolve)
.toList();
} else if (declaredType.getErasedType() == Chart.class) {
return getRegisteredPlugins()
.stream()
@@ -595,10 +685,25 @@ public class JsonSchemaGenerator {
TypeVariable<? extends Class<? extends Chart<?>>> dataFilterType = clz.getTypeParameters()[1];
ParameterizedType chartAwareColumnDescriptor = ((ParameterizedType) ((WildcardType) ((ParameterizedType) dataFilterType.getBounds()[0]).getActualTypeArguments()[1]).getUpperBounds()[0]);
dataFilters.forEach(dataFilter -> {
Type fieldsEnum = ((ParameterizedType) dataFilter.getGenericSuperclass()).getActualTypeArguments()[0];
consumer.accept(typeContext.resolve(clz, fieldsEnum, typeContext.resolve(dataFilter, typeContext.resolve(chartAwareColumnDescriptor, fieldsEnum))));
});
} else if (DataChartKPI.class.isAssignableFrom(clz)) {
List<Class<? extends DataFilterKPI<?, ?>>> dataFilterKPIs = getRegisteredPlugins()
.stream()
.flatMap(registeredPlugin -> registeredPlugin.getDataFiltersKPI().stream())
.filter(Predicate.not(io.kestra.core.models.Plugin::isInternal))
.toList();
TypeVariable<? extends Class<? extends Chart<?>>> dataFilterType = clz.getTypeParameters()[1];
ParameterizedType chartAwareColumnDescriptor = ((ParameterizedType) ((WildcardType) ((ParameterizedType) dataFilterType.getBounds()[0]).getActualTypeArguments()[1]).getUpperBounds()[0]);
dataFilterKPIs.forEach(dataFilterKPI -> {
Type fieldsEnum = ((ParameterizedType) dataFilterKPI.getGenericSuperclass()).getActualTypeArguments()[0];
consumer.accept(typeContext.resolve(clz, fieldsEnum, typeContext.resolve(dataFilterKPI, typeContext.resolve(chartAwareColumnDescriptor, fieldsEnum))));
});
} else {
consumer.accept(typeContext.resolve(clz));
}
@@ -642,10 +747,13 @@ public class JsonSchemaGenerator {
this.build(builder, false);
// we don't return base properties unless specified with @PluginProperty
// we don't return base properties unless specified with @PluginProperty and hidden is false
builder
.forFields()
.withIgnoreCheck(fieldScope -> base != null && fieldScope.getAnnotation(PluginProperty.class) == null && fieldScope.getDeclaringType().getTypeName().equals(base.getName()));
.withIgnoreCheck(fieldScope -> base != null &&
(fieldScope.getAnnotation(PluginProperty.class) == null || fieldScope.getAnnotation(PluginProperty.class).hidden()) &&
fieldScope.getDeclaringType().getTypeName().equals(base.getName())
);
SchemaGeneratorConfig schemaGeneratorConfig = builder.build();

View File

@@ -37,6 +37,7 @@ public class Plugin {
private List<String> charts;
private List<String> dataFilters;
private List<String> logExporters;
private List<String> additionalPlugins;
private List<PluginSubGroup.PluginCategory> categories;
private String subGroup;
@@ -89,17 +90,18 @@ public class Plugin {
plugin.subGroup = subgroup;
Predicate<Class<?>> packagePredicate = c -> subgroup == null || c.getPackageName().equals(subgroup);
plugin.tasks = filterAndGetClassName(registeredPlugin.getTasks(), includeDeprecated, packagePredicate).stream().toList();
plugin.triggers = filterAndGetClassName(registeredPlugin.getTriggers(), includeDeprecated, packagePredicate).stream().toList();
plugin.conditions = filterAndGetClassName(registeredPlugin.getConditions(), includeDeprecated, packagePredicate).stream().toList();
plugin.storages = filterAndGetClassName(registeredPlugin.getStorages(), includeDeprecated, packagePredicate).stream().toList();
plugin.secrets = filterAndGetClassName(registeredPlugin.getSecrets(), includeDeprecated, packagePredicate).stream().toList();
plugin.taskRunners = filterAndGetClassName(registeredPlugin.getTaskRunners(), includeDeprecated, packagePredicate).stream().toList();
plugin.apps = filterAndGetClassName(registeredPlugin.getApps(), includeDeprecated, packagePredicate).stream().toList();
plugin.appBlocks = filterAndGetClassName(registeredPlugin.getAppBlocks(), includeDeprecated, packagePredicate).stream().toList();
plugin.charts = filterAndGetClassName(registeredPlugin.getCharts(), includeDeprecated, packagePredicate).stream().toList();
plugin.dataFilters = filterAndGetClassName(registeredPlugin.getDataFilters(), includeDeprecated, packagePredicate).stream().toList();
plugin.logExporters = filterAndGetClassName(registeredPlugin.getLogExporters(), includeDeprecated, packagePredicate).stream().toList();
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);
return plugin;
}

View File

@@ -9,6 +9,9 @@ import java.util.Map;
@NoArgsConstructor
@AllArgsConstructor
@Data
@io.swagger.v3.oas.annotations.media.Schema(
name = "PluginSchema"
)
public class Schema {
private Map<String, Object> properties;
private Map<String, Object> outputs;

View File

@@ -11,6 +11,7 @@ public enum SchemaType {
TRIGGER,
PLUGINDEFAULT,
APPS,
TESTSUITES,
DASHBOARD;
@JsonCreator

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

@@ -155,6 +155,14 @@ public class HttpClient implements Closeable {
builder.addResponseInterceptorLast(new FailedResponseInterceptor());
}
if (this.configuration.getAllowedResponseCodes() != null) {
List<Integer> list = runContext.render(this.configuration.getAllowedResponseCodes()).asList(Integer.class);
if (!list.isEmpty()) {
builder.addResponseInterceptorLast(new FailedResponseInterceptor(list));
}
}
builder.addResponseInterceptorLast(new RunContextResponseInterceptor(this.runContext));
// builder object
@@ -276,7 +284,7 @@ public class HttpClient implements Closeable {
} else if (cls.isAssignableFrom(Byte[].class)) {
return (T) ArrayUtils.toObject(EntityUtils.toByteArray(entity));
} else {
return (T) JacksonMapper.ofJson().readValue(entity.getContent(), cls);
return (T) JacksonMapper.ofJson(false).readValue(entity.getContent(), cls);
}
}

View File

@@ -3,7 +3,6 @@ package io.kestra.core.http.client.apache;
import io.kestra.core.http.HttpResponse;
import io.kestra.core.http.HttpService;
import io.kestra.core.http.client.HttpClientResponseException;
import lombok.AllArgsConstructor;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.HttpEntityContainer;
import org.apache.hc.core5.http.HttpException;
@@ -12,22 +11,43 @@ import org.apache.hc.core5.http.protocol.HttpContext;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
@AllArgsConstructor
public class FailedResponseInterceptor implements HttpResponseInterceptor {
private final boolean allErrors;
private List<Integer> statusCodes;
public FailedResponseInterceptor() {
this.allErrors = true;
}
public FailedResponseInterceptor(List<Integer> statusCodes) {
this.statusCodes = statusCodes;
this.allErrors = false;
}
@Override
public void process(org.apache.hc.core5.http.HttpResponse response, EntityDetails entity, HttpContext context) throws HttpException, IOException {
if (response.getCode() >= 400) {
String error = "Failed http request with response code '" + response.getCode() + "'";
if (this.allErrors && response.getCode() >= 400) {
this.raiseError(response, context);
}
if (response instanceof HttpEntityContainer httpEntity && httpEntity.getEntity() != null) {
HttpService.HttpEntityCopy copy = HttpService.copy(httpEntity.getEntity());
httpEntity.setEntity(copy);
error += " and body:\n" + new String(copy.getBody(), StandardCharsets.UTF_8);
}
throw new HttpClientResponseException(error, HttpResponse.from(response, context));
if (this.statusCodes != null && !this.statusCodes.contains(response.getCode())) {
this.raiseError(response, context);
}
}
private void raiseError(org.apache.hc.core5.http.HttpResponse response, HttpContext context) throws IOException, HttpClientResponseException {
String error = "Failed http request with response code '" + response.getCode() + "'";
if (response instanceof HttpEntityContainer httpEntity && httpEntity.getEntity() != null) {
HttpService.HttpEntityCopy copy = HttpService.copy(httpEntity.getEntity());
httpEntity.setEntity(copy);
error += " and body:\n" + new String(copy.getBody(), StandardCharsets.UTF_8);
}
throw new HttpClientResponseException(error, HttpResponse.from(response, context));
}
}

View File

@@ -13,6 +13,7 @@ import java.net.Proxy;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
@Builder(toBuilder = true)
@Getter
@@ -35,16 +36,20 @@ public class HttpConfiguration {
@Schema(title = "Whether redirects should be followed automatically.")
@Builder.Default
private Property<Boolean> followRedirects = Property.of(true);
private Property<Boolean> followRedirects = Property.ofValue(true);
@Setter
@Schema(title = "If true, allow a failed response code (response code >= 400)")
@Builder.Default
private Property<Boolean> allowFailed = Property.of(false);
private Property<Boolean> allowFailed = Property.ofValue(false);
@Setter
@Schema(title = "List of response code allowed for this request")
private Property<List<Integer>> allowedResponseCodes;
@Schema(title = "The default charset for the request.")
@Builder.Default
private final Property<Charset> defaultCharset = Property.of(StandardCharsets.UTF_8);
private final Property<Charset> defaultCharset = Property.ofValue(StandardCharsets.UTF_8);
@Schema(title = "The enabled log.")
@PluginProperty
@@ -121,7 +126,7 @@ public class HttpConfiguration {
}
this.timeout = this.timeout.toBuilder()
.connectTimeout(Property.of(connectTimeout))
.connectTimeout(Property.ofValue(connectTimeout))
.build();
return this;
@@ -135,7 +140,7 @@ public class HttpConfiguration {
}
this.timeout = this.timeout.toBuilder()
.readIdleTimeout(Property.of(readTimeout))
.readIdleTimeout(Property.ofValue(readTimeout))
.build();
return this;
@@ -150,7 +155,7 @@ public class HttpConfiguration {
}
this.proxy = this.proxy.toBuilder()
.type(Property.of(proxyType))
.type(Property.ofValue(proxyType))
.build();
return this;
@@ -164,7 +169,7 @@ public class HttpConfiguration {
}
this.proxy = this.proxy.toBuilder()
.address(Property.of(proxyAddress))
.address(Property.ofValue(proxyAddress))
.build();
return this;
@@ -178,7 +183,7 @@ public class HttpConfiguration {
}
this.proxy = this.proxy.toBuilder()
.port(Property.of(proxyPort))
.port(Property.ofValue(proxyPort))
.build();
return this;
@@ -192,7 +197,7 @@ public class HttpConfiguration {
}
this.proxy = this.proxy.toBuilder()
.username(Property.of(proxyUsername))
.username(Property.ofValue(proxyUsername))
.build();
return this;
@@ -206,7 +211,7 @@ public class HttpConfiguration {
}
this.proxy = this.proxy.toBuilder()
.password(Property.of(proxyPassword))
.password(Property.ofValue(proxyPassword))
.build();
return this;
@@ -222,7 +227,7 @@ public class HttpConfiguration {
}
this.auth = ((BasicAuthConfiguration) this.auth).toBuilder()
.username(Property.of(basicAuthUser))
.username(Property.ofValue(basicAuthUser))
.build();
return this;
@@ -237,7 +242,7 @@ public class HttpConfiguration {
}
this.auth = ((BasicAuthConfiguration) this.auth).toBuilder()
.password(Property.of(basicAuthPassword))
.password(Property.ofValue(basicAuthPassword))
.build();
return this;

View File

@@ -14,7 +14,7 @@ import java.net.Proxy;
public class ProxyConfiguration {
@Schema(title = "The type of proxy to use.")
@Builder.Default
private final Property<java.net.Proxy.Type> type = Property.of(Proxy.Type.DIRECT);
private final Property<java.net.Proxy.Type> type = Property.ofValue(Proxy.Type.DIRECT);
@Schema(title = "The address of the proxy server.")
private final Property<String> address;

View File

@@ -15,5 +15,5 @@ public class TimeoutConfiguration {
@Schema(title = "The time allowed for a read connection to remain idle before closing it.")
@Builder.Default
Property<Duration> readIdleTimeout = Property.of(Duration.ofMinutes(5));
Property<Duration> readIdleTimeout = Property.ofValue(Duration.ofMinutes(5));
}

View File

@@ -12,6 +12,7 @@ public class KestraLogFilter extends EventEvaluatorBase<ILoggingEvent> {
// we use startWith and do all checks successfully instead of using a more elegant construct like Stream...
return message.startsWith("outOfOrder mode is active. Migration of schema") ||
message.startsWith("Version mismatch : Database version is older than what dialect POSTGRES supports") ||
message.startsWith("Failed to bind as java.util.concurrent.Executors$AutoShutdownDelegatedExecutorService is unsupported.");
message.startsWith("Failed to bind as java.util.concurrent.Executors$AutoShutdownDelegatedExecutorService is unsupported.") ||
message.startsWith("The cache 'default' is not recording statistics.");
}
}

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,16 +1,15 @@
package io.kestra.core.metrics;
import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.executions.ExecutionKilled;
import io.kestra.core.models.tasks.Task;
import io.kestra.core.models.triggers.AbstractTrigger;
import io.kestra.core.models.triggers.TriggerContext;
import io.kestra.core.runners.SubflowExecutionResult;
import io.kestra.core.runners.WorkerTask;
import io.kestra.core.runners.WorkerTaskResult;
import io.kestra.core.runners.WorkerTrigger;
import io.kestra.core.runners.*;
import io.kestra.core.schedulers.SchedulerExecutionWithTrigger;
import io.micrometer.core.instrument.*;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.search.Search;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@@ -49,13 +48,19 @@ public class MetricRegistry {
public static final String METRIC_WORKER_TRIGGER_ERROR_COUNT_DESCRIPTION = "The total number of trigger evaluations that failed inside the Worker";
public static final String METRIC_WORKER_TRIGGER_EXECUTION_COUNT = "worker.trigger.execution.count";
public static final String METRIC_WORKER_TRIGGER_EXECUTION_COUNT_DESCRIPTION = "The total number of triggers evaluated by the Worker";
public static final String METRIC_WORKER_KILLED_COUNT = "worker.killed.count";
public static final String METRIC_WORKER_KILLED_COUNT_DESCRIPTION = "The total number of executions killed events received the Executor";
public static final String METRIC_EXECUTOR_THREAD_COUNT = "executor.thread.count";
public static final String METRIC_EXECUTOR_THREAD_COUNT_DESCRIPTION = "The number of executor threads";
public static final String METRIC_EXECUTOR_TASKRUN_CREATED_COUNT = "executor.taskrun.created.count";
public static final String METRIC_EXECUTOR_TASKRUN_CREATED_COUNT_DESCRIPTION = "The total number of tasks created by the Executor";
public static final String METRIC_EXECUTOR_TASKRUN_ENDED_COUNT = "executor.taskrun.ended.count";
public static final String METRIC_EXECUTOR_TASKRUN_ENDED_COUNT_DESCRIPTION = "The total number of tasks ended by the Executor";
public static final String METRIC_EXECUTOR_TASKRUN_ENDED_DURATION = "executor.taskrun.ended.duration";
public static final String METRIC_EXECUTOR_TASKRUN_ENDED_DURATION_DESCRIPTION = "Task duration inside the Executor";
public static final String METRIC_EXECUTOR_FLOWABLE_EXECUTION_COUNT = "executor.flowable.execution.count";
public static final String METRIC_EXECUTOR_FLOWABLE_EXECUTION_COUNT_DESCRIPTION = "The total number of flowable tasks executed by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_STARTED_COUNT = "executor.execution.started.count";
public static final String METRIC_EXECUTOR_EXECUTION_STARTED_COUNT_DESCRIPTION = "The total number of executions started by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_END_COUNT = "executor.execution.end.count";
@@ -64,12 +69,29 @@ public class MetricRegistry {
public static final String METRIC_EXECUTOR_EXECUTION_DURATION_DESCRIPTION = "Execution duration inside the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_MESSAGE_PROCESS_DURATION = "executor.execution.message.process";
public static final String METRIC_EXECUTOR_EXECUTION_MESSAGE_PROCESS_DURATION_DESCRIPTION = "Duration of a single execution message processed by the Executor";
public static final String METRIC_EXECUTOR_KILLED_COUNT = "executor.killed.count";
public static final String METRIC_EXECUTOR_KILLED_COUNT_DESCRIPTION = "The total number of executions killed events received the Executor";
public static final String METRIC_EXECUTOR_SLA_EXPIRED_COUNT = "executor.sla.expired.count";
public static final String METRIC_EXECUTOR_SLA_EXPIRED_COUNT_DESCRIPTION = "The total number of expired SLA (i.e. executions with SLA of type MAX_DURATION that took longer than the SLA) evaluated by the Executor";
public static final String METRIC_EXECUTOR_SLA_VIOLATION_COUNT = "executor.sla.violation.count";
public static final String METRIC_EXECUTOR_SLA_VIOLATION_COUNT_DESCRIPTION = "The total number of expired SLA (i.e. executions with SLA of type MAX_DURATION that took longer than the SLA) evaluated by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_DELAY_CREATED_COUNT = "executor.execution.delay.created.count";
public static final String METRIC_EXECUTOR_EXECUTION_DELAY_CREATED_COUNT_DESCRIPTION = "The total number of execution delays created by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_DELAY_ENDED_COUNT = "executor.execution.delay.ended.count";
public static final String METRIC_EXECUTOR_EXECUTION_DELAY_ENDED_COUNT_DESCRIPTION = "The total number of execution delays ended (resumed) by the Executor";
public static final String METRIC_EXECUTOR_WORKER_JOB_RESUBMIT_COUNT = "executor.worker.job.resubmit.count";
public static final String METRIC_EXECUTOR_WORKER_JOB_RESUBMIT_COUNT_DESCRIPTION = "The total number of worker jobs resubmitted to the Worker by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_QUEUED_COUNT = "executor.execution.queued.count";
public static final String METRIC_EXECUTOR_EXECUTION_QUEUED_COUNT_DESCRIPTION = "The total number of executions queued by the Executor";
public static final String METRIC_EXECUTOR_EXECUTION_POPPED_COUNT = "executor.execution.popped.count";
public static final String METRIC_EXECUTOR_EXECUTION_POPPED_COUNT_DESCRIPTION = "The total number of executions popped by the Executor";
public static final String METRIC_INDEXER_REQUEST_COUNT = "indexer.request.count";
public static final String METRIC_INDEXER_REQUEST_COUNT_DESCRIPTION = "Total number of batches of records received by the Indexer";
public static final String METRIC_INDEXER_REQUEST_DURATION = "indexer.request.duration";
public static final String METRIC_INDEXER_REQUEST_DURATION_DESCRIPTION = "Batch of records duration inside the Indexer";
public static final String METRIC_INDEXER_REQUEST_RETRY_COUNT = "indexer.request.retry.count";
public static final String METRIC_INDEXER_REQUEST_RETRY_COUNT_DESCRIPTION = "Total number of batches of records retries by the Indexer";
public static final String METRIC_INDEXER_REQUEST_RETRY_COUNT_DESCRIPTION = "Total number of batches of records retried by the Indexer";
public static final String METRIC_INDEXER_SERVER_DURATION = "indexer.server.duration";
public static final String METRIC_INDEXER_SERVER_DURATION_DESCRIPTION = "Batch of records indexation duration";
public static final String METRIC_INDEXER_MESSAGE_FAILED_COUNT = "indexer.message.failed.count";
@@ -81,6 +103,8 @@ public class MetricRegistry {
public static final String METRIC_SCHEDULER_LOOP_COUNT = "scheduler.loop.count";
public static final String METRIC_SCHEDULER_LOOP_COUNT_DESCRIPTION = "Total number of evaluation loops executed by the Scheduler";
public static final String METRIC_SCHEDULER_TRIGGER_EVALUATION_DURATION = "scheduler.trigger.evaluation.duration";
public static final String METRIC_SCHEDULER_TRIGGER_EVALUATION_DURATION_DESCRIPTION = "Trigger evaluation duration for trigger executed inside the Scheduler (Schedulable triggers)";
public static final String METRIC_SCHEDULER_TRIGGER_COUNT = "scheduler.trigger.count";
public static final String METRIC_SCHEDULER_TRIGGER_COUNT_DESCRIPTION = "Total number of executions triggered by the Scheduler";
public static final String METRIC_SCHEDULER_TRIGGER_DELAY_DURATION = "scheduler.trigger.delay.duration";
@@ -102,6 +126,12 @@ public class MetricRegistry {
public static final String METRIC_QUEUE_BIG_MESSAGE_COUNT = "queue.big_message.count";
public static final String METRIC_QUEUE_BIG_MESSAGE_COUNT_DESCRIPTION = "Total number of big messages";
public static final String METRIC_QUEUE_PRODUCE_COUNT = "queue.produce.count";
public static final String METRIC_QUEUE_PRODUCE_COUNT_DESCRIPTION = "Total number of produced messages";
public static final String METRIC_QUEUE_RECEIVE_DURATION = "queue.receive.duration";
public static final String METRIC_QUEUE_RECEIVE_DURATION_DESCRIPTION = "Queue duration to receive and consume a batch of messages";
public static final String METRIC_QUEUE_POLL_SIZE = "queue.poll.size";
public static final String METRIC_QUEUE_POLL_SIZE_DESCRIPTION = "Size of a poll to the queue (message batch size)";
public static final String TAG_TASK_TYPE = "task_type";
public static final String TAG_TRIGGER_TYPE = "trigger_type";
@@ -112,6 +142,10 @@ public class MetricRegistry {
public static final String TAG_WORKER_GROUP = "worker_group";
public static final String TAG_TENANT_ID = "tenant_id";
public static final String TAG_CLASS_NAME = "class_name";
public static final String TAG_EXECUTION_KILLED_TYPE = "execution_killed_type";
public static final String TAG_QUEUE_CONSUMER = "consumer";
public static final String TAG_QUEUE_CONSUMER_GROUP = "consumer_group";
public static final String TAG_QUEUE_TYPE = "queue_type";
@Inject
private MeterRegistry meterRegistry;
@@ -183,6 +217,14 @@ public class MetricRegistry {
.register(this.meterRegistry);
}
/**
* Search for an existing Meter in the meter registry
* @param name The base metric name
*/
public Search find(String name) {
return this.meterRegistry.find(metricName(name));
}
/**
* Search for an existing Counter in the meter registry
* @param name The base metric name
@@ -316,7 +358,7 @@ public class MetricRegistry {
* Return tags for current {@link AbstractTrigger}
*
* @param trigger the current Trigger
* @return tags to applied to metrics
* @return tags to apply to metrics
*/
public String[] tags(AbstractTrigger trigger) {
return new String[]{
@@ -366,6 +408,19 @@ public class MetricRegistry {
);
}
/**
* Return tags for current {@link ExecutionKilled}
*
* @param executionKilled the current Trigger
* @return tags to apply to metrics
*/
public String[] tags(ExecutionKilled executionKilled) {
var baseTags = new String[]{
TAG_EXECUTION_KILLED_TYPE, executionKilled.getType(),
};
return executionKilled.getTenantId() == null ? baseTags : ArrayUtils.addAll(baseTags, TAG_TENANT_ID, executionKilled.getTenantId());
}
/**
* Return globals tags

View File

@@ -20,6 +20,7 @@ public record Label(@NotNull String key, @NotNull String value) {
public static final String REPLAY = SYSTEM_PREFIX + "replay";
public static final String REPLAYED = SYSTEM_PREFIX + "replayed";
public static final String SIMULATED_EXECUTION = SYSTEM_PREFIX + "simulatedExecution";
public static final String TEST = SYSTEM_PREFIX + "test";
/**
* Static helper method for converting a list of labels to a nested map.

View File

@@ -3,8 +3,10 @@ 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 java.util.ArrayList;
import lombok.Builder;
import java.util.Arrays;
@@ -43,9 +45,13 @@ public record QueryFilter(
STARTS_WITH,
ENDS_WITH,
CONTAINS,
REGEX;
REGEX,
PREFIX
}
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) {
@@ -63,9 +69,9 @@ public record QueryFilter(
case LESS_THAN_OR_EQUAL_TO:
return LessThanOrEqualTo.<T>builder().field(field).value(value).build();
case IN:
return In.<T>builder().field(field).values((List<Object>) value).build();
return In.<T>builder().field(field).values(asValues(value)).build();
case NOT_IN:
return NotIn.<T>builder().field(field).values((List<Object>) value).build();
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:
@@ -74,6 +80,8 @@ public record QueryFilter(
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);
}
@@ -83,7 +91,7 @@ public record QueryFilter(
QUERY("q") {
@Override
public List<Op> supportedOp() {
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.REGEX);
return List.of(Op.EQUALS, Op.NOT_EQUALS);
}
},
SCOPE("scope") {
@@ -95,7 +103,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);
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") {
@@ -107,19 +115,19 @@ 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") {
@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);
}
},
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") {
@@ -131,8 +139,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") {
@@ -211,7 +218,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
);
@@ -220,8 +227,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
);
}
},
@@ -242,7 +249,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
);
}
};
@@ -289,4 +297,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

@@ -22,6 +22,10 @@ import java.util.stream.Stream;
@Jacksonized
@Introspected
public class FlowUsage {
// Namespace used for 'Getting Started' flows.
private static final String TUTORIAL_NAMESPACE = "tutorial";
private final Integer count;
private final Long namespacesCount;
private final Map<String, Long> taskTypeCount;
@@ -37,12 +41,13 @@ public class FlowUsage {
}
public static FlowUsage of(List<Flow> flows) {
List<Flow> filtered = flows.stream().filter(flow -> !TUTORIAL_NAMESPACE.equals(flow.getNamespace())).toList();
return FlowUsage.builder()
.count(count(flows))
.namespacesCount(namespacesCount(flows))
.taskTypeCount(taskTypeCount(flows))
.triggerTypeCount(triggerTypeCount(flows))
.taskRunnerTypeCount(taskRunnerTypeCount(flows))
.count(count(filtered))
.namespacesCount(namespacesCount(filtered))
.taskTypeCount(taskTypeCount(filtered))
.triggerTypeCount(triggerTypeCount(filtered))
.taskRunnerTypeCount(taskRunnerTypeCount(filtered))
.build();
}

View File

@@ -0,0 +1,4 @@
package io.kestra.core.models.collectors;
public record PluginMetric(String type, double count, double totalTime, double meanTime){
}

View File

@@ -2,7 +2,7 @@ package io.kestra.core.models.collectors;
import io.kestra.core.models.ServerType;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
@@ -13,6 +13,7 @@ import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
import java.time.ZoneId;
import java.util.List;
import java.util.Map;
import java.util.Set;
@SuperBuilder(toBuilder = true)
@@ -66,4 +67,8 @@ public class Usage {
@Valid
@Nullable
private ServiceUsage services;
@Valid
@Nullable
private List<PluginMetric> pluginMetrics;
}

View File

@@ -1,7 +1,10 @@
package io.kestra.core.models.dashboards;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -21,6 +24,11 @@ public class ChartOption {
private String description;
@Builder.Default
@Min(1)
@Max(12)
private int width = 6;
public List<String> neededColumns() {
return Collections.emptyList();
}

View File

@@ -4,6 +4,7 @@ import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.dashboards.filters.AbstractFilter;
import io.kestra.core.repositories.QueryBuilderInterface;
import io.kestra.plugin.core.dashboard.data.IData;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
@@ -24,13 +25,12 @@ import java.util.Set;
@NoArgsConstructor
@Plugin
@EqualsAndHashCode
public abstract class DataFilter<F extends Enum<F>, C extends ColumnDescriptor<F>> implements io.kestra.core.models.Plugin {
public abstract class DataFilter<F extends Enum<F>, C extends ColumnDescriptor<F>> implements io.kestra.core.models.Plugin, IData<F> {
@NotNull
@NotBlank
@Pattern(regexp = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*")
private String type;
private Map<String, C> columns;
@Setter
@@ -42,8 +42,10 @@ public abstract class DataFilter<F extends Enum<F>, C extends ColumnDescriptor<F
return Collections.emptySet();
}
public void updateWhereWithGlobalFilters(List<QueryFilter> queryFilterList, ZonedDateTime startDate, ZonedDateTime endDate) {
this.where = whereWithGlobalFilters(queryFilterList, startDate, endDate, this.where);
}
public abstract Class<? extends QueryBuilderInterface<F>> repositoryClass();
public abstract void setGlobalFilter(List<QueryFilter> queryFilterList, ZonedDateTime startDate, ZonedDateTime endDate);
}

View File

@@ -0,0 +1,56 @@
package io.kestra.core.models.dashboards;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.dashboards.filters.AbstractFilter;
import io.kestra.core.repositories.QueryBuilderInterface;
import io.kestra.plugin.core.dashboard.data.IData;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@SuperBuilder(toBuilder = true)
@Getter
@NoArgsConstructor
@Plugin
@EqualsAndHashCode
public abstract class DataFilterKPI<F extends Enum<F>, C extends ColumnDescriptor<F>> implements io.kestra.core.models.Plugin, IData<F> {
@NotNull
@NotBlank
@Pattern(regexp = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*")
private String type;
private C columns;
@Setter
private List<AbstractFilter<F>> numerator;
private List<AbstractFilter<F>> where;
public Set<F> aggregationForbiddenFields() {
return Collections.emptySet();
}
public DataFilterKPI<F, C> clearFilters() {
this.numerator = Collections.emptyList();
return this;
}
public void updateWhereWithGlobalFilters(List<QueryFilter> queryFilterList, ZonedDateTime startDate, ZonedDateTime endDate) {
this.where = whereWithGlobalFilters(queryFilterList, startDate, endDate, this.where);
}
public abstract Class<? extends QueryBuilderInterface<F>> repositoryClass();
}

View File

@@ -0,0 +1,32 @@
package io.kestra.core.models.dashboards.charts;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.dashboards.DataFilterKPI;
import io.kestra.core.validations.DataChartKPIValidation;
import io.kestra.plugin.core.dashboard.chart.kpis.KpiOption;
import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@SuperBuilder(toBuilder = true)
@Getter
@NoArgsConstructor
@Plugin
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@EqualsAndHashCode
@DataChartKPIValidation
public abstract class DataChartKPI<P extends KpiOption, D extends DataFilterKPI<?, ?>> extends Chart<P> implements io.kestra.core.models.Plugin {
@NotNull
private D data;
public Integer minNumberOfAggregations() {
return null;
}
public Integer maxNumberOfAggregations() {
return null;
}
}

View File

@@ -22,10 +22,11 @@ import io.kestra.core.runners.RunContextLogger;
import io.kestra.core.serializers.ListOrMapOfLabelDeserializer;
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.MapUtils;
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.*;
@@ -112,6 +113,13 @@ public class Execution implements DeletedInterface, TenantInterface {
@Setter
String traceParent;
@With
@Nullable
List<TaskFixture> fixtures;
@Nullable
ExecutionKind kind;
/**
* Factory method for constructing a new {@link Execution} object for the given {@link Flow}.
*
@@ -148,6 +156,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));
@@ -210,7 +219,9 @@ public class Execution implements DeletedInterface, TenantInterface {
this.deleted,
this.metadata,
this.scheduleDate,
this.traceParent
this.traceParent,
this.fixtures,
this.kind
);
}
@@ -234,7 +245,9 @@ public class Execution implements DeletedInterface, TenantInterface {
this.deleted,
this.metadata,
this.scheduleDate,
this.traceParent
this.traceParent,
this.fixtures,
this.kind
);
}
@@ -271,7 +284,9 @@ public class Execution implements DeletedInterface, TenantInterface {
this.deleted,
this.metadata,
this.scheduleDate,
this.traceParent
this.traceParent,
this.fixtures,
this.kind
);
}
@@ -295,7 +310,9 @@ public class Execution implements DeletedInterface, TenantInterface {
this.deleted,
this.metadata,
this.scheduleDate,
this.traceParent
this.traceParent,
this.fixtures,
this.kind
);
}
@@ -728,6 +745,16 @@ public class Execution implements DeletedInterface, TenantInterface {
);
}
public Optional<TaskFixture> getFixtureForTaskRun(TaskRun taskRun) {
if (this.fixtures == null) {
return Optional.empty();
}
return this.fixtures.stream()
.filter(fixture -> Objects.equals(fixture.getId(), taskRun.getTaskId()) && Objects.equals(fixture.getValue(), taskRun.getValue()))
.findFirst();
}
/**
* Create a new attempt for failed worker execution
*
@@ -735,7 +762,7 @@ public class Execution implements DeletedInterface, TenantInterface {
* @param e the exception raise
* @return new taskRun with added attempt
*/
private static FailedTaskRunWithLog newAttemptsTaskRunForFailedExecution(TaskRun taskRun,
private FailedTaskRunWithLog newAttemptsTaskRunForFailedExecution(TaskRun taskRun,
Exception e) {
return new FailedTaskRunWithLog(
taskRun
@@ -746,7 +773,7 @@ public class Execution implements DeletedInterface, TenantInterface {
.withState(State.Type.FAILED))
)
.withState(State.Type.FAILED),
RunContextLogger.logEntries(loggingEventFromException(e), LogEntry.of(taskRun))
RunContextLogger.logEntries(loggingEventFromException(e), LogEntry.of(taskRun, kind))
);
}
@@ -758,7 +785,7 @@ public class Execution implements DeletedInterface, TenantInterface {
* @param e the exception raise
* @return new taskRun with updated attempt with logs
*/
private static FailedTaskRunWithLog lastAttemptsTaskRunForFailedExecution(TaskRun taskRun,
private FailedTaskRunWithLog lastAttemptsTaskRunForFailedExecution(TaskRun taskRun,
TaskRunAttempt lastAttempt, Exception e) {
return new FailedTaskRunWithLog(
taskRun
@@ -772,7 +799,7 @@ public class Execution implements DeletedInterface, TenantInterface {
.toList()
)
.withState(State.Type.FAILED),
RunContextLogger.logEntries(loggingEventFromException(e), LogEntry.of(taskRun))
RunContextLogger.logEntries(loggingEventFromException(e), LogEntry.of(taskRun, kind))
);
}
@@ -794,7 +821,7 @@ public class Execution implements DeletedInterface, TenantInterface {
/**
* Transform an exception to {@link ILoggingEvent}
*
* @param e the current execption
* @param e the current exception
* @return the {@link ILoggingEvent} waited to generate {@link LogEntry}
*/
public static ILoggingEvent loggingEventFromException(Exception e) {
@@ -827,10 +854,12 @@ public class Execution implements DeletedInterface, TenantInterface {
.forEach((taskId, taskRuns) -> {
Map<String, Object> taskOutputs = new HashMap<>();
for (TaskRun current : taskRuns) {
if (current.getIteration() != null) {
taskOutputs = MapUtils.merge(taskOutputs, outputs(current, byIds));
} else {
taskOutputs.putAll(outputs(current, byIds));
if (!MapUtils.isEmpty(current.getOutputs())) {
if (current.getIteration() != null) {
taskOutputs = MapUtils.merge(taskOutputs, outputs(current, byIds));
} else {
taskOutputs.putAll(outputs(current, byIds));
}
}
}
result.put(taskId, taskOutputs);

View File

@@ -2,7 +2,6 @@ package io.kestra.core.models.executions;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.triggers.TriggerContext;
import io.kestra.core.runners.WorkerTask;
import jakarta.validation.constraints.NotNull;
import lombok.*;
@@ -25,6 +24,11 @@ public class ExecutionKilledExecution extends ExecutionKilled implements TenantI
@NotNull
String executionId;
/**
* The state to move the execution to after kill.
*/
io.kestra.core.models.flows.State.Type executionState;
/**
* Specifies whether killing the execution, also kill all sub-flow executions.
*/

View File

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

View File

@@ -6,8 +6,8 @@ import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.triggers.AbstractTrigger;
import io.kestra.core.models.triggers.TriggerContext;
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.annotation.Nullable;
import lombok.Builder;
import lombok.Value;
import org.slf4j.event.Level;
@@ -60,6 +60,9 @@ public class LogEntry implements DeletedInterface, TenantInterface {
@Builder.Default
boolean deleted = false;
@Nullable
ExecutionKind executionKind;
public static List<Level> findLevelsByMin(Level minLevel) {
if (minLevel == null) {
return Arrays.asList(Level.values());
@@ -76,10 +79,11 @@ public class LogEntry implements DeletedInterface, TenantInterface {
.namespace(execution.getNamespace())
.flowId(execution.getFlowId())
.executionId(execution.getId())
.executionKind(execution.getKind())
.build();
}
public static LogEntry of(TaskRun taskRun) {
public static LogEntry of(TaskRun taskRun, ExecutionKind executionKind) {
return LogEntry.builder()
.tenantId(taskRun.getTenantId())
.namespace(taskRun.getNamespace())
@@ -88,24 +92,27 @@ public class LogEntry implements DeletedInterface, TenantInterface {
.executionId(taskRun.getExecutionId())
.taskRunId(taskRun.getId())
.attemptNumber(taskRun.attemptNumber())
.executionKind(executionKind)
.build();
}
public static LogEntry of(Flow flow, AbstractTrigger abstractTrigger) {
public static LogEntry of(Flow flow, AbstractTrigger abstractTrigger, ExecutionKind executionKind) {
return LogEntry.builder()
.tenantId(flow.getTenantId())
.namespace(flow.getNamespace())
.flowId(flow.getId())
.triggerId(abstractTrigger.getId())
.executionId(abstractTrigger.getId())
.build();
}
public static LogEntry of(TriggerContext triggerContext, AbstractTrigger abstractTrigger) {
public static LogEntry of(TriggerContext triggerContext, AbstractTrigger abstractTrigger, ExecutionKind executionKind) {
return LogEntry.builder()
.tenantId(triggerContext.getTenantId())
.namespace(triggerContext.getNamespace())
.flowId(triggerContext.getFlowId())
.triggerId(abstractTrigger.getId())
.executionId(abstractTrigger.getId())
.build();
}
@@ -122,7 +129,8 @@ public class LogEntry implements DeletedInterface, TenantInterface {
new AbstractMap.SimpleEntry<>("taskId", this.taskId),
new AbstractMap.SimpleEntry<>("executionId", this.executionId),
new AbstractMap.SimpleEntry<>("taskRunId", this.taskRunId),
new AbstractMap.SimpleEntry<>("triggerId", this.triggerId)
new AbstractMap.SimpleEntry<>("triggerId", this.triggerId),
new AbstractMap.SimpleEntry<>("executionKind", Optional.ofNullable(this.executionKind).map(executionKind -> executionKind.name()).orElse(null) )
)
.filter(e -> e.getValue() != null)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

View File

@@ -5,8 +5,8 @@ import io.kestra.core.models.DeletedInterface;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.executions.metrics.Counter;
import io.kestra.core.models.executions.metrics.Timer;
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.annotation.Nullable;
import lombok.Builder;
import lombok.Value;
@@ -57,7 +57,10 @@ public class MetricEntry implements DeletedInterface, TenantInterface {
@Builder.Default
boolean deleted = false;
public static MetricEntry of(TaskRun taskRun, AbstractMetricEntry<?> metricEntry) {
@Nullable
ExecutionKind executionKind;
public static MetricEntry of(TaskRun taskRun, AbstractMetricEntry<?> metricEntry, ExecutionKind executionKind) {
return MetricEntry.builder()
.tenantId(taskRun.getTenantId())
.namespace(taskRun.getNamespace())
@@ -70,6 +73,7 @@ public class MetricEntry implements DeletedInterface, TenantInterface {
.tags(metricEntry.getTags())
.value(computeValue(metricEntry))
.timestamp(metricEntry.getTimestamp())
.executionKind(executionKind)
.build();
}

View File

@@ -50,8 +50,8 @@ public class TaskRun implements TenantInterface {
List<TaskRunAttempt> attempts;
@With
@JsonInclude(JsonInclude.Include.ALWAYS) // always include outputs so it's easier to reason about in expressions
Map<String, Object> outputs;
@JsonInclude(JsonInclude.Include.ALWAYS)
Variables outputs;
@NotNull
State state;

View File

@@ -1,15 +1,15 @@
package io.kestra.core.models.executions;
import io.kestra.core.models.flows.State;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Value;
import io.kestra.core.models.flows.State;
import lombok.With;
import java.net.URI;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.With;
@Value
@Builder
public class TaskRunAttempt {
@@ -18,18 +18,22 @@ public class TaskRunAttempt {
*/
@Deprecated
public void setMetrics(List<AbstractMetricEntry<?>> metrics) {
}
@NotNull
State state;
@Nullable
String workerId;
@With
@Nullable
URI logFile;
public TaskRunAttempt withState(State.Type state) {
return new TaskRunAttempt(
this.state.withState(state),
this.workerId,
this.logFile
);
}

View File

@@ -0,0 +1,271 @@
package io.kestra.core.models.executions;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.storages.Storage;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.MapUtils;
import io.kestra.core.utils.ReadOnlyDelegatingMap;
import java.io.*;
import java.net.URI;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
import static io.kestra.core.utils.Rethrow.throwBiConsumer;
/**
* A <code>Variables</code> represent a set of output variables.
* Variables can be stored in-memory or inside the internal storage.
* <p>
* The easiest way to construct a <code>Variables</code> object is to use the {@link io.kestra.core.services.VariablesService}.
*
* @see io.kestra.core.services.VariablesService
*/
@JsonSerialize(using = Variables.Serializer.class)
@JsonDeserialize(using = Variables.Deserializer.class)
public sealed interface Variables extends Map<String, Object> {
String TYPE = "io.kestra.datatype:outputs";
Variables EMPTY = new InMemoryVariables(Collections.emptyMap());
/**
* Returns an empty Variables.
*/
static Variables empty() {
return EMPTY;
}
/**
* Creates an InMemoryVariables with an output map.
* This is safer to use {@link io.kestra.core.services.VariablesService#of(io.kestra.core.storages.StorageContext, Map)} instead.
*
* @see InMemoryVariables
* @see io.kestra.core.services.VariablesService
*/
static Variables inMemory(Map<String, Object> outputs) {
if (MapUtils.isEmpty(outputs)) {
return empty();
}
return new InMemoryVariables(outputs);
}
/**
* Creates an InStorageVariables with a {@link Storage} and an output map.
* The output map will be immediately stored inside the internal storage.
*
* @see InStorageVariables
* @see io.kestra.core.services.VariablesService
*/
static Variables inStorage(Storage storage, Map<String, Object> outputs) {
if (MapUtils.isEmpty(outputs)) {
return empty();
}
return new InStorageVariables(storage, outputs);
}
/**
* Creates an InStorageVariables with an internal storage URI.
* The output map will be read lazily from the internal storage URI at access time.
*
* @see InStorageVariables
* @see io.kestra.core.services.VariablesService
*/
static Variables inStorage(StorageContext storageContext, URI uri) {
return new InStorageVariables(storageContext, uri);
}
record StorageContext(String tenantId, String namespace) {}
final class InMemoryVariables extends ReadOnlyDelegatingMap<String, Object> implements Variables {
private final Map<String, Object> delegate;
InMemoryVariables(Map<String, Object> outputs) {
this.delegate = outputs;
}
@Override
protected Map<String, Object> getDelegate() {
return MapUtils.emptyOnNull(delegate);
}
}
final class InStorageVariables extends ReadOnlyDelegatingMap<String, Object> implements Variables {
private static final ObjectMapper ION_MAPPER = JacksonMapper.ofIon();
private final URI storageUri;
private final StorageContext storageContext;
private Map<String, Object> delegate;
private State state;
// we need to store the tenantId and namespace for loading the file from the storage
InStorageVariables(Storage storage, Map<String, Object> outputs) {
// expand the map in case it already contains variable in it
this.delegate = expand(outputs);
this.state = State.DEFLATED;
this.storageContext = new StorageContext(storage.namespace().tenantId(), storage.namespace().namespace());
if (!MapUtils.isEmpty(outputs)) {
try {
File file = Files.createTempFile("output-", ".ion").toFile();
ION_MAPPER.writeValue(file, outputs);
this.storageUri = storage.putFile(file);
} catch (IOException e) {
// FIXME check if we should not declare it
throw new UncheckedIOException(e);
}
} else {
this.storageUri = null;
}
}
InStorageVariables(StorageContext storageContext, URI storageUri) {
this.storageUri = storageUri;
this.state = State.INIT;
this.storageContext = storageContext;
}
URI getStorageUri() {
return storageUri;
}
StorageContext getStorageContext() {
return storageContext;
}
@Override
protected Map<String, Object> getDelegate() {
return loadFromStorage();
}
private Map<String, Object> loadFromStorage() {
if (this.state == State.INIT) {
if (storageUri == null) {
return Collections.emptyMap();
}
StorageInterface storage = KestraContext.getContext().getStorageInterface();
try (InputStream file = storage.get(storageContext.tenantId(), storageContext.namespace(), storageUri)) {
delegate = ION_MAPPER.readValue(file, JacksonMapper.MAP_TYPE_REFERENCE);
state = State.DEFLATED;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
// check all entries to possibly deflate them also
return MapUtils.emptyOnNull(expand(delegate));
}
return MapUtils.emptyOnNull(delegate);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> expand(Map<String, Object> variables) {
if (MapUtils.isEmpty(variables)) {
return variables;
}
return variables.entrySet()
.stream()
.map(entry -> {
if (entry.getValue() instanceof InStorageVariables var) {
return Map.entry(entry.getKey(), (Object) expand(var.loadFromStorage()));
} else if (entry.getValue() instanceof Map<?, ?> map) {
if (TYPE.equals(map.get("type"))) {
String uriString = (String) map.get("storageUri");
if (uriString != null) {
Map<String, String> storageContextMap = (Map<String, String>) map.get("storageContext");
StorageContext storageContext = new StorageContext(storageContextMap.get("tenantId"), storageContextMap.get("namespace"));
URI storageUri = URI.create(uriString);
InStorageVariables inStorage = new InStorageVariables(storageContext, storageUri);
return Map.entry(entry.getKey(), (Object) expand(inStorage.loadFromStorage()));
}
InStorageVariables inStorage = new InStorageVariables((StorageContext) null, null);
return Map.entry(entry.getKey(), (Object) inStorage.loadFromStorage());
}
else {
return Map.entry(entry.getKey(), (Object) expand((Map<String, Object>) map));
}
} else {
return entry;
}
})
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));
}
enum State { INIT, DEFLATED }
}
class Serializer extends StdSerializer<Variables> {
protected Serializer() {
super(Variables.class);
}
@Override
public void serialize(Variables value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
gen.writeNull();
} else {
switch (value) {
case InMemoryVariables inMemory -> {
// we must write entry by entry otherwise nulls are not included
gen.writeStartObject();
inMemory.getDelegate().forEach(throwBiConsumer((k, v) -> gen.writeObjectField(k, v)));
gen.writeEndObject();
}
case InStorageVariables inStorage -> {
gen.writeStartObject();
gen.writeStringField("type", TYPE); // marker to be sure at deserialization time it's a Variables not some random Map
gen.writeStringField("storageUri", inStorage.getStorageUri() != null ? inStorage.getStorageUri().toString() : null);
gen.writeObjectField("storageContext", inStorage.getStorageContext());
gen.writeEndObject();
}
}
}
}
}
class Deserializer extends StdDeserializer<Variables> {
public Deserializer() {
super(Variables.class);
}
@Override
@SuppressWarnings("unchecked")
public Variables deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
if (parser.hasToken(JsonToken.VALUE_NULL)) {
return null;
} else if (parser.hasToken(JsonToken.START_OBJECT)) {
// deserialize as map
Map<String, Object> ret = ctx.readValue(parser, Map.class);
if (TYPE.equals(ret.get("type"))) {
String uriString = (String) ret.get("storageUri");
if (uriString != null) {
Map<String, String> storageContextMap = (Map<String, String>) ret.get("storageContext");
StorageContext storageContext = new StorageContext(storageContextMap.get("tenantId"), storageContextMap.get("namespace"));
URI storageUri = URI.create(uriString);
return new InStorageVariables(storageContext, storageUri);
}
return new InStorageVariables((StorageContext) null, null);
}
// If the type is not TYPE, a real map has been serialized so we build a Variables with it.
return new InMemoryVariables(ret);
}
throw new IllegalArgumentException("Unable to deserialize value as it's not an object");
}
}
}

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

@@ -27,6 +27,7 @@ public class FlowWithPath {
public static FlowWithPath of(FlowInterface flow, String path) {
return FlowWithPath.builder()
.tenantId(flow.getTenantId())
.id(flow.getId())
.namespace(flow.getNamespace())
.path(path)

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;
@@ -253,9 +254,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

@@ -7,7 +7,7 @@ import io.kestra.core.models.executions.TaskRun;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.models.tasks.*;
import io.kestra.core.runners.FlowExecutorInterface;
import io.kestra.core.runners.FlowMetaStoreInterface;
import io.kestra.core.runners.RunContext;
import io.kestra.core.runners.SubflowExecution;
import io.kestra.core.runners.SubflowExecutionResult;
@@ -48,7 +48,7 @@ public class SubflowGraphTask extends AbstractGraphTask {
public record SubflowTaskWrapper<T extends Output>(RunContext runContext, ExecutableTask<T> subflowTask) implements TaskInterface, ExecutableTask<T> {
@Override
public List<SubflowExecution<?>> createSubflowExecutions(RunContext runContext, FlowExecutorInterface flowExecutorInterface, Flow currentFlow, Execution currentExecution, TaskRun currentTaskRun) throws InternalException {
public List<SubflowExecution<?>> createSubflowExecutions(RunContext runContext, FlowMetaStoreInterface flowExecutorInterface, Flow currentFlow, Execution currentExecution, TaskRun currentTaskRun) throws InternalException {
return subflowTask.createSubflowExecutions(runContext, flowExecutorInterface, currentFlow, currentExecution, currentTaskRun);
}

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.of(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.of(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.of(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, and `file` for host local 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

@@ -8,9 +8,11 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.google.common.annotations.VisibleForTesting;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.RunContext;
import io.kestra.core.serializers.JacksonMapper;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -45,10 +47,16 @@ public class Property<T> {
private String expression;
private T value;
/**
* @deprecated use {@link #ofExpression(String)} instead.
*/
@Deprecated
// Note: when not used, this constructor would not be deleted but made private so it can only be used by ofExpression(String) and the deserializer
public Property(String expression) {
this.expression = expression;
}
@VisibleForTesting
public Property(Map<?, ?> map) {
try {
expression = MAPPER.writeValueAsString(map);
@@ -65,8 +73,10 @@ public class Property<T> {
* Build a new Property object with a value already set.<br>
*
* A property build with this method will always return the value passed at build time, no rendering will be done.
*
* Use {@link #ofExpression(String)} to build a property with a Pebble expression instead.
*/
public static <V> Property<V> of(V value) {
public static <V> Property<V> ofValue(V value) {
// trick the serializer so the property would not be null at deserialization time
String expression;
if (value instanceof Map<?, ?> || value instanceof List<?>) {
@@ -93,6 +103,28 @@ public class Property<T> {
return p;
}
/**
* @deprecated use {@link #ofValue(Object)} instead.
*/
@Deprecated
public static <V> Property<V> of(V value) {
return ofValue(value);
}
/**
* Build a new Property object with a Pebble expression.<br>
*
* Use {@link #ofValue(Object)} to build a property with a value instead.
*/
public static <V> Property<V> ofExpression(@NotNull String expression) {
Objects.requireNonNull(expression, "'expression' is required");
if(!expression.contains("{")) {
throw new IllegalArgumentException("'expression' must be a valid Pebble expression");
}
return new Property<>(expression);
}
/**
* Render a property then convert it to its target type.<br>
*

View File

@@ -0,0 +1,106 @@
package io.kestra.core.models.property;
import io.kestra.core.runners.DefaultRunContext;
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.StorageContext;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Path;
import java.util.Collections;
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 String FILE_SCHEME = "file";
private static final List<String> SUPPORTED_SCHEMES = List.of(StorageContext.KESTRA_SCHEME, 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 + "://"));
}
/**
* 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 FILE_SCHEME -> {
Path path = Path.of(uri).toRealPath(); // toRealPath() will protect about path traversal issues
Path workingDirectory = runContext.workingDir().path();
if (!path.startsWith(workingDirectory)) {
// we need to check that it's on an allowed path
List<String> globalAllowedPaths = ((DefaultRunContext) runContext).getApplicationContext().getProperty("kestra.plugins.allowed-paths", List.class, Collections.emptyList());
if (globalAllowedPaths.stream().noneMatch(path::startsWith)) {
// if not globally allowed, we check it's allowed for this specific plugin
List<String> pluginAllowedPaths = (List<String>) runContext.pluginConfiguration("allowed-paths").orElse(Collections.emptyList());
if (pluginAllowedPaths.stream().noneMatch(path::startsWith)) {
throw new SecurityException("The path " + path + " is not authorized. " +
"Only files inside the working directory are allowed by default, other path must be allowed either globally inside the Kestra configuration using the `kestra.plugins.allowed-paths` property, " +
"or by plugin using the `allowed-paths` plugin configuration.");
}
}
}
yield new FileInputStream(path.toFile());
}
default -> throw new IllegalArgumentException("Scheme not supported: " + uri.getScheme());
};
}
}

View File

@@ -6,7 +6,7 @@ import io.kestra.core.models.executions.TaskRun;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.FlowId;
import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.runners.FlowExecutorInterface;
import io.kestra.core.runners.FlowMetaStoreInterface;
import io.kestra.core.runners.RunContext;
import io.kestra.core.runners.SubflowExecution;
import io.kestra.core.runners.SubflowExecutionResult;
@@ -23,7 +23,7 @@ public interface ExecutableTask<T extends Output>{
* Each SubflowExecution will generate a subflow execution.
*/
List<SubflowExecution<?>> createSubflowExecutions(RunContext runContext,
FlowExecutorInterface flowExecutorInterface,
FlowMetaStoreInterface flowExecutorInterface,
Flow currentFlow, Execution currentExecution,
TaskRun currentTaskRun) throws InternalException;

View File

@@ -23,7 +23,7 @@ public class NamespaceFiles {
title = "Whether to enable namespace files to be loaded into the working directory. If explicitly set to `true` in a task, it will load all [Namespace Files](https://kestra.io/docs/developer-guide/namespace-files) into the task's working directory. Note that this property is by default set to `true` so that you can specify only the `include` and `exclude` properties to filter the files to load without having to explicitly set `enabled` to `true`."
)
@Builder.Default
private Property<Boolean> enabled = Property.of(true);
private Property<Boolean> enabled = Property.ofValue(true);
@Schema(
title = "A list of filters to include only matching glob patterns. This allows you to only load a subset of the [Namespace Files](https://kestra.io/docs/developer-guide/namespace-files) into the working directory."
@@ -41,12 +41,12 @@ public class NamespaceFiles {
title = "A list of namespaces in which searching files. The files are loaded in the namespace order, and only the latest version of a file is kept. Meaning if a file is present in the first and second namespace, only the file present on the second namespace will be loaded."
)
@Builder.Default
private Property<List<String>> namespaces = new Property<>("""
private Property<List<String>> namespaces = Property.ofExpression("""
["{{flow.namespace}}"]""");
@Schema(
title = "Comportment of the task if a file already exist in the working directory."
)
@Builder.Default
private Property<FileExistComportment> ifExists = Property.of(FileExistComportment.OVERWRITE);
private Property<FileExistComportment> ifExists = Property.ofValue(FileExistComportment.OVERWRITE);
}

View File

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.executions.TaskRun;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.retrys.AbstractRetry;
@@ -31,33 +32,44 @@ abstract public class Task implements TaskInterface {
protected String type;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected String version;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private String description;
@Valid
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected AbstractRetry retry;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected Property<Duration> timeout;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected Boolean disabled = false;
@Valid
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private WorkerGroup workerGroup;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private Level logLevel;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean allowFailure = false;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean logToFile = false;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private String runIf = "true";
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean allowWarning = false;
public Optional<Task> findById(String id) {

View File

@@ -6,6 +6,7 @@ import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.Plugin;
import io.kestra.core.models.PluginVersioning;
import io.kestra.core.models.WorkerJobLifecycle;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.core.runner.Process;
@@ -39,6 +40,7 @@ public abstract class TaskRunner<T extends TaskRunnerDetailResult> implements Pl
@Pattern(regexp="\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*")
protected String type;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected String version;
@JsonIgnore

View File

@@ -46,6 +46,7 @@ public class Template implements DeletedInterface, TenantInterface, HasUID {
})
.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
@Setter
@Hidden
@Pattern(regexp = "^[a-z0-9][a-z0-9_-]*")
private String tenantId;

View File

@@ -34,24 +34,29 @@ abstract public class AbstractTrigger implements TriggerInterface {
protected String type;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
protected String version;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private String description;
@Valid
@PluginProperty
@PluginProperty(group = PluginProperty.CORE_GROUP)
@Schema(
title = "List of conditions in order to limit the flow trigger."
)
protected List<Condition> conditions;
@Valid
protected List<@Valid @NotNull Condition> conditions;
@NotNull
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean disabled = false;
@Valid
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private WorkerGroup workerGroup;
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private Level logLevel;
@Schema(
@@ -60,15 +65,17 @@ abstract public class AbstractTrigger implements TriggerInterface {
)
@JsonSerialize(using = ListOrMapOfLabelSerializer.class)
@JsonDeserialize(using = ListOrMapOfLabelDeserializer.class)
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private List<@NoSystemLabelValidation Label> labels;
@PluginProperty
@PluginProperty(group = PluginProperty.CORE_GROUP)
@Schema(
title = "List of execution states after which a trigger should be stopped (a.k.a. disabled)."
)
private List<State.Type> stopAfter;
@Builder.Default
@PluginProperty(hidden = true, group = PluginProperty.CORE_GROUP)
private boolean logToFile = false;
/**

View File

@@ -3,6 +3,7 @@ package io.kestra.core.models.validations;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.micronaut.core.annotation.Introspected;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@@ -22,6 +23,7 @@ import java.util.List;
@Introspected
@ToString
@Slf4j
@EqualsAndHashCode
public class ValidateConstraintViolation {
private String flow;

View File

@@ -0,0 +1,20 @@
package io.kestra.core.plugins;
import io.kestra.core.models.Plugin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@io.kestra.core.models.annotations.Plugin
@SuperBuilder(toBuilder = true)
@Getter
@NoArgsConstructor
public abstract class AdditionalPlugin implements Plugin {
@NotNull
@NotBlank
@Pattern(regexp="\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*")
protected String type;
}

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

@@ -120,6 +120,7 @@ public class LocalPluginManager implements PluginManager {
@Nullable Path localRepositoryPath) {
Objects.requireNonNull(artifact, "cannot install null artifact");
log.info("Installing managed plugin artifact '{}'", artifact);
final PluginArtifact resolvedPluginArtifact = mavenPluginDownloader.resolve(artifact.toString(), repositoryConfigs);
return install(resolvedPluginArtifact, installForRegistration, localRepositoryPath);
@@ -129,7 +130,6 @@ public class LocalPluginManager implements PluginManager {
final boolean installForRegistration,
Path localRepositoryPath) {
log.info("Installing managed plugin artifact '{}'", artifact);
localRepositoryPath = createLocalRepositoryIfNotExist(Optional.ofNullable(localRepositoryPath).orElse(this.localRepositoryPath));
Path localPluginPath = getLocalPluginPath(localRepositoryPath, artifact);
@@ -151,9 +151,11 @@ 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 {
return install(PluginArtifact.fromFile(file), installForRegistration, localRepositoryPath);
PluginArtifact artifact = PluginArtifact.fromFile(file);
log.info("Installing managed plugin artifact '{}'", artifact);
return install(artifact, installForRegistration, localRepositoryPath);
} catch (IOException e) {
throw new RuntimeException(e);
}

View File

@@ -1,6 +1,7 @@
package io.kestra.core.plugins;
import io.kestra.core.contexts.MavenPluginRepositoryConfig;
import io.kestra.core.exceptions.KestraRuntimeException;
import io.kestra.core.utils.Version;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.annotation.Nullable;
@@ -170,11 +171,11 @@ public class MavenPluginDownloader implements Closeable {
try {
FileUtils.deleteDirectory(new File(tmpDir));
} catch (IOException e) {
throw new RuntimeException(e);
throw new KestraRuntimeException(e);
}
}));
} catch (IOException e) {
throw new RuntimeException(e);
throw new KestraRuntimeException(e);
}
}
@@ -207,7 +208,7 @@ public class MavenPluginDownloader implements Closeable {
result.getArtifact().getFile().toPath().toUri()
);
} catch (VersionRangeResolutionException | ArtifactResolutionException e) {
throw new RuntimeException("Failed to resolve dependency: '" + dependency + "'", e);
throw new KestraRuntimeException("Failed to resolve dependency: '" + dependency + "'", e);
}
}

View File

@@ -15,7 +15,6 @@ import java.util.Base64;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -46,14 +45,14 @@ public class PluginCatalogService {
*
* @param httpClient the HTTP Client to connect to Kestra API.
* @param icons specifies whether icons must be loaded for plugins.
* @param oss specifies whether only OSS plugins must be returned.
* @param communityOnly specifies whether only OSS plugins must be returned.
*/
public PluginCatalogService(final HttpClient httpClient,
final boolean icons,
final boolean oss) {
final boolean communityOnly) {
this.httpClient = httpClient;
this.icons = icons;
this.oss = oss;
this.oss = communityOnly;
// Immediately trigger an async load of plugin artifacts.
this.isLoaded.set(true);

View File

@@ -45,6 +45,7 @@ public class PluginClassLoader extends URLClassLoader {
+ "|org.reactivestreams"
+ "|dev.failsafe"
+ "|reactor"
+ "|io.opentelemetry"
+ ")\\..*$");
private final ClassLoader parent;

View File

@@ -1,7 +1,24 @@
package io.kestra.core.plugins;
import org.apache.commons.lang3.tuple.Pair;
/**
* Represents the fully qualify identifier of a Kestra's plugin.
*/
public interface PluginIdentifier { }
public interface PluginIdentifier {
/**
* Helper method for parsing a string plugin identifier to extract a type and version.
*
* @param identifier a string type identifier.
* @return a {@link Pair} of (type, version).
*/
static Pair<String, String> parseIdentifier(final String identifier) {
int index = identifier.indexOf(':');
if (index == -1) {
return Pair.of(identifier, null);
} else {
return Pair.of(identifier.substring(0, index), identifier.substring(index + 1));
}
}
}

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.

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