Skip to content

Commit 57ded0d

Browse files
authored
Merge branch 'main' into dependabot/gradle/com.vanniktech.maven.publish-0.36.0
2 parents 29a1250 + 6382f5a commit 57ded0d

34 files changed

+505
-141
lines changed

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ body:
2121
validations:
2222
required: false
2323
labels:
24-
- bug
25-
- area/plugin
24+
- area/plugin
25+
type: Bug
26+
projects: ["kestra-io/15"]

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ contact_links:
22
- name: Chat
33
url: https://kestra.io/slack
44
about: Chat with us on Slack.
5+
blank_issues_enabled: false

.github/ISSUE_TEMPLATE/feature.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ body:
88
validations:
99
required: true
1010
labels:
11-
- enhancement
12-
- area/plugin
11+
- area/plugin
12+
type: Feature
13+
projects: ["kestra-io/15"]

.github/pull_request_template.md

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,47 +40,4 @@ Thank you for your contribution. ❤️ -->
4040

4141
### Contributor Checklist ✅
4242

43-
- [ ] PR Title and commits follows [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
44-
- [ ] Add a `closes #ISSUE_ID` or `fixes #ISSUE_ID` in the description if the PR relates to an opened issue.
45-
- [ ] Documentation updated (plugin docs from `@Schema` for properties and outputs, `@Plugin` with examples, `README.md` file with basic knowledge and specifics).
46-
- [ ] Setup instructions included if needed (API keys, accounts, etc.).
47-
- [ ] Prefix all rendered properties by `r` not `rendered` (eg: `rHost`).
48-
- [ ] Use `runContext.logger()` to log enough important infos where it's needed and with the best level (DEBUG, INFO, WARN or ERROR).
49-
50-
⚙️ **Properties**
51-
- [ ] Properties are declared with `Property<T>` carrier type, do **not** use `@PluginProperty`.
52-
- [ ] Mandatory properties must be annotated with `@NotNull` and checked during the rendering.
53-
- [ ] You can model a JSON thanks to a simple `Property<Map<String, Object>>`.
54-
55-
🌐 **HTTP**
56-
- [ ] Must use Kestra’s internal HTTP client from `io.kestra.core.http.client`
57-
58-
📦 **JSON**
59-
- [ ] If you are serializing response from an external API, you may have to add a `@JsonIgnoreProperties(ignoreUnknown = true)` at the mapped class level. So that we will avoid to crash the plugin if the provider add a new field suddenly.
60-
- [ ] Must use Jackson mappers provided by core (`io.kestra.core.serializers`)
61-
62-
**New plugins / subplugins**
63-
- [ ] Make sure your new plugin is configured like mentioned [here](https://kestra.io/docs/plugin-developer-guide/gradle#mandatory-configuration).
64-
- [ ] Add a `package-info.java` under each sub package respecting [this format](https://github.com/kestra-io/plugin-odoo/blob/main/src/main/java/io/kestra/plugin/odoo/package-info.java) and choosing the right category.
65-
- [ ] Every time you use `runContext.metric(...)` you have to add a `@Metric` ([see this doc](https://kestra.io/docs/plugin-developer-guide/document#document-the-plugin-metrics))
66-
- [ ] Docs don't support to have both tasks/triggers in the root package (e.g. `io.kestra.plugin.kubernetes`) and in a sub package (e.g. `io.kestra.plugin.kubernetes.kubectl`), whether it's: all tasks/triggers in the root package OR only tasks/triggers in sub packages.
67-
- [ ] Icons added in `src/main/resources/icons` in SVG format and not in thumbnail (keep it big):
68-
- `plugin-icon.svg`
69-
- One icon per package, e.g. `io.kestra.plugin.aws.svg`
70-
- For subpackages, e.g. `io.kestra.plugin.aws.s3`, add `io.kestra.plugin.aws.s3.svg`
71-
See example [here](https://github.com/kestra-io/plugin-elasticsearch/blob/master/src/main/java/io/kestra/plugin/elasticsearch/Search.java#L76).
72-
- [ ] Use `"{{ secret('YOUR_SECRET') }}"` in the examples for sensible infos such as an API KEY.
73-
- [ ] If you are fetching data (one, many or too many), you must add a `Property<FetchType> fetchType` to be able to use `FETCH_ONE`, `FETCH` and even `STORE` to store big amount of data in the internal storage.
74-
- [ ] Align the `"""` to close examples blocks with the flow id.
75-
- [ ] Update the existing `index.yaml` for the main plugin, and for each new subpackage add a metadata file named exactly after the subpackage (e.g. `s3.yaml` for `io.kestra.plugin.aws.s3`) under `src/main/resources/metadata/`, following the same schema.
76-
77-
🧪 **Tests**
78-
- [ ] Unit Tests added or updated to cover the change (using the `RunContext` to actually run tasks).
79-
- [ ] Add sanity checks if possible with a YAML flow inside `src/test/resources/flows`.
80-
- [ ] Avoid disabling tests for CI. Instead, configure a local environment whenever it's possible with `.github/setup-unit.sh` (to be set executable with `chmod +x setup-unit.sh`) (which can be executed locally and in the CI) all along with a new `docker-compose-ci.yml` file (do **not** edit the existing `docker-compose.yml`). If needed, create an executable (`chmod +x cleanup-unit.sh`) `cleanup-unit.sh` to remove the potential costly resources (tables, datasets, etc).
81-
- [ ] Provide screenshots from your QA / tests locally in the PR description. The goal here is to use the JAR of the plugin and directly test it locally in Kestra UI to ensure it integrates well.
82-
83-
📤 **Outputs**
84-
- [ ] Do not send back as outputs the same infos you already have in your properties.
85-
- [ ] If you do not have any output use `VoidOutput`.
86-
- [ ] Do not output twice the same infos (eg: a status code, an error code saying the same thing...).
43+
- [ ] I have read and followed the [plugin contribution guidelines](https://kestra.io/docs/plugin-developer-guide/contribution-guidelines)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
id "idea"
66
id 'jacoco'
77
id "com.adarshr.test-logger" version "4.0.0"
8-
id "com.gradleup.shadow" version "9.3.0"
8+
id "com.gradleup.shadow" version "9.3.1"
99
id 'signing'
1010
id "com.github.ben-manes.versions" version "0.53.0"
1111
id 'net.researchgate.release' version '3.1.0'

src/main/java/io/kestra/plugin/fs/ftp/Trigger.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
host: localhost
7373
port: 21
7474
username: foo
75-
password: bar
75+
password: "{{ secret('FTP_PASSWORD') }}"
7676
uri: "/in/{{ taskrun.value | jq('.name') }}"
7777
7878
triggers:
@@ -81,7 +81,7 @@
8181
host: localhost
8282
port: 21
8383
username: foo
84-
password: bar
84+
password: "{{ secret('FTP_PASSWORD') }}"
8585
from: "/in/"
8686
interval: PT10S
8787
action: NONE
@@ -109,12 +109,12 @@
109109
host: localhost
110110
port: "21"
111111
username: foo
112-
password: bar
112+
password: "{{ secret('FTP_PASSWORD') }}"
113113
from: "mydir/"
114114
regExp: ".*.csv"
115115
action: MOVE
116116
moveDirectory: "archive/"
117-
interval: PTS
117+
interval: PT10S
118118
"""
119119
)
120120
}

src/main/java/io/kestra/plugin/fs/ftps/Trigger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
regExp: ".*.csv"
8383
action: MOVE
8484
moveDirectory: "archive/"
85-
interval: PTS
85+
interval: PT10S
8686
"""
8787
)
8888
}

src/main/java/io/kestra/plugin/fs/local/Downloads.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ public class Downloads extends AbstractLocalTask implements RunnableTask<Downloa
111111
@Builder.Default
112112
private Property<Boolean> recursive = Property.ofValue(false);
113113

114+
@Builder.Default
115+
@Schema(
116+
title = "The maximum number of files to retrieve at once"
117+
)
118+
private Property<Integer> maxFiles = Property.ofValue(25);
119+
114120
static void performAction(
115121
java.util.List<File> files,
116122
Action action,
@@ -166,10 +172,20 @@ public Output run(RunContext runContext) throws Exception {
166172
.from(Property.ofValue(renderedFrom))
167173
.regExp(this.regExp)
168174
.recursive(this.recursive)
175+
.maxFiles(this.maxFiles)
169176
.build();
170177

171178
io.kestra.plugin.fs.local.List.Output listOutput = listTask.run(runContext);
172179

180+
int rMaxFiles = runContext.render(this.maxFiles).as(Integer.class).orElse(25);
181+
if (listOutput.getFiles().size() > rMaxFiles) {
182+
runContext.logger().warn("Too many files to process, skipping");
183+
return Output.builder()
184+
.files(java.util.List.of())
185+
.outputFiles(Map.of())
186+
.build();
187+
}
188+
173189
List<File> downloadedFiles = listOutput
174190
.getFiles()
175191
.stream()

src/main/java/io/kestra/plugin/fs/local/List.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
import io.kestra.core.runners.RunContext;
88
import io.kestra.plugin.fs.local.models.File;
99
import io.swagger.v3.oas.annotations.media.Schema;
10+
import jakarta.validation.constraints.NotNull;
1011
import lombok.*;
1112
import lombok.experimental.SuperBuilder;
1213

13-
import jakarta.validation.constraints.NotNull;
14-
15-
import java.nio.file.*;
14+
import java.nio.file.Files;
15+
import java.nio.file.Path;
1616
import java.nio.file.attribute.BasicFileAttributes;
17-
import java.util.*;
18-
import java.util.stream.Collectors;
17+
import java.util.Objects;
1918

2019
import static io.kestra.core.utils.Rethrow.throwFunction;
2120

@@ -80,6 +79,12 @@ public class List extends AbstractLocalTask implements RunnableTask<List.Output>
8079
@Builder.Default
8180
private Property<Boolean> recursive = Property.ofValue(false);
8281

82+
@Builder.Default
83+
@Schema(
84+
title = "The maximum number of files to retrieve at once"
85+
)
86+
private Property<Integer> maxFiles = Property.ofValue(25);
87+
8388
@Override
8489
public Output run(RunContext runContext) throws Exception {
8590
String resolvedDirectory = runContext.render(this.from).as(String.class).orElseThrow();
@@ -93,15 +98,22 @@ public Output run(RunContext runContext) throws Exception {
9398
String fileRegex = this.regExp != null ? runContext.render(this.regExp).as(String.class).orElseThrow() : ".*";
9499
int maxDepth = runContext.render(recursive).as(Boolean.class).orElse(false) ? Integer.MAX_VALUE : 1;
95100

96-
java.util.List<File> files = Files.find(directoryPath, maxDepth, (path, basicFileAttributes) -> {
97-
return basicFileAttributes.isRegularFile() && path.toString().matches(fileRegex);
98-
})
101+
java.util.List<File> files = Files.find(directoryPath, maxDepth, (path, basicFileAttributes) -> basicFileAttributes.isRegularFile() && path.toString().matches(fileRegex))
99102
.map(throwFunction(path -> {
100103
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
101104
return File.from(path, attrs);
102105
}))
103106
.filter(Objects::nonNull)
104-
.collect(Collectors.toList());
107+
.toList();
108+
109+
int rMaxFiles = runContext.render(this.maxFiles).as(Integer.class).orElse(25);
110+
if (files.size() > rMaxFiles) {
111+
runContext.logger().warn("Too many files to process, skipping");
112+
return Output.builder()
113+
.files(java.util.List.of())
114+
.count(0)
115+
.build();
116+
}
105117

106118
return Output.builder()
107119
.files(files)
@@ -122,4 +134,4 @@ public static class Output implements io.kestra.core.models.tasks.Output {
122134
)
123135
private Integer count;
124136
}
125-
}
137+
}

src/main/java/io/kestra/plugin/fs/local/Trigger.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,16 @@ public class Trigger extends AbstractTrigger implements PollingTriggerInterface,
112112

113113
private Property<Duration> stateTtl;
114114

115+
@Builder.Default
116+
@Schema(
117+
title = "The maximum number of files to retrieve at once"
118+
)
119+
private Property<Integer> maxFiles = Property.ofValue(25);
120+
115121
@Override
116122
public Optional<Execution> evaluate(ConditionContext conditionContext, TriggerContext triggerContext) throws Exception {
117123
RunContext runContext = conditionContext.getRunContext();
124+
var logger = runContext.logger();
118125
var rOn = runContext.render(on).as(On.class).orElse(On.CREATE_OR_UPDATE);
119126
var rStateKey = runContext.render(stateKey).as(String.class).orElse(StatefulTriggerService.defaultKey(triggerContext.getNamespace(), triggerContext.getFlowId(), id));
120127
var rStateTtl = runContext.render(stateTtl).as(Duration.class);
@@ -126,6 +133,7 @@ public Optional<Execution> evaluate(ConditionContext conditionContext, TriggerCo
126133
.from(Property.ofValue(rFrom))
127134
.regExp(this.regExp)
128135
.recursive(this.recursive)
136+
.maxFiles(this.maxFiles)
129137
.build();
130138

131139
io.kestra.plugin.fs.local.List.Output listOutput = listTask.run(runContext);
@@ -183,6 +191,11 @@ public Optional<Execution> evaluate(ConditionContext conditionContext, TriggerCo
183191
return Optional.empty();
184192
}
185193

194+
if (toFire.size() > runContext.render(this.maxFiles).as(Integer.class).orElse(25)) {
195+
logger.warn("Too many files to process, skipping");
196+
return Optional.empty();
197+
}
198+
186199
Downloads.Action selectedAction = this.action != null ?
187200
runContext.render(this.action).as(Downloads.Action.class).orElse(Downloads.Action.NONE) :
188201
Downloads.Action.NONE;

0 commit comments

Comments
 (0)