Compare commits

...

565 Commits

Author SHA1 Message Date
Sandip Mandal
f5a0dcc024 chore(core): make sure kv listing is filterable (#11536)
Closes https://github.com/kestra-io/kestra/issues/11413.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-29 09:30:09 +02:00
Satvik Kushwaha
5c079b8b6b chore(namespaces): update page title on single namespace page (#11551)
Closes https://github.com/kestra-io/kestra/issues/11428.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-29 09:21:26 +02:00
Barthélémy Ledoux
343d6b4eb9 refactor(plugins): update documentation to use typescript and composition api (#11543) 2025-09-27 09:33:26 +01:00
Kenneth Rabe
d34d547412 fix(pebble): correct return format of timestampMicro 2025-09-26 16:51:35 +02:00
Nicolas K.
7a542a24e2 fix(executor): remove debug log (#11548)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-26 15:03:08 +02:00
Nicolas K.
5b1db68752 fix(test): flaky test with unwanted repeat test annotation (#11547)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-26 14:50:26 +02:00
Nicolas K.
5b07b643d3 fix(test): disable flaky test and add configuration to the ELS indexe… (#11539)
* fix(test): disable flaky test and add configuration to the ELS indexer poll duration

* fix(test): retry a flaky test and fix a flaky

* feat(test): disable a test until we have time to fix the bug

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-26 14:19:20 +02:00
Barthélémy Ledoux
0e059772e4 chore: remove posthog in dev mode (#11540) 2025-09-26 10:49:27 +01:00
Loïc Mathieu
f72e294e54 chore(system): log machine information at startup
This will log this kind of line at startup, helping to understand possible infrastructure limitation by looking at the starting logs.

```
14:38:17.018 INFO  main         i.k.c.c.s.AbstractServerCommand Machine information: 16 available cpu(s), 2048MB max memory, Java version 21.0.5+11-LTS
```
2025-09-26 10:55:05 +02:00
Loïc Mathieu
98dd884149 chore(executions): always log errors from the executor
- Logs errors from the Executor catched execution
- Logs errors from the Scheduler catched execution
- Avoid most places where the warning "unable to change state already..." could occur
- Log using the run context logger flow issues from executable tasks so they appears inside execution logs
2025-09-26 10:43:05 +02:00
Loïc Mathieu
26c4f080fd chore(deps): use the version of bcpkix-jdk18on from the platform 2025-09-26 10:42:47 +02:00
yuri1969
01293de91c fix(core): enable runIf at execution updating tasks 2025-09-25 10:23:13 +02:00
Mustafa Tarek
892b69f10e fix(core): Add warning logs for mismatched (Parent-Subflow) inputs (#11431)
* fix(core): Add warning logs for mismatched (Parent-Subflow) inputs for subflow plugin.

* feat: add check and log to FlowInputOutput.java

* enhancement: avoid unnecessary input validation in ExecutableUtils.subflowExecution() when no mismatches exist
2025-09-25 10:08:37 +02:00
yuri1969
6f70d4d275 fix(core): amend test
Adjusted to e1d2c30e which made the execution fail on empty value.
2025-09-25 09:49:19 +02:00
yuri1969
b41d2e456f fix(core): do not allow empty labels
* Filtered empty  entries on Labels task.
* Checking empty Flow labels via validation.
* Adjusted UI to disallow setting empty labels.
2025-09-25 09:49:19 +02:00
UncleBigBay
5ec08eda8c feat (layout): new sidebar total collapse behaviour (#11471)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-09-25 12:06:24 +05:30
dependabot[bot]
7ed6b883ff build(deps): bump io.micronaut.openapi:micronaut-openapi-bom
Bumps [io.micronaut.openapi:micronaut-openapi-bom](https://github.com/micronaut-projects/micronaut-openapi) from 6.18.0 to 6.18.1.
- [Release notes](https://github.com/micronaut-projects/micronaut-openapi/releases)
- [Commits](https://github.com/micronaut-projects/micronaut-openapi/compare/v6.18.0...v6.18.1)

---
updated-dependencies:
- dependency-name: io.micronaut.openapi:micronaut-openapi-bom
  dependency-version: 6.18.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:22:28 +02:00
dependabot[bot]
eb166c9321 build(deps): bump jakarta.mail:jakarta.mail-api from 2.1.4 to 2.1.5
Bumps [jakarta.mail:jakarta.mail-api](https://github.com/jakartaee/mail-api) from 2.1.4 to 2.1.5.
- [Release notes](https://github.com/jakartaee/mail-api/releases)
- [Commits](https://github.com/jakartaee/mail-api/compare/2.1.4...2.1.5)

---
updated-dependencies:
- dependency-name: jakarta.mail:jakarta.mail-api
  dependency-version: 2.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:22:05 +02:00
dependabot[bot]
57aad1b931 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.13 to 0.39.0.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.13...v0.39.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:21:47 +02:00
dependabot[bot]
60fe5b5c76 build(deps): bump org.apache.logging.log4j:log4j-to-slf4j
Bumps org.apache.logging.log4j:log4j-to-slf4j from 2.25.1 to 2.25.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:21:29 +02:00
dependabot[bot]
98c69b53bb build(deps): bump software.amazon.awssdk:bom from 2.33.11 to 2.34.2
Bumps software.amazon.awssdk:bom from 2.33.11 to 2.34.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:21:10 +02:00
dependabot[bot]
d5d38559b4 build(deps): bump com.github.oshi:oshi-core from 6.8.3 to 6.9.0
Bumps [com.github.oshi:oshi-core](https://github.com/oshi/oshi) from 6.8.3 to 6.9.0.
- [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.3...oshi-parent-6.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:20:50 +02:00
dependabot[bot]
4273ddc4f6 build(deps): bump org.apache.httpcomponents.core5:httpcore5-h2
Bumps [org.apache.httpcomponents.core5:httpcore5-h2](https://github.com/apache/httpcomponents-core) from 5.3.5 to 5.3.6.
- [Changelog](https://github.com/apache/httpcomponents-core/blob/rel/v5.3.6/RELEASE_NOTES.txt)
- [Commits](https://github.com/apache/httpcomponents-core/compare/rel/v5.3.5...rel/v5.3.6)

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents.core5:httpcore5-h2
  dependency-version: 5.3.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:20:10 +02:00
dependabot[bot]
980c573a30 build(deps): bump org.eclipse.angus:jakarta.mail from 2.0.4 to 2.0.5
Bumps org.eclipse.angus:jakarta.mail from 2.0.4 to 2.0.5.

---
updated-dependencies:
- dependency-name: org.eclipse.angus:jakarta.mail
  dependency-version: 2.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:18:43 +02:00
dependabot[bot]
27109015f9 build(deps): bump org.projectlombok:lombok from 1.18.40 to 1.18.42
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.40 to 1.18.42.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.40...v1.18.42)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:18:15 +02:00
dependabot[bot]
eba7d4f375 build(deps): bump bouncycastleVersion from 1.81 to 1.82
Bumps `bouncycastleVersion` from 1.81 to 1.82.

Updates `org.bouncycastle:bcprov-jdk18on` from 1.81 to 1.82
- [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.81 to 1.82
- [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.81 to 1.82
- [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.82'
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcpg-jdk18on
  dependency-version: '1.82'
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcpkix-jdk18on
  dependency-version: '1.82'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 16:17:53 +02:00
dependabot[bot]
655a1172ee build(deps): bump org.assertj:assertj-core from 3.27.4 to 3.27.6
Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.4 to 3.27.6.
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.6)

---
updated-dependencies:
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 15:45:31 +02:00
dependabot[bot]
6e49a85acd build(deps): bump org.owasp.dependencycheck from 12.1.3 to 12.1.5
Bumps org.owasp.dependencycheck from 12.1.3 to 12.1.5.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 15:44:40 +02:00
Barthélémy Ledoux
4515bad6bd fix(flows): delete flows should work (#11469) 2025-09-24 09:35:47 +02:00
Loïc Mathieu
226dbd30c9 fix(tests): fix test flow namespace and id 2025-09-24 09:19:31 +02:00
mustafatarek
6b0c190edc feat: added test case covering ForEach Iteration 2025-09-24 09:19:31 +02:00
mustafatarek
c64df40a36 refactor: change iteration to start with 0 2025-09-24 09:19:31 +02:00
mustafatarek
8af22d1bb2 fix(core): fix ForEach plugin task.iteration property to show the correct number of Iteration 2025-09-24 09:19:31 +02:00
Nicolas K.
b294457953 feat(tests): rework runner utils to not use the queue during testing (#11380)
* feat(tests): rework runner utils to not use the queue during testing

* feat(tests): rework runner utils to not use the queue during testing

* test: rework RetryCaseTest to not rely on executionQueue

* fix(tests): don't catch the Queue exception

* fix(tests): don't catch the Queue exception

* fix compile

* fix(test): concurrency error and made runner test parallel ready

* fix(tests): remove test instance

* feat(tests): use Test Runner Utils

* fix(tests): flaky tests

* fix(test): flaky tests

* feat(tests): rework runner utils to not use the queue during testing

* feat(tests): rework runner utils to not use the queue during testing

* test: rework RetryCaseTest to not rely on executionQueue

* fix(tests): don't catch the Queue exception

* fix(tests): don't catch the Queue exception

* fix compile

* fix(test): concurrency error and made runner test parallel ready

* fix(tests): remove test instance

* feat(tests): use Test Runner Utils

* fix(tests): flaky tests

* fix(test): flaky tests

* fix(tests): flaky set test

* fix(tests): remove RunnerUtils

* fix(tests): fix flaky

* feat(test): rework runner tests to remove the queue usage

* feat(test): fix a flaky and remove parallelism from mysql test suit

* fix(tests): flaky tests

* clean(tests): unwanted test

* add debug exec when fail

* feat(tests): add thread to mysql thread pool

* fix(test): flaky and disable a test

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>
2025-09-24 08:18:02 +02:00
Loïc Mathieu
02d9c589fb chore(system): remove the task run page
Part-of: https://github.com/kestra-io/kestra-ee/issues/5174
2025-09-23 14:48:30 +02:00
Sanjay Ramsinghani
6340d1c72f chore(core): align toggle icon in failed execution collapse element (#11430)
Closes https://github.com/kestra-io/kestra/issues/11406.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-23 14:14:24 +02:00
Raj Gupta
f439bd53d7 chore(system): clean up filters config (#11405)
closes #11378
2025-09-23 14:11:00 +02:00
github-actions[bot]
e54e3d5308 chore(core): localize to languages other than english (#11464)
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-09-23 13:43:37 +02:00
Emmanuel Adeniyi Adekeye
d084f2cd26 chore(core): improve display format in dashboard charts (#11456)
Closes https://github.com/kestra-io/kestra/issues/11171.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-23 13:41:55 +02:00
Ritoban Dutta
015960c78e chore(core): update background color of context panel menu (#11441)
Closes https://github.com/kestra-io/kestra/issues/11426.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-23 12:57:12 +02:00
yummyash
39a09ecb67 chore(core): replace illustration on multi-panel empty screen (#11457)
Closes https://github.com/kestra-io/kestra/issues/11244.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-23 12:54:19 +02:00
Miloš Paunović
45ce878d65 fix(executions): properly parse defaults for json-type inputs (#11459)
Closes https://github.com/kestra-io/kestra/issues/11449.
2025-09-23 12:48:05 +02:00
Miloš Paunović
3ee647b9a8 feat(triggers): show dialog when clicking the backfill button (#11445)
Closes https://github.com/kestra-io/kestra/issues/11433.
2025-09-23 12:24:57 +02:00
github-actions[bot]
7a7cb006bf chore(core): localize to languages other than english (#11455)
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-09-23 11:06:08 +02:00
Piyush Bhaskar
911e6d5705 fix(core): fix pagination load data changes (#11453) 2025-09-23 14:25:20 +05:30
brian-mulier-p
bf1458dde7 fix(ai): avoid moving cursor twice after using AI Copilot (#11451)
closes #11314
2025-09-23 10:30:37 +02:00
yuri1969
bd31e0eebd fix(tests): sanitize E2E control scripts 2025-09-23 10:16:06 +02:00
Florian Hussonnois
de02e4dd70 fix(triggers): handle RecoverMissedSchedules on trigger batch update
* Fix and clean code in TriggerController
* Remove duplicate code in Trigger class
2025-09-23 10:06:03 +02:00
Karuna Tata
ec235b91fc feat: add fix with AI button for error tasks (#11416) 2025-09-23 11:53:07 +05:30
brian.mulier
ff1efa9958 fix(system): avoid trigger locking after scheduler restart
closes #11434
2025-09-22 19:26:58 +02:00
brian.mulier
e43c8ce387 fix(ci): add on pull request for release branches 2025-09-22 19:05:05 +02:00
Barthélémy Ledoux
2bd4e82b42 chore: make a lot of progress on the typescript front (#11234)
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-09-22 13:39:52 +02:00
Jeffrey Ricker
e63d6d1d86 feat(flows): add Pebble nanoId function
* nanoid function

* nanoid function

* Update core/src/main/java/io/kestra/core/runners/pebble/functions/NanoIDFunction.java

Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>

* Update core/src/test/java/io/kestra/core/runners/pebble/functions/NanoIDFuntionTest.java

Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>

* fix: nanoId to parse Long to work with Kestra yaml

---------

Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>
2025-09-22 11:30:44 +02:00
Florian Hussonnois
a9752e65f2 chore(websever): make kvStore method in KVController protected
Related-to: kestra-io/kestra-ee#5055
2025-09-22 11:30:10 +02:00
Florian Hussonnois
151c56f3de feat(core): add new findMetadataAndValue to KVStore
Related-to: kestra-io/kestra-ee#5055
2025-09-22 11:30:10 +02:00
Piyush Bhaskar
d562ce3e65 fix: fix ci build error 2025-09-22 11:06:59 +02:00
Florian Hussonnois
681386a05b fix(kvstores): fix description not set when editing 2025-09-22 11:06:59 +02:00
Sehnya
51ddfaf155 chore(core): remove shadow above the user selector (#11364)
Closes https://github.com/kestra-io/kestra/issues/11352.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-22 09:26:24 +02:00
Pratyush Kumar
caee0a293f Add feature to also show an Outputs column in the summary table (#11412)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-09-22 12:25:21 +05:30
github-actions[bot]
ba92880fa3 chore(core): localize to languages other than english (#11414)
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-09-22 08:48:58 +02:00
rhodemilk
36b27510fb chore(executions): rename label in overview page (#11363)
Closes https://github.com/kestra-io/kestra/issues/11287.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-22 08:46:48 +02:00
Siddharthrane07
da2907e096 fix(core): show proper light mode tooltip. (#11407)
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-09-22 12:01:12 +05:30
Ludovic DEHON
9b40665e64 chore(build): use remote actions for java report 2025-09-19 23:56:32 +02:00
Ludovic DEHON
0d35b5b355 fix(system): make skip flow and namespace resilient to errors 2025-09-19 23:53:17 +02:00
Roman Acevedo
339eb79854 ci: migrate kestra-devtools to npm 2025-09-19 16:59:59 +02:00
brian-mulier-p
0ee753529b fix(tests): enforce closing consumers after each tests (#11399) 2025-09-19 16:27:37 +02:00
Miloš Paunović
84668fdfb9 chore(namespaces): add disabled attribute to typescript interface for namespace tabs (#11398)
Related to https://github.com/kestra-io/kestra-ee/issues/4726.
2025-09-19 13:54:37 +02:00
Miloš Paunović
9802f046e8 chore(triggers): amend labels on table column header and switch element (#11395)
Closes https://github.com/kestra-io/kestra-ee/issues/5196.
2025-09-19 11:40:38 +02:00
brian-mulier-p
848b4d6577 fix(core): avoid ClassCastException when doing secret decryption (#11393)
closes kestra-io/kestra-ee#5191
2025-09-19 11:24:39 +02:00
github-actions[bot]
1159bc5eb9 chore(core): localize to languages other than english (#11394)
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-09-19 11:05:14 +02:00
Sandip Mandal
9b7ef37d14 fix(core: webhook curl coomand needs tenant. (#11391)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-19 14:06:08 +05:30
Piyush Bhaskar
89dfd18658 fix(admin): humanize label for trigger keys (#11377)
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-19 12:08:20 +05:30
Loïc Mathieu
13ed2252bc fix(executions): computing subflow outputs could fail when the executioin is failing or killing
Fixes https://github.com/kestra-io/kestra/issues/11379
2025-09-18 17:41:13 +02:00
Barthélémy Ledoux
c73b103bb3 fix: restore sidebar icon zindex (#11371) 2025-09-18 14:36:45 +02:00
Will Russell
396a077942 docs(overview): new video (#11374) 2025-09-18 12:56:30 +01:00
Miloš Paunović
68e6fa2a4c feat(flows): save editor panel layout after creation (#11276)
Closes https://github.com/kestra-io/kestra/issues/9887.

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-09-18 12:47:31 +02:00
Piyush Bhaskar
a18748b3b2 refactor(core): remove TaskRuns page (#11366) 2025-09-18 15:58:20 +05:30
Loïc Mathieu
236fcff7b4 fix(executions): concurrency limit should update the executioin
As if it's not updated in the database, it would not be detected as changed so that terminal actions (like purge) would not be done.

Fixes  #11022
Fixes #11025
Fixes #8143
2025-09-18 12:08:54 +02:00
Roman Acevedo
cbbd697732 ci: hide by default error logs in test report PR (#11354) 2025-09-18 12:04:30 +02:00
Loïc Mathieu
6b84737651 fix(executions): the Exit task was not correctly ends parent tasks
Fixes https://github.com/kestra-io/kestra-ee/issues/5168
2025-09-18 11:36:23 +02:00
Florian Hussonnois
6ee7ecbd6b fix(core): fix NPE in JackMapping.applyPatchesOnJsonNode method 2025-09-18 10:57:00 +02:00
Roman Acevedo
504f925085 test: make AbstractExecutionRepositoryTest parallelizable (#11295)
* test: make AbstractExecutionRepositoryTest parallelizable

* feat(tests): play jdbc h2 tests in parallel

* fix(tests): failing unit tests

* tests: add await until timeout on some tests

* fix(tests): failing unit tests

* fix(tests): failing unit tests

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: Nicolas K. <nk_mikmak@hotmail.com>
2025-09-17 17:41:10 +02:00
Loïc Mathieu
7d37d2be93 fix(executions): possible NPE on dynamic taskrun
Fixes https://github.com/kestra-io/kestra-ee/issues/5166
2025-09-17 15:55:52 +02:00
brian.mulier
94751a3b21 fix(core): filters weren't applying anymore 2025-09-17 12:55:17 +02:00
Piyush Bhaskar
ba83b91680 fix(core): conditionally disable current route (#11353) 2025-09-17 15:51:12 +05:30
Piyush Bhaskar
56f62fb89f fix(core): show subgroups card only if exist, else show main group (#11348)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-17 15:18:21 +05:30
Loïc Mathieu
a0efe4b1f3 fix(system): properly pass Micronaut env 2025-09-17 11:35:59 +02:00
dependabot[bot]
9af6338ae5 build(deps): bump dev.langchain4j:langchain4j-bom from 1.4.0 to 1.5.0
Bumps [dev.langchain4j:langchain4j-bom](https://github.com/langchain4j/langchain4j) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/langchain4j/langchain4j/releases)
- [Commits](https://github.com/langchain4j/langchain4j/compare/1.4.0...1.5.0)

---
updated-dependencies:
- dependency-name: dev.langchain4j:langchain4j-bom
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 11:32:55 +02:00
dependabot[bot]
d53b933bdf build(deps): bump jakarta.xml.bind:jakarta.xml.bind-api
Bumps [jakarta.xml.bind:jakarta.xml.bind-api](https://github.com/jakartaee/jaxb-api) from 4.0.2 to 4.0.4.
- [Release notes](https://github.com/jakartaee/jaxb-api/releases)
- [Commits](https://github.com/jakartaee/jaxb-api/compare/4.0.2...4.0.4)

---
updated-dependencies:
- dependency-name: jakarta.xml.bind:jakarta.xml.bind-api
  dependency-version: 4.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 11:32:43 +02:00
dependabot[bot]
a35c2816c5 build(deps): bump dev.langchain4j:langchain4j-community-bom
Bumps [dev.langchain4j:langchain4j-community-bom](https://github.com/langchain4j/langchain4j-community) from 1.4.0-beta10 to 1.5.0-beta11.
- [Release notes](https://github.com/langchain4j/langchain4j-community/releases)
- [Commits](https://github.com/langchain4j/langchain4j-community/compare/1.4.0-beta10...1.5.0-beta11)

---
updated-dependencies:
- dependency-name: dev.langchain4j:langchain4j-community-bom
  dependency-version: 1.5.0-beta11
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 11:31:47 +02:00
Loïc Mathieu
d88eb9974c fix(system): use the Langchain Gemini lib version from the platform 2025-09-17 11:14:11 +02:00
Florian Hussonnois
af3d5a384a fix(core): fix plugin stable version resolution (kestra-io/kestra-ee#5129)
Rename incremental field to patch

Fixes: kestra-io/kestra-ee#5129
2025-09-17 11:10:40 +02:00
Miloš Paunović
e9ad352ccf chore(core): remove unused decompress library (#11346) 2025-09-17 11:04:36 +02:00
yuri
1a95b83fb7 chore(logs): make search queries case-insensitive (#11313)
Execution logs' filter query used to be case-sensitive - for example, the `hello` query did not match `Hello World` log lines.
2025-09-17 11:04:07 +02:00
dependabot[bot]
095939ff7a build(deps): bump software.amazon.awssdk:bom from 2.33.5 to 2.33.11
Bumps software.amazon.awssdk:bom from 2.33.5 to 2.33.11.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:46:42 +02:00
Piyush Bhaskar
094f523874 fix(core): remove object Object from tab title. (#11347) 2025-09-17 14:08:50 +05:30
brian.mulier
c7efb2514a fix(core): avoid filters from overlapping on other pages when changing query params 2025-09-17 10:36:20 +02:00
brian.mulier
887537d8c1 fix(core): avoid clearing filters when reclicking on current left menu item
closes #9476
2025-09-17 10:36:20 +02:00
brian.mulier
0630b741b9 fix(core): avoid undefined error on refresh chart 2025-09-17 10:36:20 +02:00
dependabot[bot]
d2b7e723e1 build(deps): bump io.qameta.allure:allure-bom from 2.29.1 to 2.30.0
Bumps [io.qameta.allure:allure-bom](https://github.com/allure-framework/allure-java) from 2.29.1 to 2.30.0.
- [Release notes](https://github.com/allure-framework/allure-java/releases)
- [Commits](https://github.com/allure-framework/allure-java/compare/2.29.1...2.30.0)

---
updated-dependencies:
- dependency-name: io.qameta.allure:allure-bom
  dependency-version: 2.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:22:27 +02:00
dependabot[bot]
080ceadf37 build(deps): bump org.jooq:jooq from 3.20.6 to 3.20.7
Bumps org.jooq:jooq from 3.20.6 to 3.20.7.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:21:49 +02:00
dependabot[bot]
a89d902bc2 build(deps): bump andrcuns/allure-publish-action from 2.9.0 to 2.10.0
Bumps [andrcuns/allure-publish-action](https://github.com/andrcuns/allure-publish-action) from 2.9.0 to 2.10.0.
- [Release notes](https://github.com/andrcuns/allure-publish-action/releases)
- [Commits](https://github.com/andrcuns/allure-publish-action/compare/v2.9.0...v2.10.0)

---
updated-dependencies:
- dependency-name: andrcuns/allure-publish-action
  dependency-version: 2.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:20:02 +02:00
dependabot[bot]
e2ef7d412a 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.11 to 0.38.13.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.11...v0.38.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:19:13 +02:00
dependabot[bot]
54c667ec4b build(deps): bump com.google.cloud:libraries-bom from 26.67.0 to 26.68.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.67.0 to 26.68.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.67.0...v26.68.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 10:18:19 +02:00
Piyush Bhaskar
1c53758d33 refactor(core): composable equivalent for mixins (#11277)
* refactor(core): composable equivalent for mixins

* fix: few tweaks

* fix: remove extension
2025-09-17 11:31:20 +05:30
Ludovic DEHON
d092556bc2 chore(build): use remote actions 2025-09-16 18:09:54 +02:00
Roman Acevedo
308106d532 ci: make generated test report retrocompatible with older releases (#11308)
* ci: make generated test report retrocompatible with older realeases

* ci: fix cli
2025-09-16 15:21:56 +02:00
Piyush Bhaskar
8fe8f96278 refactor(core): use el-splitter instead of custom sliders (#11309)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-16 18:35:57 +05:30
Miloš Paunović
a5cad6d87c chore(core): improve coloring scheme for dependencies graph (#11306) 2025-09-16 14:26:15 +02:00
Loïc Mathieu
199d67fbe2 chore(system): share the application.yaml config file between OSS and EE 2025-09-16 10:53:53 +02:00
Loïc Mathieu
558a2e3f01 fix(flows): properly coompute flow dependencies with preconditions
When both upstream flows and where are set, it should be a AND between the two as dependencies must match the upstream flows.

Fixes #11164
2025-09-16 10:43:55 +02:00
HARSH THAKARE
e1d2c30e54 fix(core): add validation to prevent empty label values in Labels task (#11273)
part of #11227

---------

Co-authored-by: harshinfomaticae <harsh.thakare@infomaticae.co.in>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-16 10:26:46 +02:00
Loïc Mathieu
700c6de411 fix(system): allow flattening a map with duplicated keys 2025-09-16 10:24:43 +02:00
Florian Hussonnois
2b838a5012 fix(executions): add missing CrudEvent on purge execution
Related-to: kestra-io/kestra-ee#5061
2025-09-16 09:34:19 +02:00
Loïc Mathieu
617daa79db fix(executions): truncate the execution_running table as in 0.24 there was an issue in the purge
This table contains executions for flows that have a concurrency that are currently running.
It has been added in 0.24 but in that release there was a bug that may prevent some records to being correctly removed from this table.
To fix that, we truncate it once.
2025-09-15 17:29:28 +02:00
Roman Acevedo
1791127acb test: unflaky FileChangedEventListener and PluginDefaultServiceTest, debug log on JdbcServiceLivenessCoordinatorTest
* test: parallelize AbstractRunnerTest

* test: add TestsUtils.randomTenant(..) function

* test: i think i found a bug

* revert debug

* test: add comment on potential bug, make test pass

* test: fix test metadata

* test: unflaky PluginDefaultServiceTest by separating class

* test: add log on JdbcServiceLivenessCoordinatorTest to debug

* test: cleanup debug log

* fix
2025-09-15 17:07:37 +02:00
brian-mulier-p
7feb571fb3 fix(test): add tenant-in-path storage test (#11292)
part of kestra-io/storage-s3#166
2025-09-15 16:49:02 +02:00
brian-mulier-p
a315bd0e1c fix(security): enhance basic auth security (#11285)
closes kestra-io/kestra-ee#5111
2025-09-15 16:27:14 +02:00
Roman Acevedo
e2ac1e7e98 ci: prevent commenting PR test report when cancelled 2025-09-15 16:01:07 +02:00
Miloš Paunović
c6f40eff52 fix(core): adjust positioning of default tour elements (#11286)
The problem occurred when `No Code` was selected as the `Default Editor Type` in `Settings`. This `PR` resolves the issue.

Closes https://github.com/kestra-io/kestra/issues/9556.
2025-09-15 14:55:00 +02:00
Miloš Paunović
ccd42f7a1a chore(core): remove superfluous button attribute in settings page (#11283) 2025-09-15 12:27:19 +02:00
Florian Hussonnois
ef08c8ac30 fix(plugins): remove regex validation on version property
Changes:
* Fixes stable method in Version class
* Remove regex validation on 'version' property

Related-to: kestra-io/kestra-ee#5090
2025-09-15 11:54:10 +02:00
github-actions[bot]
7b527c85a9 chore(core): localize to languages other than english (#11280)
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-09-15 11:09:17 +02:00
Hamza
d121867066 chore(flows): trigger editor autocompletion when backspace is pressed (#10797)
Closes https://github.com/kestra-io/kestra/issues/10776.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-15 11:07:20 +02:00
Roman Acevedo
a084a9f6f0 ci: fix Summary report test path 2025-09-15 10:50:25 +02:00
Karthik D
f6fff11081 chore(core): add reset to defaults option to settings page (#11226)
Closes https://github.com/kestra-io/kestra/issues/10640.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-15 10:45:11 +02:00
Roman Acevedo
3d5015938f ci: add total header to generateTestReportSummary 2025-09-15 10:32:22 +02:00
Florian Hussonnois
951c93cedb fix(core): fix CrudEvent model for DELETE operation
Refactor XxxRepository class to use new factory methods
from the CrudEvent class

Related-to: kestra-io/kestra-ee#4727
2025-09-15 10:06:52 +02:00
Antoine Gauthier
9c06b37989 chore(core): resolve button text overflow on system overview page (#11271)
Closes https://github.com/kestra-io/kestra/issues/11245.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-15 09:57:10 +02:00
Anna Geller
a916a03fdd fix(stats): update edition comparison with latest features and improved descriptions (#11272) 2025-09-14 12:35:26 +02:00
Roman Acevedo
4e728da331 test: disable one last test 2025-09-12 20:24:08 +02:00
Roman Acevedo
166a3932c9 test: do not parallelize yet AbstractRunnerTest 2025-09-12 20:24:08 +02:00
Roman Acevedo
0a21971bbf ci: only comment PR with test report in PR 2025-09-12 20:24:08 +02:00
Roman Acevedo
8c4d7c0f9e test: disable failing tests, they will be fixed soon
- will be treated in https://github.com/kestra-io/kestra/issues/11269
2025-09-12 20:24:08 +02:00
Nicolas K.
b709913071 test: run core tests in parallel (#11265)
- advance on #11264

* feat(ci-cd): play tests in parallel and synchronize plugin registry init

* fix(tests): change memory to h2 because the configuration have changed

* feat(tests): use tenant id to run runner tests in parallel

* run AbstractRunnerTest test methods in parallel

* feat(tests): use tenant id to run runner tests in parallel

* feat(tests): remove unwanted generated files

---------

Co-authored-by: Roman Acevedo <roman.acevedo62@gmail.com>
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-12 19:29:38 +02:00
Roman Acevedo
5be401d23c ci: add a kestra-devtools cli, and comment PR with failed tests
this is a POC, I think it can already be useful. Next step will be to move kestra-devtools to a separate repo and publish it to npm
2025-09-12 18:48:12 +02:00
Roman Acevedo
bb9f4be8c2 Revert "chore(sanitycheck): refactor PurgeCurrentExecutionFiles (#11115)"
This reverts commit fc690bf7cd.
Python task cannot be used here, it is not available. This commit was
wrongly merged with a red CI
2025-09-12 17:49:02 +02:00
François Delbrayelle
01e8e46b77 Revert "feat(retry): use the retry policy on HttpClient (#10922)" (#11263)
This reverts commit a236688be6.
2025-09-12 17:46:28 +02:00
Miloš Paunović
d00f4b0768 chore(core): ensure editor suggestion widget renders above other elements (#11258)
Closes https://github.com/kestra-io/kestra/issues/10702.
Closes https://github.com/kestra-io/kestra/issues/11033.
2025-09-12 14:48:56 +02:00
Barthélémy Ledoux
279f59c874 fix(core): only display close all tabs when there is more than one tab (#11257) 2025-09-12 14:20:54 +02:00
Barthélémy Ledoux
d897509726 fix(flows): clear tasks list when last task is deleted (#11255) 2025-09-12 14:20:42 +02:00
Pradumna Saraf
0d592342af chore(sanitycheck): add for OutputValues (#11105) 2025-09-12 16:53:13 +05:30
Pradumna Saraf
fc690bf7cd chore(sanitycheck): refactor PurgeCurrentExecutionFiles (#11115) 2025-09-12 16:52:37 +05:30
Antoine Gauthier
0a1b919863 chore(logs): display copy button only on row hover (#11254)
Closes https://github.com/kestra-io/kestra/issues/11220.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-12 12:00:08 +02:00
Piyush Bhaskar
2f4e981a29 fix(core): add gradient at footer to avoid hard cut (#11252) 2025-09-12 14:35:47 +05:30
brian-mulier-p
5e7739432e fix(core): add ability to remap sort keys (#11233)
part of kestra-io/kestra-ee#5075
2025-09-12 09:43:39 +02:00
Miloš Paunović
8aba863b8c feat(core): introduce close all panels functionality (#11225)
Closes https://github.com/kestra-io/kestra/issues/10785.
2025-09-12 09:01:24 +02:00
dependabot[bot]
7eaa43c50f build(deps): bump axios (#11243)
Bumps the npm_and_yarn group with 1 update in the /ui directory: [axios](https://github.com/axios/axios).


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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-12 08:36:02 +02:00
Piyush Bhaskar
267ff78bfe fix(admin): change the header and add description on hover (#11241)
Co-authored-by: GitHub Action <actions@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-12 12:00:41 +05:30
François Delbrayelle
7272cfe01f feat(ai_copilot): gray italic placeholder + rename AiAgent to AiCopilot (#11235) 2025-09-11 20:24:04 +02:00
brian.mulier
91e2fdb2cc fix(ai): increase maxOutputToken default 2025-09-11 18:11:52 +02:00
François Delbrayelle
a236688be6 feat(retry): use the retry policy on HttpClient (#10922) 2025-09-11 15:00:25 +02:00
Antoine Gauthier
81763d40ae fix(docs): center main container in DocsLayout (#11222)
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-09-11 16:18:12 +05:30
Miloš Paunović
677efb6739 fix(namespaces): open details page at top (#11221)
Closes https://github.com/kestra-io/kestra/issues/10536.
2025-09-11 10:52:47 +02:00
Nicolas K.
b35924fef1 fix(tests): add server type mock in the kestra context (#11176)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-11 09:45:51 +02:00
Jaem Dessources
9dd93294b6 fix(core): align copy logs button to each row’s right edge (#11216)
Closes https://github.com/kestra-io/kestra/issues/10898.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-11 08:55:01 +02:00
Piyush Bhaskar
fac6dfe9a0 fix(core): update router usage in loadAutocomplete. (#11219) 2025-09-11 12:13:05 +05:30
Bisesh
3bf9764505 fix(core): make sidebar tab color consistent when unfocused (#11217)
Closes https://github.com/kestra-io/kestra/issues/11156.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-11 08:33:57 +02:00
Piyush Bhaskar
c35cea5d19 fix(core): override the ns module. (#11218) 2025-09-11 11:53:00 +05:30
Barthélémy Ledoux
4d8e9479f1 refactor: finally get rid of vuex (#11211) 2025-09-10 22:44:21 +02:00
Florian Hussonnois
3f24e8e838 fix(core): make CRC32 for plugin JARs lazy
Make CRC32 calculation for lazy plugin JAR files
to avoid excessive startup time and performance impact.

Avoid byte buffer reallocation while computing CRC32.
2025-09-10 17:42:02 +02:00
Miloš Paunović
7175fcb666 fix(executions): refactor link creation to ensure the id is rendered as a clickable link (#11209)
Related to https://github.com/kestra-io/kestra/issues/10906.
2025-09-10 15:01:29 +02:00
Barthélémy Ledoux
2ddfa13b1b refactor: make-axios-composable (#11177) 2025-09-10 14:54:00 +02:00
Barthélémy Ledoux
ba2a5dfec8 chore: revert monaco update (#11207) 2025-09-10 13:34:33 +02:00
Loïc Mathieu
f84441dac7 fix(ci): disable publishing docker image on fork
I should have not trusted an AI for this but copy/paste what I know work: the Quarkus CI!
2025-09-10 12:17:25 +02:00
Barthélémy Ledoux
433b788e4a chore: a bunch of performance fixes detected by oxlint (eslint-unicorn) (#10050) 2025-09-10 11:35:07 +02:00
dependabot[bot]
65c5fd6331 build(deps): bump org.projectlombok:lombok from 1.18.38 to 1.18.40
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.38 to 1.18.40.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.38...v1.18.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 11:12:24 +02:00
dependabot[bot]
421ab40276 build(deps): bump io.micrometer:micrometer-core from 1.15.3 to 1.15.4
Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.15.3...v1.15.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 11:11:48 +02:00
dependabot[bot]
efb2779693 build(deps): bump flyingSaucerVersion from 9.13.3 to 10.0.0
Bumps `flyingSaucerVersion` from 9.13.3 to 10.0.0.

Updates `org.xhtmlrenderer:flying-saucer-core` from 9.13.3 to 10.0.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.13.3...v10.0.0)

Updates `org.xhtmlrenderer:flying-saucer-pdf` from 9.13.3 to 10.0.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.13.3...v10.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 11:10:59 +02:00
dependabot[bot]
74d371c0ca build(deps): bump com.azure:azure-sdk-bom from 1.2.37 to 1.2.38
Bumps [com.azure:azure-sdk-bom](https://github.com/azure/azure-sdk-for-java) from 1.2.37 to 1.2.38.
- [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.37...azure-sdk-bom_1.2.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 11:10:10 +02:00
Loïc Mathieu
90a7869020 fixsystem): always load netty from the app classloader
As Netty is used in core and a lot of plugins, and we already load project reactor from the app classloader that depends in Netty.

Fixes https://github.com/kestra-io/kestra-ee/issues/5038
2025-09-10 10:50:22 +02:00
dependabot[bot]
d9ccb50b0f build(deps): bump actions/github-script from 7 to 8
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:47:17 +02:00
Loïc Mathieu
9a144fc3fe fix(system): we don't need to advance the parser anymore to the first token 2025-09-10 10:46:44 +02:00
Loïc Mathieu
ddd9cebc63 chore(deps): upgrade to Jackson 2.20.0
Jackson annotation now uses a version scheme without micro version so it has been updated to 2.20.

Closes #11069
2025-09-10 10:46:44 +02:00
dependabot[bot]
1bebbb9b73 build(deps): bump com.gorylenko.gradle-git-properties
Bumps com.gorylenko.gradle-git-properties from 2.5.2 to 2.5.3.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:46:26 +02:00
dependabot[bot]
8de4dc867e build(deps): bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:46:08 +02:00
dependabot[bot]
fc49694e76 build(deps): bump actions/setup-node from 4 to 5
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:45:47 +02:00
dependabot[bot]
152300abae build(deps): bump io.micronaut.openapi:micronaut-openapi-bom
Bumps [io.micronaut.openapi:micronaut-openapi-bom](https://github.com/micronaut-projects/micronaut-openapi) from 6.17.3 to 6.18.0.
- [Release notes](https://github.com/micronaut-projects/micronaut-openapi/releases)
- [Commits](https://github.com/micronaut-projects/micronaut-openapi/compare/v6.17.3...v6.18.0)

---
updated-dependencies:
- dependency-name: io.micronaut.openapi:micronaut-openapi-bom
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:45:13 +02:00
dependabot[bot]
1ff5dda4e1 build(deps): bump software.amazon.awssdk:bom from 2.33.2 to 2.33.5
Bumps software.amazon.awssdk:bom from 2.33.2 to 2.33.5.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 10:44:50 +02:00
Miloš Paunović
84f9b8876d chore(deps): regular dependency update (#11200)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-09-10 10:18:33 +02:00
brian-mulier-p
575955567f fix(flows): avoid failing flow dependencies with dynamic defaults (#11166)
closes #11117
2025-09-10 09:59:51 +02:00
brian-mulier-p
d6d2580b45 fix(namespaces): avoid adding 'company.team' as default ns (#11174)
closes #11168
2025-09-09 17:13:48 +02:00
Miloš Paunović
070e54b902 chore(flows): display correct flow dependency count (#11169)
Closes https://github.com/kestra-io/kestra/issues/11127.
2025-09-09 13:56:17 +02:00
Roman Acevedo
829ca4380f fix(flows): topology would not load when having many flows and cyclic relations
- this will probably fix https://github.com/kestra-io/kestra-ee/issues/4980

the issue was recursiveFlowTopology was returning a lot of duplicates, it was aggravated when having many Flows and multiple Flow triggers
2025-09-09 13:06:20 +02:00
Karthik D
381c7a75ad chore(core): use simple search input on blueprints listing (#11034)
Closes https://github.com/kestra-io/kestra/issues/11002.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-09 12:54:58 +02:00
louispy
1688c489a9 chore(flows): improve visibility of horizontal scroll bar on listing (#11163)
Closes https://github.com/kestra-io/kestra/issues/11158.

Co-authored-by: louispy <louisleslie98@gmail.com>
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-09-09 12:40:28 +02:00
AKSHAT GUPTA
93ccbf5f9b chore(core): separate data loading from graph node rendering on dependency view (#11155)
Relates to https://github.com/kestra-io/kestra/issues/11125.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-09 12:25:58 +02:00
Barthélémy Ledoux
ac1cb235e5 refactor: avoid importing all of lodash when we only need groupBy (#10870) 2025-09-09 11:34:13 +02:00
dependabot[bot]
9d3d3642e8 build(deps): bump kafkaVersion from 4.0.0 to 4.1.0
Bumps `kafkaVersion` from 4.0.0 to 4.1.0.

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

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-09 09:56:38 +02:00
Suguresh
3d306a885e feat(core): add extra date format options (#10237)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-09 09:31:49 +02:00
Antoine Gauthier
ef193c5774 feat(core): add a new date format option with milliseconds (#11108)
Closes https://github.com/kestra-io/kestra/issues/11028.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-09 09:20:37 +02:00
AmbarMishra973
d0f46169f4 feat(executions): make the id field a link that can be opened in a new tab (#10963)
Closes https://github.com/kestra-io/kestra/issues/10906.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-09-09 09:13:49 +02:00
François Delbrayelle
3005ab527c fix(outputs): open external file was not working (#11154) 2025-09-08 17:45:19 +02:00
Barthélémy Ledoux
688e2af12b chore: update eslint config for vue files (#9891) 2025-09-08 16:42:33 +02:00
Nicolas K.
4c0a05f484 fix(test): flaky Scheduler trigger change test (#11153)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-09-08 16:33:23 +02:00
zaib shamsi
108f8fc2c7 feat(executions): nicer exception message for the HttpFunction
### What I did

- Improved the exception message in HttpFunction.java to make debugging easier.

### Why

- The original message was too generic. This change makes it clearer where the issue occurs.
2025-09-08 15:04:12 +02:00
Barthélémy Ledoux
8b81a37559 refactor: make folder structure of no-code use "no-code" (#11122) 2025-09-08 14:15:04 +02:00
Barthélémy Ledoux
9222f97d63 fix(core): multipanel split creates super big panels (#11123) 2025-09-08 14:14:40 +02:00
brian.mulier
43e3591417 chore(ci): fail-safe update-plugin-kestra-version.sh 2025-09-08 12:02:28 +02:00
brian.mulier
438dc9ecf6 chore(ci): create branch if not exist on update-plugin-kestra-version.sh 2025-09-08 11:45:15 +02:00
brian-mulier-p
7292837c58 chore(ci): add LTS tagging (#11131) 2025-09-08 11:13:16 +02:00
brian.mulier
7fa93d7764 chore(version): update to version 'v1.1.0-SNAPSHOT'. 2025-09-08 10:08:34 +02:00
brian.mulier
a3c9b35b25 fix(ci): no more RC semver check on plugins 2025-09-08 09:56:11 +02:00
brian.mulier
2c03101422 fix(ci): no more RC semver check on plugins 2025-09-08 09:54:42 +02:00
brian.mulier
7ee2cca3ae fix(ci): no more RC semver check 2025-09-08 09:54:42 +02:00
brian.mulier
ddb48a4384 fix(ci): no more RC semver check 2025-09-08 09:51:31 +02:00
AJ Emerich
a62c5ab637 fix(docs): correct core properties and other docs (#11026)
* fix(docs): correct core properties and other docs

Correct grammar, punctuation, and consistency

* Apply suggestions from code review

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>

* Apply suggestions from code review

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>

* Apply suggestions from code review

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>

---------

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>
2025-09-05 17:44:04 +02:00
AJ Emerich
1b934d31f1 fix(docs): fix trigger docs#11018 2025-09-05 17:40:02 +02:00
Miloš Paunović
f887f53c25 fix(core): allow triggering the task from playground again after a 422 error (#11112)
Closes https://github.com/kestra-io/kestra/issues/11109.
2025-09-05 15:43:43 +02:00
Roman Acevedo
098fa5a4ef fix(topology): prevent flowTopology failing on a Flow for bugged relation
- fixes https://github.com/kestra-io/kestra/issues/11096
2025-09-05 15:16:00 +02:00
Barthélémy Ledoux
c833ab6bc1 fix(flows): avoid updating code if no-code has not changed (#11094) 2025-09-05 14:14:08 +02:00
Krie
dfb7c61455 docs: clarify java version on devcontainer 2025-09-05 13:56:13 +02:00
Florian Hussonnois
ed509d4461 fix(plugins): fix registration of a same plugins and doc reload
Compute a quick CRC32 of each plugin based on the Central Directory
of the JarFile to ensure change detection - allowing re-upload
of a same plugin version (EE)

Fix: kestra-io/kestra-ee#4925
Fix: kestra-io/kestra-ee#4882
2025-09-05 12:55:19 +02:00
dependabot[bot]
8b50f191d8 build(deps): bump mermaid in /ui in the npm_and_yarn group (#10833)
Bumps the npm_and_yarn group in /ui with 1 update: [mermaid](https://github.com/mermaid-js/mermaid).


Updates `mermaid` from 11.8.1 to 11.10.0
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/mermaid@11.8.1...mermaid@11.10.0)

---
updated-dependencies:
- dependency-name: mermaid
  dependency-version: 11.10.0
  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-09-05 12:36:38 +02:00
Piyush Bhaskar
7c5b531117 fix(core): export flow from settings (#11111) 2025-09-05 14:03:18 +05:30
Miloš Paunović
810579bce9 chore(core): amend dependency graph coloring scheme (#11107) 2025-09-05 09:59:46 +02:00
Piyush Bhaskar
a0e7c50b28 fix(core): show inherited kv pairs button only on kv tab (#11104) 2025-09-05 11:40:50 +05:30
François Delbrayelle
bfbc3f70a4 build(main): add skip-test as an option for workflows (#11103) 2025-09-04 19:33:06 +02:00
Ludovic DEHON
9b5c4b0052 feat(build): allow skip test on main ci 2025-09-04 18:55:03 +02:00
AJ Emerich
b7063d986b docs(flow-trigger): add example with conditions (#11099)
Closes https://github.com/kestra-io/kestra/issues/10197
2025-09-04 18:33:37 +02:00
brian.mulier
46ec0ae701 fix(ai): move maxOutputToken default from 50000 to 4000 2025-09-04 18:28:02 +02:00
brian.mulier
ba0615ba01 fix(ai): add some properties to Posthog events 2025-09-04 18:28:02 +02:00
Florian Hussonnois
0a26098a91 fix(core): add method to DefaultPluginRegistry to override of plugin registration 2025-09-04 17:55:56 +02:00
Barthélémy Ledoux
0e2863e6fd feat(flows): update DEFAULT_ACTIVE_TABS to follow settings (#11095) 2025-09-04 16:55:55 +02:00
brian-mulier-p
4b6559203c fix(dashboards): blueprints working for dashboards (#11082)
part of #11076
2025-09-04 15:39:23 +02:00
Malaydewangan09
b6993d71f2 feat(plugins): add plugins 2025-09-04 18:59:28 +05:30
Barthélémy Ledoux
ea6daf381d fix(core): Multipanel layout fixes (#11092) 2025-09-04 15:23:57 +02:00
dependabot[bot]
0649c1309b build(deps): bump software.amazon.awssdk:bom from 2.32.31 to 2.33.1
Bumps software.amazon.awssdk:bom from 2.32.31 to 2.33.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 15:01:05 +02:00
François Delbrayelle
6e21d650f9 feat(plugin): add new priority attr on Plugin annotation (#10975) 2025-09-04 14:21:38 +02:00
Piyush Bhaskar
88acc91323 chore(version): update @kestra-io/ui-libs to version 0.0.244 (#11088) 2025-09-04 17:44:45 +05:30
Miloš Paunović
a822f3b372 fix(flow)*: properly handle tab closing by clicking the cross icon in the corner of the panel (#11086)
Closes https://github.com/kestra-io/kestra/issues/10981.
2025-09-04 14:11:34 +02:00
github-actions[bot]
4a3c6ee9e9 chore(core): remove empty lines at the end of translation files (#11089) 2025-09-04 14:07:38 +02:00
Loïc Mathieu
0ed4e5853d fix(deps): add worker to the platform 2025-09-04 13:33:42 +02:00
Loïc Mathieu
71cdd02230 fix(executions): add logs in case of concurrency limit failure
Fixes #11004
2025-09-04 13:03:00 +02:00
brian.mulier
fedddcde00 fix(ai): move back to Gemini as default 2025-09-04 12:49:18 +02:00
Ludovic DEHON
03f256cb9b chore(deps): follow platform on com.microsoft.playwright:playwright 2025-09-04 11:37:01 +02:00
dependabot[bot]
f9317ba8ea build(deps): bump google-github-actions/setup-gcloud from 2 to 3
Bumps [google-github-actions/setup-gcloud](https://github.com/google-github-actions/setup-gcloud) from 2 to 3.
- [Release notes](https://github.com/google-github-actions/setup-gcloud/releases)
- [Changelog](https://github.com/google-github-actions/setup-gcloud/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/setup-gcloud/compare/v2...v3)

---
updated-dependencies:
- dependency-name: google-github-actions/setup-gcloud
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:35:56 +02:00
dependabot[bot]
eefca3d7a4 build(deps): bump google-github-actions/auth from 2 to 3
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2 to 3.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2...v3)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:35:37 +02:00
dependabot[bot]
96b9e3c74b build(deps): bump mailchecker from 6.0.17 to 6.0.18 in /ui
Bumps [mailchecker](https://github.com/FGRibreau/mailchecker) from 6.0.17 to 6.0.18.
- [Changelog](https://github.com/FGRibreau/mailchecker/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FGRibreau/mailchecker/compare/v6.0.17...v6.0.18)

---
updated-dependencies:
- dependency-name: mailchecker
  dependency-version: 6.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:34:34 +02:00
dependabot[bot]
0a78778e5c 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.9 to 0.38.11.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.9...v0.38.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:27:48 +02:00
dependabot[bot]
5342948bfb build(deps): bump aquasecurity/trivy-action from 0.32.0 to 0.33.0
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.32.0 to 0.33.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](https://github.com/aquasecurity/trivy-action/compare/0.32.0...0.33.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:26:05 +02:00
brian.mulier
f9beb0f4af fix(ai): add model-name to configuration example when Copilot is not configured 2025-09-04 11:25:21 +02:00
Ludovic DEHON
70c1621025 chore(deps): update most of js deps 2025-09-04 11:24:37 +02:00
Loïc Mathieu
a9098e7dc9 fix(tests): reduce test duration 2025-09-04 11:04:13 +02:00
Loïc Mathieu
249839833c chore(system): move the standalone runner to the cli module 2025-09-04 11:04:13 +02:00
Loïc Mathieu
97ec24fc6a chore(system): merge Indexer with the IndexerInterface 2025-09-04 11:04:13 +02:00
Loïc Mathieu
be5e24217b chore(system): extract the scheduler to its own module 2025-09-04 11:04:13 +02:00
Loïc Mathieu
a5724bcb18 chore(system): extract the executor to its own module 2025-09-04 11:04:13 +02:00
Loïc Mathieu
f3057d2d57 chore(system): extract the worker to its own module 2025-09-04 11:04:13 +02:00
Roman Acevedo
e8a953fc6b test: disable flaky test AbstractRunnerTest.flowTriggerWithConcurrencyLimit
- sometimes fails on Kafka tests: https://github.com/kestra-io/kestra-ee/actions/runs/17382883576/attempts/1#summary-49344101977
- it will be fixed during cooldown here https://github.com/kestra-io/kestra/issues/10758
2025-09-04 10:42:17 +02:00
Barthélémy Ledoux
267f4fcc86 fix(flow): cleanup executions' graph and flow on execution reset (#11075)
* fix: typescript issue in LowCodeEditor

* fix(flow): cleanup executions' graph and flow on execution reset

* add tsexpect error
2025-09-04 10:17:48 +02:00
github-actions[bot]
af1e2e3059 chore(core): localize to languages other than english (#11074)
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-09-04 09:51:32 +02:00
Anna Geller
638d58697b fix: too long sidebar names (#11073) 2025-09-04 09:44:36 +02:00
brian-mulier-p
0ae9374bf5 fix(ai): optional flowYaml in generateFlow endpoint (#10974)
closes kestra-io/kestra-ee#4286
2025-09-03 14:50:59 +02:00
Miloš Paunović
6a0344a09e chore(core): improve dependency graph user experience (#10994)
Closes https://github.com/kestra-io/kestra/issues/10925.
Closes https://github.com/kestra-io/kestra-ee/issues/4865.
2025-09-03 14:41:40 +02:00
Miloš Paunović
e46b4a75d1 fix(flows): pass proper namespace id on flow creation (#11031) 2025-09-03 13:57:04 +02:00
Ludovic DEHON
8fe1bae739 chore(deps): remove unrequired deps from MakeFile 2025-09-03 12:54:57 +02:00
Ludovic DEHON
9ef59fdd23 chore(deps): upgrade some platform deps 2025-09-03 12:54:09 +02:00
Roman Acevedo
79ab4415ad fix(storage): avoid NPE in PurgeKV when no metadata or expiration date
- fixes https://github.com/kestra-io/kestra/issues/11019
2025-09-03 12:52:20 +02:00
brian.mulier
dd3829cc48 fix(ai): enhance FlowYamlBuilder prompt (#11027) 2025-09-03 12:08:54 +02:00
brian.mulier
fa187904f9 fix(ai): remove @Requires on API key as it's already done transitively (#11027) 2025-09-03 12:08:54 +02:00
brian.mulier
c659599b1f chore(deps): add langchain4j version to platform (#11027) 2025-09-03 12:08:54 +02:00
Florian Hussonnois
85db1eafa7 fix(plugins): add plugin registry hash to invalidate cache
Fixes: kestra-io/kestra-ee#4882
2025-09-03 11:51:39 +02:00
Florian Hussonnois
9863f0807f fix(flows): fix dynamic default inputs (#11014)
Fixes: #11014
2025-09-03 10:25:33 +02:00
brian-mulier-p
b3b0d630cf feat(ai): langchain4j implementation of AI Copilot (#10995)
closes kestra-io/kestra-ee#4710
2025-09-03 10:04:07 +02:00
Florian Hussonnois
97665449a8 fix(system): rename service EMPTY state to INACTIVE (kestra-io/kestra-ee#4838)
Related-to: kestra-io/kestra-ee#4838
2025-09-03 09:11:36 +02:00
AJ Emerich
2e1ed792e9 fix(docs): fix grammar and punctuation in core storage (#11020)
* fix(docs): fix grammar and punctuation in core storage

* Apply suggestions from code review

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>

---------

Co-authored-by: Anna Geller <anna.m.geller@gmail.com>
2025-09-02 23:49:01 +02:00
Ludovic DEHON
59e3ae5922 chore(deps): use a common http5 client 2025-09-02 22:49:53 +02:00
Anna Geller
d46b54746a fix(docs): improve grammar and examples (#11017)
* fix(docs): improve grammar and examples

* fix: comma and whitespace issues in CI
2025-09-02 20:04:44 +02:00
Ludovic DEHON
4fbaed744b chore(deps): bump micronaut to 4.9.3 2025-09-02 19:44:19 +02:00
AJ Emerich
b0638437d5 fix(kv-purge): clean up the docs (#11016) 2025-09-02 19:21:01 +02:00
Ludovic DEHON
e3f9d0f8ff chore(deps): bump org.sonarqube from 6.2.0.5505 to 6.3.1.5724 2025-09-02 18:23:30 +02:00
Barthélémy Ledoux
ae80738f33 fix(docs): remove url hash change when opening a docs (#11000) 2025-09-02 15:44:55 +02:00
Barthélémy Ledoux
2b4f208569 refactor(namespaces): less code in namespace files editor (#9912) 2025-09-02 14:41:24 +02:00
Barthélémy Ledoux
8acbc8ba03 fix(nocode): KeyValue Pairs have a bug (#10998) 2025-09-02 14:19:55 +02:00
github-actions[bot]
d92cc099c7 chore(core): localize to languages other than english (#11012)
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-09-02 14:07:51 +02:00
Piyush Bhaskar
3d806022bc feat(executions): allow changing the value of input before replaying an execution (#11010) 2025-09-02 16:39:28 +05:30
Roman Acevedo
b72bafe344 Revert "chore(deps): bump com.gradleup.shadow to 9.1.0"
This reverts commit 55c89244b4.
2025-09-02 12:22:05 +02:00
Barthélémy Ledoux
5e2063aa57 fix(no-code): explore allOf clauses for $deprecated flags (#10999) 2025-09-02 11:35:46 +02:00
Miloš Paunović
3838f8c87f fix(executions): clear errors on selected value change in outputs tab (#11007)
Closes https://github.com/kestra-io/kestra/issues/10979.
2025-09-02 11:16:59 +02:00
Ludovic DEHON
55c89244b4 chore(deps): bump com.gradleup.shadow to 9.1.0 2025-09-02 10:02:03 +02:00
Roman Acevedo
59c9ae57b7 ci: fix setversion-tag.yml not triggering a main.yml job on a pushed tag
the missing token: ${{ secrets.GH_PERSONAL_TOKEN }} is the only difference between this CI and EE CI, so it is probably the right fix
2025-09-01 16:25:04 +02:00
Roman Acevedo
1b8a2cd19a tests: add default false value to ui-anonymous-usage-report.enabled
to avoid having to configure it in tests
2025-09-01 16:02:17 +02:00
Miloš Paunović
16992626d2 fix(core): allow removal of block items from no code editor (#10992)
Closes https://github.com/kestra-io/kestra-ee/issues/4862.

Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-09-01 10:50:06 +02:00
Ludovic DEHON
2c94922736 feat(core): add thread http client, deadlock and virtual thread metrics 2025-08-31 23:57:34 +02:00
Ludovic DEHON
b45c0b13be refactor(ui): posthog as composable and option for ui telemetry
relate to kestra-io/kestra-ee#4831
2025-08-29 19:36:58 +02:00
Nicolas K.
aed055dcb1 fix(storage): delete the metadata with the key when we delete an KV s… (#10990)
* fix(storage): delete the metadata with the key when we delete an KV store entry

* Update core/src/main/java/io/kestra/core/storages/kv/InternalKVStore.java

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

* fix(storage): fix typo

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: brian-mulier-p <bmmulier@hotmail.fr>
2025-08-29 17:28:39 +02:00
Nicolas K.
cfe107705b feat(storage): add purge kv task (#10964)
* feat(storage): add purge kv task

* feat(storage): add purge kv task

* feat(storage): add sanity check

* feat(storage): clean code

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-29 16:24:41 +02:00
brian-mulier-p
58da5fe7d8 fix(flows): add version autocompletion (#10973)
closes kestra-io/kestra-ee#4702
2025-08-29 15:34:37 +02:00
brian.mulier
869f7c718c fix(secrets): base64-encoded secrets value obfuscation
closes kestra-io/kestra-ee#4639
2025-08-29 15:33:52 +02:00
brian.mulier
985ed2ac89 fix(secrets): empty secrets ignored in secret obfuscation
closes #10526
2025-08-29 15:33:52 +02:00
Loïc Mathieu
bf0361778d fix(executions): clear errors/finally/afterExecution branches when changing the state of a taskrun
As changing the state of a taskrun will restart the flow, if we didn't clear those branches, the flow would not resart properly.

Fixes https://github.com/kestra-io/kestra-ee/issues/3211
2025-08-29 15:13:06 +02:00
Miloš Paunović
04a6adf012 chore(executions): make dependency graph table links navigate to execution pages (#10988)
Closes https://github.com/kestra-io/kestra-ee/issues/4866.
2025-08-29 14:27:08 +02:00
Piyush Bhaskar
0ffb71c25d fix(ui): do not allow white space in password (#10987) 2025-08-29 16:47:45 +05:30
Miloš Paunović
63659eca79 chore(executions): optimize dependency graph state updates (#10985)
Closes https://github.com/kestra-io/kestra/issues/10795.
2025-08-29 12:58:03 +02:00
Loïc Mathieu
357d4e0d69 feat(executions): allow flow trigger on concurrency limit
Closes https://github.com/kestra-io/kestra-ee/issues/3270

This allow listening to the QUEUED state on the flow trigger.
This also fixes an issue that when concurrency limit is setup, you would not listen to the RUNNING state.
2025-08-29 11:07:43 +02:00
Piyush Bhaskar
cf301a1192 chore(core): fix border color of validation btn and add loading state in Action button (#10982) 2025-08-29 14:08:23 +05:30
Ludovic DEHON
bc08fc7d07 fix(core): disable useless health check 2025-08-28 20:47:02 +02:00
Ludovic DEHON
85ac124740 feat(core): add netty metrics on micrometer 2025-08-28 20:46:28 +02:00
Ludovic DEHON
8021257bf4 fix(core): align open source & ee configuration 2025-08-28 20:45:50 +02:00
dependabot[bot]
c4022d2e3c build(deps): bump flyingSaucerVersion from 9.13.2 to 9.13.3
Bumps `flyingSaucerVersion` from 9.13.2 to 9.13.3.

Updates `org.xhtmlrenderer:flying-saucer-core` from 9.13.2 to 9.13.3
- [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.13.2...v9.13.3)

Updates `org.xhtmlrenderer:flying-saucer-pdf` from 9.13.2 to 9.13.3
- [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.13.2...v9.13.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 16:10:35 +02:00
dependabot[bot]
ee48865706 build(deps): bump software.amazon.awssdk:bom from 2.32.26 to 2.32.31
Bumps software.amazon.awssdk:bom from 2.32.26 to 2.32.31.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 14:34:54 +02:00
dependabot[bot]
f7a23ae459 build(deps): bump org.jsoup:jsoup from 1.21.1 to 1.21.2
Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.21.1 to 1.21.2.
- [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.21.1...jsoup-1.21.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 14:33:28 +02:00
Miloš Paunović
a13909337e feat(namespaces): introduce inherited key/value pairs drawer (#10967)
Closes https://github.com/kestra-io/kestra-ee/issues/2830.
2025-08-28 13:06:10 +02:00
Piyush Bhaskar
502f0362e3 fix(flows): properly delete task from topology to reflect everywhere (#10924)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-28 16:17:18 +05:30
brian-mulier-p
dbaa35370f fix(plugins): hide "apps", "appBlocks", "charts", "dataFilters", "dataFiltersKPI" types in Plugins page (#10965)
closes #10464
2025-08-28 11:36:50 +02:00
dependabot[bot]
59a93b2ab9 build(deps): bump com.github.ksuid:ksuid from 1.1.3 to 1.1.4
Bumps [com.github.ksuid:ksuid](https://github.com/ksuid/ksuid) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/ksuid/ksuid/releases)
- [Commits](https://github.com/ksuid/ksuid/compare/ksuid-1.1.3...ksuid-1.1.4)

---
updated-dependencies:
- dependency-name: com.github.ksuid:ksuid
  dependency-version: 1.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 11:03:27 +02:00
dependabot[bot]
bff8026ebb build(deps): bump actions/setup-java from 4 to 5
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 11:02:21 +02:00
dependabot[bot]
4481318023 build(deps): bump jakarta.mail:jakarta.mail-api from 2.1.3 to 2.1.4
Bumps [jakarta.mail:jakarta.mail-api](https://github.com/jakartaee/mail-api) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/jakartaee/mail-api/releases)
- [Commits](https://github.com/jakartaee/mail-api/compare/2.1.3...2.1.4)

---
updated-dependencies:
- dependency-name: jakarta.mail:jakarta.mail-api
  dependency-version: 2.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 10:59:56 +02:00
dependabot[bot]
c8b33dd690 build(deps): bump net.thisptr:jackson-jq from 1.4.0 to 1.5.0
Bumps [net.thisptr:jackson-jq](https://github.com/eiiches/jackson-jq) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/eiiches/jackson-jq/releases)
- [Commits](https://github.com/eiiches/jackson-jq/compare/1.4.0...1.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 10:58:36 +02:00
Nicolas K.
05b485e6cc feat(API): add a new endpoint to replay and execution / task with new… (#10868)
* feat(API): add a new endpoint to replay and execution / task with new inputs

* clean(API): code review

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-28 10:35:39 +02:00
brian-mulier-p
78a489882f feat(executions): add autoselectFirst property to select inputs (#10919)
closes #9691
2025-08-28 09:39:05 +02:00
github-actions[bot]
b872223995 chore(core): localize to languages other than english (#10933)
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-08-28 08:26:32 +02:00
YannC
e3d2b93c6b feat: export auditlogs through a streamed file (#10569) 2025-08-27 23:44:34 +02:00
brian.mulier
1699403c95 fix(dashboard): working dashboard edit 2025-08-27 22:36:15 +02:00
brian.mulier
b3fa5ead6d fix(dashboard): don't duplicate id on source retrieval 2025-08-27 21:04:02 +02:00
YannC.
d4e7b0cde4 fix: throw an error when trying to create a flow with a reserved keyword id
close #5832
2025-08-27 19:17:04 +02:00
brian-mulier-p
5da4d88738 feat(dashboard): mandatory id + add autogenerated id to source for legacy handling (#10912)
closes kestra-io/kestra-ee#4484
2025-08-27 14:10:28 +02:00
Miloš Paunović
d60ec87375 chore(core): align flow options in tour to the top of the page (#10920)
Closes https://github.com/kestra-io/kestra/issues/10915.
2025-08-27 13:54:07 +02:00
brian-mulier-p
cf87145bb9 fix(docs): move proxy target from kestra to localhost and add UI README.md (#10916)
closes #10902
2025-08-27 11:50:19 +02:00
brian.mulier
0e2ddda6c7 fix(core): allow some left menu methods inheritance
part of kestra-io/kestra-ee#4728
2025-08-27 10:47:29 +02:00
brian-mulier-p
3b17b741f1 fix(doc): remove .env.development.local instructions as it's no longer required
closes #10902
2025-08-27 10:22:28 +02:00
Miloš Paunović
21c43e79e2 feat(core): implement improved graph for namespace dependencies view (#10909)
Closes https://github.com/kestra-io/kestra/issues/10634.
2025-08-27 08:34:24 +02:00
Piyush Bhaskar
810e80d989 fix(plugins): improve plugin documentation update logic for element selection (#10908) 2025-08-26 16:53:30 +05:30
Loïc Mathieu
2aafe15124 chore: add JacksonMapperTest.toMap() 2025-08-26 10:38:22 +02:00
Loïc Mathieu
cf866c059a fix: pause tasks didn't process erros or onFinally tasks
Fixes #9794

The Pause task was previously immediatly termindated without taken into account any errors or finally block.
To allow processing those blocks, we need to store the terminated state in the output, then use it to resolve the final state.
2025-08-26 10:38:22 +02:00
Loïc Mathieu
370fe210e5 fix: allow timeout on the Pause task 2025-08-26 10:38:22 +02:00
Abdur Rahman S
83e98be413 chore(executions): add parent execution link to execution overview page (#10810)
Closes https://github.com/kestra-io/kestra/issues/10745.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-26 10:12:37 +02:00
Piyush Bhaskar
7d4d1631d2 fix(core): do not overflow the version selection on release notes (#10903) 2025-08-26 13:25:58 +05:30
github-actions[bot]
98534f16e2 chore(core): localize to languages other than english (#10904)
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-08-26 09:48:43 +02:00
Barthélémy Ledoux
b308697449 refactor(flows): generalize no code editor (#10873) 2025-08-26 09:33:21 +02:00
Piyush Bhaskar
62e0550efd fix(ui): bring better small chart and tooltip. (#10839)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-26 12:59:16 +05:30
YannC
1711e7fa05 fix: allow to enforce editor view when list is unreadable, also truncate too long column (#10885) 2025-08-26 09:10:39 +02:00
github-actions[bot]
04a3978fd2 chore(core): localize to languages other than english (#10901)
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-08-26 08:47:39 +02:00
Biplab Bera
2d348786c3 chore(core): added closing button for horizontal panel in playground (#10777)
Closes https://github.com/kestra-io/kestra/issues/10660.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-26 08:45:08 +02:00
Miloš Paunović
041a31e022 chore(core): make playground feature enabled by default (#10891)
Related to https://github.com/kestra-io/kestra-ee/issues/4555.
2025-08-26 08:30:44 +02:00
brian.mulier
11a6189bb8 fix(logs): emitAsync is now keeping messages order 2025-08-25 16:31:46 +02:00
brian.mulier
5c864eecc8 fix(logs): higher max message length to keep stacktraces in a single log 2025-08-25 16:31:46 +02:00
brian.mulier
af6d15dd13 chore(deps): bump Micronaut platform to 4.9.2
closes #10626
closes #10788
2025-08-25 16:31:46 +02:00
Piyush Bhaskar
0b555b3773 fix(core): return URI as string (#10892) 2025-08-25 18:55:54 +05:30
Piyush Bhaskar
6ed4c5af7e fix(core): show the logs for the task from topology graph. (#10890) 2025-08-25 18:39:30 +05:30
Barthélémy Ledoux
3752481756 chore(flows): load dependencies only once (#10782)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-25 14:59:30 +02:00
Karthik D
94dc62aee1 chore(core): prevent running the invalid flow in playground (#10869)
Closes https://github.com/kestra-io/kestra/issues/10659.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-25 14:51:04 +02:00
Piyush Bhaskar
09c79f76d7 fix(core): show the proper origin in webhook curl command (#10878)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-25 14:20:04 +05:30
Piyush Bhaskar
086fd2a4cb fix(core): scope the styling to fix overflow of trigger render. (#10880) 2025-08-25 14:18:00 +05:30
YannC
3f9a2d9a57 feat: add action to merge release note between OSS and EE (#10882) 2025-08-25 10:41:53 +02:00
YannC
119bd51170 fix: do no trim . in file path when it starts with one when creating namespace file (#10876) 2025-08-25 10:18:41 +02:00
Anna Geller
552b3d7476 docs: add agents guidelines (#10875) 2025-08-25 08:53:17 +02:00
Florian Hussonnois
795f9c9a17 fix(core): add missing equals/hashcode methods on UnitTest 2025-08-22 13:29:13 +02:00
Florian Hussonnois
df430ded61 fix(system): fix count in AbstractJdbcRepository 2025-08-22 13:29:13 +02:00
Roman Acevedo
a6844e0ecf ci: fix by making inputs accept both dispatch and callable 2025-08-22 11:13:58 +02:00
Roman Acevedo
f71574cfb5 ci: simplify docker ci and push minor semver (#10848)
This PR modify our existing CI to allow publishing our docker image with 2 semver tags.
Example: for a CI on a tag v0.24.99 it will push both tags v0.24.99 and v0.24.

When this CI is settled on this repo (after one micro release for example), I will do the same for EE.

What has been done:

merge docker.yml into workflow-publish-docker.yml
make workflow-publish-docker.yml handle both tags (releases) and develop CI
when in a tag CI, extract the minor version, push it as well as the full vMAJOR.MINOR.PATCH version (see the related issue Add Multiple Semantic Version (SemVer) Tags for Docker Images #10575)
2025-08-22 10:41:59 +02:00
Nicolas K.
c5341e56e9 fix(tests): flaky consumer test (#10853)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-22 09:37:43 +02:00
Piyush Bhaskar
88b0723147 fix(flows): fixes revision restore for a flow (#10841) 2025-08-22 12:50:13 +05:30
Piyush Bhaskar
f79fcf5734 chore(versions) : bump the ui-libs (#10862) 2025-08-22 12:45:12 +05:30
Barthélémy Ledoux
cf27827f20 fix(core): when refreshing a multipanel editor, sizes are not kept (#10858) 2025-08-22 12:16:51 +05:30
Barthélémy Ledoux
408b6b97a7 fix(flows): in no-code refreshing a message will update its value (#10851) 2025-08-21 22:32:39 +02:00
Piyush Bhaskar
d57753e62b fix(core): Choose File button and hover on btn text in light theme (#10857) 2025-08-21 23:20:27 +05:30
Nicolas K.
2571eaf56c fix: #4442 extract tenant id from file path (#10850)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-21 17:40:10 +02:00
Florian Hussonnois
37ea7f31a0 feat(flows): add pebble expression support for all input defaults (#9762)
Fix: #9762
2025-08-21 17:14:15 +02:00
Roman Acevedo
478c911718 fix(tests): a TestSuite with any ERROR could not end in ERROR 2025-08-21 16:43:16 +02:00
Piyush Bhaskar
1bce0d673f fix(core): update params for flow navigation (#10847) 2025-08-21 19:43:26 +05:30
Florian Hussonnois
609a5b8066 feat(flow): add support for optional flow outputs
Add the new required property to the flow output
model. By default, all flow's outputs are required

Fixes: kestra-io/kestra-ee#3969
2025-08-21 16:09:22 +02:00
Florian Hussonnois
6182015a6f feat(system): report additional server events
Part-of: kestra-io/kestra-ee#3014
2025-08-21 14:50:11 +02:00
brian.mulier
6f8044f347 fix(ai): make sure accept / decline AI banner doesn't hide code editor (#10835)
closes kestra-io/kestra-ee#4273
2025-08-21 14:45:32 +02:00
brian.mulier
b3b7596bf4 fix(ai): AI Copilot instructions for better results (#10835)
closes kestra-io/kestra-ee#4273
2025-08-21 14:45:32 +02:00
brian.mulier
36b1c14424 fix(ai): add instructions for AI Copilot configuration if not enabled yet (#10835)
closes kestra-io/kestra-ee#4273
2025-08-21 14:45:32 +02:00
brian-mulier-p
1aef9578d9 fix(kv): Set task should convert numbers to string if kvType == STRING (#10836) 2025-08-21 09:33:03 +02:00
Piyush Bhaskar
6a07e3c048 fix(core): truncate the overflowing text from button when zoomed #10775 2025-08-21 01:14:28 +05:30
Owen Warnack
b643954921 fix(ui): show lock icon for namespace in No-Code editor (#10667)
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-08-21 00:06:23 +05:30
Piyush Bhaskar
fe1ae290d0 fix(core): show validation button icon 2025-08-20 23:48:14 +05:30
Hamza
6ae2fde78f fix(core): truncate the overflowing text from button when zoomed (#10775)
Co-authored-by: Piyush Bhaskar <impiyush0012@gmail.com>
2025-08-20 23:28:53 +05:30
Loïc Mathieu
260f5c427b fix(system): properly close the ScheduledExecutorService tasks
This avoids having running threads while the component is supposed to be closed.
2025-08-20 14:23:13 +02:00
dependabot[bot]
f2dbc41cdb build(deps): bump opensearchRestVersion from 3.1.0 to 3.2.0
Bumps `opensearchRestVersion` from 3.1.0 to 3.2.0.

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 14:00:48 +02:00
dependabot[bot]
39fdb7ed5d build(deps): bump com.github.oshi:oshi-core from 6.8.2 to 6.8.3
Bumps [com.github.oshi:oshi-core](https://github.com/oshi/oshi) from 6.8.2 to 6.8.3.
- [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.2...oshi-parent-6.8.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 13:57:41 +02:00
dependabot[bot]
c6b9c445c5 build(deps): bump com.github.docker-java:docker-java-transport-httpclient5
Bumps [com.github.docker-java:docker-java-transport-httpclient5](https://github.com/docker-java/docker-java) from 3.5.3 to 3.6.0.
- [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.3...3.6.0)

---
updated-dependencies:
- dependency-name: com.github.docker-java:docker-java-transport-httpclient5
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 13:57:10 +02:00
dependabot[bot]
da8992f130 build(deps): bump com.google.cloud:libraries-bom from 26.65.0 to 26.66.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.65.0 to 26.66.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.65.0...v26.66.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 13:56:43 +02:00
dependabot[bot]
e448690086 build(deps): bump software.amazon.awssdk:bom from 2.32.21 to 2.32.26
Bumps software.amazon.awssdk:bom from 2.32.21 to 2.32.26.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 13:56:21 +02:00
Florian Hussonnois
3929bf6172 feat(system): add distinct server-events for reporting
Refactor the services used to generate periodic reports on server usage.

Related-to: kestra-io/kestra-ee#3014
2025-08-20 12:20:31 +02:00
Piyush Bhaskar
ab9951466d feat(core): implement tab tracking on editor events (#10781) 2025-08-20 14:26:46 +05:30
brian.mulier
ef59a6de26 fix(tests): add test on task runners to assert they can work and transmit their wdir 2025-08-20 09:55:01 +02:00
lizi3
0a64ae7e63 perf(sql):Optimize SQL performance by replacing SQL_CALC_FOUND_ROWS with COUNT(*) 2025-08-20 09:54:39 +02:00
lizi3
8c3cd2856a perf(sql):Optimize SQL performance by replacing SQL_CALC_FOUND_ROWS with COUNT(*) 2025-08-20 09:54:39 +02:00
AJ Emerich
6def8ef831 fix(webhook-trigger): fix documentation typos (#10790) 2025-08-20 09:18:42 +02:00
Piyush Bhaskar
0cc1bffc20 refactor(core): new No Data page when no versioned plugins (#10751)
* refactor(core): new No Data page when no versioned plugins

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

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

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <actions@github.com>
2025-08-20 12:23:51 +05:30
Barthélémy Ledoux
3bdf55a649 refactor(flows): rename MultiPanelFlowEditorView and extract MultiPanelEditorTabs component (#10783) 2025-08-19 16:31:34 +02:00
Barthélémy Ledoux
767a375292 fix(ui): update context docs menu links and section titles (#10768) 2025-08-19 16:24:16 +02:00
brian.mulier
1509ce9b98 fix(core): change cache policy on files returned by webserver that needs to stay fresh
closes #7499
2025-08-19 11:52:48 +02:00
brian.mulier
5a3f3d3312 fix(namespaces): properly send editor content upon creating / updating ns file
part of #7499
2025-08-19 11:52:48 +02:00
Roman Acevedo
6394c337ae fix(tests): filter out ExecutionKind.TEST from FlowTriggers
- fixes Silence flow trigger on TEST-kind executions kestra-ee#4689
2025-08-19 11:03:48 +02:00
Piyush Bhaskar
be4518466f fix(kv): fixes KV creation using authStore 2025-08-19 11:39:29 +05:30
Piyush Bhaskar
543bed48c9 feat(core): changes to introduce Namespace Context (#10750) 2025-08-19 11:06:58 +05:30
Barthélémy Ledoux
5e57d11b73 refactor: make auth store use pinia (#10558)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
Co-authored-by: Piyush-r-bhaskar <impiyush0012@gmail.com>
2025-08-18 15:32:13 +02:00
Piyush Bhaskar
98189392a2 fix(core): show flow graph inside blueprint detail (#10771) 2025-08-18 17:59:13 +05:30
Piyush Bhaskar
ac9a01964a refactor(executions): implement splitter for execution outputs (#10677) 2025-08-18 17:58:50 +05:30
Piyush Bhaskar
8479323f97 refactor: migrate Splitpanes for Element Plus el-splitter. (#10669)
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-08-18 16:05:34 +05:30
brian.mulier
4b80b92423 refacto(namespaces): uniformize namespaces usage & retrieval
closes kestra-io/kestra-ee#3500
closes kestra-io/kestra-ee#3356
closes kestra-io/kestra-ee#3163
closes kestra-io/kestra-ee#4713
closes kestra-io/kestra-ee#3210
closes kestra-io/kestra#10700
related to kestra-io/kestra#10701
2025-08-18 12:18:47 +02:00
brian.mulier
2e7d714bcb chore(deps): bump ui-libs from 0.0.237 to 0.0.238 2025-08-18 12:18:47 +02:00
Roman Acevedo
73cf7f04fb test(e2e): make sure used docker image is local 2025-08-18 12:03:44 +02:00
Roman Acevedo
ac0ab7e8fa Revert "build(deps): bump com.gradleup.shadow from 8.3.9 to 9.0.1"
This reverts commit fa6da9bd0b.
2025-08-18 12:03:44 +02:00
Roman Acevedo
c1876e69ed test(e2e): print logs if backend failed to start 2025-08-18 12:03:44 +02:00
Roman Acevedo
cf73a80f2e test(e2e): fix e2e marked as cancelled when near timeout 2025-08-18 12:03:44 +02:00
Barthélémy Ledoux
53687f4a1f fix(core): avoid triggering hundreds of reactivity updates for each icon (#10766) 2025-08-18 11:37:37 +02:00
Florian Hussonnois
749bf94125 fix(core): fix preconditions rendering for ExecutionOutputs (#10651)
Ensure that preconditions are always re-rendered for any
new executions

Changes:
* add new fluent skipCache methods on RunContextProperty and Property
  classes

Fix: #10651
2025-08-18 09:24:58 +02:00
Nicolas K.
25a7994f63 fix(test): disable kafka concurrency queue test (#10755)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-14 16:59:21 +02:00
Anna Geller
e03c894f3a fix: spelling 2025-08-14 15:27:09 +02:00
Piyush Bhaskar
99772c1a48 fix(ui): fixes logo cut off on no permission interface (#10739) 2025-08-14 18:43:28 +05:30
Roman Acevedo
93d6b816bf fix(tests): namespace binding was breaking filtering in Flow page
fixes https://github.com/kestra-io/kestra-ee/issues/4691

the additional namespace binding in Tabs was added in PR https://github.com/kestra-io/kestra/pull/10543 to solve the special case of Namespace creation
2025-08-14 13:39:42 +02:00
Nicolas K.
a3b0512bec feat(storages): #10636 add tenant id to mock trigger (#10749)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-14 12:07:21 +02:00
Loïc Mathieu
265f72b629 fix(execution): parallel flowable may not ends all child flowable
Parallel flowable tasks like `Parallel`, `Dag` and `ForEach` are racy. When a task fail in a branch, other concurrent branches that have flowable may never ends.
We make sure that all children are terminated when a flowable is itself terminated.

Fixes #6780
2025-08-14 12:06:15 +02:00
YannC
07a8d9a665 fix: avoid file being displayed as diff in namespace file editor (#10746)
close #10744
2025-08-14 10:38:33 +02:00
Piyush Bhaskar
59bd607db2 refactor(misc): add misc module to override (#10737) 2025-08-14 13:48:29 +05:30
Nicolas K.
1618815df4 Feat/add get path without tenant (#10741)
* feat(storages): #10636 add get path without tenant id

* feat(storages): #10636 remove first / from get path method

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-13 17:48:03 +02:00
Nicolas K.
a2c3799ab7 feat(storages): #10636 add get path without tenant id (#10740)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-13 16:51:09 +02:00
Loïc Mathieu
986a2b4d11 chore(ci): don't run docker PR image workflow on forks 2025-08-13 15:32:41 +02:00
Loïc Mathieu
cdd591dab7 fix(tests): makes JdbcQueueTest less flaky 2025-08-13 14:56:39 +02:00
Malaydewangan09
9f5cf5aeb9 fix(): subgroups for better readability 2025-08-13 14:41:47 +05:30
Nicolas K.
cc5f73ae06 wip(storages): add non tenant dependant method to storage interface (#10637)
* wip(storages): add non tenant dependant method to storage interface

* feat(storages): #10636 add instance method to retrieve resources without the tenant id

* fix(stores): #4353 failing unit tests after now that tenant id can't be null

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-13 11:00:25 +02:00
dependabot[bot]
e461e46a1c build(deps): bump io.micrometer:micrometer-core from 1.15.2 to 1.15.3
Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.15.2 to 1.15.3.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.15.2...v1.15.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:52:52 +02:00
dependabot[bot]
fa6da9bd0b build(deps): bump com.gradleup.shadow from 8.3.9 to 9.0.1
Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 8.3.9 to 9.0.1.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](https://github.com/GradleUp/shadow/compare/8.3.9...9.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:52:21 +02:00
dependabot[bot]
3cb6815eac build(deps): bump org.assertj:assertj-core from 3.27.3 to 3.27.4
Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.3 to 3.27.4.
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.3...assertj-build-3.27.4)

---
updated-dependencies:
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:19:45 +02:00
dependabot[bot]
bde9972b26 build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:09:06 +02:00
dependabot[bot]
bc828efec9 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.8 to 0.38.9.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.8...v0.38.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:07:37 +02:00
dependabot[bot]
c62f503f1a build(deps): bump software.amazon.awssdk:bom from 2.32.16 to 2.32.21
Bumps software.amazon.awssdk:bom from 2.32.16 to 2.32.21.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:06:21 +02:00
dependabot[bot]
15a6323122 build(deps): bump flyingSaucerVersion from 9.13.1 to 9.13.2
Bumps `flyingSaucerVersion` from 9.13.1 to 9.13.2.

Updates `org.xhtmlrenderer:flying-saucer-core` from 9.13.1 to 9.13.2
- [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.13.1...v9.13.2)

Updates `org.xhtmlrenderer:flying-saucer-pdf` from 9.13.1 to 9.13.2
- [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.13.1...v9.13.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:05:10 +02:00
dependabot[bot]
21cb7b497d build(deps): bump org.jooq:jooq from 3.20.5 to 3.20.6
Bumps org.jooq:jooq from 3.20.5 to 3.20.6.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 10:03:54 +02:00
Loïc Mathieu
26cb6ef9ad fix(execution): concurrency limit didn't work with afterExecutions
This is because the execution is never considered fully terminated so concurrency limit is not handled properly.
This should also affect SLA, trigger lock, and other cleaning stuff.

The root issue is that, with a worker task from afterExecution, there are no other update on the execution itself (as it's already terminated) so no execution messages are again processed by the executor.

Because of that, the worker task result message from the afterExecution block is the last message, but unfortunatly as messages from the worker task result have no flow attached, the computation of the final termination is incorrect.
The solution is to load the flow if null inside the executor and the execution is terminated which should only occurs inside afterExecution.

Fixes #10657
Fixes #8459
Fixes #8609
2025-08-13 09:29:46 +02:00
Piyush Bhaskar
95c438515d fix(core): pass viewTypes to initYamlSource (#10704) 2025-08-13 12:32:17 +05:30
Florian Hussonnois
194ae826e5 chore(system): add WorkerJobQueueInterface to properly pass workerId on subscribe 2025-08-12 19:26:31 +02:00
Prayag
31dbecec77 fix(core): Enter key is now validating filter / refreshing data (#9630)
closes #9471

---------

Co-authored-by: brian.mulier <bmmulier@hotmail.fr>
2025-08-12 17:23:10 +02:00
Anna Geller
b39bcce2e8 fix(translation): close https://github.com/kestra-io/kestra/issues/9857 2025-08-12 13:00:14 +02:00
github-actions[bot]
95ac5ce8a7 chore(core): localize to languages other than english (#10697)
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-08-12 12:54:34 +02:00
Piyush Bhaskar
90f913815d fix(core): fix misc store to access configs. (#10692) 2025-08-12 16:24:17 +05:30
Anna Geller
5944db5cc8 fix: translation for sample prompt (#10696) 2025-08-12 12:51:10 +02:00
Loïc Mathieu
577f813eef fix(executions): SLA monitor should take into account restarted executions 2025-08-12 11:46:58 +02:00
Loïc Mathieu
06a9f13676 fix(executions): concurrency limit exceeded when restarting an execution
Fixes #7880
2025-08-12 11:46:58 +02:00
Loïc Mathieu
1fd6e23f96 feat(flows): Flow SLA out of beta
Part-of: https://github.com/kestra-io/kestra-ee/issues/4555
2025-08-12 11:29:32 +02:00
Piyush Bhaskar
9a32780c8c fix(flow): fixes flow deletion inside actions (#10693) 2025-08-12 14:56:31 +05:30
Nicolas K.
af140baa66 Feat/add filters to repositories (#10629)
* wip(repositories): use query filter in the log repository

* feat(repositories): #10628 refactor query builder engine

* fix(repositories): #10628 add sort to findAsych query

* Update core/src/main/java/io/kestra/core/utils/ListUtils.java

Co-authored-by: Loïc Mathieu <loikeseke@gmail.com>

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
Co-authored-by: Loïc Mathieu <loikeseke@gmail.com>
2025-08-12 11:17:47 +02:00
Florian Hussonnois
54b0183b95 fix(system): avoid unsupported type error on ServiceType enum 2025-08-12 10:01:30 +02:00
Loïc Mathieu
64de3d5fa8 fix(executions): correctly fail the request when trying to resume an execution with the wrong inputs
Fixes #9959
2025-08-12 09:39:02 +02:00
Piyush Bhaskar
4c17aadb81 fix(ui): more visible color for deafult edge (#10690) 2025-08-12 12:44:20 +05:30
Piyush Bhaskar
bf424fbf53 fix(core): reduce size of code block text and padding (#10689) 2025-08-12 11:46:52 +05:30
brian.mulier
edcdb88559 fix(dashboard): avoid duplicate dashboard calls + properly refresh dashboards on refresh button + don't discard component entirely on refresh 2025-08-11 22:28:19 +02:00
brian.mulier
9a9d0b995a fix(dashboard): properly use time filters in queries
closes kestra-io/kestra-ee#4389
2025-08-11 22:28:19 +02:00
brian-mulier-p
5c5d313fb0 fix(metrics): restore autocompletion on metrics filter (#10688) 2025-08-11 21:08:56 +02:00
Nicolas K.
dfd4d87867 feat(releases): add test jar to meven central deployment (#10675)
Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-11 15:56:51 +02:00
Piyush Bhaskar
367d773a86 fix(flows): enable the save and makes tab dirty when have unsaved changes in no code (#10671) 2025-08-11 18:35:56 +05:30
brian.mulier
c819f15c66 tests(core): add a test to taskrunners to ensure it's working multiple times on the same working directory
part of kestra-io/plugin-ee-kubernetes#45
2025-08-11 14:59:15 +02:00
Loïc Mathieu
673b5c994c feat(flows): add upstream dependencies in flow dependencies
Closes #10638
2025-08-11 12:43:33 +02:00
Loïc Mathieu
2acf37e0e6 fix(executions): properly fail the task if it contains unsupported unicode sequence
This occurs in Postgres using the `\u0000` unicode sequence. Postgres refuse to store any JSONB with this sequence as it has no textual representation.
We now properly detect that and fail the task.

Fixes #10326
2025-08-11 11:53:39 +02:00
Ludovic DEHON
0d7fcbb936 build(core): create a docker image for each pull request (#10644)
relate to kestra-io/kestra#10643
2025-08-09 00:18:28 +02:00
Miloš Paunović
42b01d6951 chore(core): reload number of dependencies on flow save action (#10663)
Closes https://github.com/kestra-io/kestra/issues/10484.
2025-08-08 15:11:41 +02:00
Miloš Paunović
9edfb01920 chore(core): uniform dependency table namespace label (#10655) 2025-08-08 13:14:53 +02:00
Miloš Paunović
7813337f48 fix(core): ensure dependency table updates occur after dom is fully rendered (#10654)
Closes https://github.com/kestra-io/kestra/issues/10639.
2025-08-08 12:52:16 +02:00
Miloš Paunović
ea0342f82a refactor(core): remove revision property from flow nodes in dependency graph (#10650)
Related to https://github.com/kestra-io/kestra/issues/10633.
2025-08-08 12:21:01 +02:00
Piyush Bhaskar
ca8f25108e fix(core): update flow store usage. (#10649) 2025-08-08 11:34:09 +02:00
Miloš Paunović
49b6c331a6 chore(core): amend edge color scheme in execution dependency graph (#10648)
Related to https://github.com/kestra-io/kestra/issues/10639.
2025-08-08 11:29:11 +02:00
Miloš Paunović
e409fb7ac0 chore(core): lower the wheel sensitivity on zooming of dependency graph (#10647)
Relates to https://github.com/kestra-io/kestra/issues/10639.
2025-08-08 10:27:51 +02:00
Miloš Paunović
0b64c29794 fix(flows): properly import pinia store into a dependency graph composable (#10646) 2025-08-08 10:25:58 +02:00
Piyush Bhaskar
c4665460aa fix(flows): copy trigger url propely. (#10645) 2025-08-08 12:57:41 +05:30
Barthélémy Ledoux
5423b6e3a7 refactor: move flow store to pinia (#10620) 2025-08-08 09:04:33 +02:00
Vanshika Kumar
114669e1b5 chore(core): add padding around user image in left sidebar (#10553)
Co-authored-by: Vanshika Kumar <vanshika.kumar-ext@infra.market>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-08-08 08:34:23 +02:00
Loïc Mathieu
d75f0ced38 fix(executions): allow caching tasks that use the 'workingDir' variable
Fixes #10253
2025-08-07 17:26:24 +02:00
brian.mulier
0a788d8429 fix(core): ensure props with defaults are not marked as required in generated doc 2025-08-07 15:07:00 +02:00
brian.mulier
8c25d1bbd7 fix(core): wrong @NotNull import leading to key not being marked as required
closes #9287
2025-08-07 15:07:00 +02:00
YannC
4e2e8f294f fix: avoid calling nextExecutionDate if value is null when resetting trigger (#10547) 2025-08-07 14:51:27 +02:00
Barthélémy Ledoux
2c34804ce2 fix(core): update necessary node viewer in gradle build (#10624) 2025-08-07 13:38:29 +02:00
Piyush Bhaskar
bab4eef790 refactor(namespace): migrate namespace module to pinia (#10571)
* refactor(namespace): migrate namespace module to pinia

* refactor(namespaces): override the store and fix the test

* fix:  test in good way

* refactor: rename action as ee

* refactor: state and action is different

* refactor:  namespaces store in composition  API and composable to use the common state, actions

* fix: export validate
2025-08-07 16:20:51 +05:30
Miloš Paunović
94aa628ac1 feat(core): implement different graph type for dependencies view (#10240)
Closes https://github.com/kestra-io/kestra/issues/5350.
Closes https://github.com/kestra-io/kestra/issues/10446.
Closes https://github.com/kestra-io/kestra/issues/10563.
Closes https://github.com/kestra-io/kestra-ee/issues/3431.
Closes https://github.com/kestra-io/kestra-ee/issues/4509.

Relates to https://github.com/kestra-io/kestra/issues/10484.
Relates to https://github.com/kestra-io/kestra-ee/issues/3550.
2025-08-07 12:12:12 +02:00
Loïc Mathieu
da180fbc00 chore(system): add a note on MapUtils.nestedToFlattenMap() method 2025-08-07 12:01:31 +02:00
Anna Geller
c7bd592bc7 fix(ai-agent): add prompt suggestion 2025-08-07 10:42:35 +02:00
Florian Hussonnois
693d174960 chore(system): provide a more useful Either utility class
Rewrite and add tests to Either class to be a bit
more useable
2025-08-07 10:31:28 +02:00
Florian Hussonnois
8ee492b9c5 fix(system): fix consumer commit on JDBC queue
Ensure that JDBC queue records are committed to the consumer
after processing. This fixes a rare issue where executions could be blocked after a runner crash.
2025-08-07 10:31:17 +02:00
Loïc Mathieu
d6b8ba34ea chore(system): provide a MapUtils.nestedToFlattenMap() method
It will be used to nest a previously flatten map when needed.
2025-08-07 10:00:13 +02:00
dependabot[bot]
08cc853e00 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.7 to 0.38.8.
- [Release notes](https://github.com/awslabs/aws-crt-java/releases)
- [Commits](https://github.com/awslabs/aws-crt-java/compare/v0.38.7...v0.38.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-07 09:19:01 +02:00
dependabot[bot]
4f68715483 build(deps): bump org.apache.commons:commons-compress
Bumps [org.apache.commons:commons-compress](https://github.com/apache/commons-compress) from 1.27.1 to 1.28.0.
- [Changelog](https://github.com/apache/commons-compress/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-compress/compare/rel/commons-compress-1.27.1...rel/commons-compress-1.28.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-07 09:18:02 +02:00
Karthik D
edde1b6730 fix(core): fixes overflow of outputs content
* fix

* fix

* fix: minor tweaks

* fix: scope the style

---------

Co-authored-by: Piyush-r-bhaskar <impiyush0012@gmail.com>
2025-08-07 12:37:44 +05:30
Biplab Bera
399446f52e feat: disabled the preview button in output tabs for zip files (#10535)
Co-authored-by: Piyush Bhaskar <102078527+Piyush-r-bhaskar@users.noreply.github.com>
2025-08-07 11:56:58 +05:30
Florian Hussonnois
c717890fbc fix(build): fix and enhance release-plugins.sh
Skip gradle release when tag already exists
Check for staging files before commiting
2025-08-06 17:17:50 +02:00
Barthélémy Ledoux
5328b0c574 fix(flows): allow date inputs in playground (#10611) 2025-08-06 15:36:29 +02:00
Barthélémy Ledoux
de14cae1f0 fix(flows): playground only clear highlighted lines on leave task (#10612) 2025-08-06 15:36:17 +02:00
Miloš Paunović
d8a3e703e7 feat(core): add animated edges to topology graph (#10616)
Closes kestra-io/kestra#10614.
2025-08-06 14:49:31 +02:00
dependabot[bot]
90659bc320 build(deps): bump com.azure:azure-sdk-bom from 1.2.36 to 1.2.37
Bumps [com.azure:azure-sdk-bom](https://github.com/azure/azure-sdk-for-java) from 1.2.36 to 1.2.37.
- [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.36...azure-sdk-bom_1.2.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 12:55:33 +02:00
dependabot[bot]
37d1d8856e build(deps): bump software.amazon.awssdk:bom from 2.32.11 to 2.32.16
Bumps software.amazon.awssdk:bom from 2.32.11 to 2.32.16.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 11:56:59 +02:00
Florian Hussonnois
93a4eb5cbc build: add plugin-datagen to plugin list 2025-08-06 11:11:46 +02:00
Miloš Paunović
de160c8a2d chore(deps): regular dependency update (#10607)
Performing a weekly round of dependency updates in the NPM ecosystem to keep everything up to date.
2025-08-06 10:20:32 +02:00
dependabot[bot]
28458b59eb build(deps): bump com.mysql:mysql-connector-j from 9.3.0 to 9.4.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 9.3.0 to 9.4.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/9.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/9.3.0...9.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 09:50:39 +02:00
dependabot[bot]
2a256d9505 build(deps): bump org.eclipse.angus:jakarta.mail from 2.0.3 to 2.0.4
Bumps org.eclipse.angus:jakarta.mail from 2.0.3 to 2.0.4.

---
updated-dependencies:
- dependency-name: org.eclipse.angus:jakarta.mail
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 09:50:20 +02:00
dependabot[bot]
9008b21007 build(deps): bump com.google.cloud:libraries-bom from 26.64.0 to 26.65.0
Bumps [com.google.cloud:libraries-bom](https://github.com/googleapis/java-cloud-bom) from 26.64.0 to 26.65.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.64.0...v26.65.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 09:49:35 +02:00
dependabot[bot]
8c13bf6a71 build(deps): bump com.gradleup.shadow from 8.3.8 to 8.3.9
Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 8.3.8 to 8.3.9.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](https://github.com/GradleUp/shadow/compare/8.3.8...8.3.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 09:49:06 +02:00
dependabot[bot]
43888cc3dd build(deps): bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 09:48:47 +02:00
Piyush Bhaskar
c94093d9f6 fix(flows): ensure plugin documentation change on flow switch (#10546)
Co-authored-by: Barthélémy Ledoux <bledoux@kestra.io>
2025-08-05 14:29:36 +05:30
Barthélémy Ledoux
8779dec28a fix(flows): add conditional rendering for restart button based on execution (#10570) 2025-08-05 10:22:13 +02:00
Nicolas K.
41614c3a6e feat(stores): #4353 list all KV for namespace and parent namespaces (#10470)
* feat(stores): #4353 list all KV for namespace and parent namespaces

* feat(stores): #4353 list all KV for namespace and parent namespaces

* feat(stores): #4353 list all KV for namespace and parent namespaces

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-08-05 09:55:41 +02:00
Barthélémy Ledoux
6b4fdd0688 fix: restore InputForm (#10568) 2025-08-05 09:44:39 +02:00
Loïc Mathieu
0319f3d267 feat(system): set the default number of worker threads to 8x available cpu cores
This is a better default for mixed workloads and provides better tail latency.
This is also what we advise to our customer.
2025-08-05 09:19:14 +02:00
brian.mulier
0b37fe2cb8 fix(namespaces): autocomplete in kv & secrets
related to kestra-io/kestra-ee#4559
2025-08-04 20:29:56 +02:00
brian.mulier
e623dd7729 fix(executions): avoid SSE error in follow execution dependencies
closes #10560
2025-08-04 20:22:32 +02:00
Barthélémy Ledoux
db4f7cb4ff fix(flows)*: load flow for execution needs to be stored most of the time (#10566) 2025-08-04 18:54:01 +02:00
Abhilash T
b14b16db0e fix: Updated InputsForm.vue to clear Radio Button Selection (#9654)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-08-04 16:03:25 +02:00
brian.mulier
77f6cec0e4 fix(executions): restore execution redirect & subflow logs view from parent
closes #10528
closes #10551
2025-08-04 15:46:48 +02:00
Piyush Bhaskar
1748b18d66 chore(core): remove variable and directly assign. (#10554) 2025-08-04 18:45:19 +05:30
Piyush Bhaskar
32f96348c1 fix(core): proper state detection from parsed data (#10527) 2025-08-04 18:41:05 +05:30
Barthélémy Ledoux
07db0a8c80 fix(flows): no-code - when changing type message avoid warning (#10498) 2025-08-04 14:57:28 +02:00
Barthélémy Ledoux
2035fd42c3 refactor: use composition api and ts on revision component (#10529) 2025-08-04 14:56:36 +02:00
Barthélémy Ledoux
2856bf07e8 refactor: move editor from vuex to pinia (#10533)
Co-authored-by: Piyush-r-bhaskar <impiyush0012@gmail.com>
2025-08-04 14:55:55 +02:00
Barthélémy Ledoux
f5327cec33 fix: remove debugging value from playground (#10541) 2025-08-04 14:54:45 +02:00
Anna Geller
42955936b2 fix: demo no longer exists 2025-08-04 14:38:13 +02:00
Miloš Paunović
771b98e023 chore(namespaces): add the needed prop for loading all namespaces inside a selector (#10544) 2025-08-04 12:44:38 +02:00
Miloš Paunović
b80e8487e3 fix(namespaces): amend problems with namespace secrets and kv pairs (#10543)
Closes https://github.com/kestra-io/kestra-ee/issues/4584.
2025-08-04 12:19:52 +02:00
YannC.
f35a0b6d60 fix: add missing webhook releases secrets for github releases 2025-08-01 23:21:27 +02:00
brian.mulier
0c9ed17f1c fix(core): remove icon for inputs in no-code
closes #10520
2025-08-01 16:32:08 +02:00
brian.mulier
7ca20371f8 fix(executions): avoid race condition leading to never-ending follow with non-terminal state 2025-08-01 13:12:14 +02:00
brian.mulier
8ff3454cbd fix(core): ensure instances can read all messages when no consumer group / queue type 2025-08-01 13:12:14 +02:00
Piyush Bhaskar
09593d9fd2 fix(namespaces): fixes loading of additional ns (#10518) 2025-08-01 16:28:01 +05:30
Loïc Mathieu
d3cccf36f0 feat(flow): pull up description to the FlowInterface
This avoid the need to parse the flow for ex by AI to get the description.
2025-08-01 12:43:49 +02:00
Loïc Mathieu
eeb91cd9ed fix(tests): RunContextLoggerTest.secrets(): wrong number of logs in awaitLogs() 2025-08-01 12:41:41 +02:00
Loïc Mathieu
2679b0f067 feat(flows): warn on runnable only properties on non-runnable tasks
Closes #9967
Closes #10500
2025-08-01 12:41:08 +02:00
Piyush Bhaskar
54281864c8 fix(executions): do not rely on monaco to get value (#10515) 2025-08-01 13:23:43 +05:30
Loïc Mathieu
e4f9b11d0c fix(ci): workflow build artifact doesn't need the plugin version 2025-08-01 09:41:48 +02:00
Barthélémy Ledoux
12cef0593c fix(flows): playground need to use ui-libs (#10506) 2025-08-01 09:06:11 +02:00
Piyush Bhaskar
c6cf8f307f fix(flows): route to flow page (#10514) 2025-08-01 12:10:56 +05:30
Piyush Bhaskar
3b4eb55f84 fix(executions): properly handle methods and computed for tabs (#10513) 2025-08-01 12:10:27 +05:30
YannC
d32949985d fix: handle empty flows list in lastExecutions correctly (#10493) 2025-08-01 07:21:00 +02:00
YannC
c051ca2e66 fix(ui): load correctly filters + refresh dashboard on filter change (#10504) 2025-08-01 07:15:46 +02:00
Piyush Bhaskar
93a456963b fix(editor): adjust padding for editor (#10497)
* fix(editor): adjust padding for editor

* fix: make padding 16px
2025-07-31 19:10:46 +05:30
YannC.
9a45f17680 fix(ci): do not run github release on tag 2025-07-31 14:37:51 +02:00
github-actions[bot]
5fb6806d74 chore(core): localize to languages other than english (#10494)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 17:44:10 +05:30
Barthélémy Ledoux
f3cff72edd fix(flows): forget all old taskRunId when a new execution (#10487) 2025-07-31 13:41:57 +02:00
Barthélémy Ledoux
0abc660e7d fix(flows): wait longer for widgets to be rendered (#10485) 2025-07-31 13:41:46 +02:00
Barthélémy Ledoux
f09ca3d92e fix(flows): load flows documentation when coming back to no-code root (#10374) 2025-07-31 13:41:36 +02:00
YannC
9fd778fca1 feat(ui): added http method autocompletion (#10492) 2025-07-31 13:28:59 +02:00
Loïc Mathieu
667af25e1b fix(executions): Don't create outputs from the Subflow task when we didn't wait
As, well, if we didn't wait for the subflow execution, we cannot have access to its outputs.
2025-07-31 13:06:58 +02:00
github-actions[bot]
1b1aed5ff1 chore(core): localize to languages other than english (#10489)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 12:14:37 +02:00
Barthélémy Ledoux
da1bb58199 fix(flows): add the load errors to the flow errors (#10483) 2025-07-31 11:53:43 +02:00
Loïc Mathieu
d3e661f9f8 feat(system): improve performance of computeSchedulable
- Store flowIds in a list to avoid computing the multiple times
- Storeg triggers by ID in a map to avoid iterating the list of triggers for each flow
2025-07-31 11:35:01 +02:00
yuri1969
2126c8815e feat(core): validate URL configuration
Used the `ServerCommandValidator` style.

BREAKING CHANGE: app won't start due invalid `kestra.url`
2025-07-31 11:24:21 +02:00
yuri1969
6cfc5b8799 fix(build): reduce Gradle warnings 2025-07-31 11:21:01 +02:00
Barthélémy Ledoux
16d44034f0 fix(flows): hide executionkind meta in the logs (#10482) 2025-07-31 10:50:34 +02:00
Barthélémy Ledoux
f76e62a4af fix(executions): do not rely on monaco to get value (#10467) 2025-07-31 09:28:33 +02:00
Piyush Bhaskar
f6645da94c fix(core): remove top spacing from no execution page and removing the redundant code (#10445)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-07-31 12:03:58 +05:30
github-actions[bot]
93b2bbf0d0 chore(core): localize to languages other than english (#10471)
Extended localization support by adding translations for multiple languages using English as the base. This enhances accessibility and usability for non-English-speaking users while keeping English as the source reference.

Co-authored-by: GitHub Action <actions@github.com>
2025-07-31 08:23:08 +02:00
Piyush Bhaskar
9d46e2aece fix(executions): make columns that are not links normal text (#10460)
* fix(executions): make it normal text

* fix(executions): use monospace font only
2025-07-31 10:33:33 +05:30
brian.mulier
133315a2a5 chore(deps): hardcode vue override version 2025-07-30 19:25:50 +02:00
brian.mulier
b96b9bb414 fix(core): avoid follow execution from being discarded too early
closes #10472
closes #7623
2025-07-30 19:25:50 +02:00
Barthélémy Ledoux
9865d8a7dc fix(flows): playground - implement new designs (#10459)
Co-authored-by: brian.mulier <bmmulier@hotmail.fr>
2025-07-30 17:54:46 +02:00
brian-mulier-p
29f22c2f81 fix(core): redesign playground run task button (#10423)
closes #10389
2025-07-30 15:23:33 +02:00
dependabot[bot]
3e69469381 build(deps): bump net.thisptr:jackson-jq from 1.3.0 to 1.4.0
Bumps [net.thisptr:jackson-jq](https://github.com/eiiches/jackson-jq) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/eiiches/jackson-jq/releases)
- [Commits](https://github.com/eiiches/jackson-jq/compare/1.3.0...1.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 15:08:39 +02:00
dependabot[bot]
38c24ccf7f build(deps): bump software.amazon.awssdk:bom from 2.32.6 to 2.32.11
Bumps software.amazon.awssdk:bom from 2.32.6 to 2.32.11.

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 15:07:49 +02:00
Loïc Mathieu
12cf41a309 fix(ci): don't publish docker in build-artifact 2025-07-30 14:42:16 +02:00
Malaydewangan09
7b8ea0d885 feat(plugins): add script plugins 2025-07-30 17:27:48 +05:30
Barthélémy Ledoux
cf88bbcb12 fix(flows): playground align restart button button (#10415) 2025-07-30 11:57:24 +02:00
Loïc Mathieu
6abe7f96e7 fix(ci): add missing build artifact job 2025-07-30 11:47:10 +02:00
Loïc Mathieu
e73ac78d8b build(ci): allow downloading the exe from the workflow and not the release
This would allow running the workflow even if the release step fail
2025-07-30 11:23:43 +02:00
François Delbrayelle
b0687eb702 fix(): fix icons 2025-07-30 10:28:10 +02:00
weibo1
85f9070f56 feat: Trigger Initialization Method Performance Optimization 2025-07-30 09:23:48 +02:00
YannC
0a42ab40ec fix(dashboard): pageSize & pageNumber is now correctly pass when fetching a chart (#10413) 2025-07-30 08:45:20 +02:00
Piyush Bhaskar
856d2d1d51 refactor(flows): remove execution chart (#10425) 2025-07-30 11:54:35 +05:30
YannC.
a7d6dbc8a3 feat(ci): allow to run github release ci on dispatch 2025-07-29 15:04:50 +02:00
YannC.
cf82109da6 fix(ci): correctly pass GH token to release workflow 2025-07-29 15:01:36 +02:00
Barthélémy Ledoux
d4168ba424 fix(flows): playground clear current execution when clearExecutions() (#10414) 2025-07-29 14:43:11 +02:00
Loïc Mathieu
46a294f25a chore(version): upgrade to v1.0.0-SNAPSHOT 2025-07-29 14:23:19 +02:00
Loïc Mathieu
a229036d8d chore(version): update to version 'v0.24.0-rc0-SNAPSHOT'. 2025-07-29 14:21:49 +02:00
1025 changed files with 31252 additions and 23231 deletions

View File

@@ -23,9 +23,19 @@ In the meantime, you can move onto the next step...
---
### Requirements
- Java 21 (LTS versions).
> ⚠️ Java 24 and above are not supported yet and will fail with `invalid source release: 21`.
- Gradle (comes with wrapper `./gradlew`)
- Docker (optional, for running Kestra in containers)
### Development:
- Create a `.env.development.local` file in the `ui` folder and paste the following:
- (Optional) By default, your dev server will target `localhost:8080`. If your backend is running elsewhere, you can create `.env.development.local` under `ui` folder with this content:
```
VITE_APP_API_URL={myApiUrl}
```
- Navigate into the `ui` folder and run `npm install` to install the dependencies for the frontend project.

View File

@@ -2,7 +2,7 @@ name: Auto-Translate UI keys and create PR
on:
schedule:
- cron: "0 9-21 * * *" # Every hour from 9 AM to 9 PM
- cron: "0 9-21/3 * * *" # Every 3 hours from 9 AM to 9 PM
workflow_dispatch:
inputs:
retranslate_modified_keys:
@@ -20,13 +20,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
name: Checkout
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.x"
@@ -39,7 +39,7 @@ jobs:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20.x"

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -50,7 +50,7 @@ jobs:
# Set up JDK
- name: Set up JDK
uses: actions/setup-java@v4
uses: actions/setup-java@v5
if: ${{ matrix.language == 'java' }}
with:
distribution: 'temurin'

View File

@@ -1,147 +0,0 @@
name: Create Docker images on Release
on:
workflow_dispatch:
inputs:
retag-latest:
description: 'Retag latest Docker images'
required: true
type: string
default: "false"
options:
- "true"
- "false"
release-tag:
description: 'Kestra Release Tag'
required: false
type: string
plugin-version:
description: 'Plugin version'
required: false
type: string
default: "LATEST"
env:
PLUGIN_VERSION: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
jobs:
plugins:
name: List Plugins
runs-on: ubuntu-latest
outputs:
plugins: ${{ steps.plugins.outputs.plugins }}
steps:
# Checkout
- uses: actions/checkout@v4
# Get Plugins List
- name: Get Plugins List
uses: ./.github/actions/plugins-list
id: plugins
with:
plugin-version: ${{ env.PLUGIN_VERSION }}
docker:
name: Publish Docker
needs: [ plugins ]
runs-on: ubuntu-latest
strategy:
matrix:
image:
- name: "-no-plugins"
plugins: ""
packages: jattach
python-libs: ""
- name: ""
plugins: ${{needs.plugins.outputs.plugins}}
packages: python3 python-is-python3 python3-pip curl jattach
python-libs: kestra
steps:
- uses: actions/checkout@v4
# Vars
- name: Set image name
id: vars
run: |
if [[ "${{ inputs.release-tag }}" == "" ]]; then
TAG=${GITHUB_REF#refs/*/}
echo "tag=${TAG}" >> $GITHUB_OUTPUT
else
TAG="${{ inputs.release-tag }}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
fi
if [[ "${{ env.PLUGIN_VERSION }}" == *"-SNAPSHOT" ]]; then
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ ${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT;
else
echo "plugins=${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT
fi
# Download release
- name: Download release
uses: robinraju/release-downloader@v1.12
with:
tag: ${{steps.vars.outputs.tag}}
fileName: 'kestra-*'
out-file-path: build/executable
- name: Copy exe to image
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra
# Docker setup
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Docker - Fix Qemu
shell: bash
run: |
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Docker Login
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Docker Build and push
- name: Push to Docker Hub
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }}
platforms: linux/amd64,linux/arm64
build-args: |
KESTRA_PLUGINS=${{ steps.vars.outputs.plugins }}
APT_PACKAGES=${{ matrix.image.packages }}
PYTHON_LIBRARIES=${{ matrix.image.python-libs }}
- name: Install regctl
if: github.event.inputs.retag-latest == 'true'
uses: regclient/actions/regctl-installer@main
- name: Retag to latest
if: github.event.inputs.retag-latest == 'true'
run: |
regctl image copy ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }} ${{ format('kestra/kestra:latest{0}', matrix.image.name) }}
end:
runs-on: ubuntu-latest
needs:
- docker
if: always()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
# Slack
- name: Slack notification
uses: Gamesight/slack-workflow-status@master
if: ${{ always() && env.SLACK_WEBHOOK_URL != 0 }}
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
name: GitHub Actions
icon_emoji: ':github-actions:'
channel: 'C02DQ1A7JLR' # _int_git channel

View File

@@ -19,7 +19,7 @@ on:
default: "no input"
jobs:
check:
timeout-minutes: 10
timeout-minutes: 15
runs-on: ubuntu-latest
env:
GOOGLE_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}
@@ -32,12 +32,12 @@ jobs:
password: ${{ github.token }}
- name: Checkout kestra
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
path: kestra
# Setup build
- uses: kestra-io/actions/.github/actions/setup-build@main
- uses: kestra-io/actions/composite/setup-build@main
name: Setup - Build
id: build
with:

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
releaseVersion:
description: 'The release version (e.g., 0.21.0-rc1)'
description: 'The release version (e.g., 0.21.0)'
required: true
type: string
nextVersion:
@@ -21,25 +21,17 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
# Checkout GitHub Actions
- uses: actions/checkout@v4
with:
repository: kestra-io/actions
path: actions
ref: main
# Setup build
- uses: ./actions/.github/actions/setup-build
- uses: kestra-io/actions/composite/setup-build@main
id: build
with:
java-enabled: true
node-enabled: true
python-enabled: true
caches-enabled: true
# Get Plugins List
- name: Get Plugins List
@@ -60,7 +52,7 @@ jobs:
GITHUB_PAT: ${{ secrets.GH_PERSONAL_TOKEN }}
run: |
chmod +x ./dev-tools/release-plugins.sh;
./dev-tools/release-plugins.sh \
--release-version=${{github.event.inputs.releaseVersion}} \
--next-version=${{github.event.inputs.nextVersion}} \
@@ -73,10 +65,10 @@ jobs:
GITHUB_PAT: ${{ secrets.GH_PERSONAL_TOKEN }}
run: |
chmod +x ./dev-tools/release-plugins.sh;
./dev-tools/release-plugins.sh \
--release-version=${{github.event.inputs.releaseVersion}} \
--next-version=${{github.event.inputs.nextVersion}} \
--dry-run \
--yes \
${{ steps.plugins-list.outputs.repositories }}
${{ steps.plugins-list.outputs.repositories }}

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
releaseVersion:
description: 'The release version (e.g., 0.21.0-rc1)'
description: 'The release version (e.g., 0.21.0)'
required: true
type: string
nextVersion:
@@ -23,8 +23,8 @@ jobs:
# Checks
- name: Check Inputs
run: |
if ! [[ "$RELEASE_VERSION" =~ ^[0-9]+(\.[0-9]+)\.0-rc[01](-SNAPSHOT)?$ ]]; then
echo "Invalid release version. Must match regex: ^[0-9]+(\.[0-9]+)\.0-rc[01](-SNAPSHOT)?$"
if ! [[ "$RELEASE_VERSION" =~ ^[0-9]+(\.[0-9]+)\.0$ ]]; then
echo "Invalid release version. Must match regex: ^[0-9]+(\.[0-9]+)\.0$"
exit 1
fi
@@ -33,20 +33,13 @@ jobs:
exit 1;
fi
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
path: kestra
# Checkout GitHub Actions
- uses: actions/checkout@v4
with:
repository: kestra-io/actions
path: actions
ref: main
# Setup build
- uses: ./actions/.github/actions/setup-build
- uses: kestra-io/actions/composite/setup-build@main
id: build
with:
java-enabled: true
@@ -78,7 +71,6 @@ jobs:
git checkout develop;
if [[ "$RELEASE_VERSION" == *"-SNAPSHOT" ]]; then
# -SNAPSHOT qualifier maybe used to test release-candidates
./gradlew release -Prelease.useAutomaticVersion=true \
-Prelease.releaseVersion="${RELEASE_VERSION}" \
-Prelease.newVersion="${NEXT_VERSION}" \
@@ -89,4 +81,4 @@ jobs:
-Prelease.releaseVersion="${RELEASE_VERSION}" \
-Prelease.newVersion="${NEXT_VERSION}" \
-Prelease.pushReleaseVersionBranch="${PUSH_RELEASE_BRANCH}"
fi
fi

View File

@@ -3,10 +3,17 @@ name: Main Workflow
on:
workflow_dispatch:
inputs:
skip-test:
description: 'Skip test'
type: choice
required: true
default: 'false'
options:
- "true"
- "false"
plugin-version:
description: "Kestra version"
default: 'LATEST'
required: true
description: "plugins version"
required: false
type: string
push:
branches:
@@ -25,16 +32,17 @@ jobs:
tests:
name: Execute tests
uses: ./.github/workflows/workflow-test.yml
if: ${{ github.event.inputs.skip-test == 'false' || github.event.inputs.skip-test == '' }}
with:
report-status: false
release:
name: Release
needs: [tests]
if: "!startsWith(github.ref, 'refs/heads/releases')"
if: "!failure() && !cancelled() && !startsWith(github.ref, 'refs/heads/releases')"
uses: ./.github/workflows/workflow-release.yml
with:
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
plugin-version: ${{ inputs.plugin-version != '' && inputs.plugin-version || (github.ref == 'refs/heads/develop' && 'LATEST-SNAPSHOT' || 'LATEST') }}
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
@@ -43,14 +51,14 @@ jobs:
SONATYPE_GPG_KEYID: ${{ secrets.SONATYPE_GPG_KEYID }}
SONATYPE_GPG_PASSWORD: ${{ secrets.SONATYPE_GPG_PASSWORD }}
SONATYPE_GPG_FILE: ${{ secrets.SONATYPE_GPG_FILE }}
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}
end:
runs-on: ubuntu-latest
needs:
- release
if: always()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
- name: Trigger EE Workflow
uses: peter-evans/repository-dispatch@v3
@@ -60,14 +68,9 @@ jobs:
repository: kestra-io/kestra-ee
event-type: "oss-updated"
# Slack
- name: Slack - Notification
uses: Gamesight/slack-workflow-status@master
if: ${{ always() && env.SLACK_WEBHOOK_URL != 0 }}
if: ${{ failure() && env.SLACK_WEBHOOK_URL != 0 && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }}
uses: kestra-io/actions/composite/slack-status@main
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
name: GitHub Actions
icon_emoji: ":github-actions:"
channel: "C02DQ1A7JLR" # _int_git channel
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}

View File

@@ -4,6 +4,7 @@ on:
pull_request:
branches:
- develop
- releases/*
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-pr
@@ -60,19 +61,3 @@ jobs:
name: E2E - Tests
uses: ./.github/workflows/e2e.yml
end:
name: End
runs-on: ubuntu-latest
if: always()
needs: [frontend, backend]
steps:
# Slack
- name: Slack notification
uses: Gamesight/slack-workflow-status@master
if: ${{ always() && env.SLACK_WEBHOOK_URL != 0 }}
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
name: GitHub Actions
icon_emoji: ":github-actions:"
channel: "C02DQ1A7JLR"

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0

View File

@@ -34,11 +34,14 @@ jobs:
fi
# Checkout
- uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
token: ${{ secrets.GH_PERSONAL_TOKEN }}
- name: Configure Git
# Configure
- name: Git - Configure
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
@@ -54,4 +57,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 --tags
git push --tags

View File

@@ -17,17 +17,10 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
# Checkout GitHub Actions
- uses: actions/checkout@v4
with:
repository: kestra-io/actions
path: actions
ref: main
# Setup build
- uses: ./actions/.github/actions/setup-build
id: build
@@ -66,19 +59,12 @@ jobs:
actions: read
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
# Checkout GitHub Actions
- uses: actions/checkout@v4
with:
repository: kestra-io/actions
path: actions
ref: main
# Setup build
- uses: ./actions/.github/actions/setup-build
- uses: kestra-io/actions/composite/setup-build@main
id: build
with:
java-enabled: false
@@ -87,7 +73,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.32.0
uses: aquasecurity/trivy-action@0.33.1
with:
image-ref: kestra/kestra:develop
format: 'template'
@@ -111,28 +97,20 @@ jobs:
actions: read
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
# Checkout GitHub Actions
- uses: actions/checkout@v4
with:
repository: kestra-io/actions
path: actions
ref: main
# Setup build
- uses: ./actions/.github/actions/setup-build
- uses: kestra-io/actions/composite/setup-build@main
id: build
with:
java-enabled: false
node-enabled: false
caches-enabled: true
# Run Trivy image scan for Docker vulnerabilities, see https://github.com/aquasecurity/trivy-action
- name: Docker Vulnerabilities Check
uses: aquasecurity/trivy-action@0.32.0
uses: aquasecurity/trivy-action@0.33.1
with:
image-ref: kestra/kestra:latest
format: table

View File

@@ -20,6 +20,7 @@ permissions:
contents: write
checks: write
actions: read
pull-requests: write
jobs:
test:
@@ -29,13 +30,13 @@ jobs:
GOOGLE_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
name: Checkout - Current ref
with:
fetch-depth: 0
# Setup build
- uses: kestra-io/actions/.github/actions/setup-build@main
- uses: kestra-io/actions/composite/setup-build@main
name: Setup - Build
id: build
with:
@@ -59,84 +60,15 @@ jobs:
export GOOGLE_APPLICATION_CREDENTIALS=$HOME/.gcp-service-account.json
./gradlew check javadoc --parallel
# report test
- name: Test - Publish Test Results
uses: dorny/test-reporter@v2
if: always()
with:
name: Java Tests Report
reporter: java-junit
path: '**/build/test-results/test/TEST-*.xml'
list-suites: 'failed'
list-tests: 'failed'
fail-on-error: 'false'
token: ${{ secrets.GITHUB_AUTH_TOKEN }}
# Sonar
- name: Test - Analyze with Sonar
if: env.SONAR_TOKEN != ''
- name: comment PR with test report
if: ${{ !cancelled() && github.event_name == 'pull_request' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_AUTH_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: bash
run: ./gradlew sonar --info
run: npx --yes @kestra-io/kestra-devtools generateTestReportSummary --only-errors --ci $(pwd)
# GCP
- name: GCP - Auth with unit test account
id: auth
if: always() && env.GOOGLE_SERVICE_ACCOUNT != ''
continue-on-error: true
uses: "google-github-actions/auth@v2"
with:
credentials_json: "${{ secrets.GOOGLE_SERVICE_ACCOUNT }}"
- name: GCP - Setup Cloud SDK
if: env.GOOGLE_SERVICE_ACCOUNT != ''
uses: "google-github-actions/setup-gcloud@v2"
# Allure check
- 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
# Jacoco
- name: Jacoco - Copy reports
if: env.GOOGLE_SERVICE_ACCOUNT != ''
continue-on-error: true
shell: bash
run: |
mv build/reports/jacoco/testCodeCoverageReport build/reports/jacoco/test/
mv build/reports/jacoco/test/testCodeCoverageReport.xml build/reports/jacoco/test/jacocoTestReport.xml
gsutil -m rsync -d -r build/reports/jacoco/test/ gs://internal-kestra-host/${{ format('{0}/{1}', github.repository, 'jacoco') }}
# Codecov
- name: Codecov - Upload coverage reports
uses: codecov/codecov-action@v5
# Report Java
- name: Report - Java
uses: kestra-io/actions/composite/report-java@main
if: ${{ !cancelled() }}
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: backend
- name: Codecov - Upload test results
uses: codecov/test-results-action@v1
if: ${{ !cancelled() }}
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: backend
secrets: ${{ toJSON(secrets) }}

View File

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

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Cache Node Modules
id: cache-node-modules

View File

@@ -1,14 +1,17 @@
name: Github - Release
on:
workflow_dispatch:
workflow_call:
secrets:
GH_PERSONAL_TOKEN:
description: "The Github personal token."
required: true
push:
tags:
- '*'
SLACK_RELEASES_WEBHOOK_URL:
description: "The Slack webhook URL."
required: true
jobs:
publish:
@@ -17,25 +20,16 @@ jobs:
steps:
# Check out
- name: Checkout - Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
submodules: true
# Checkout GitHub Actions
- name: Checkout - Actions
uses: actions/checkout@v4
with:
repository: kestra-io/actions
sparse-checkout-cone-mode: true
path: actions
sparse-checkout: |
.github/actions
# Download Exec
# Must be done after checkout actions
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
if: startsWith(github.ref, 'refs/tags/v')
with:
name: exe
@@ -56,7 +50,7 @@ jobs:
# GitHub Release
- name: Create GitHub release
uses: ./actions/.github/actions/github-release
uses: kestra-io/actions/composite/github-release@main
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
MAKE_LATEST: ${{ steps.is_latest.outputs.latest }}
@@ -75,4 +69,11 @@ jobs:
"new_version": "${{ github.ref_name }}",
"github_repository": "${{ github.repository }}",
"github_actor": "${{ github.actor }}"
}
}
- name: Merge Release Notes
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
uses: kestra-io/actions/composite/github-release-note-merge@main
env:
GITHUB_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
RELEASE_TAG: ${{ github.ref_name }}

View File

@@ -1,22 +1,45 @@
name: Publish - Docker
name: Create Docker images on Release
on:
workflow_dispatch:
inputs:
plugin-version:
description: "Kestra version"
default: 'LATEST'
retag-latest:
description: 'Retag latest Docker images'
required: true
type: choice
default: "false"
options:
- "true"
- "false"
retag-lts:
description: 'Retag LTS Docker images'
required: true
type: choice
default: "false"
options:
- "true"
- "false"
release-tag:
description: 'Kestra Release Tag (by default, deduced with the ref)'
required: false
type: string
plugin-version:
description: 'Plugin version'
required: false
type: string
default: "LATEST"
force-download-artifact:
description: 'Force download artifact'
required: false
type: string
type: choice
default: "true"
options:
- "true"
- "false"
workflow_call:
inputs:
plugin-version:
description: "Kestra version"
description: "Plugin version"
default: 'LATEST'
required: false
type: string
@@ -33,47 +56,93 @@ on:
description: "The Dockerhub password."
required: true
env:
PLUGIN_VERSION: ${{ inputs.plugin-version != null && inputs.plugin-version || 'LATEST' }}
jobs:
plugins:
name: List Plugins
runs-on: ubuntu-latest
outputs:
plugins: ${{ steps.plugins.outputs.plugins }}
steps:
# Checkout
- uses: actions/checkout@v5
# Get Plugins List
- name: Get Plugins List
uses: ./.github/actions/plugins-list
id: plugins
with: # remap LATEST-SNAPSHOT to LATEST
plugin-version: ${{ env.PLUGIN_VERSION == 'LATEST-SNAPSHOT' && 'LATEST' || env.PLUGIN_VERSION }}
# ********************************************************************************************************************
# Build
# ********************************************************************************************************************
build-artifacts:
name: Build Artifacts
if: ${{ github.event.inputs.force-download-artifact == 'true' }}
if: ${{ inputs.force-download-artifact == 'true' }}
uses: ./.github/workflows/workflow-build-artifacts.yml
with:
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
# ********************************************************************************************************************
# Docker
# ********************************************************************************************************************
publish:
name: Publish - Docker
docker:
name: Publish Docker
needs: [ plugins, build-artifacts ]
if: always()
runs-on: ubuntu-latest
needs: build-artifacts
if: |
always() &&
(needs.build-artifacts.result == 'success' ||
github.event.inputs.force-download-artifact != 'true')
env:
PLUGIN_VERSION: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
strategy:
matrix:
image:
- tag: -no-plugins
- name: "-no-plugins"
plugins: ""
packages: jattach
plugins: false
python-libraries: ""
- tag: ""
plugins: true
packages: python3 python3-venv python-is-python3 python3-pip nodejs npm curl zip unzip jattach
python-libraries: kestra
python-libs: ""
- name: ""
plugins: ${{needs.plugins.outputs.plugins}}
packages: python3 python-is-python3 python3-pip curl jattach
python-libs: kestra
steps:
- name: Checkout - Current ref
uses: actions/checkout@v4
- uses: actions/checkout@v5
# Vars
- name: Set image name
id: vars
run: |
if [[ "${{ inputs.release-tag }}" == "" ]]; then
TAG=${GITHUB_REF#refs/*/}
echo "tag=${TAG}" >> $GITHUB_OUTPUT
else
TAG="${{ inputs.release-tag }}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
fi
if [[ $GITHUB_REF == refs/tags/* ]]; then
if [[ $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# this will remove the patch version number
MINOR_SEMVER=${TAG%.*}
echo "minor_semver=${MINOR_SEMVER}" >> $GITHUB_OUTPUT
else
echo "Tag '$TAG' is not a valid semver (vMAJOR.MINOR.PATCH), skipping minor_semver"
fi
fi
if [[ "${{ env.PLUGIN_VERSION }}" == *"-SNAPSHOT" ]]; then
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ ${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT;
else
echo "plugins=${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT
fi
# Download executable from artifact
- name: Artifacts - Download executable
uses: actions/download-artifact@v5
with:
name: exe
path: build/executable
- name: Copy exe to image
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra
# Docker setup
- name: Docker - Setup QEMU
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Docker - Fix Qemu
@@ -81,66 +150,59 @@ jobs:
run: |
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
- name: Docker - Setup Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Docker Login
- name: Docker - Login to DockerHub
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# # Get Plugins List
- name: Plugins - Get List
uses: ./.github/actions/plugins-list
id: plugins-list
if: ${{ matrix.image.plugins}}
with:
plugin-version: ${{ env.PLUGIN_VERSION }}
# Vars
- name: Docker - Set variables
shell: bash
id: vars
run: |
TAG=${GITHUB_REF#refs/*/}
PLUGINS="${{ matrix.image.plugins == true && steps.plugins-list.outputs.plugins || '' }}"
if [[ $TAG == v* ]]; then
TAG="${TAG}";
echo "plugins=${{ matrix.image.plugins }}" >> $GITHUB_OUTPUT
elif [[ $TAG = "develop" ]]; then
TAG="develop";
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ $PLUGINS" >> $GITHUB_OUTPUT
else
TAG="build-${{ github.run_id }}";
echo "plugins=--repositories=https://central.sonatype.com/repository/maven-snapshots/ $PLUGINS" >> $GITHUB_OUTPUT
fi
echo "tag=${TAG}${{ matrix.image.tag }}" >> $GITHUB_OUTPUT
# Build Docker Image
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
with:
name: exe
path: build/executable
- name: Docker - Copy exe to image
shell: bash
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra
# Docker Build and push
- name: Docker - Build image
- name: Push to Docker Hub
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: kestra/kestra:${{ steps.vars.outputs.tag }}
tags: ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }}
platforms: linux/amd64,linux/arm64
build-args: |
KESTRA_PLUGINS=${{ steps.vars.outputs.plugins }}
APT_PACKAGES=${{ matrix.image.packages }}
PYTHON_LIBRARIES=${{ matrix.image.python-libraries }}
PYTHON_LIBRARIES=${{ matrix.image.python-libs }}
- name: Install regctl
if: startsWith(github.ref, 'refs/tags/v')
uses: regclient/actions/regctl-installer@main
- name: Retag to minor semver version
if: startsWith(github.ref, 'refs/tags/v') && steps.vars.outputs.minor_semver != ''
run: |
regctl image copy ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }} ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.minor_semver, matrix.image.name) }}
- name: Retag to latest
if: startsWith(github.ref, 'refs/tags/v') && inputs.retag-latest == 'true'
run: |
regctl image copy ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }} ${{ format('kestra/kestra:latest{0}', matrix.image.name) }}
- name: Retag to LTS
if: startsWith(github.ref, 'refs/tags/v') && inputs.retag-lts == 'true'
run: |
regctl image copy ${{ format('kestra/kestra:{0}{1}', steps.vars.outputs.tag, matrix.image.name) }} ${{ format('kestra/kestra:latest-lts{0}', matrix.image.name) }}
end:
runs-on: ubuntu-latest
needs:
- docker
if: always()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
- name: Slack notification
if: ${{ failure() && env.SLACK_WEBHOOK_URL != 0 }}
uses: kestra-io/actions/composite/slack-status@main
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}

View File

@@ -25,11 +25,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout - Current ref
uses: actions/checkout@v4
uses: actions/checkout@v5
# Setup build
- name: Setup - Build
uses: kestra-io/actions/.github/actions/setup-build@main
uses: kestra-io/actions/composite/setup-build@main
id: build
with:
java-enabled: true

View File

@@ -0,0 +1,16 @@
name: Pull Request - Delete Docker
on:
pull_request:
types: [closed]
jobs:
publish:
name: Pull Request - Delete Docker
if: github.repository == 'kestra-io/kestra' # prevent running on forks
runs-on: ubuntu-latest
steps:
- uses: dataaxiom/ghcr-cleanup-action@v1
with:
package: kestra-pr
delete-tags: ${{ github.event.pull_request.number }}

View File

@@ -0,0 +1,78 @@
name: Pull Request - Publish Docker
on:
pull_request:
branches:
- develop
jobs:
build-artifacts:
name: Build Artifacts
if: github.repository == 'kestra-io/kestra' # prevent running on forks
uses: ./.github/workflows/workflow-build-artifacts.yml
publish:
name: Publish Docker
if: github.repository == 'kestra-io/kestra' # prevent running on forks
runs-on: ubuntu-latest
needs: build-artifacts
env:
GITHUB_IMAGE_PATH: "ghcr.io/kestra-io/kestra-pr"
steps:
- name: Checkout - Current ref
uses: actions/checkout@v5
with:
fetch-depth: 0
# Docker setup
- name: Docker - Setup QEMU
uses: docker/setup-qemu-action@v3
- name: Docker - Setup Docker Buildx
uses: docker/setup-buildx-action@v3
# Docker Login
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Build Docker Image
- name: Artifacts - Download executable
uses: actions/download-artifact@v5
with:
name: exe
path: build/executable
- name: Docker - Copy exe to image
shell: bash
run: |
cp build/executable/* docker/app/kestra && chmod +x docker/app/kestra
- name: Docker - Build image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.pr
push: true
tags: ${{ env.GITHUB_IMAGE_PATH }}:${{ github.event.pull_request.number }}
platforms: linux/amd64,linux/arm64
# Add comment on pull request
- name: Add comment to PR
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `**🐋 Docker image**: \`${{ env.GITHUB_IMAGE_PATH }}:${{ github.event.pull_request.number }}\`\n` +
`\n` +
`\`\`\`bash\n` +
`docker run --pull=always --rm -it -p 8080:8080 --user=root -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp ${{ env.GITHUB_IMAGE_PATH }}:${{ github.event.pull_request.number }} server local\n` +
`\`\`\``
})

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
plugin-version:
description: "Kestra version"
description: "plugins version"
default: 'LATEST'
required: false
type: string
@@ -16,7 +16,7 @@ on:
workflow_call:
inputs:
plugin-version:
description: "Kestra version"
description: "plugins version"
default: 'LATEST'
required: false
type: string
@@ -42,21 +42,25 @@ on:
SONATYPE_GPG_FILE:
description: "The Sonatype GPG file."
required: true
GH_PERSONAL_TOKEN:
description: "GH personnal Token."
required: true
SLACK_RELEASES_WEBHOOK_URL:
description: "Slack webhook for releases channel."
required: true
jobs:
build-artifacts:
name: Build - Artifacts
uses: ./.github/workflows/workflow-build-artifacts.yml
with:
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
Docker:
name: Publish Docker
needs: build-artifacts
uses: ./.github/workflows/workflow-publish-docker.yml
if: startsWith(github.ref, 'refs/heads/develop') || github.event.inputs.publish-docker == 'true'
if: github.ref == 'refs/heads/develop' || inputs.publish-docker == 'true'
with:
force-download-artifact: 'false'
plugin-version: ${{ github.event.inputs.plugin-version != null && github.event.inputs.plugin-version || 'LATEST' }}
plugin-version: ${{ inputs.plugin-version != null && inputs.plugin-version || 'LATEST' }}
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
@@ -77,4 +81,5 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v')
uses: ./.github/workflows/workflow-github-release.yml
secrets:
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}

View File

@@ -27,7 +27,7 @@ jobs:
ui: ${{ steps.changes.outputs.ui }}
backend: ${{ steps.changes.outputs.backend }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
if: "!startsWith(github.ref, 'refs/tags/v')"
- uses: dorny/paths-filter@v3
if: "!startsWith(github.ref, 'refs/tags/v')"
@@ -84,14 +84,12 @@ jobs:
name: Notify - Slack
runs-on: ubuntu-latest
needs: [ frontend, backend ]
if: github.event_name == 'schedule'
steps:
- name: Notify failed CI
id: send-ci-failed
if: |
always() && (needs.frontend.result != 'success' ||
needs.backend.result != 'success')
uses: kestra-io/actions/.github/actions/send-ci-failed@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
always() &&
(needs.frontend.result != 'success' || needs.backend.result != 'success') &&
(github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
uses: kestra-io/actions/composite/slack-status@main
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}

View File

@@ -19,6 +19,7 @@
#plugin-databricks:io.kestra.plugin:plugin-databricks:LATEST
#plugin-datahub:io.kestra.plugin:plugin-datahub:LATEST
#plugin-dataform:io.kestra.plugin:plugin-dataform:LATEST
#plugin-datagen:io.kestra.plugin:plugin-datagen:LATEST
#plugin-dbt:io.kestra.plugin:plugin-dbt:LATEST
#plugin-debezium:io.kestra.plugin:plugin-debezium-db2:LATEST
#plugin-debezium:io.kestra.plugin:plugin-debezium-mongodb:LATEST
@@ -35,6 +36,7 @@
#plugin-gemini:io.kestra.plugin:plugin-gemini:LATEST
#plugin-git:io.kestra.plugin:plugin-git:LATEST
#plugin-github:io.kestra.plugin:plugin-github:LATEST
#plugin-gitlab:io.kestra.plugin:plugin-gitlab: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
@@ -87,13 +89,18 @@
#plugin-powerbi:io.kestra.plugin:plugin-powerbi:LATEST
#plugin-pulsar:io.kestra.plugin:plugin-pulsar:LATEST
#plugin-redis:io.kestra.plugin:plugin-redis:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-bun:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-deno:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-go:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-groovy:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-jbang:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-julia:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-jython:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-lua:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-nashorn:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-node:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-perl:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-php:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-powershell:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-python:LATEST
#plugin-scripts:io.kestra.plugin:plugin-script-r:LATEST
@@ -102,16 +109,17 @@
#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
#plugin-spark:io.kestra.plugin:plugin-spark:LATEST
#plugin-sqlmesh:io.kestra.plugin:plugin-sqlmesh:LATEST
#plugin-supabase:io.kestra.plugin:plugin-supabase:LATEST
#plugin-surrealdb:io.kestra.plugin:plugin-surrealdb:LATEST
#plugin-terraform:io.kestra.plugin:plugin-terraform:LATEST
#plugin-transform:io.kestra.plugin:plugin-transform-grok:LATEST
#plugin-transform:io.kestra.plugin:plugin-transform-json:LATEST
#plugin-tika:io.kestra.plugin:plugin-tika:LATEST
#plugin-trivy:io.kestra.plugin:plugin-trivy:LATEST
#plugin-weaviate:io.kestra.plugin:plugin-weaviate:LATEST
#plugin-zendesk:io.kestra.plugin:plugin-zendesk:LATEST
#plugin-typesense:io.kestra.plugin:plugin-typesense:LATEST

305
AGENTS.md Normal file
View File

@@ -0,0 +1,305 @@
# Kestra AGENTS.md
This file provides guidance for AI coding agents working on the Kestra project. Kestra is an open-source data orchestration and scheduling platform built with Java (Micronaut) and Vue.js.
## Repository Layout
- **`core/`**: Core Kestra framework and task definitions
- **`cli/`**: Command-line interface and server implementation
- **`webserver/`**: REST API server implementation
- **`ui/`**: Vue.js frontend application
- **`jdbc-*`**: Database connector modules (H2, MySQL, PostgreSQL)
- **`script/`**: Script execution engine
- **`storage-local/`**: Local file storage implementation
- **`repository-memory/`**: In-memory repository implementation
- **`runner-memory/`**: In-memory execution runner
- **`processor/`**: Task processing engine
- **`model/`**: Data models and Data Transfer Objects
- **`platform/`**: Platform-specific implementations
- **`tests/`**: Integration test framework
- **`e2e-tests/`**: End-to-end testing suite
## Development Environment
### Prerequisites
- Java 21+
- Node.js 22+ and npm
- Python 3, pip, and python venv
- Docker & Docker Compose
- Gradle (wrapper included)
### Quick Setup with Devcontainer
The easiest way to get started is using the provided devcontainer:
1. Install VSCode Remote Development extension
2. Run `Dev Containers: Open Folder in Container...` from command palette
3. Select the Kestra root folder
4. Wait for Gradle build to complete
### Manual Setup
1. Clone the repository
2. Run `./gradlew build` to build the backend
3. Navigate to `ui/` and run `npm install`
4. Create configuration files as described below
## Configuration Files
### Backend Configuration
Create `cli/src/main/resources/application-override.yml`:
**Local Mode (H2 database):**
```yaml
micronaut:
server:
cors:
enabled: true
configurations:
all:
allowedOrigins:
- http://localhost:5173
```
**Standalone Mode (PostgreSQL):**
```yaml
kestra:
repository:
type: postgres
storage:
type: local
local:
base-path: "/app/storage"
queue:
type: postgres
tasks:
tmp-dir:
path: /tmp/kestra-wd/tmp
anonymous-usage-report:
enabled: false
datasources:
postgres:
url: jdbc:postgresql://host.docker.internal:5432/kestra
driverClassName: org.postgresql.Driver
username: kestra
password: k3str4
flyway:
datasources:
postgres:
enabled: true
locations:
- classpath:migrations/postgres
ignore-migration-patterns: "*:missing,*:future"
out-of-order: true
micronaut:
server:
cors:
enabled: true
configurations:
all:
allowedOrigins:
- http://localhost:5173
```
### Frontend Configuration
Create `ui/.env.development.local` for environment variables.
## Running the Application
### Backend
- **Local mode**: `./gradlew runLocal` (uses H2 database)
- **Standalone mode**: Use VSCode Run and Debug with main class `io.kestra.cli.App` and args `server standalone`
### Frontend
- Navigate to `ui/` directory
- Run `npm run dev` for development server (port 5173)
- Run `npm run build` for production build
## Building and Testing
### Backend
```bash
# Build the project
./gradlew build
# Run tests
./gradlew test
# Run specific module tests
./gradlew :core:test
# Clean build
./gradlew clean build
```
### Frontend
```bash
cd ui
npm install
npm run test
npm run lint
npm run build
```
### End-to-End Tests
```bash
# Build and start E2E tests
./build-and-start-e2e-tests.sh
# Or use the Makefile
make install
make install-plugins
make start-standalone-postgres
```
## Development Guidelines
### Java Backend
- Use Java 21 features
- Follow Micronaut framework patterns
- Add Swagger annotations for API documentation
- Use annotation processors (enable in IDE)
- Set `MICRONAUT_ENVIRONMENTS=local,override` for custom config
- Set `KESTRA_PLUGINS_PATH` for custom plugin loading
### Vue.js Frontend
- Vue 3 with Composition API
- TypeScript for type safety
- Vite for build tooling
- ESLint and Prettier for code quality
- Component-based architecture in `src/components/`
### Code Style
- Follow `.editorconfig` settings
- Use 4 spaces for Java, 2 spaces for YAML/JSON/CSS
- Enable format on save in VSCode
- Use Prettier for frontend code formatting
## Testing Strategy
### Backend Testing
- Unit tests in `src/test/java/`
- Integration tests in `tests/` module
- Use Micronaut test framework
- Test both local and standalone modes
### Frontend Testing
- Unit tests with Jest
- E2E tests with Playwright
- Component testing with Storybook
- Run `npm run test:unit` and `npm run test:e2e`
## Plugin Development
### Creating Plugins
- Follow the [Plugin Developer Guide](https://kestra.io/docs/plugin-developer-guide/)
- Place JAR files in `KESTRA_PLUGINS_PATH`
- Use the plugin template structure
- Test with both local and standalone modes
### Plugin Loading
- Set `KESTRA_PLUGINS_PATH` environment variable
- Use devcontainer mounts for local development
- Plugins are loaded at startup
## Common Issues and Solutions
### JavaScript Heap Out of Memory
Set `NODE_OPTIONS=--max-old-space-size=4096` environment variable.
### CORS Issues
Ensure backend CORS is configured for `http://localhost:5173` when using frontend dev server.
### Database Connection Issues
- Use `host.docker.internal` instead of `localhost` when connecting from devcontainer
- Verify PostgreSQL is running and accessible
- Check database credentials and permissions
### Gradle Build Issues
- Clear Gradle cache: `./gradlew clean`
- Check Java version compatibility
- Verify all dependencies are available
## Pull Request Guidelines
### Before Submitting
1. Run all tests: `./gradlew test` and `npm test`
2. Check code formatting: `./gradlew spotlessCheck`
3. Verify CORS configuration if changing API
4. Test both local and standalone modes
5. Update documentation for user-facing changes
### Commit Messages
- Follow conventional commit format
- Use present tense ("Add feature" not "Added feature")
- Reference issue numbers when applicable
- Keep commits focused and atomic
### Review Checklist
- [ ] All tests pass
- [ ] Code follows project style guidelines
- [ ] Documentation is updated
- [ ] No breaking changes without migration guide
- [ ] CORS properly configured if API changes
- [ ] Both local and standalone modes tested
## Useful Commands
```bash
# Quick development commands
./gradlew runLocal # Start local backend
./gradlew :ui:build # Build frontend
./gradlew clean build # Clean rebuild
npm run dev # Start frontend dev server
make install # Install Kestra locally
make start-standalone-postgres # Start with PostgreSQL
# Testing commands
./gradlew test # Run all backend tests
./gradlew :core:test # Run specific module tests
npm run test # Run frontend tests
npm run lint # Lint frontend code
```
## Getting Help
- Open a [GitHub issue](https://github.com/kestra-io/kestra/issues)
- Join the [Kestra Slack community](https://kestra.io/slack)
- Check the [main documentation](https://kestra.io/docs)
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `MICRONAUT_ENVIRONMENTS` | Custom config environments | `local,override` |
| `KESTRA_PLUGINS_PATH` | Path to custom plugins | `/workspaces/kestra/local/plugins` |
| `NODE_OPTIONS` | Node.js options | `--max-old-space-size=4096` |
| `JAVA_HOME` | Java installation path | `/usr/java/jdk-21` |
Remember: Always test your changes in both local and standalone modes, and ensure CORS is properly configured for frontend development.

7
Dockerfile.pr Normal file
View File

@@ -0,0 +1,7 @@
FROM kestra/kestra:develop
USER root
COPY --chown=kestra:kestra docker /
USER kestra

View File

@@ -89,7 +89,7 @@ build-docker: build-exec
--compress \
--rm \
-f ./Dockerfile \
--build-arg="APT_PACKAGES=python3 python3-venv python-is-python3 python3-pip nodejs npm curl zip unzip jattach" \
--build-arg="APT_PACKAGES=python3 python-is-python3 python3-pip curl jattach" \
--build-arg="PYTHON_LIBRARIES=kestra" \
-t ${DOCKER_IMAGE}:${VERSION} ${DOCKER_PATH} || exit 1 ;

View File

@@ -33,10 +33,10 @@
<p align="center">
<a href="https://go.kestra.io/video/product-overview" target="_blank">
<img src="https://kestra.io/startvideo.png" alt="Get started in 4 minutes with Kestra" width="640px" />
<img src="https://kestra.io/startvideo.png" alt="Get started in 3 minutes with Kestra" width="640px" />
</a>
</p>
<p align="center" style="color:grey;"><i>Click on the image to learn how to get started with Kestra in 4 minutes.</i></p>
<p align="center" style="color:grey;"><i>Click on the image to learn how to get started with Kestra in 3 minutes.</i></p>
## 🌟 What is Kestra?
@@ -65,10 +65,6 @@ Kestra is an open-source, event-driven orchestration platform that makes both **
## 🚀 Quick Start
### Try the Live Demo
Try Kestra with our [**Live Demo**](https://demo.kestra.io/ui/login?auto). No installation required!
### Get Started Locally in 5 Minutes
#### Launch Kestra in Docker

View File

@@ -7,7 +7,7 @@ set -e
# run tests on this image
LOCAL_IMAGE_VERSION="local-e2e"
LOCAL_IMAGE_VERSION="local-e2e-$(date +%s)"
echo "Running E2E"
echo "Start time: $(date '+%Y-%m-%d %H:%M:%S')"
@@ -15,6 +15,7 @@ start_time=$(date +%s)
echo ""
echo "Building the image for this current repository"
make clean
make build-docker VERSION=$LOCAL_IMAGE_VERSION
end_time=$(date +%s)
@@ -32,7 +33,7 @@ echo "npm i"
npm i
echo 'sh ./run-e2e-tests.sh --kestra-docker-image-to-test "kestra/kestra:$LOCAL_IMAGE_VERSION"'
sh ./run-e2e-tests.sh --kestra-docker-image-to-test "kestra/kestra:$LOCAL_IMAGE_VERSION"
./run-e2e-tests.sh --kestra-docker-image-to-test "kestra/kestra:$LOCAL_IMAGE_VERSION"
end_time2=$(date +%s)
elapsed2=$(( end_time2 - start_time2 ))

View File

@@ -16,12 +16,12 @@ plugins {
id "java"
id 'java-library'
id "idea"
id "com.gradleup.shadow" version "8.3.8"
id "com.gradleup.shadow" version "8.3.9"
id "application"
// test
id "com.adarshr.test-logger" version "4.0.0"
id "org.sonarqube" version "6.2.0.5505"
id "org.sonarqube" version "6.3.1.5724"
id 'jacoco-report-aggregation'
// helper
@@ -32,12 +32,12 @@ plugins {
// release
id 'net.researchgate.release' version '3.1.0'
id "com.gorylenko.gradle-git-properties" version "2.5.2"
id "com.gorylenko.gradle-git-properties" version "2.5.3"
id 'signing'
id "com.vanniktech.maven.publish" version "0.34.0"
// OWASP dependency check
id "org.owasp.dependencycheck" version "12.1.3" apply false
id "org.owasp.dependencycheck" version "12.1.5" apply false
}
idea {
@@ -168,8 +168,9 @@ allprojects {
/**********************************************************************************************************************\
* Test
**********************************************************************************************************************/
subprojects {
if (it.name != 'platform' && it.name != 'jmh-benchmarks') {
subprojects {subProj ->
if (subProj.name != 'platform' && subProj.name != 'jmh-benchmarks') {
apply plugin: "com.adarshr.test-logger"
java {
@@ -207,6 +208,13 @@ subprojects {
test {
useJUnitPlatform()
reports {
junitXml.required = true
junitXml.outputPerTestCase = true
junitXml.mergeReruns = true
junitXml.includeSystemErrLog = true;
junitXml.outputLocation = layout.buildDirectory.dir("test-results/test")
}
// set Xmx for test workers
maxHeapSize = '4g'
@@ -222,17 +230,26 @@ subprojects {
environment 'SECRET_PASSWORD', "cGFzc3dvcmQ="
environment 'ENV_TEST1', "true"
environment 'ENV_TEST2', "Pass by env"
if (subProj.name == 'core' || subProj.name == 'jdbc-h2' || subProj.name == 'jdbc-mysql' || subProj.name == 'jdbc-postgres') {
// JUnit 5 parallel settings
systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
systemProperty 'junit.jupiter.execution.parallel.mode.default', 'concurrent'
systemProperty 'junit.jupiter.execution.parallel.mode.classes.default', 'same_thread'
systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'dynamic'
}
}
testlogger {
theme 'mocha-parallel'
showExceptions true
showFullStackTraces true
showCauses true
slowThreshold 2000
showStandardStreams true
showPassedStandardStreams false
showSkippedStandardStreams true
theme = 'mocha-parallel'
showExceptions = true
showFullStackTraces = true
showCauses = true
slowThreshold = 2000
showStandardStreams = true
showPassedStandardStreams = false
showSkippedStandardStreams = true
}
}
}
@@ -410,7 +427,7 @@ jar {
shadowJar {
archiveClassifier.set(null)
mergeServiceFiles()
zip64 true
zip64 = true
}
distZip.dependsOn shadowJar
@@ -427,8 +444,8 @@ def executableDir = layout.buildDirectory.dir("executable")
def executable = layout.buildDirectory.file("executable/${project.name}-${project.version}").get().asFile
tasks.register('writeExecutableJar') {
group "build"
description "Write an executable jar from shadow jar"
group = "build"
description = "Write an executable jar from shadow jar"
dependsOn = [shadowJar]
final shadowJarFile = tasks.shadowJar.outputs.files.singleFile
@@ -454,8 +471,8 @@ tasks.register('writeExecutableJar') {
}
tasks.register('executableJar', Zip) {
group "build"
description "Zip the executable jar"
group = "build"
description = "Zip the executable jar"
dependsOn = [writeExecutableJar]
archiveFileName = "${project.name}-${project.version}.zip"
@@ -620,6 +637,28 @@ subprojects {subProject ->
}
}
}
if (subProject.name != 'platform' && subProject.name != 'cli') {
// only if a test source set actually exists (avoids empty artifacts)
def hasTests = subProject.extensions.findByName('sourceSets')?.findByName('test') != null
if (hasTests) {
// wire the artifact onto every Maven publication of this subproject
publishing {
publications {
withType(MavenPublication).configureEach { pub ->
// keep the normal java component + sources/javadoc already configured
pub.artifact(subProject.tasks.named('testsJar').get())
}
}
}
// make sure publish tasks build the tests jar first
tasks.matching { it.name.startsWith('publish') }.configureEach {
dependsOn subProject.tasks.named('testsJar')
}
}
}
}
}

View File

@@ -33,8 +33,13 @@ dependencies {
implementation project(":storage-local")
// Kestra server components
implementation project(":executor")
implementation project(":scheduler")
implementation project(":webserver")
implementation project(":worker")
//test
testImplementation project(':tests')
testImplementation "org.wiremock:wiremock-jetty12"
}

View File

@@ -49,7 +49,7 @@ import java.util.concurrent.Callable;
@Introspected
public class App implements Callable<Integer> {
public static void main(String[] args) {
execute(App.class, args);
execute(App.class, new String [] { Environment.CLI }, args);
}
@Override
@@ -57,13 +57,13 @@ public class App implements Callable<Integer> {
return PicocliRunner.call(App.class, "--help");
}
protected static void execute(Class<?> cls, String... args) {
protected static void execute(Class<?> cls, String[] environments, String... args) {
// Log Bridge
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
// Init ApplicationContext
ApplicationContext applicationContext = App.applicationContext(cls, args);
ApplicationContext applicationContext = App.applicationContext(cls, environments, args);
// Call Picocli command
int exitCode = 0;
@@ -80,6 +80,7 @@ public class App implements Callable<Integer> {
System.exit(Objects.requireNonNullElse(exitCode, 0));
}
/**
* Create an {@link ApplicationContext} with additional properties based on configuration files (--config) and
* forced Properties from current command.
@@ -88,12 +89,13 @@ public class App implements Callable<Integer> {
* @return the application context created
*/
protected static ApplicationContext applicationContext(Class<?> mainClass,
String[] environments,
String[] args) {
ApplicationContextBuilder builder = ApplicationContext
.builder()
.mainClass(mainClass)
.environments(Environment.CLI);
.environments(environments);
CommandLine cmd = new CommandLine(mainClass, CommandLine.defaultFactory());
continueOnParsingErrors(cmd);

View File

@@ -1,15 +1,14 @@
package io.kestra.core.runners;
package io.kestra.cli;
import io.kestra.core.schedulers.AbstractScheduler;
import io.kestra.core.runners.*;
import io.kestra.core.server.Service;
import io.kestra.core.utils.Await;
import io.kestra.core.utils.ExecutorsUtils;
import io.kestra.worker.DefaultWorker;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.annotation.Value;
import jakarta.annotation.PreDestroy;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@@ -24,9 +23,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
@SuppressWarnings("try")
@Slf4j
@Singleton
@Requires(missingBeans = RunnerInterface.class)
public class StandAloneRunner implements RunnerInterface, AutoCloseable {
public class StandAloneRunner implements Runnable, AutoCloseable {
@Setter protected int workerThread = Math.max(3, Runtime.getRuntime().availableProcessors());
@Setter protected boolean schedulerEnabled = true;
@Setter protected boolean workerEnabled = true;
@@ -45,7 +42,7 @@ public class StandAloneRunner implements RunnerInterface, AutoCloseable {
private final AtomicBoolean running = new AtomicBoolean(false);
private volatile ExecutorService poolExecutor;
private ExecutorService poolExecutor;
@Override
public void run() {
@@ -57,20 +54,20 @@ public class StandAloneRunner implements RunnerInterface, AutoCloseable {
if (workerEnabled) {
// FIXME: For backward-compatibility with Kestra 0.15.x and earliest we still used UUID for Worker ID instead of IdUtils
String workerID = UUID.randomUUID().toString();
Worker worker = applicationContext.createBean(Worker.class, workerID, workerThread, null);
Worker worker = applicationContext.createBean(DefaultWorker.class, workerID, workerThread, null);
applicationContext.registerSingleton(worker); //
poolExecutor.execute(worker);
servers.add(worker);
}
if (schedulerEnabled) {
AbstractScheduler scheduler = applicationContext.getBean(AbstractScheduler.class);
Scheduler scheduler = applicationContext.getBean(Scheduler.class);
poolExecutor.execute(scheduler);
servers.add(scheduler);
}
if (indexerEnabled) {
IndexerInterface indexer = applicationContext.getBean(IndexerInterface.class);
Indexer indexer = applicationContext.getBean(Indexer.class);
poolExecutor.execute(indexer);
servers.add(indexer);
}

View File

@@ -8,7 +8,7 @@ import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.repositories.LocalFlowRepositoryLoader;
import io.kestra.core.runners.FlowInputOutput;
import io.kestra.core.runners.RunnerUtils;
import io.kestra.core.runners.StandAloneRunner;
import io.kestra.cli.StandAloneRunner;
import io.micronaut.context.ApplicationContext;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
@@ -72,7 +72,6 @@ public class FlowTestCommand extends AbstractApiCommand {
public Integer call() throws Exception {
super.call();
StandAloneRunner runner = applicationContext.getBean(StandAloneRunner.class);
LocalFlowRepositoryLoader repositoryLoader = applicationContext.getBean(LocalFlowRepositoryLoader.class);
FlowRepositoryInterface flowRepository = applicationContext.getBean(FlowRepositoryInterface.class);
FlowInputOutput flowInputOutput = applicationContext.getBean(FlowInputOutput.class);
@@ -89,7 +88,7 @@ public class FlowTestCommand extends AbstractApiCommand {
inputs.put(this.inputs.get(i), this.inputs.get(i+1));
}
try {
try (StandAloneRunner runner = applicationContext.createBean(StandAloneRunner.class);){
runner.run();
repositoryLoader.load(tenantService.getTenantId(tenantId), file.toFile());
@@ -103,8 +102,6 @@ public class FlowTestCommand extends AbstractApiCommand {
(flow, execution) -> flowInputOutput.readExecutionInputs(flow, execution, inputs),
Duration.ofHours(1)
);
runner.close();
} catch (ConstraintViolationException e) {
throw new CommandLine.ParameterException(this.spec.commandLine(), e.getMessage());
} catch (IOException | TimeoutException e) {

View File

@@ -2,20 +2,28 @@ package io.kestra.cli.commands.servers;
import io.kestra.cli.AbstractCommand;
import io.kestra.core.contexts.KestraContext;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
abstract public class AbstractServerCommand extends AbstractCommand implements ServerCommandInterface {
@Slf4j
public abstract class AbstractServerCommand extends AbstractCommand implements ServerCommandInterface {
@CommandLine.Option(names = {"--port"}, description = "The port to bind")
Integer serverPort;
@Override
public Integer call() throws Exception {
log.info("Machine information: {} available cpu(s), {}MB max memory, Java version {}", Runtime.getRuntime().availableProcessors(), maxMemoryInMB(), Runtime.version());
this.shutdownHook(true, () -> KestraContext.getContext().shutdown());
return super.call();
}
private long maxMemoryInMB() {
return Runtime.getRuntime().maxMemory() / 1024 / 1024;
}
protected static int defaultWorkerThread() {
return Runtime.getRuntime().availableProcessors() * 4;
return Runtime.getRuntime().availableProcessors() * 8;
}
}

View File

@@ -3,7 +3,7 @@ package io.kestra.cli.commands.servers;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.models.ServerType;
import io.kestra.core.runners.ExecutorInterface;
import io.kestra.core.services.SkipExecutionService;
import io.kestra.executor.SkipExecutionService;
import io.kestra.core.services.StartExecutorService;
import io.kestra.core.utils.Await;
import io.micronaut.context.ApplicationContext;

View File

@@ -2,7 +2,7 @@ package io.kestra.cli.commands.servers;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.models.ServerType;
import io.kestra.core.runners.IndexerInterface;
import io.kestra.core.runners.Indexer;
import io.kestra.core.utils.Await;
import io.micronaut.context.ApplicationContext;
import jakarta.inject.Inject;
@@ -29,7 +29,7 @@ public class IndexerCommand extends AbstractServerCommand {
public Integer call() throws Exception {
super.call();
IndexerInterface indexer = applicationContext.getBean(IndexerInterface.class);
Indexer indexer = applicationContext.getBean(Indexer.class);
indexer.run();
Await.until(() -> !this.applicationContext.isRunning());

View File

@@ -2,7 +2,7 @@ package io.kestra.cli.commands.servers;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.models.ServerType;
import io.kestra.core.schedulers.AbstractScheduler;
import io.kestra.scheduler.AbstractScheduler;
import io.kestra.core.utils.Await;
import io.micronaut.context.ApplicationContext;
import jakarta.inject.Inject;

View File

@@ -6,8 +6,8 @@ import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.repositories.LocalFlowRepositoryLoader;
import io.kestra.core.runners.StandAloneRunner;
import io.kestra.core.services.SkipExecutionService;
import io.kestra.cli.StandAloneRunner;
import io.kestra.executor.SkipExecutionService;
import io.kestra.core.services.StartExecutorService;
import io.kestra.core.utils.Await;
import io.micronaut.context.ApplicationContext;
@@ -48,7 +48,7 @@ public class StandAloneCommand extends AbstractServerCommand {
@CommandLine.Option(names = "--tenant", description = "Tenant identifier, Required to load flows from path with the enterprise edition")
private String tenantId;
@CommandLine.Option(names = {"--worker-thread"}, description = "the number of worker threads, defaults to four times the number of available processors. Set it to 0 to avoid starting a worker.")
@CommandLine.Option(names = {"--worker-thread"}, description = "the number of worker threads, defaults to eight times the number of available processors. Set it to 0 to avoid starting a worker.")
private int workerThread = defaultWorkerThread();
@CommandLine.Option(names = {"--skip-executions"}, split=",", description = "a list of execution identifiers to skip, separated by a coma; for troubleshooting purpose only")
@@ -109,26 +109,27 @@ public class StandAloneCommand extends AbstractServerCommand {
}
}
StandAloneRunner standAloneRunner = applicationContext.getBean(StandAloneRunner.class);
try (StandAloneRunner standAloneRunner = applicationContext.getBean(StandAloneRunner.class)) {
if (this.workerThread == 0) {
standAloneRunner.setWorkerEnabled(false);
} else {
standAloneRunner.setWorkerThread(this.workerThread);
if (this.workerThread == 0) {
standAloneRunner.setWorkerEnabled(false);
} else {
standAloneRunner.setWorkerThread(this.workerThread);
}
if (this.indexerDisabled) {
standAloneRunner.setIndexerEnabled(false);
}
standAloneRunner.run();
if (fileWatcher != null) {
fileWatcher.startListeningFromConfig();
}
Await.until(() -> !this.applicationContext.isRunning());
}
if (this.indexerDisabled) {
standAloneRunner.setIndexerEnabled(false);
}
standAloneRunner.run();
if (fileWatcher != null) {
fileWatcher.startListeningFromConfig();
}
Await.until(() -> !this.applicationContext.isRunning());
return 0;
}
}

View File

@@ -2,7 +2,7 @@ package io.kestra.cli.commands.servers;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.models.ServerType;
import io.kestra.core.runners.IndexerInterface;
import io.kestra.core.runners.Indexer;
import io.kestra.core.utils.Await;
import io.kestra.core.utils.ExecutorsUtils;
import io.micronaut.context.ApplicationContext;
@@ -54,7 +54,7 @@ public class WebServerCommand extends AbstractServerCommand {
if (!indexerDisabled) {
log.info("Starting an embedded indexer, this can be disabled by using `--no-indexer`.");
poolExecutor = executorsUtils.cachedThreadPool("webserver-indexer");
poolExecutor.execute(applicationContext.getBean(IndexerInterface.class));
poolExecutor.execute(applicationContext.getBean(Indexer.class));
shutdownHook(false, () -> poolExecutor.shutdown());
}

View File

@@ -22,7 +22,7 @@ public class WorkerCommand extends AbstractServerCommand {
@Inject
private ApplicationContext applicationContext;
@Option(names = {"-t", "--thread"}, description = "The max number of worker threads, defaults to four times the number of available processors")
@Option(names = {"-t", "--thread"}, description = "The max number of worker threads, defaults to eight times the number of available processors")
private int thread = defaultWorkerThread();
@Option(names = {"-g", "--worker-group"}, description = "The worker group key, must match the regex [a-zA-Z0-9_-]+ (EE only)")

View File

@@ -10,24 +10,21 @@ import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.services.FlowListenersInterface;
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.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.ConstraintViolationException;
import java.util.concurrent.CopyOnWriteArrayList;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
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")
@@ -49,13 +46,9 @@ public class FileChangedEventListener {
@Inject
protected FlowListenersInterface flowListeners;
@Nullable
@Value("${micronaut.io.watch.tenantId}")
private String tenantId;
FlowFilesManager flowFilesManager;
private List<FlowWithPath> flows = new ArrayList<>();
private List<FlowWithPath> flows = new CopyOnWriteArrayList<>();
private boolean isStarted = false;
@@ -113,8 +106,6 @@ 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);
}
@@ -157,7 +148,7 @@ public class FileChangedEventListener {
flows.add(FlowWithPath.of(flow.get(), filePath.toString()));
}
flowFilesManager.createOrUpdateFlow(GenericFlow.fromYaml(tenantId, content));
flowFilesManager.createOrUpdateFlow(GenericFlow.fromYaml(getTenantIdFromPath(filePath), content));
log.info("Flow {} from file {} has been created or modified", flow.get().getId(), entry);
}
@@ -201,8 +192,6 @@ 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
@@ -222,7 +211,7 @@ public class FileChangedEventListener {
if (flow.isPresent() && flows.stream().noneMatch(flowWithPath -> flowWithPath.uidWithoutRevision().equals(flow.get().uidWithoutRevision()))) {
flows.add(FlowWithPath.of(flow.get(), file.toString()));
flowFilesManager.createOrUpdateFlow(GenericFlow.fromYaml(tenantId, content));
flowFilesManager.createOrUpdateFlow(GenericFlow.fromYaml(getTenantIdFromPath(file), content));
}
}
return FileVisitResult.CONTINUE;
@@ -246,10 +235,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);
FlowWithSource flow = pluginDefaultService.parseFlowWithAllDefaults(getTenantIdFromPath(entry), content, false);
modelValidator.validate(flow);
return Optional.of(flow);
} catch (ConstraintViolationException | FlowProcessingException e) {
@@ -273,4 +260,10 @@ public class FileChangedEventListener {
private Path buildPath(FlowInterface flow) {
return fileWatchConfiguration.getPaths().getFirst().resolve(flow.uidWithoutRevision() + ".yml");
}
private String getTenantIdFromPath(Path path) {
// FIXME there is probably a bug here when a tenant has '_' in its name,
// a valid tenant name is defined with following regex: "^[a-z0-9][a-z0-9_-]*"
return path.getFileName().toString().split("_")[0];
}
}

View File

@@ -18,6 +18,10 @@ micronaut:
root:
paths: classpath:root
mapping: /**
codec:
json:
additional-types:
- application/scim+json
server:
max-request-size: 10GB
multipart:
@@ -78,8 +82,19 @@ micronaut:
type: scheduled
core-pool-size: 1
# Disable OpenTelemetry metrics by default, users that need it must enable it and configure the collector URL.
metrics:
binders:
retry:
enabled: true
netty:
queues:
enabled: true
bytebuf-allocators:
enabled: true
channels:
enabled: true
# Disable OpenTelemetry metrics by default, users that need it must enable it and configure the collector URL.
export:
otlp:
enabled: false
@@ -92,6 +107,8 @@ jackson:
serialization-inclusion: non_null
deserialization:
FAIL_ON_UNKNOWN_PROPERTIES: false
mapper:
ACCEPT_CASE_INSENSITIVE_ENUMS: true
endpoints:
all:
@@ -100,6 +117,10 @@ endpoints:
sensitive: false
health:
details-visible: ANONYMOUS
disk-space:
enabled: false
discovery-client:
enabled: false
loggers:
write-sensitive: false
env:
@@ -133,12 +154,46 @@ kestra:
tutorial-flows:
# Automatically loads all tutorial flows at startup.
enabled: true
retries:
attempts: 5
multiplier: 2.0
delay: 1s
maxDelay: ""
server:
basic-auth:
# These URLs will not be authenticated, by default we open some of the Micronaut default endpoints but not all for security reasons
open-urls:
- "/ping"
- "/api/v1/executions/webhook/"
- "/api/v1/main/executions/webhook/"
- "/api/v1/*/executions/webhook/"
preview:
initial-rows: 100
max-rows: 5000
# The expected time for this server to complete all its tasks before initiating a graceful shutdown.
terminationGracePeriod: 5m
workerTaskRestartStrategy: AFTER_TERMINATION_GRACE_PERIOD
# Configuration for Liveness and Heartbeat mechanism between servers.
liveness:
enabled: true
# The expected time between liveness probe.
interval: 10s
# The timeout used to detect service failures.
timeout: 1m
# The time to wait before executing a liveness probe.
initialDelay: 1m
# The expected time between service heartbeats.
heartbeatInterval: 3s
service:
purge:
initial-delay: 1h
fixed-delay: 1d
retention: 30d
jdbc:
queues:
min-poll-interval: 25ms
@@ -150,7 +205,7 @@ kestra:
fixed-delay: 1h
retention: 7d
types:
- type : io.kestra.core.models.executions.LogEntry
- type: io.kestra.core.models.executions.LogEntry
retention: 1h
- type: io.kestra.core.models.executions.MetricEntry
retention: 1h
@@ -182,37 +237,12 @@ kestra:
traces:
root: DISABLED
server:
basic-auth:
# These URLs will not be authenticated, by default we open some of the Micronaut default endpoints but not all for security reasons
open-urls:
- "/ping"
- "/api/v1/executions/webhook/"
preview:
initial-rows: 100
max-rows: 5000
# The expected time for this server to complete all its tasks before initiating a graceful shutdown.
terminationGracePeriod: 5m
workerTaskRestartStrategy: AFTER_TERMINATION_GRACE_PERIOD
# Configuration for Liveness and Heartbeat mechanism between servers.
liveness:
enabled: true
# The expected time between liveness probe.
interval: 10s
# The timeout used to detect service failures.
timeout: 1m
# The time to wait before executing a liveness probe.
initialDelay: 1m
# The expected time between service heartbeats.
heartbeatInterval: 3s
service:
purge:
initial-delay: 1h
fixed-delay: 1d
retention: 30d
ui-anonymous-usage-report:
enabled: true
anonymous-usage-report:
enabled: true
uri: https://api.kestra.io/v1/reports/usages
uri: https://api.kestra.io/v1/reports/server-events
initial-delay: 5m
fixed-delay: 1h

View File

@@ -37,7 +37,7 @@ class AppTest {
final String[] args = new String[]{"server", serverType, "--help"};
try (ApplicationContext ctx = App.applicationContext(App.class, args)) {
try (ApplicationContext ctx = App.applicationContext(App.class, new String [] { Environment.CLI }, args)) {
new CommandLine(App.class, new MicronautFactory(ctx)).execute(args);
assertTrue(ctx.getProperty("kestra.server-type", ServerType.class).isEmpty());
@@ -52,7 +52,7 @@ class AppTest {
final String[] argsWithMissingParams = new String[]{"flow", "namespace", "update"};
try (ApplicationContext ctx = App.applicationContext(App.class, argsWithMissingParams)) {
try (ApplicationContext ctx = App.applicationContext(App.class, new String [] { Environment.CLI }, argsWithMissingParams)) {
new CommandLine(App.class, new MicronautFactory(ctx)).execute(argsWithMissingParams);
assertThat(out.toString()).startsWith("Missing required parameters: ");

View File

@@ -1,13 +1,14 @@
package io.kestra.cli.services;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.GenericFlow;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.utils.Await;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.*;
import org.junitpioneer.jupiter.RetryingTest;
import java.io.IOException;
import java.nio.file.Files;
@@ -17,8 +18,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junitpioneer.jupiter.RetryingTest;
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;
@@ -56,10 +57,11 @@ class FileChangedEventListenerTest {
}
}
@RetryingTest(5) // Flaky on CI but always pass locally
@Test
void test() throws IOException, TimeoutException {
var tenant = TestsUtils.randomTenant(FileChangedEventListenerTest.class.getSimpleName(), "test");
// remove the flow if it already exists
flowRepository.findByIdWithSource(MAIN_TENANT, "io.kestra.tests.watch", "myflow").ifPresent(flow -> flowRepository.delete(flow));
flowRepository.findByIdWithSource(tenant, "io.kestra.tests.watch", "myflow").ifPresent(flow -> flowRepository.delete(flow));
// create a basic flow
String flow = """
@@ -71,30 +73,33 @@ class FileChangedEventListenerTest {
type: io.kestra.plugin.core.log.Log
message: Hello World! 🚀
""";
Files.write(Path.of(FILE_WATCH + "/myflow.yaml"), flow.getBytes());
GenericFlow genericFlow = GenericFlow.fromYaml(tenant, flow);
Files.write(Path.of(FILE_WATCH + "/" + genericFlow.uidWithoutRevision() + ".yaml"), flow.getBytes());
Await.until(
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").isPresent(),
() -> flowRepository.findById(tenant, "io.kestra.tests.watch", "myflow").isPresent(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
Flow myflow = flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").orElseThrow();
Flow myflow = flowRepository.findById(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");
// delete the flow
Files.delete(Path.of(FILE_WATCH + "/myflow.yaml"));
Files.delete(Path.of(FILE_WATCH + "/" + genericFlow.uidWithoutRevision() + ".yaml"));
Await.until(
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "myflow").isEmpty(),
() -> flowRepository.findById(tenant, "io.kestra.tests.watch", "myflow").isEmpty(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
}
@RetryingTest(5) // Flaky on CI but always pass locally
@RetryingTest(2)
void testWithPluginDefault() throws IOException, TimeoutException {
var tenant = TestsUtils.randomTenant(FileChangedEventListenerTest.class.getName(), "testWithPluginDefault");
// remove the flow if it already exists
flowRepository.findByIdWithSource(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").ifPresent(flow -> flowRepository.delete(flow));
flowRepository.findByIdWithSource(tenant, "io.kestra.tests.watch", "pluginDefault").ifPresent(flow -> flowRepository.delete(flow));
// create a flow with plugin default
String pluginDefault = """
@@ -110,21 +115,22 @@ class FileChangedEventListenerTest {
values:
message: Hello World!
""";
Files.write(Path.of(FILE_WATCH + "/plugin-default.yaml"), pluginDefault.getBytes());
GenericFlow genericFlow = GenericFlow.fromYaml(tenant, pluginDefault);
Files.write(Path.of(FILE_WATCH + "/" + genericFlow.uidWithoutRevision() + ".yaml"), pluginDefault.getBytes());
Await.until(
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").isPresent(),
() -> flowRepository.findById(tenant, "io.kestra.tests.watch", "pluginDefault").isPresent(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);
Flow pluginDefaultFlow = flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").orElseThrow();
Flow pluginDefaultFlow = flowRepository.findById(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");
// delete both files
Files.delete(Path.of(FILE_WATCH + "/plugin-default.yaml"));
Files.delete(Path.of(FILE_WATCH + "/" + genericFlow.uidWithoutRevision() + ".yaml"));
Await.until(
() -> flowRepository.findById(MAIN_TENANT, "io.kestra.tests.watch", "pluginDefault").isEmpty(),
() -> flowRepository.findById(tenant, "io.kestra.tests.watch", "pluginDefault").isEmpty(),
Duration.ofMillis(100),
Duration.ofSeconds(10)
);

View File

@@ -37,15 +37,15 @@ dependencies {
implementation 'nl.basjes.gitignore:gitignore-reader'
implementation group: 'dev.failsafe', name: 'failsafe'
implementation 'com.github.ben-manes.caffeine:caffeine'
implementation 'com.github.ksuid:ksuid:1.1.3'
implementation 'com.github.ksuid:ksuid:1.1.4'
api 'org.apache.httpcomponents.client5:httpclient5'
// plugins
implementation 'org.apache.maven.resolver:maven-resolver-impl'
implementation 'org.apache.maven.resolver:maven-resolver-supplier'
implementation 'org.apache.maven.resolver:maven-resolver-supplier-mvn3'
implementation 'org.apache.maven.resolver:maven-resolver-connector-basic'
implementation 'org.apache.maven.resolver:maven-resolver-transport-file'
implementation 'org.apache.maven.resolver:maven-resolver-transport-http'
implementation 'org.apache.maven.resolver:maven-resolver-transport-apache'
// scheduler
implementation group: 'com.cronutils', name: 'cron-utils'
@@ -63,6 +63,10 @@ dependencies {
exclude group: 'com.fasterxml.jackson.core'
}
// micrometer
implementation "io.micronaut.micrometer:micronaut-micrometer-observation"
implementation 'io.micrometer:micrometer-java21'
// test
testAnnotationProcessor project(':processor')
testImplementation project(':tests')
@@ -70,6 +74,9 @@ dependencies {
testImplementation project(':repository-memory')
testImplementation project(':runner-memory')
testImplementation project(':storage-local')
testImplementation project(':worker')
testImplementation project(':scheduler')
testImplementation project(':executor')
testImplementation "io.micronaut:micronaut-http-client"
testImplementation "io.micronaut:micronaut-http-server-netty"
@@ -77,7 +84,7 @@ dependencies {
testImplementation "org.testcontainers:testcontainers:1.21.3"
testImplementation "org.testcontainers:junit-jupiter:1.21.3"
testImplementation "org.bouncycastle:bcpkix-jdk18on:1.81"
testImplementation "org.bouncycastle:bcpkix-jdk18on"
testImplementation "org.wiremock:wiremock-jetty12"
}

View File

@@ -53,6 +53,8 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static io.kestra.core.docs.AbstractClassDocumentation.flattenWithoutType;
import static io.kestra.core.docs.AbstractClassDocumentation.required;
import static io.kestra.core.serializers.JacksonMapper.MAP_TYPE_REFERENCE;
@Singleton
@@ -92,12 +94,16 @@ public class JsonSchemaGenerator {
}
public <T> Map<String, Object> schemas(Class<? extends T> cls, boolean arrayOf, List<String> allowedPluginTypes) {
return this.schemas(cls, arrayOf, allowedPluginTypes, false);
}
public <T> Map<String, Object> schemas(Class<? extends T> cls, boolean arrayOf, List<String> allowedPluginTypes, boolean withOutputs) {
SchemaGeneratorConfigBuilder builder = new SchemaGeneratorConfigBuilder(
SchemaVersion.DRAFT_7,
OptionPreset.PLAIN_JSON
);
this.build(builder, true, allowedPluginTypes);
this.build(builder, true, allowedPluginTypes, withOutputs);
SchemaGeneratorConfig schemaGeneratorConfig = builder.build();
@@ -122,12 +128,13 @@ public class JsonSchemaGenerator {
if (jsonNode instanceof ObjectNode clazzSchema && clazzSchema.get("required") instanceof ArrayNode requiredPropsNode && clazzSchema.get("properties") instanceof ObjectNode properties) {
List<String> requiredFieldValues = StreamSupport.stream(requiredPropsNode.spliterator(), false)
.map(JsonNode::asText)
.toList();
.collect(Collectors.toList());
properties.fields().forEachRemaining(e -> {
int indexInRequiredArray = requiredFieldValues.indexOf(e.getKey());
if (indexInRequiredArray != -1 && e.getValue() instanceof ObjectNode valueNode && valueNode.has("default")) {
requiredPropsNode.remove(indexInRequiredArray);
requiredFieldValues.remove(indexInRequiredArray);
}
});
@@ -248,6 +255,10 @@ public class JsonSchemaGenerator {
}
protected void build(SchemaGeneratorConfigBuilder builder, boolean draft7, List<String> allowedPluginTypes) {
this.build(builder, draft7, allowedPluginTypes, false);
}
protected void build(SchemaGeneratorConfigBuilder builder, boolean draft7, List<String> allowedPluginTypes, boolean withOutputs) {
// builder.withObjectMapper(builder.getObjectMapper().configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false));
builder
.with(new JakartaValidationModule(
@@ -429,6 +440,13 @@ public class JsonSchemaGenerator {
if (pluginAnnotation.beta()) {
collectedTypeAttributes.put("$beta", true);
}
if (withOutputs) {
Map<String, Object> outputsSchema = this.outputs(null, scope.getType().getErasedType());
collectedTypeAttributes.set("outputs", context.getGeneratorConfig().createObjectNode().pojoNode(
flattenWithoutType(AbstractClassDocumentation.properties(outputsSchema), required(outputsSchema))
));
}
}
// handle deprecated tasks

View File

@@ -36,6 +36,7 @@ public class Plugin {
private List<PluginElementMetadata> appBlocks;
private List<PluginElementMetadata> charts;
private List<PluginElementMetadata> dataFilters;
private List<PluginElementMetadata> dataFiltersKPI;
private List<PluginElementMetadata> logExporters;
private List<PluginElementMetadata> additionalPlugins;
private List<PluginSubGroup.PluginCategory> categories;
@@ -96,6 +97,7 @@ public class Plugin {
plugin.appBlocks = filterAndGetTypeWithMetadata(registeredPlugin.getAppBlocks(), packagePredicate);
plugin.charts = filterAndGetTypeWithMetadata(registeredPlugin.getCharts(), packagePredicate);
plugin.dataFilters = filterAndGetTypeWithMetadata(registeredPlugin.getDataFilters(), packagePredicate);
plugin.dataFiltersKPI = filterAndGetTypeWithMetadata(registeredPlugin.getDataFiltersKPI(), packagePredicate);
plugin.logExporters = filterAndGetTypeWithMetadata(registeredPlugin.getLogExporters(), packagePredicate);
plugin.additionalPlugins = filterAndGetTypeWithMetadata(registeredPlugin.getAdditionalPlugins(), packagePredicate);

View File

@@ -3,30 +3,88 @@ package io.kestra.core.events;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.context.ServerRequestContext;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
import java.util.Objects;
@Getter
public class CrudEvent<T> {
T model;
private final T model;
@Nullable
T previousModel;
CrudEventType type;
HttpRequest<?> request;
private final T previousModel;
private final CrudEventType type;
private final HttpRequest<?> request;
/**
* Static helper method for creating a new {@link CrudEventType#UPDATE} CrudEvent.
*
* @param model the new created model.
* @param <T> type of the model.
* @return the new {@link CrudEvent}.
*/
public static <T> CrudEvent<T> create(T model) {
Objects.requireNonNull(model, "Can't create CREATE event with a null model");
return new CrudEvent<>(model, null, CrudEventType.CREATE);
}
/**
* Static helper method for creating a new {@link CrudEventType#DELETE} CrudEvent.
*
* @param model the deleted model.
* @param <T> type of the model.
* @return the new {@link CrudEvent}.
*/
public static <T> CrudEvent<T> delete(T model) {
Objects.requireNonNull(model, "Can't create DELETE event with a null model");
return new CrudEvent<>(null, model, CrudEventType.DELETE);
}
/**
* Static helper method for creating a new CrudEvent.
*
* @param before the model before the update.
* @param after the model after the update.
* @param <T> type of the model.
* @return the new {@link CrudEvent}.
*/
public static <T> CrudEvent<T> of(T before, T after) {
if (before == null && after == null) {
throw new IllegalArgumentException("Both before and after cannot be null");
}
if (before == null) {
return create(after);
}
if (after == null) {
return delete(before);
}
return new CrudEvent<>(after, before, CrudEventType.UPDATE);
}
/**
* @deprecated use the static factory methods.
*/
@Deprecated
public CrudEvent(T model, CrudEventType type) {
this.model = model;
this.type = type;
this.previousModel = null;
this.request = ServerRequestContext.currentRequest().orElse(null);
this(
CrudEventType.DELETE.equals(type) ? null : model,
CrudEventType.DELETE.equals(type) ? model : null,
type,
ServerRequestContext.currentRequest().orElse(null)
);
}
public CrudEvent(T model, T previousModel, CrudEventType type) {
this(model, previousModel, type, ServerRequestContext.currentRequest().orElse(null));
}
public CrudEvent(T model, T previousModel, CrudEventType type, HttpRequest<?> request) {
this.model = model;
this.previousModel = previousModel;
this.type = type;
this.request = ServerRequestContext.currentRequest().orElse(null);
this.request = request;
}
}

View File

@@ -6,16 +6,24 @@ import io.kestra.core.http.HttpRequest;
import io.kestra.core.http.HttpResponse;
import io.kestra.core.http.client.apache.*;
import io.kestra.core.http.client.configurations.HttpConfiguration;
import io.kestra.core.runners.DefaultRunContext;
import io.kestra.core.runners.RunContext;
import io.kestra.core.serializers.JacksonMapper;
import io.micrometer.common.KeyValues;
import io.micrometer.core.instrument.binder.httpcomponents.hc5.ApacheHttpClientContext;
import io.micrometer.core.instrument.binder.httpcomponents.hc5.DefaultApacheHttpClientObservationConvention;
import io.micrometer.core.instrument.binder.httpcomponents.hc5.ObservationExecChainHandler;
import io.micrometer.observation.ObservationRegistry;
import io.micronaut.http.MediaType;
import jakarta.annotation.Nullable;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.ContextBuilder;
import org.apache.hc.client5.http.auth.*;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.impl.ChainElement;
import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
@@ -30,7 +38,6 @@ import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.Timeout;
import org.codehaus.plexus.util.StringUtils;
import java.io.Closeable;
import java.io.IOException;
@@ -50,11 +57,16 @@ public class HttpClient implements Closeable {
private transient CloseableHttpClient client;
private final RunContext runContext;
private final HttpConfiguration configuration;
private ObservationRegistry observationRegistry;
@Builder
public HttpClient(RunContext runContext, @Nullable HttpConfiguration configuration) throws IllegalVariableEvaluationException {
this.runContext = runContext;
this.configuration = configuration == null ? HttpConfiguration.builder().build() : configuration;
if (runContext instanceof DefaultRunContext defaultRunContext) {
this.observationRegistry = defaultRunContext.getApplicationContext().findBean(ObservationRegistry.class).orElse(null);
}
this.client = this.createClient();
}
@@ -67,6 +79,13 @@ public class HttpClient implements Closeable {
.disableDefaultUserAgent()
.setUserAgent("Kestra");
if (observationRegistry != null) {
// micrometer, must be placed before the retry strategy (see https://docs.micrometer.io/micrometer/reference/reference/httpcomponents.html#_retry_strategy_considerations)
builder.addExecInterceptorAfter(ChainElement.RETRY.name(), "micrometer",
new ObservationExecChainHandler(observationRegistry, new CustomApacheHttpClientObservationConvention())
);
}
// logger
if (this.configuration.getLogs() != null && this.configuration.getLogs().length > 0) {
if (ArrayUtils.contains(this.configuration.getLogs(), HttpConfiguration.LoggingType.REQUEST_HEADERS) ||
@@ -297,4 +316,14 @@ public class HttpClient implements Closeable {
this.client.close();
}
}
public static class CustomApacheHttpClientObservationConvention extends DefaultApacheHttpClientObservationConvention {
@Override
public KeyValues getLowCardinalityKeyValues(ApacheHttpClientContext context) {
return KeyValues.concat(
super.getLowCardinalityKeyValues(context),
KeyValues.of("type", "core-client")
);
}
}
}

View File

@@ -0,0 +1,34 @@
package io.kestra.core.metrics;
import io.micrometer.core.instrument.binder.jvm.JvmThreadDeadlockMetrics;
import io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics;
import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Primary;
import io.micronaut.context.annotation.Requires;
import jakarta.inject.Singleton;
import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
import static io.micronaut.core.util.StringUtils.FALSE;
@Factory
@RequiresMetrics
public class MeterRegistryBinderFactory {
@Bean
@Primary
@Singleton
@Requires(property = MICRONAUT_METRICS_BINDERS + ".jvm.enabled", notEquals = FALSE)
public VirtualThreadMetrics virtualThreadMetrics() {
return new VirtualThreadMetrics();
}
@Bean
@Primary
@Singleton
@Requires(property = MICRONAUT_METRICS_BINDERS + ".jvm.enabled", notEquals = FALSE)
public JvmThreadDeadlockMetrics threadDeadlockMetricsMetrics() {
return new JvmThreadDeadlockMetrics();
}
}

View File

@@ -6,7 +6,6 @@ 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.*;
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;
@@ -395,19 +394,6 @@ public class MetricRegistry {
return triggerContext.getTenantId() == null ? baseTags : ArrayUtils.addAll(baseTags, TAG_TENANT_ID, triggerContext.getTenantId());
}
/**
* Return tags for current {@link SchedulerExecutionWithTrigger}.
*
* @param schedulerExecutionWithTrigger the current SchedulerExecutionWithTrigger
* @return tags to apply to metrics
*/
public String[] tags(SchedulerExecutionWithTrigger schedulerExecutionWithTrigger, String... tags) {
return ArrayUtils.addAll(
this.tags(schedulerExecutionWithTrigger.getExecution()),
tags
);
}
/**
* Return tags for current {@link ExecutionKilled}
*

View File

@@ -2,12 +2,13 @@ package io.kestra.core.models;
import io.kestra.core.utils.MapUtils;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.NotEmpty;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public record Label(@NotNull String key, @NotNull String value) {
public record Label(@NotEmpty String key, @NotEmpty String value) {
public static final String SYSTEM_PREFIX = "system.";
// system labels
@@ -41,7 +42,7 @@ public record Label(@NotNull String key, @NotNull String value) {
public static Map<String, String> toMap(@Nullable List<Label> labels) {
if (labels == null || labels.isEmpty()) return Collections.emptyMap();
return labels.stream()
.filter(label -> label.value() != null && label.key() != null)
.filter(label -> label.value() != null && !label.value().isEmpty() && label.key() != null && !label.key().isEmpty())
// using an accumulator in case labels with the same key exists: the second is kept
.collect(Collectors.toMap(Label::key, Label::value, (first, second) -> second, LinkedHashMap::new));
}
@@ -56,6 +57,7 @@ public record Label(@NotNull String key, @NotNull String value) {
public static List<Label> deduplicate(@Nullable List<Label> labels) {
if (labels == null || labels.isEmpty()) return Collections.emptyList();
return toMap(labels).entrySet().stream()
.filter(getEntryNotEmptyPredicate())
.map(entry -> new Label(entry.getKey(), entry.getValue()))
.collect(Collectors.toCollection(ArrayList::new));
}
@@ -70,6 +72,7 @@ public record Label(@NotNull String key, @NotNull String value) {
if (map == null || map.isEmpty()) return List.of();
return map.entrySet()
.stream()
.filter(getEntryNotEmptyPredicate())
.map(entry -> new Label(entry.getKey(), entry.getValue()))
.toList();
}
@@ -88,4 +91,14 @@ public record Label(@NotNull String key, @NotNull String value) {
}
return map;
}
/**
* Provides predicate for not empty entries.
*
* @return The non-empty filter
*/
public static Predicate<Map.Entry<String, String>> getEntryNotEmptyPredicate() {
return entry -> entry.getKey() != null && !entry.getKey().isEmpty() &&
entry.getValue() != null && !entry.getValue().isEmpty();
}
}

View File

@@ -1,16 +1,33 @@
package io.kestra.core.models;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Pattern;
import java.util.List;
import java.util.Map;
/**
* Interface that can be implemented by classes supporting plugin versioning.
*
* @see Plugin
*/
public interface PluginVersioning {
String TITLE = "Plugin Version";
String DESCRIPTION = """
Defines the version of the plugin to use.
@Pattern(regexp="\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9-]+)?|([a-zA-Z0-9]+)")
@Schema(title = "The version of the plugin to use.")
The version must follow the Semantic Versioning (SemVer) specification:
- A single-digit MAJOR version (e.g., `1`).
- A MAJOR.MINOR version (e.g., `1.1`).
- A MAJOR.MINOR.PATCH version, optionally with any qualifier
(e.g., `1.1.2`, `1.1.0-SNAPSHOT`).
""";
@Schema(
title = TITLE,
description = DESCRIPTION
)
String getVersion();
}

View File

@@ -139,6 +139,12 @@ public record QueryFilter(
return List.of(Op.EQUALS, Op.NOT_EQUALS, Op.CONTAINS, Op.STARTS_WITH, Op.ENDS_WITH, Op.IN, Op.NOT_IN);
}
},
EXECUTION_ID("executionId") {
@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);
}
},
CHILD_FILTER("childFilter") {
@Override
public List<Op> supportedOp() {
@@ -213,7 +219,7 @@ public record QueryFilter(
@Override
public List<Field> supportedField() {
return List.of(Field.QUERY, Field.SCOPE, Field.NAMESPACE, Field.START_DATE,
Field.END_DATE, Field.FLOW_ID, Field.TRIGGER_ID, Field.MIN_LEVEL
Field.END_DATE, Field.FLOW_ID, Field.TRIGGER_ID, Field.MIN_LEVEL, Field.EXECUTION_ID
);
}
},
@@ -248,19 +254,7 @@ public record QueryFilter(
*
* @return List of {@code ResourceField} with resource names, fields, and operations.
*/
public static List<ResourceField> asResourceList() {
return Arrays.stream(values())
.map(Resource::toResourceField)
.toList();
}
private static ResourceField toResourceField(Resource resource) {
List<FieldOp> fieldOps = resource.supportedField().stream()
.map(Resource::toFieldInfo)
.toList();
return new ResourceField(resource.name().toLowerCase(), fieldOps);
}
private static FieldOp toFieldInfo(Field field) {
List<Operation> operations = field.supportedOp().stream()
.map(Resource::toOperation)
@@ -273,9 +267,6 @@ public record QueryFilter(
}
}
public record ResourceField(String name, List<FieldOp> fields) {
}
public record FieldOp(String name, String value, List<Operation> operations) {
}

View File

@@ -17,31 +17,12 @@ import java.util.List;
@Introspected
public class ExecutionUsage {
private final List<DailyExecutionStatistics> dailyExecutionsCount;
private final List<DailyExecutionStatistics> dailyTaskRunsCount;
public static ExecutionUsage of(final String tenantId,
final ExecutionRepositoryInterface executionRepository,
final ZonedDateTime from,
final ZonedDateTime to) {
List<DailyExecutionStatistics> dailyTaskRunsCount = null;
try {
dailyTaskRunsCount = executionRepository.dailyStatistics(
null,
tenantId,
null,
null,
null,
from,
to,
DateUtils.GroupType.DAY,
null,
true);
} catch (UnsupportedOperationException ignored) {
}
return ExecutionUsage.builder()
.dailyExecutionsCount(executionRepository.dailyStatistics(
null,
@@ -52,28 +33,13 @@ public class ExecutionUsage {
from,
to,
DateUtils.GroupType.DAY,
null,
false))
.dailyTaskRunsCount(dailyTaskRunsCount)
null))
.build();
}
public static ExecutionUsage of(final ExecutionRepositoryInterface repository,
final ZonedDateTime from,
final ZonedDateTime to) {
List<DailyExecutionStatistics> dailyTaskRunsCount = null;
try {
dailyTaskRunsCount = repository.dailyStatisticsForAllTenants(
null,
null,
null,
from,
to,
DateUtils.GroupType.DAY,
true
);
} catch (UnsupportedOperationException ignored) {}
return ExecutionUsage.builder()
.dailyExecutionsCount(repository.dailyStatisticsForAllTenants(
null,
@@ -81,10 +47,8 @@ public class ExecutionUsage {
null,
from,
to,
DateUtils.GroupType.DAY,
false
DateUtils.GroupType.DAY
))
.dailyTaskRunsCount(dailyTaskRunsCount)
.build();
}
}

View File

@@ -62,6 +62,7 @@ public record ServiceUsage(
List<DailyServiceStatistics> statistics = Arrays
.stream(ServiceType.values())
.filter(it -> !it.equals(ServiceType.INVALID))
.map(type -> of(from, to, repository, type, interval))
.toList();
return new ServiceUsage(statistics);

View File

@@ -1,74 +0,0 @@
package io.kestra.core.models.collectors;
import io.kestra.core.models.ServerType;
import io.micronaut.core.annotation.Introspected;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
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)
@Getter
@Jacksonized
@Introspected
@AllArgsConstructor
public class Usage {
@NotNull
private final String uuid;
@NotNull
private final String startUuid;
@NotNull
private final String instanceUuid;
@NotNull
private final ServerType serverType;
@NotNull
private final String version;
@NotNull
private final ZoneId zoneId;
@Nullable
private final String uri;
@Nullable
private final Set<String> environments;
@NotNull
private final Instant startTime;
@Valid
private final HostUsage host;
@Valid
private final ConfigurationUsage configurations;
@Valid
private final List<PluginUsage> plugins;
@Valid
private final FlowUsage flows;
@Valid
private final ExecutionUsage executions;
@Valid
@Nullable
private ServiceUsage services;
@Valid
@Nullable
private List<PluginMetric> pluginMetrics;
}

View File

@@ -132,7 +132,7 @@ public class Execution implements DeletedInterface, TenantInterface {
* @param labels The Flow labels.
* @return a new {@link Execution}.
*/
public static Execution newExecution(final Flow flow, final List<Label> labels) {
public static Execution newExecution(final FlowInterface flow, final List<Label> labels) {
return newExecution(flow, null, labels, Optional.empty());
}
@@ -441,6 +441,28 @@ public class Execution implements DeletedInterface, TenantInterface {
@Nullable List<ResolvedTask> resolvedErrors,
@Nullable List<ResolvedTask> resolvedFinally,
TaskRun parentTaskRun
) {
return findTaskDependingFlowState(resolvedTasks, resolvedErrors, resolvedFinally, parentTaskRun, null);
}
/**
* Determine if the current execution is on error &amp; normal tasks
* <p>
* if the current have errors, return tasks from errors if not, return the normal tasks
*
* @param resolvedTasks normal tasks
* @param resolvedErrors errors tasks
* @param resolvedFinally finally tasks
* @param parentTaskRun the parent task
* @param terminalState the parent task terminal state
* @return the flow we need to follow
*/
public List<ResolvedTask> findTaskDependingFlowState(
List<ResolvedTask> resolvedTasks,
@Nullable List<ResolvedTask> resolvedErrors,
@Nullable List<ResolvedTask> resolvedFinally,
TaskRun parentTaskRun,
@Nullable State.Type terminalState
) {
resolvedTasks = removeDisabled(resolvedTasks);
resolvedErrors = removeDisabled(resolvedErrors);
@@ -454,10 +476,15 @@ public class Execution implements DeletedInterface, TenantInterface {
return resolvedFinally == null ? Collections.emptyList() : resolvedFinally;
}
// Check if flow has failed task
// check if the parent task should fail, and there is error tasks so we start them
if (errorsFlow.isEmpty() && terminalState == State.Type.FAILED) {
return resolvedErrors == null ? resolvedFinally == null ? Collections.emptyList() : resolvedFinally : resolvedErrors;
}
// Check if flow has failed tasks
if (!errorsFlow.isEmpty() || this.hasFailed(resolvedTasks, parentTaskRun)) {
// Check if among the failed task, they will be retried
if (!this.hasFailedNoRetry(resolvedTasks, parentTaskRun)) {
if (!this.hasFailedNoRetry(resolvedTasks, parentTaskRun) && terminalState != State.Type.FAILED) {
return Collections.emptyList();
}
@@ -666,6 +693,11 @@ public class Execution implements DeletedInterface, TenantInterface {
public State.Type guessFinalState(List<ResolvedTask> currentTasks, TaskRun parentTaskRun,
boolean allowFailure, boolean allowWarning) {
return guessFinalState(currentTasks, parentTaskRun, allowFailure, allowWarning, State.Type.SUCCESS);
}
public State.Type guessFinalState(List<ResolvedTask> currentTasks, TaskRun parentTaskRun,
boolean allowFailure, boolean allowWarning, State.Type terminalState) {
List<TaskRun> taskRuns = this.findTaskRunByTasks(currentTasks, parentTaskRun);
var state = this
.findLastByState(taskRuns, State.Type.KILLED)
@@ -682,7 +714,7 @@ public class Execution implements DeletedInterface, TenantInterface {
.findLastByState(taskRuns, State.Type.PAUSED)
.map(taskRun -> taskRun.getState().getCurrent())
)
.orElse(State.Type.SUCCESS);
.orElse(terminalState);
if (state == State.Type.FAILED && allowFailure) {
if (allowWarning) {
@@ -833,20 +865,18 @@ public class Execution implements DeletedInterface, TenantInterface {
* @param e the exception raise
* @return new taskRun with updated attempt with logs
*/
private FailedTaskRunWithLog lastAttemptsTaskRunForFailedExecution(TaskRun taskRun,
TaskRunAttempt lastAttempt, Exception e) {
private FailedTaskRunWithLog lastAttemptsTaskRunForFailedExecution(TaskRun taskRun, TaskRunAttempt lastAttempt, Exception e) {
TaskRun failed = taskRun
.withAttempts(
Stream
.concat(
taskRun.getAttempts().stream().limit(taskRun.getAttempts().size() - 1),
Stream.of(lastAttempt.getState().isFailed() ? lastAttempt : lastAttempt.withState(State.Type.FAILED))
)
.toList()
);
return new FailedTaskRunWithLog(
taskRun
.withAttempts(
Stream
.concat(
taskRun.getAttempts().stream().limit(taskRun.getAttempts().size() - 1),
Stream.of(lastAttempt
.withState(State.Type.FAILED))
)
.toList()
)
.withState(State.Type.FAILED),
failed.getState().isFailed() ? failed : failed.withState(State.Type.FAILED),
RunContextLogger.logEntries(loggingEventFromException(e), LogEntry.of(taskRun, kind))
);
}
@@ -1040,6 +1070,16 @@ public class Execution implements DeletedInterface, TenantInterface {
return result;
}
/**
* Find all children of this {@link TaskRun}.
*/
public List<TaskRun> findChildren(TaskRun parentTaskRun) {
return taskRunList.stream()
.filter(taskRun -> parentTaskRun.getId().equals(taskRun.getParentTaskRunId()))
.toList();
}
public List<String> findParentsValues(TaskRun taskRun, boolean withCurrent) {
return (withCurrent ?
Stream.concat(findParents(taskRun).stream(), Stream.of(taskRun)) :

View File

@@ -38,6 +38,8 @@ public abstract class AbstractFlow implements FlowInterface {
@Min(value = 1)
Integer revision;
String description;
@Valid
List<Input<?>> inputs;
@@ -60,6 +62,7 @@ public abstract class AbstractFlow implements FlowInterface {
@JsonSerialize(using = ListOrMapOfLabelSerializer.class)
@JsonDeserialize(using = ListOrMapOfLabelDeserializer.class)
@Schema(implementation = Object.class, oneOf = {List.class, Map.class})
@Valid
List<Label> labels;
@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE)

View File

@@ -61,13 +61,10 @@ public class Flow extends AbstractFlow implements HasUID {
}
});
String description;
Map<String, Object> variables;
@Valid
@NotEmpty
@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE)
List<Task> tasks;
@@ -125,7 +122,7 @@ public class Flow extends AbstractFlow implements HasUID {
AbstractRetry retry;
@Valid
@PluginProperty(beta = true)
@PluginProperty
List<SLA> sla;
public Stream<String> allTypes() {

View File

@@ -4,6 +4,7 @@ import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.triggers.Trigger;
import io.kestra.core.utils.IdUtils;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import java.util.Optional;
@@ -57,6 +58,7 @@ public interface FlowId {
@Getter
@AllArgsConstructor
@EqualsAndHashCode
class Default implements FlowId {
private final String tenantId;
private final String namespace;

View File

@@ -31,6 +31,8 @@ public interface FlowInterface extends FlowId, DeletedInterface, TenantInterface
Pattern YAML_REVISION_MATCHER = Pattern.compile("(?m)^revision: \\d+\n?");
String getDescription();
boolean isDisabled();
boolean isDeleted();

View File

@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.kestra.core.models.flows.input.*;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.micronaut.core.annotation.Introspected;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.ConstraintViolationException;
@@ -16,6 +18,8 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.function.Function;
@SuppressWarnings("deprecation")
@SuperBuilder
@Getter
@@ -78,7 +82,7 @@ public abstract class Input<T> implements Data {
@Schema(
title = "The default value to use if no value is specified."
)
T defaults;
Property<T> defaults;
@Schema(
title = "The display name of the input."

View File

@@ -43,4 +43,11 @@ public class Output implements Data {
Type type;
String displayName;
/**
* Specifies whether the output is required or not.
* <p>
* By default, an output is always required.
*/
Boolean required;
}

View File

@@ -116,7 +116,7 @@ public class State {
}
public Instant maxDate() {
if (this.histories.size() == 0) {
if (this.histories.isEmpty()) {
return Instant.now();
}
@@ -124,7 +124,7 @@ public class State {
}
public Instant minDate() {
if (this.histories.size() == 0) {
if (this.histories.isEmpty()) {
return Instant.now();
}
@@ -173,6 +173,11 @@ public class State {
return this.current.isBreakpoint();
}
@JsonIgnore
public boolean isQueued() {
return this.current.isQueued();
}
@JsonIgnore
public boolean isRetrying() {
return this.current.isRetrying();
@@ -206,6 +211,14 @@ public class State {
return this.histories.get(this.histories.size() - 2).state.isPaused();
}
/**
* Return true if the execution has failed, then was restarted.
* This is to disambiguate between a RESTARTED after PAUSED and RESTARTED after FAILED state.
*/
public boolean failedThenRestarted() {
return this.current == Type.RESTARTED && this.histories.get(this.histories.size() - 2).state.isFailed();
}
@Introspected
public enum Type {
CREATED,
@@ -264,6 +277,10 @@ public class State {
return this == Type.KILLED;
}
public boolean isQueued(){
return this == Type.QUEUED;
}
/**
* @return states that are terminal to an execution
*/

View File

@@ -6,19 +6,21 @@ import jakarta.validation.ConstraintViolationException;
import jakarta.validation.constraints.NotNull;
/**
* Represents a
* Represents an input along with its associated value and validation state.
*
* @param input The flow's {@link Input}.
* @param value The flow's input value/data.
* @param enabled Specify whether the input is enabled.
* @param exception The input validation exception.
* @param input The {@link Input} definition of the flow.
* @param value The provided value for the input.
* @param enabled {@code true} if the input is enabled; {@code false} otherwise.
* @param isDefault {@code true} if the provided value is the default; {@code false} otherwise.
* @param exception The validation exception, if the input value is invalid; {@code null} otherwise.
*/
public record InputAndValue(
Input<?> input,
Object value,
boolean enabled,
boolean isDefault,
ConstraintViolationException exception) {
/**
* Creates a new {@link InputAndValue} instance.
*
@@ -26,6 +28,6 @@ public record InputAndValue(
* @param value The value.
*/
public InputAndValue(@NotNull Input<?> input, @Nullable Object value) {
this(input, value, true, null);
this(input, value, true, false, null);
}
}

View File

@@ -3,6 +3,7 @@ package io.kestra.core.models.flows.input;
import io.kestra.core.models.flows.Input;
import io.kestra.core.models.flows.RenderableInput;
import io.kestra.core.models.flows.Type;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.validations.ManualConstraintViolation;
import io.kestra.core.validations.Regex;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -13,6 +14,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -56,6 +58,23 @@ public class MultiselectInput extends Input<List<String>> implements ItemTypeInt
@Builder.Default
Boolean allowCustomValue = false;
@Schema(
title = "Whether the first value of the multi-select should be selected by default."
)
@NotNull
@Builder.Default
Boolean autoSelectFirst = false;
@Override
public Property<List<String>> getDefaults() {
Property<List<String>> baseDefaults = super.getDefaults();
if (baseDefaults == null && autoSelectFirst && !Optional.ofNullable(values).map(Collection::isEmpty).orElse(true)) {
return Property.ofValue(List.of(values.getFirst()));
}
return baseDefaults;
}
@Override
public void validate(List<String> inputs) throws ConstraintViolationException {
if (values != null && options != null) {
@@ -100,6 +119,7 @@ public class MultiselectInput extends Input<List<String>> implements ItemTypeInt
.dependsOn(getDependsOn())
.itemType(getItemType())
.displayName(getDisplayName())
.autoSelectFirst(getAutoSelectFirst())
.build();
}
return this;

View File

@@ -2,6 +2,7 @@ package io.kestra.core.models.flows.input;
import io.kestra.core.models.flows.Input;
import io.kestra.core.models.flows.RenderableInput;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.validations.ManualConstraintViolation;
import io.kestra.core.validations.Regex;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -12,6 +13,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -46,6 +48,23 @@ public class SelectInput extends Input<String> implements RenderableInput {
@Builder.Default
Boolean isRadio = false;
@Schema(
title = "Whether the first value of the select should be selected by default."
)
@NotNull
@Builder.Default
Boolean autoSelectFirst = false;
@Override
public Property<String> getDefaults() {
Property<String> baseDefaults = super.getDefaults();
if (baseDefaults == null && autoSelectFirst && !Optional.ofNullable(values).map(Collection::isEmpty).orElse(true)) {
return Property.ofValue(values.getFirst());
}
return baseDefaults;
}
@Override
public void validate(String input) throws ConstraintViolationException {
if (!values.contains(input) && this.getRequired()) {
@@ -78,6 +97,7 @@ public class SelectInput extends Input<String> implements RenderableInput {
.dependsOn(getDependsOn())
.displayName(getDisplayName())
.isRadio(getIsRadio())
.autoSelectFirst(getAutoSelectFirst())
.build();
}
return this;

View File

@@ -68,6 +68,19 @@ public class Property<T> {
String getExpression() {
return expression;
}
/**
* Returns a new {@link Property} with no cached rendered value,
* so that the next render will evaluate its original Pebble expression.
* <p>
* The returned property will still cache its rendered result.
* To re-evaluate on a subsequent render, call {@code skipCache()} again.
*
* @return a new {@link Property} without a pre-rendered value
*/
public Property<T> skipCache() {
return Property.ofExpression(expression);
}
/**
* Build a new Property object with a value already set.<br>
@@ -132,8 +145,8 @@ public class Property<T> {
*
* @see io.kestra.core.runners.RunContextProperty#as(Class)
*/
public static <T> T as(Property<T> property, RunContext runContext, Class<T> clazz) throws IllegalVariableEvaluationException {
return as(property, runContext, clazz, Map.of());
public static <T> T as(Property<T> property, PropertyContext context, Class<T> clazz) throws IllegalVariableEvaluationException {
return as(property, context, clazz, Map.of());
}
/**
@@ -143,9 +156,9 @@ public class Property<T> {
*
* @see io.kestra.core.runners.RunContextProperty#as(Class, Map)
*/
public static <T> T as(Property<T> property, RunContext runContext, Class<T> clazz, Map<String, Object> variables) throws IllegalVariableEvaluationException {
public static <T> T as(Property<T> property, PropertyContext context, Class<T> clazz, Map<String, Object> variables) throws IllegalVariableEvaluationException {
if (property.value == null) {
String rendered = runContext.render(property.expression, variables);
String rendered = context.render(property.expression, variables);
property.value = MAPPER.convertValue(rendered, clazz);
}
@@ -159,8 +172,8 @@ public class Property<T> {
*
* @see io.kestra.core.runners.RunContextProperty#asList(Class)
*/
public static <T, I> T asList(Property<T> property, RunContext runContext, Class<I> itemClazz) throws IllegalVariableEvaluationException {
return asList(property, runContext, itemClazz, Map.of());
public static <T, I> T asList(Property<T> property, PropertyContext context, Class<I> itemClazz) throws IllegalVariableEvaluationException {
return asList(property, context, itemClazz, Map.of());
}
/**
@@ -171,7 +184,7 @@ public class Property<T> {
* @see io.kestra.core.runners.RunContextProperty#asList(Class, Map)
*/
@SuppressWarnings("unchecked")
public static <T, I> T asList(Property<T> property, RunContext runContext, Class<I> itemClazz, Map<String, Object> variables) throws IllegalVariableEvaluationException {
public static <T, I> T asList(Property<T> property, PropertyContext context, Class<I> itemClazz, Map<String, Object> variables) throws IllegalVariableEvaluationException {
if (property.value == null) {
JavaType type = MAPPER.getTypeFactory().constructCollectionLikeType(List.class, itemClazz);
try {
@@ -179,7 +192,7 @@ public class Property<T> {
// We need to detect if the expression is already a list or if it's a pebble expression (for eg. referencing a variable containing a list).
// Doing that allows us to, if it's an expression, first render then read it as a list.
if (trimmedExpression.startsWith("{{") && trimmedExpression.endsWith("}}")) {
property.value = MAPPER.readValue(runContext.render(property.expression, variables), type);
property.value = MAPPER.readValue(context.render(property.expression, variables), type);
}
// Otherwise, if it's already a list, we read it as a list first then render it from run context which handle list rendering by rendering each item of the list
else {
@@ -187,9 +200,9 @@ public class Property<T> {
property.value = (T) asRawList.stream()
.map(throwFunction(item -> {
if (item instanceof String str) {
return MAPPER.convertValue(runContext.render(str, variables), itemClazz);
return MAPPER.convertValue(context.render(str, variables), itemClazz);
} else if (item instanceof Map map) {
return MAPPER.convertValue(runContext.render(map, variables), itemClazz);
return MAPPER.convertValue(context.render(map, variables), itemClazz);
}
return item;
}))

View File

@@ -0,0 +1,38 @@
package io.kestra.core.models.property;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import java.util.Map;
/**
* Contextual object for rendering properties.
*
* @see Property
*/
public interface PropertyContext {
String render(String inline, Map<String, Object> variables) throws IllegalVariableEvaluationException;
Map<String, Object> render(Map<String, Object> inline, Map<String, Object> variables) throws IllegalVariableEvaluationException;
/**
* Static helper method for creating a new {@link PropertyContext} from a given {@link VariableRenderer}.
*
* @param renderer the {@link VariableRenderer}.
* @return a new {@link PropertyContext}.
*/
static PropertyContext create(final VariableRenderer renderer) {
return new PropertyContext() {
@Override
public String render(String inline, Map<String, Object> variables) throws IllegalVariableEvaluationException {
return renderer.render(inline, variables);
}
@Override
public Map<String, Object> render(Map<String, Object> inline, Map<String, Object> variables) throws IllegalVariableEvaluationException {
return renderer.render(inline, variables);
}
};
}
}

View File

@@ -185,34 +185,6 @@ public class Trigger extends TriggerContext implements HasUID {
.build();
}
public static Trigger update(Trigger currentTrigger, Trigger newTrigger, ZonedDateTime nextExecutionDate) throws Exception {
Trigger updated = currentTrigger;
// If a backfill is created, we update the currentTrigger
// and set the nextExecutionDate() as the previous one
if (newTrigger.getBackfill() != null) {
updated = currentTrigger.toBuilder()
.backfill(
newTrigger
.getBackfill()
.toBuilder()
.end(newTrigger.getBackfill().getEnd() != null ? newTrigger.getBackfill().getEnd() : ZonedDateTime.now())
.currentDate(
newTrigger.getBackfill().getStart()
)
.previousNextExecutionDate(
currentTrigger.getNextExecutionDate())
.build())
.build();
}
return updated.toBuilder()
.nextExecutionDate(newTrigger.getDisabled() ?
null : nextExecutionDate)
.disabled(newTrigger.getDisabled())
.build();
}
public Trigger resetExecution(Flow flow, Execution execution, ConditionContext conditionContext) {
boolean disabled = this.getStopAfter() != null ? this.getStopAfter().contains(execution.getState().getCurrent()) : this.getDisabled();
if (!disabled) {
@@ -222,6 +194,7 @@ public class Trigger extends TriggerContext implements HasUID {
}
// If trigger is a schedule and execution ended after the next execution date
else if (abstractTrigger instanceof Schedule schedule &&
this.getNextExecutionDate() != null &&
execution.getState().getEndDate().get().isAfter(this.getNextExecutionDate().toInstant())
) {
RecoverMissedSchedules recoverMissedSchedules = Optional.ofNullable(schedule.getRecoverMissedSchedules())
@@ -275,27 +248,22 @@ public class Trigger extends TriggerContext implements HasUID {
.build();
}
public Trigger initBackfill(Trigger newTrigger) {
// If a backfill is created, we update the currentTrigger
public Trigger withBackfill(final Backfill backfill) {
Trigger updated = this;
// If a backfill is created, we update the trigger
// and set the nextExecutionDate() as the previous one
if (newTrigger.getBackfill() != null) {
return this.toBuilder()
if (backfill != null) {
updated = this.toBuilder()
.backfill(
newTrigger
.getBackfill()
backfill
.toBuilder()
.end(newTrigger.getBackfill().getEnd() != null ? newTrigger.getBackfill().getEnd() : ZonedDateTime.now())
.currentDate(
newTrigger.getBackfill().getStart()
)
.previousNextExecutionDate(
this.getNextExecutionDate())
.end(backfill.getEnd() != null ? backfill.getEnd() : ZonedDateTime.now())
.currentDate(backfill.getStart())
.previousNextExecutionDate(this.getNextExecutionDate())
.build())
.build();
}
return this;
return updated;
}
// if the next date is after the backfill end, we remove the backfill

View File

@@ -3,7 +3,6 @@ package io.kestra.core.models.triggers.multipleflows;
import io.kestra.core.exceptions.InternalException;
import io.kestra.core.models.conditions.Condition;
import io.kestra.core.models.conditions.ConditionContext;
import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.triggers.TimeWindow;
import io.kestra.core.utils.Rethrow;
import org.slf4j.Logger;
@@ -24,7 +23,7 @@ public interface MultipleCondition extends Rethrow.PredicateChecked<ConditionCon
/**
* This conditions will only validate previously calculated value on
* {@link io.kestra.core.services.FlowTriggerService#computeExecutionsFromFlowTriggers(Execution, List, Optional)}} and {@link MultipleConditionStorageInterface#save(List)} by the executor.
* io.kestra.executor.FlowTriggerService#computeExecutionsFromFlowTriggers(Execution, List, Optional) and {@link MultipleConditionStorageInterface#save(List)} by the executor.
* The real validation is done here.
*/
@Override

View File

@@ -43,7 +43,7 @@ public class DefaultPluginRegistry implements PluginRegistry {
static final DefaultPluginRegistry INSTANCE = new DefaultPluginRegistry();
}
private final Map<PluginIdentifier, PluginClassAndMetadata<? extends Plugin>> pluginClassByIdentifier = new ConcurrentHashMap<>();
protected final Map<PluginIdentifier, PluginClassAndMetadata<? extends Plugin>> pluginClassByIdentifier = new ConcurrentHashMap<>();
private final Map<PluginBundleIdentifier, RegisteredPlugin> plugins = new ConcurrentHashMap<>();
private final PluginScanner scanner = new PluginScanner(DefaultPluginRegistry.class.getClassLoader());
private final AtomicBoolean initialized = new AtomicBoolean(false);
@@ -56,7 +56,7 @@ public class DefaultPluginRegistry implements PluginRegistry {
*
* @return the {@link DefaultPluginRegistry}.
*/
public static DefaultPluginRegistry getOrCreate() {
public synchronized static DefaultPluginRegistry getOrCreate() {
DefaultPluginRegistry instance = LazyHolder.INSTANCE;
if (!instance.isInitialized()) {
instance.init();
@@ -74,7 +74,7 @@ public class DefaultPluginRegistry implements PluginRegistry {
/**
* Initializes the registry by loading all core plugins.
*/
protected void init() {
protected synchronized void init() {
if (initialized.compareAndSet(false, true)) {
register(scanner.scan());
}
@@ -103,11 +103,13 @@ public class DefaultPluginRegistry implements PluginRegistry {
*/
@Override
public void registerIfAbsent(final Path pluginPath) {
long start = System.currentTimeMillis();
if (isPluginPathValid(pluginPath) && !isPluginPathScanned(pluginPath)) {
List<RegisteredPlugin> scanned = scanner.scan(pluginPath);
scanned.forEach(this::register);
scannedPluginPaths.add(pluginPath);
}
log.debug("Registered if absent plugins from path {} in {} ms", pluginPath, System.currentTimeMillis() - start);
}
private boolean isPluginPathScanned(final Path pluginPath) {
@@ -119,10 +121,12 @@ public class DefaultPluginRegistry implements PluginRegistry {
*/
@Override
public void register(final Path pluginPath) {
long start = System.currentTimeMillis();
if (isPluginPathValid(pluginPath)) {
List<RegisteredPlugin> scanned = scanner.scan(pluginPath);
scanned.forEach(this::register);
}
log.debug("Registered plugins from path {} in {} ms", pluginPath, System.currentTimeMillis() - start);
}
/**
@@ -191,21 +195,28 @@ public class DefaultPluginRegistry implements PluginRegistry {
*/
public void register(final RegisteredPlugin plugin) {
final PluginBundleIdentifier identifier = PluginBundleIdentifier.of(plugin);
// Skip registration if plugin-bundle already exists in the registry.
if (containsPluginBundle(identifier)) {
return;
// Skip registration if the same plugin already exists in the registry.
final RegisteredPlugin existing = plugins.get(identifier);
if (existing != null && existing.crc32() == plugin.crc32()) {
return; // same plugin already registered
}
lock.lock();
try {
if (existing != null) {
unregister(List.of(existing));
}
plugins.put(PluginBundleIdentifier.of(plugin), plugin);
pluginClassByIdentifier.putAll(getPluginClassesByIdentifier(plugin));
registerAll(getPluginClassesByIdentifier(plugin));
} finally {
lock.unlock();
}
}
protected void registerAll(Map<PluginIdentifier, PluginClassAndMetadata<? extends Plugin>> plugins) {
pluginClassByIdentifier.putAll(plugins);
}
@SuppressWarnings("unchecked")
protected Map<PluginIdentifier, PluginClassAndMetadata<? extends Plugin>> getPluginClassesByIdentifier(final RegisteredPlugin plugin) {
Map<PluginIdentifier, PluginClassAndMetadata<? extends Plugin>> classes = new HashMap<>();

View File

@@ -6,6 +6,12 @@ import lombok.Getter;
import lombok.ToString;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.CRC32;
@AllArgsConstructor
@Getter
@@ -14,4 +20,59 @@ import java.net.URL;
public class ExternalPlugin {
private final URL location;
private final URL[] resources;
private volatile Long crc32; // lazy-val
public ExternalPlugin(URL location, URL[] resources) {
this.location = location;
this.resources = resources;
}
public Long getCrc32() {
if (this.crc32 == null) {
synchronized (this) {
if (this.crc32 == null) {
this.crc32 = computeJarCrc32(location);
}
}
}
return crc32;
}
/**
* Compute a CRC32 of the JAR File without reading the whole file
*
* @param location of the JAR File.
* @return the CRC32 of {@code -1} if the checksum can't be computed.
*/
private static long computeJarCrc32(final URL location) {
CRC32 crc = new CRC32();
try (JarFile jar = new JarFile(location.toURI().getPath(), false)) {
Enumeration<JarEntry> entries = jar.entries();
byte[] buffer = new byte[Long.BYTES]; // reusable buffer to avoid re-allocation
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
crc.update(entry.getName().getBytes(StandardCharsets.UTF_8));
updateCrc32WithLong(crc, buffer, entry.getSize());
updateCrc32WithLong(crc, buffer, entry.getCrc());
}
return crc.getValue();
} catch (Exception e) {
return -1;
}
}
private static void updateCrc32WithLong(CRC32 crc32, byte[] reusable, long val) {
// fast long -> byte conversion
reusable[0] = (byte) (val >>> 56);
reusable[1] = (byte) (val >>> 48);
reusable[2] = (byte) (val >>> 40);
reusable[3] = (byte) (val >>> 32);
reusable[4] = (byte) (val >>> 24);
reusable[5] = (byte) (val >>> 16);
reusable[6] = (byte) (val >>> 8);
reusable[7] = (byte) val;
crc32.update(reusable);;
}
}

View File

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

View File

@@ -2,10 +2,14 @@ package io.kestra.core.plugins;
import io.kestra.core.models.Plugin;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
/**
* Registry for managing all Kestra's {@link Plugin}.
@@ -123,4 +127,24 @@ public interface PluginRegistry {
* @return {@code true} if supported. Otherwise {@code false}.
*/
boolean isVersioningSupported();
/**
* Computes a CRC32 hash value representing the current content of the plugin registry.
*
* @return a {@code long} containing the CRC32 checksum value, serving as a compact
* representation of the registry's content
*/
default long hash() {
Checksum crc32 = new CRC32();
for (RegisteredPlugin plugin : plugins()) {
Optional.ofNullable(plugin.getExternalPlugin())
.map(ExternalPlugin::getCrc32)
.ifPresent(checksum -> {
byte[] bytes = ByteBuffer.allocate(Long.BYTES).putLong(checksum).array();
crc32.update(bytes, 0, bytes.length);
});
}
return crc32.getValue();
}
}

View File

@@ -5,11 +5,15 @@ import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.CRC32;
@Slf4j
public class PluginResolver {
@@ -119,4 +123,5 @@ public class PluginResolver {
return urls;
}
}

View File

@@ -308,6 +308,10 @@ public class RegisteredPlugin {
}
return null;
}
public long crc32() {
return Optional.ofNullable(externalPlugin).map(ExternalPlugin::getCrc32).orElse(-1L);
}
@Override
public String toString() {

View File

@@ -144,7 +144,7 @@ public final class PluginDeserializer<T extends Plugin> extends JsonDeserializer
static String extractPluginRawIdentifier(final JsonNode node, final boolean isVersioningSupported) {
String type = Optional.ofNullable(node.get(TYPE)).map(JsonNode::textValue).orElse(null);
String version = Optional.ofNullable(node.get(VERSION)).map(JsonNode::textValue).orElse(null);
String version = Optional.ofNullable(node.get(VERSION)).map(JsonNode::asText).orElse(null);
if (type == null || type.isEmpty()) {
return null;

View File

@@ -5,11 +5,9 @@ import io.kestra.core.models.executions.ExecutionKilled;
import io.kestra.core.models.executions.LogEntry;
import io.kestra.core.models.executions.MetricEntry;
import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.templates.Template;
import io.kestra.core.models.triggers.Trigger;
import io.kestra.core.runners.*;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.templates.Template;
public interface QueueFactoryInterface {
String EXECUTION_NAMED = "executionQueue";
@@ -34,7 +32,7 @@ public interface QueueFactoryInterface {
QueueInterface<Executor> executor();
QueueInterface<WorkerJob> workerJob();
WorkerJobQueueInterface workerJob();
QueueInterface<WorkerTaskResult> workerTaskResult();

View File

@@ -5,6 +5,7 @@ import io.kestra.core.models.Pauseable;
import io.kestra.core.utils.Either;
import java.io.Closeable;
import java.util.List;
import java.util.function.Consumer;
public interface QueueInterface<T> extends Closeable, Pauseable {
@@ -18,7 +19,15 @@ public interface QueueInterface<T> extends Closeable, Pauseable {
emitAsync(null, message);
}
void emitAsync(String consumerGroup, T message) throws QueueException;
default void emitAsync(String consumerGroup, T message) throws QueueException {
emitAsync(consumerGroup, List.of(message));
}
default void emitAsync(List<T> messages) throws QueueException {
emitAsync(null, messages);
}
void emitAsync(String consumerGroup, List<T> messages) throws QueueException;
default void delete(T message) throws QueueException {
delete(null, message);
@@ -27,7 +36,7 @@ public interface QueueInterface<T> extends Closeable, Pauseable {
void delete(String consumerGroup, T message) throws QueueException;
default Runnable receive(Consumer<Either<T, DeserializationException>> consumer) {
return receive((String) null, consumer);
return receive(null, consumer, false);
}
default Runnable receive(String consumerGroup, Consumer<Either<T, DeserializationException>> consumer) {

View File

@@ -0,0 +1,12 @@
package io.kestra.core.queues;
import java.io.Serial;
public class UnsupportedMessageException extends QueueException {
@Serial
private static final long serialVersionUID = 1L;
public UnsupportedMessageException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,12 @@
package io.kestra.core.queues;
import io.kestra.core.exceptions.DeserializationException;
import io.kestra.core.runners.WorkerJob;
import io.kestra.core.utils.Either;
import java.util.function.Consumer;
public interface WorkerJobQueueInterface extends QueueInterface<WorkerJob> {
Runnable subscribe(String workerId, String workerGroup, Consumer<Either<WorkerJob, DeserializationException>> consumer);
}

View File

@@ -0,0 +1,29 @@
package io.kestra.core.reporter;
public abstract class AbstractReportable<T extends Reportable.Event> implements Reportable<T> {
private final Type type;
private final ReportingSchedule schedule;
private final boolean isTenantSupported;
public AbstractReportable(Type type, ReportingSchedule schedule, boolean isTenantSupported) {
this.type = type;
this.schedule = schedule;
this.isTenantSupported = isTenantSupported;
}
@Override
public boolean isTenantSupported() {
return isTenantSupported;
}
@Override
public Type type() {
return type;
}
@Override
public ReportingSchedule schedule() {
return schedule;
}
}

View File

@@ -0,0 +1,94 @@
package io.kestra.core.reporter;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
/**
* Interface for reporting server event for a specific type.
*
* @param <T>
*/
public interface Reportable<T extends Reportable.Event> {
/**
* Gets the type of the event to report.
*/
Type type();
/**
* Gets the reporting schedule.
*/
ReportingSchedule schedule();
/**
* Generates a report for the given timestamp.
*
* @param now the time when the report is triggered.
* @return an Optional containing the report data if available.
*/
T report(Instant now, TimeInterval interval);
default T report(Instant now) {
ZonedDateTime to = now.atZone(ZoneId.systemDefault());
ZonedDateTime from = to.minus(Duration.ofDays(1));
return report(now, new TimeInterval(from, to));
}
/**
* Checks whether this reportable is enabled for scheduled reporting.
*/
boolean isEnabled();
/**
* Generates a report for the given timestamp and tenant.
*
* @param now the time when the report is triggered.
* @param tenant the tenant for which the report is triggered.
* @return the event to report.
*/
default T report(Instant now, TimeInterval interval, String tenant) {
throw new UnsupportedOperationException();
}
default T report(Instant now, String tenant) {
ZonedDateTime to = now.atZone(ZoneId.systemDefault());
ZonedDateTime from = to.minus(Duration.ofDays(1));
return report(now, new TimeInterval(from, to), tenant);
}
/**
* Checks whether this {@link Reportable} can accept a tenant.
*
* @return {@code true} a {@link #report(Instant, TimeInterval, String)} can called, Otherwise {@code false}.
*/
default boolean isTenantSupported() {
return false;
}
record TimeInterval(ZonedDateTime from, ZonedDateTime to){
public static TimeInterval of(ZonedDateTime from, ZonedDateTime to) {
return new TimeInterval(from, to);
}
}
/**
* Marker interface indicating that the returned event
* must be a structured, domain-specific object
* (not a primitive wrapper, String, collection, or other basic type).
*/
interface Event {
}
/**
* Defines the schedule for a report.
*/
interface ReportingSchedule {
/**
* Determines whether a report should run at the given instant.
*/
boolean shouldRun(Instant now);
}
}

View File

@@ -0,0 +1,40 @@
package io.kestra.core.reporter;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@Singleton
@Slf4j
public class ReportableRegistry {
private final Map<Type, Reportable<?>> reportables = new ConcurrentHashMap<>();
/**
* Creates a new {@link ReportableRegistry} instance.
*
* @param reportables The {@link Reportable reportables}
*/
@Inject
public ReportableRegistry(final List<Reportable<?>> reportables) {
reportables.forEach(reportable -> this.reportables.put(reportable.type(), reportable));
}
public void register(final Reportable<?> reportable) {
Objects.requireNonNull(reportable, "reportable must not be null");
if (reportables.containsKey(reportable.type())) {
log.warn("Event already registered for type '{}'", reportable.type());
} else {
reportables.put(reportable.type(), reportable);
}
}
public List<Reportable<?>> getAll() {
return List.copyOf(reportables.values());
}
}

View File

@@ -0,0 +1,43 @@
package io.kestra.core.reporter;
import io.micronaut.context.annotation.Requires;
import io.micronaut.scheduling.annotation.Scheduled;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.time.Clock;
import java.time.Instant;
@Singleton
@Requires(property = "kestra.anonymous-usage-report.enabled", value = "true")
@Requires(property = "kestra.server-type")
@Slf4j
public class ReportableScheduler {
private final ReportableRegistry registry;
private final ServerEventSender sender;
private final Clock clock;
@Inject
public ReportableScheduler(ReportableRegistry registry, ServerEventSender sender) {
this.registry = registry;
this.sender = sender;
this.clock = Clock.systemDefaultZone();
}
@Scheduled(fixedDelay = "5m", initialDelay = "${kestra.anonymous-usage-report.initial-delay}")
public void tick() {
Instant now = clock.instant();
for (Reportable<?> r : registry.getAll()) {
if (r.isEnabled() && r.schedule().shouldRun(now)) {
try {
Object value = r.report(now);
if (value != null) sender.send(now, r.type(), value);
} catch (Exception e) {
log.debug("Failed to send report for event-type '{}'", r.type(), e);
}
}
}
}
}

View File

@@ -0,0 +1,57 @@
package io.kestra.core.reporter;
import io.kestra.core.reporter.Reportable.ReportingSchedule;
import java.time.Duration;
import java.time.Instant;
/**
* Utility class providing common implementations of {@link Reportable.ReportingSchedule}.
*/
public class Schedules {
/**
* Creates a reporting schedule that triggers after the specified period has elapsed
* since the last execution.
*
* @param period the duration between successive runs; must be positive
* @return a {@link Reportable.ReportingSchedule} that runs at the given interval
* @throws IllegalArgumentException if {@code period} is zero or negative
*/
public static ReportingSchedule every(final Duration period) {
if (period.isZero() || period.isNegative()) {
throw new IllegalArgumentException("Period must be positive");
}
return new ReportingSchedule() {
private Instant lastRun = Instant.EPOCH;
@Override
public boolean shouldRun(Instant now) {
if (Duration.between(lastRun, now).compareTo(period) >= 0) {
lastRun = now;
return true;
}
return false;
}
};
}
/**
* Creates a reporting schedule that triggers once every hour.
*
* @return a schedule running every 1 hour
*/
public static ReportingSchedule hourly() {
return every(Duration.ofHours(1));
}
/**
* Creates a reporting schedule that triggers once every day.
*
* @return a schedule running every 24 hours
*/
public static ReportingSchedule daily() {
return every(Duration.ofDays(1));
}
}

View File

@@ -0,0 +1,31 @@
package io.kestra.core.reporter;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.kestra.core.models.ServerType;
import lombok.Builder;
import java.time.ZoneId;
import java.time.ZonedDateTime;
/**
* Represents a Kestra Server Event.
*/
@Builder(toBuilder = true)
public record ServerEvent(
String instanceUuid,
String sessionUuid,
ServerType serverType,
String serverVersion,
ZoneId zoneId,
Object payload,
String uuid,
ZonedDateTime reportedAt
) {
@JsonUnwrapped
public Object payload() {
return payload;
}
}

View File

@@ -0,0 +1,91 @@
package io.kestra.core.reporter;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.models.collectors.Result;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.services.InstanceService;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.VersionProvider;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.hateoas.JsonError;
import io.micronaut.reactor.http.client.ReactorHttpClient;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.net.URI;
import java.time.Instant;
import java.time.ZoneId;
import java.util.UUID;
@Singleton
@Slf4j
public class ServerEventSender {
private static final String SESSION_UUID = IdUtils.create();
private static final ObjectMapper OBJECT_MAPPER = JacksonMapper.ofJson();
@Inject
@Client
private ReactorHttpClient client;
@Inject
private VersionProvider versionProvider;
@Inject
private InstanceService instanceService;
private final ServerType serverType;
@Value("${kestra.anonymous-usage-report.uri}")
protected URI url;
public ServerEventSender( ) {
this.serverType = KestraContext.getContext().getServerType();
}
public void send(final Instant now, final Type type, Object event) {
ServerEvent serverEvent = ServerEvent
.builder()
.uuid(UUID.randomUUID().toString())
.sessionUuid(SESSION_UUID)
.instanceUuid(instanceService.fetch())
.serverType(serverType)
.serverVersion(versionProvider.getVersion())
.reportedAt(now.atZone(ZoneId.systemDefault()))
.payload(event)
.zoneId(ZoneId.systemDefault())
.build();
try {
MutableHttpRequest<ServerEvent> request = this.request(serverEvent, type);
if (log.isTraceEnabled()) {
log.trace("Report anonymous usage: '{}'", OBJECT_MAPPER.writeValueAsString(serverEvent));
}
this.handleResponse(client.toBlocking().retrieve(request, Argument.of(Result.class), Argument.of(JsonError.class)));
} catch (HttpClientResponseException t) {
log.trace("Unable to report anonymous usage with body '{}'", t.getResponse().getBody(String.class), t);
} catch (Exception t) {
log.trace("Unable to handle anonymous usage", t);
}
}
private void handleResponse (Result result){
}
protected MutableHttpRequest<ServerEvent> request(ServerEvent event, Type type) throws Exception {
URI baseUri = URI.create(this.url.toString().endsWith("/") ? this.url.toString() : this.url + "/");
URI resolvedUri = baseUri.resolve(type.name().toLowerCase());
return HttpRequest.POST(resolvedUri, event)
.header("User-Agent", "Kestra/" + versionProvider.getVersion());
}
}

View File

@@ -0,0 +1,9 @@
package io.kestra.core.reporter;
/**
* A reportable event type.
*/
public interface Type {
String name();
}

View File

@@ -0,0 +1,12 @@
package io.kestra.core.reporter;
/**
* All supported reportable event type.
*/
public enum Types implements Type {
USAGE,
SYSTEM_INFORMATION,
PLUGIN_METRICS,
SERVICE_USAGE,
PLUGIN_USAGE;
}

View File

@@ -0,0 +1,6 @@
package io.kestra.core.reporter.model;
public record Count(
long count
) {
}

View File

@@ -0,0 +1,80 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.models.collectors.ExecutionUsage;
import io.kestra.core.models.collectors.FlowUsage;
import io.kestra.core.reporter.AbstractReportable;
import io.kestra.core.reporter.Schedules;
import io.kestra.core.reporter.Types;
import io.kestra.core.reporter.model.Count;
import io.kestra.core.repositories.DashboardRepositoryInterface;
import io.kestra.core.repositories.ExecutionRepositoryInterface;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.micronaut.core.annotation.Introspected;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
import java.util.Objects;
@Singleton
public class FeatureUsageReport extends AbstractReportable<FeatureUsageReport.UsageEvent> {
private final FlowRepositoryInterface flowRepository;
private final ExecutionRepositoryInterface executionRepository;
private final DashboardRepositoryInterface dashboardRepository;
private final boolean enabled;
@Inject
public FeatureUsageReport(FlowRepositoryInterface flowRepository,
ExecutionRepositoryInterface executionRepository,
DashboardRepositoryInterface dashboardRepository) {
super(Types.USAGE, Schedules.hourly(), true);
this.flowRepository = flowRepository;
this.executionRepository = executionRepository;
this.dashboardRepository = dashboardRepository;
ServerType serverType = KestraContext.getContext().getServerType();
this.enabled = ServerType.EXECUTOR.equals(serverType) || ServerType.STANDALONE.equals(serverType);
}
@Override
public UsageEvent report(final Instant now, TimeInterval interval) {
return UsageEvent
.builder()
.flows(FlowUsage.of(flowRepository))
.executions(ExecutionUsage.of(executionRepository, interval.from(), interval.to()))
.dashboards(new Count(dashboardRepository.count()))
.build();
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public UsageEvent report(Instant now, TimeInterval interval, String tenant) {
Objects.requireNonNull(tenant, "tenant is null");
Objects.requireNonNull(interval, "interval is null");
return UsageEvent
.builder()
.flows(FlowUsage.of(tenant, flowRepository))
.executions(ExecutionUsage.of(tenant, executionRepository, interval.from(), interval.to()))
.build();
}
@SuperBuilder(toBuilder = true)
@Getter
@Jacksonized
@Introspected
public static class UsageEvent implements Event {
private ExecutionUsage executions;
private FlowUsage flows;
private Count dashboards;
}
}

View File

@@ -0,0 +1,105 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.metrics.MetricRegistry;
import io.kestra.core.models.ServerType;
import io.kestra.core.models.collectors.PluginMetric;
import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.reporter.AbstractReportable;
import io.kestra.core.reporter.Schedules;
import io.kestra.core.reporter.Types;
import io.kestra.core.utils.ListUtils;
import io.micrometer.core.instrument.Timer;
import io.micronaut.core.annotation.Introspected;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Builder;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Singleton
public class PluginMetricReport extends AbstractReportable<PluginMetricReport.PluginMetricEvent> {
private final PluginRegistry pluginRegistry;
private final MetricRegistry metricRegistry;
private final boolean enabled;
@Inject
public PluginMetricReport(PluginRegistry pluginRegistry,
MetricRegistry metricRegistry) {
super(Types.PLUGIN_METRICS, Schedules.daily(), false);
this.metricRegistry = metricRegistry;
this.pluginRegistry = pluginRegistry;
ServerType serverType = KestraContext.getContext().getServerType();
this.enabled = ServerType.SCHEDULER.equals(serverType) || ServerType.WORKER.equals(serverType) || ServerType.STANDALONE.equals(serverType);
}
@Override
public PluginMetricEvent report(final Instant now, final TimeInterval period) {
return PluginMetricEvent
.builder()
.pluginMetrics(pluginMetrics())
.build();
}
@Override
public boolean isEnabled() {
return enabled;
}
@Builder
@Introspected
public record PluginMetricEvent (
List<PluginMetric> pluginMetrics
) implements Event {
}
private List<PluginMetric> pluginMetrics() {
List<PluginMetric> taskMetrics = pluginRegistry.plugins().stream()
.flatMap(registeredPlugin -> registeredPlugin.getTasks().stream())
.map(Class::getName)
.map(this::taskMetric)
.flatMap(Optional::stream)
.toList();
List<PluginMetric> triggerMetrics = pluginRegistry.plugins().stream()
.flatMap(registeredPlugin -> registeredPlugin.getTriggers().stream())
.map(Class::getName)
.map(this::triggerMetric)
.flatMap(Optional::stream)
.toList();
return ListUtils.concat(taskMetrics, triggerMetrics);
}
private Optional<PluginMetric> taskMetric(String type) {
Timer duration = metricRegistry.find(MetricRegistry.METRIC_WORKER_ENDED_DURATION).tag(MetricRegistry.TAG_TASK_TYPE, type).timer();
return fromTimer(type, duration);
}
private Optional<PluginMetric> triggerMetric(String type) {
Timer duration = metricRegistry.find(MetricRegistry.METRIC_WORKER_TRIGGER_DURATION).tag(MetricRegistry.TAG_TRIGGER_TYPE, type).timer();
if (duration == null) {
// this may be because this is a trigger executed by the scheduler, we search there instead
duration = metricRegistry.find(MetricRegistry.METRIC_SCHEDULER_TRIGGER_EVALUATION_DURATION).tag(MetricRegistry.TAG_TRIGGER_TYPE, type).timer();
}
return fromTimer(type, duration);
}
private Optional<PluginMetric> fromTimer(String type, Timer timer) {
if (timer == null || timer.count() == 0) {
return Optional.empty();
}
double count = timer.count();
double totalTime = timer.totalTime(TimeUnit.MILLISECONDS);
double meanTime = timer.mean(TimeUnit.MILLISECONDS);
return Optional.of(new PluginMetric(type, count, totalTime, meanTime));
}
}

View File

@@ -0,0 +1,51 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.models.collectors.PluginUsage;
import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.reporter.AbstractReportable;
import io.kestra.core.reporter.Schedules;
import io.kestra.core.reporter.Types;
import io.micronaut.core.annotation.Introspected;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Builder;
import java.time.Instant;
import java.util.List;
@Singleton
public class PluginUsageReport extends AbstractReportable<PluginUsageReport.PluginUsageEvent> {
private final PluginRegistry pluginRegistry;
private final boolean enabled;
@Inject
public PluginUsageReport(PluginRegistry pluginRegistry) {
super(Types.PLUGIN_USAGE, Schedules.daily(), false);
this.pluginRegistry = pluginRegistry;
ServerType serverType = KestraContext.getContext().getServerType();
this.enabled = ServerType.EXECUTOR.equals(serverType) || ServerType.STANDALONE.equals(serverType);
}
@Override
public PluginUsageEvent report(final Instant now, final TimeInterval period) {
return PluginUsageEvent
.builder()
.plugins(PluginUsage.of(pluginRegistry))
.build();
}
@Override
public boolean isEnabled() {
return enabled;
}
@Builder
@Introspected
public record PluginUsageEvent(
List<PluginUsage> plugins
) implements Event {
}
}

View File

@@ -0,0 +1,53 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.contexts.KestraContext;
import io.kestra.core.models.ServerType;
import io.kestra.core.models.collectors.ServiceUsage;
import io.kestra.core.reporter.AbstractReportable;
import io.kestra.core.reporter.Schedules;
import io.kestra.core.reporter.Types;
import io.kestra.core.repositories.ServiceInstanceRepositoryInterface;
import io.micronaut.core.annotation.Introspected;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Builder;
import java.time.Duration;
import java.time.Instant;
@Singleton
public class ServiceUsageReport extends AbstractReportable<ServiceUsageReport.ServiceUsageEvent> {
private final ServiceInstanceRepositoryInterface serviceInstanceRepository;
private final boolean isEnabled;
@Inject
public ServiceUsageReport(ServiceInstanceRepositoryInterface serviceInstanceRepository) {
super(Types.SERVICE_USAGE, Schedules.daily(), false);
this.serviceInstanceRepository = serviceInstanceRepository;
ServerType serverType = KestraContext.getContext().getServerType();
this.isEnabled = ServerType.STANDALONE.equals(serverType) || ServerType.EXECUTOR.equals(serverType);
}
@Override
public ServiceUsageEvent report(final Instant now, final TimeInterval period) {
return ServiceUsageEvent
.builder()
.services(ServiceUsage.of(period.from().toInstant(), period.to().toInstant(), serviceInstanceRepository, Duration.ofMinutes(5)))
.build();
}
@Override
public boolean isEnabled() {
return isEnabled;
}
@Builder
@Introspected
public record ServiceUsageEvent(
ServiceUsage services
) implements Event {
}
}

View File

@@ -0,0 +1,63 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.models.collectors.ConfigurationUsage;
import io.kestra.core.models.collectors.HostUsage;
import io.kestra.core.reporter.AbstractReportable;
import io.kestra.core.reporter.Schedules;
import io.kestra.core.reporter.Types;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import io.micronaut.core.annotation.Introspected;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.Builder;
import java.lang.management.ManagementFactory;
import java.time.Instant;
import java.util.Set;
@Singleton
public class SystemInformationReport extends AbstractReportable<SystemInformationReport.SystemInformationEvent> {
private final Environment environment;
private final ApplicationContext applicationContext;
private final String kestraUrl;
private final Instant startTime;
@Inject
public SystemInformationReport(ApplicationContext applicationContext) {
super(Types.SYSTEM_INFORMATION, Schedules.daily(), false);
this.environment = applicationContext.getEnvironment();
this.applicationContext = applicationContext;
this.kestraUrl = applicationContext.getProperty("kestra.url", String.class).orElse(null);
this.startTime = Instant.ofEpochMilli(ManagementFactory.getRuntimeMXBean().getStartTime());
}
@Override
public SystemInformationEvent report(final Instant now, final TimeInterval timeInterval) {
return SystemInformationEvent
.builder()
.environments(environment.getActiveNames())
.configurations(ConfigurationUsage.of(applicationContext))
.startTime(startTime)
.host(HostUsage.of())
.uri(kestraUrl)
.build();
}
@Override
public boolean isEnabled() {
return true;
}
@Builder
@Introspected
public record SystemInformationEvent(
Set<String> environments,
HostUsage host,
ConfigurationUsage configurations,
Instant startTime,
String uri
) implements Event {
}
}

View File

@@ -16,6 +16,14 @@ import java.util.Map;
import java.util.Optional;
public interface DashboardRepositoryInterface {
/**
* Gets the total number of Dashboards.
*
* @return the total number.
*/
long count();
Boolean isEnabled();
Optional<Dashboard> get(String tenantId, String id);

View File

@@ -25,8 +25,6 @@ import java.util.Optional;
import java.util.function.Function;
public interface ExecutionRepositoryInterface extends SaveRepositoryInterface<Execution>, QueryBuilderInterface<Executions.Fields> {
Boolean isTaskRunEnabled();
default Optional<Execution> findById(String tenantId, String id) {
return findById(tenantId, id, false);
}
@@ -96,12 +94,6 @@ public interface ExecutionRepositoryInterface extends SaveRepositoryInterface<Ex
Flux<Execution> findAllAsync(@Nullable String tenantId);
ArrayListTotal<TaskRun> findTaskRun(
Pageable pageable,
@Nullable String tenantId,
List<QueryFilter> filters
);
Execution delete(Execution execution);
Integer purge(Execution execution);
@@ -112,8 +104,7 @@ public interface ExecutionRepositoryInterface extends SaveRepositoryInterface<Ex
@Nullable String flowId,
@Nullable ZonedDateTime startDate,
@Nullable ZonedDateTime endDate,
@Nullable DateUtils.GroupType groupBy,
boolean isTaskRun
@Nullable DateUtils.GroupType groupBy
);
List<DailyExecutionStatistics> dailyStatistics(
@@ -125,8 +116,7 @@ public interface ExecutionRepositoryInterface extends SaveRepositoryInterface<Ex
@Nullable ZonedDateTime startDate,
@Nullable ZonedDateTime endDate,
@Nullable DateUtils.GroupType groupBy,
List<State.Type> state,
boolean isTaskRun
List<State.Type> state
);
@Getter
@@ -161,7 +151,7 @@ public interface ExecutionRepositoryInterface extends SaveRepositoryInterface<Ex
}
List<Execution> lastExecutions(
@Nullable String tenantId,
String tenantId,
@Nullable List<FlowFilter> flows
);
}

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