Repository: kestra-io/kestra
Issue: Make the flow validate CLI command report flow warnings
Labels: enhancement

### Feature description

The `kestra flow validate` CLI command should detect and report flow **warnings** as the UI does.

![image](https://github.com/kestra-io/kestra/assets/13468636/843fba20-bf6f-4945-89f4-6da256020cac)

Currently, only _OK_/_ERROR_ validation states are reported.

Reporting also the _WARNING_ validation state would make flow maintenance/migration at scale easier. 

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/cli/src/main/java/io/kestra/cli/AbstractValidateCommand.java b/cli/src/main/java/io/kestra/cli/AbstractValidateCommand.java
index ff4b4a571c..cd1d23cfb2 100644
--- a/cli/src/main/java/io/kestra/cli/AbstractValidateCommand.java
+++ b/cli/src/main/java/io/kestra/cli/AbstractValidateCommand.java
@@ -74,7 +74,8 @@ public Integer call(
         Class<?> cls,
         YamlFlowParser yamlFlowParser,
         ModelValidator modelValidator,
-        Function<Object, String> identity
+        Function<Object, String> identity,
+        Function<Object, List<String>> warningsFunction
     ) throws Exception {
         super.call();
 
@@ -90,6 +91,8 @@ public Integer call(
                             Object parse = yamlFlowParser.parse(path.toFile(), cls);
                             modelValidator.validate(parse);
                             stdOut("@|green \u2713|@ - " + identity.apply(parse));
+                            List<String> warnings = warningsFunction.apply(parse);
+                            warnings.forEach(warning -> stdOut("@|bold,yellow \u26A0|@ - " + warning));
                         } catch (ConstraintViolationException e) {
                             stdErr("@|red \u2718|@ - " + path);
                             FlowValidateCommand.handleException(e, clsName);
diff --git a/cli/src/main/java/io/kestra/cli/commands/flows/FlowValidateCommand.java b/cli/src/main/java/io/kestra/cli/commands/flows/FlowValidateCommand.java
index d747ea0e8d..e5d5172958 100644
--- a/cli/src/main/java/io/kestra/cli/commands/flows/FlowValidateCommand.java
+++ b/cli/src/main/java/io/kestra/cli/commands/flows/FlowValidateCommand.java
@@ -4,9 +4,13 @@
 import io.kestra.core.models.flows.Flow;
 import io.kestra.core.models.validations.ModelValidator;
 import io.kestra.core.serializers.YamlFlowParser;
+import io.kestra.core.services.FlowService;
 import jakarta.inject.Inject;
 import picocli.CommandLine;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @CommandLine.Command(
     name = "validate",
     description = "validate a flow"
@@ -18,6 +22,9 @@ public class FlowValidateCommand extends AbstractValidateCommand {
     @Inject
     private ModelValidator modelValidator;
 
+    @Inject
+    private FlowService flowService;
+
     @Override
     public Integer call() throws Exception {
         return this.call(
@@ -27,6 +34,13 @@ public Integer call() throws Exception {
             (Object object) -> {
                 Flow flow = (Flow) object;
                 return flow.getNamespace() + " / " + flow.getId();
+            },
+            (Object object) -> {
+                Flow flow = (Flow) object;
+                List<String> warnings = new ArrayList<>();
+                warnings.addAll(flowService.deprecationPaths(flow).stream().map(deprecation -> deprecation + " is deprecated").toList());
+                warnings.addAll(flowService.warnings(flow));
+                return warnings;
             }
         );
     }
diff --git a/cli/src/main/java/io/kestra/cli/commands/templates/TemplateValidateCommand.java b/cli/src/main/java/io/kestra/cli/commands/templates/TemplateValidateCommand.java
index 8b12e6d654..74e3e29868 100644
--- a/cli/src/main/java/io/kestra/cli/commands/templates/TemplateValidateCommand.java
+++ b/cli/src/main/java/io/kestra/cli/commands/templates/TemplateValidateCommand.java
@@ -8,6 +8,8 @@
 import jakarta.inject.Inject;
 import picocli.CommandLine;
 
+import java.util.Collections;
+
 @CommandLine.Command(
     name = "validate",
     description = "validate a template"
@@ -29,7 +31,8 @@ public Integer call() throws Exception {
             (Object object) -> {
                 Template template = (Template) object;
                 return template.getNamespace() + " / " + template.getId();
-            }
+            },
+            (Object object) -> Collections.emptyList()
         );
     }
 }


Test patch:
diff --git a/cli/src/test/java/io/kestra/cli/commands/flows/FlowValidateCommandTest.java b/cli/src/test/java/io/kestra/cli/commands/flows/FlowValidateCommandTest.java
index 0a40b056cc..40a947564b 100644
--- a/cli/src/test/java/io/kestra/cli/commands/flows/FlowValidateCommandTest.java
+++ b/cli/src/test/java/io/kestra/cli/commands/flows/FlowValidateCommandTest.java
@@ -33,4 +33,25 @@ void run() {
             assertThat(out.toString(), containsString("✓ - io.kestra.cli / include"));
         }
     }
+
+    @Test
+    void warning() {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        System.setOut(new PrintStream(out));
+
+        try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
+            EmbeddedServer embeddedServer = ctx.getBean(EmbeddedServer.class);
+            embeddedServer.start();
+
+            String[] args = {
+                "--local",
+                "src/test/resources/warning/flow-with-warning.yaml"
+            };
+            Integer call = PicocliRunner.call(FlowValidateCommand.class, ctx, args);
+
+            assertThat(call, is(0));
+            assertThat(out.toString(), containsString("tasks[0] is deprecated"));
+            assertThat(out.toString(), containsString("The system namespace is reserved for background workflows"));
+        }
+    }
 }
\ No newline at end of file
diff --git a/cli/src/test/resources/warning/flow-with-warning.yaml b/cli/src/test/resources/warning/flow-with-warning.yaml
new file mode 100644
index 0000000000..0e29a9d382
--- /dev/null
+++ b/cli/src/test/resources/warning/flow-with-warning.yaml
@@ -0,0 +1,7 @@
+id: warning
+namespace: system
+
+tasks:
+  - id: deprecated
+    type: io.kestra.core.tasks.debugs.Echo
+    format: Hello World
\ No newline at end of file