You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by ri...@apache.org on 2024/11/13 15:35:12 UTC

(incubator-kie-tools) branch main updated: kie-issues#2601: [kn-plugin-workflow] Minify the openAPI spec files to trim operations only used by the workflows in the current project (#2711)

This is an automated email from the ASF dual-hosted git repository.

ricardozanini pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new 85311606a4f kie-issues#2601: [kn-plugin-workflow] Minify the openAPI spec files to trim operations only used by the workflows in the current project (#2711)
85311606a4f is described below

commit 85311606a4f13fb9e10088a2ab4de4d6f672a284
Author: Dmitrii Tikhomirov <tr...@users.noreply.github.com>
AuthorDate: Wed Nov 13 07:35:08 2024 -0800

    kie-issues#2601: [kn-plugin-workflow] Minify the openAPI spec files to trim operations only used by the workflows in the current project (#2711)
    
    Co-authored-by: Dmitrii Tikhomirov <tr...@Dmitriis-MacBook-Pro.local>
---
 packages/kn-plugin-workflow/go.mod                 |  14 +-
 packages/kn-plugin-workflow/go.sum                 |  31 +-
 packages/kn-plugin-workflow/pkg/command/deploy.go  |   6 +
 .../pkg/command/deploy_undeploy_common.go          |  59 ++--
 .../kn-plugin-workflow/pkg/command/specs/minify.go |  50 ++++
 .../pkg/command/specs/minify_test.go               |  46 +++
 .../pkg/command/specs/openapi.go                   |  92 ++++++
 .../pkg/command/specs/openapi_test.go              |  44 +++
 .../kn-plugin-workflow/pkg/command/specs/specs.go  |  48 ++++
 .../pkg/command/specs/specs_test.go                |  46 +++
 packages/kn-plugin-workflow/pkg/common/io.go       |  27 ++
 packages/kn-plugin-workflow/pkg/root/root.go       |   2 +
 packages/kn-plugin-workflow/pkg/root/root_test.go  |   1 +
 .../pkg/specs/openapi_minifier.go                  | 288 +++++++++++++++++++
 .../pkg/specs/openapi_minifier_test.go             | 315 +++++++++++++++++++++
 .../pkg/specs/testdata/flink-openapi-json.json     | 123 ++++++++
 .../pkg/specs/testdata/flink-openapi.yaml          |  79 ++++++
 .../pkg/specs/testdata/flink1-openapi.yaml         |  37 +++
 .../pkg/specs/testdata/flink2-openapi.yaml         |  43 +++
 .../pkg/specs/testdata/flink3-openapi.yaml         |  59 ++++
 .../pkg/specs/testdata/flink4-openapi.yaml         |  37 +++
 .../pkg/specs/testdata/greetingAPI.yaml            | 282 ++++++++++++++++++
 .../pkg/specs/testdata/hello.sw.json               |  33 +++
 .../pkg/specs/testdata/hello.sw.yaml               |  12 +
 .../pkg/specs/testdata/subflow-custom.sw.json      |  33 +++
 .../pkg/specs/testdata/subflow-custom.sw.yaml      |  22 ++
 .../pkg/specs/testdata/subflow-mySpecsDir.sw.yaml  |  30 ++
 .../pkg/specs/testdata/subflow.sw.yaml             |  30 ++
 .../pkg/specs/testdata/workflow-empty.sw.yaml      |  33 +++
 .../pkg/specs/testdata/workflow-empty2.sw.yaml     |  29 ++
 .../pkg/specs/testdata/workflow-greeting.sw.yaml   |  18 ++
 .../specs/testdata/workflow-json-openapi.sw.json   |  70 +++++
 .../workflow-mySpecsDir-one-finction.sw.yaml       |  35 +++
 .../pkg/specs/testdata/workflow-mySpecsDir.sw.yaml |  41 +++
 .../specs/testdata/workflow-subflow-custom.sw.yaml |  35 +++
 .../pkg/specs/testdata/workflow.sw.json            |  70 +++++
 .../pkg/specs/testdata/workflow.sw.yaml            |  41 +++
 .../pkg/specs/testdata/workflow2.sw.yaml           |  41 +++
 38 files changed, 2254 insertions(+), 48 deletions(-)

diff --git a/packages/kn-plugin-workflow/go.mod b/packages/kn-plugin-workflow/go.mod
index b8dfab167a6..eeb1dcaeb2e 100644
--- a/packages/kn-plugin-workflow/go.mod
+++ b/packages/kn-plugin-workflow/go.mod
@@ -15,12 +15,14 @@ require (
 	github.com/docker/distribution v2.8.2+incompatible
 	github.com/docker/docker v24.0.9+incompatible
 	github.com/docker/go-connections v0.4.0
+	github.com/getkin/kin-openapi v0.128.0
 	github.com/jstemmer/go-junit-report/v2 v2.0.0
 	github.com/ory/viper v1.7.5
 	github.com/spf13/afero v1.9.5
 	github.com/spf13/cobra v1.7.0
-	github.com/stretchr/testify v1.8.4
+	github.com/stretchr/testify v1.9.0
 	gopkg.in/yaml.v2 v2.4.0
+	gopkg.in/yaml.v3 v3.0.1
 	k8s.io/apiextensions-apiserver v0.28.1
 	k8s.io/apimachinery v0.28.1
 	k8s.io/client-go v0.28.1
@@ -41,9 +43,9 @@ require (
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
 	github.com/go-logr/logr v1.2.4 // indirect
-	github.com/go-openapi/jsonpointer v0.20.0 // indirect
+	github.com/go-openapi/jsonpointer v0.21.0 // indirect
 	github.com/go-openapi/jsonreference v0.20.2 // indirect
-	github.com/go-openapi/swag v0.22.4 // indirect
+	github.com/go-openapi/swag v0.23.0 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect
 	github.com/go-playground/validator/v10 v10.15.4 // indirect
@@ -58,6 +60,7 @@ require (
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/imdario/mergo v1.0.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
+	github.com/invopop/yaml v0.3.1 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
@@ -68,12 +71,14 @@ require (
 	github.com/moby/term v0.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
 	github.com/morikuni/aec v1.0.0 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.0.2 // indirect
 	github.com/pb33f/libopenapi v0.10.1 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
+	github.com/perimeterx/marshmallow v1.1.5 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/prometheus/client_golang v1.17.0 // indirect
@@ -88,7 +93,7 @@ require (
 	github.com/spf13/cast v1.5.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/stretchr/objx v0.5.0 // indirect
+	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect
 	golang.org/x/crypto v0.21.0 // indirect
@@ -107,7 +112,6 @@ require (
 	google.golang.org/protobuf v1.33.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gotest.tools/v3 v3.3.0 // indirect
 	k8s.io/api v0.28.1 // indirect
 	k8s.io/component-base v0.28.1 // indirect
diff --git a/packages/kn-plugin-workflow/go.sum b/packages/kn-plugin-workflow/go.sum
index 7c2d83ca084..81238cb336f 100644
--- a/packages/kn-plugin-workflow/go.sum
+++ b/packages/kn-plugin-workflow/go.sum
@@ -104,6 +104,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
 github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
+github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4=
+github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -113,13 +115,13 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV
 github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
 github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
 github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
-github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
 github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
 github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
 github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
-github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -131,6 +133,8 @@ github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QX
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
+github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -222,6 +226,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
 github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
+github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -262,6 +268,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
 github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -296,6 +304,8 @@ github.com/pb33f/libopenapi v0.10.1/go.mod h1:s8uj6S0DjWrwZVj20ianJBz+MMjHAbeeRY
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
 github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
+github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
@@ -314,8 +324,8 @@ github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/
 github.com/relvacode/iso8601 v1.3.0 h1:HguUjsGpIMh/zsTczGN3DVJFxTU/GX+MMmzcKoMO7ko=
 github.com/relvacode/iso8601 v1.3.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
@@ -347,8 +357,9 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -358,11 +369,13 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
+github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
 github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk=
 github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
diff --git a/packages/kn-plugin-workflow/pkg/command/deploy.go b/packages/kn-plugin-workflow/pkg/command/deploy.go
index 4a3098960b4..6db7f23f6ce 100644
--- a/packages/kn-plugin-workflow/pkg/command/deploy.go
+++ b/packages/kn-plugin-workflow/pkg/command/deploy.go
@@ -81,6 +81,11 @@ func NewDeployCommand() *cobra.Command {
 	cmd.Flags().StringP("specs-dir", "p", "", "Specify a custom specs files directory")
 	cmd.Flags().StringP("subflows-dir", "s", "", "Specify a custom subflows files directory")
 	cmd.Flags().StringP("schemas-dir", "t", "", "Specify a custom schemas files directory")
+	cmd.Flags().BoolP("minify", "f", true, "Minify the OpenAPI specs files before deploying")
+
+	if err := viper.BindPFlag("minify", cmd.Flags().Lookup("minify")); err != nil {
+		fmt.Println("āŒ ERROR: failed to bind minify flag")
+	}
 
 	cmd.SetHelpFunc(common.DefaultTemplatedHelp)
 
@@ -159,6 +164,7 @@ func runDeployCmdConfig(cmd *cobra.Command) (cfg DeployUndeployCmdConfig, err er
 		SpecsDir:                   viper.GetString("specs-dir"),
 		SchemasDir:                 viper.GetString("schemas-dir"),
 		SubflowsDir:                viper.GetString("subflows-dir"),
+		Minify:                     viper.GetBool("minify"),
 	}
 
 	if len(cfg.SubflowsDir) == 0 {
diff --git a/packages/kn-plugin-workflow/pkg/command/deploy_undeploy_common.go b/packages/kn-plugin-workflow/pkg/command/deploy_undeploy_common.go
index 2f3f32afdc9..3519c8e99fc 100644
--- a/packages/kn-plugin-workflow/pkg/command/deploy_undeploy_common.go
+++ b/packages/kn-plugin-workflow/pkg/command/deploy_undeploy_common.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
 	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata"
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/specs"
 	apimetadata "github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api/metadata"
 	"github.com/apache/incubator-kie-tools/packages/sonataflow-operator/workflowproj"
 )
@@ -46,9 +47,10 @@ type DeployUndeployCmdConfig struct {
 	Profile                    string
 	Image                      string
 	SchemasFilesPath           []string
-	SpecsFilesPath             []string
+	SpecsFilesPath             map[string]string
 	SubFlowsFilesPath          []string
 	DashboardsPath             []string
+	Minify                     bool
 }
 
 func checkEnvironment(cfg *DeployUndeployCmdConfig) error {
@@ -87,7 +89,7 @@ func generateManifests(cfg *DeployUndeployCmdConfig) error {
 	fmt.Println("\nšŸ› ļø  Generating your manifests...")
 
 	fmt.Println("šŸ” Looking for your SonataFlow files...")
-	if file, err := findSonataFlowFile(workflowExtensionsType); err != nil {
+	if file, err := common.FindSonataFlowFile(workflowExtensionsType); err != nil {
 		return err
 	} else {
 		cfg.SonataFlowFile = file
@@ -122,13 +124,25 @@ func generateManifests(cfg *DeployUndeployCmdConfig) error {
 	supportFileExtensions := []string{metadata.JSONExtension, metadata.YAMLExtension, metadata.YMLExtension}
 
 	fmt.Println("šŸ” Looking for specs files...")
-	files, err = common.FindFilesWithExtensions(cfg.SpecsDir, supportFileExtensions)
-	if err != nil {
-		return fmt.Errorf("āŒ ERROR: failed to get supportFiles directory: %w", err)
-	}
-	cfg.SpecsFilesPath = files
-	for _, file := range cfg.SpecsFilesPath {
-		fmt.Printf(" - āœ… Specs file found: %s\n", file)
+	if cfg.Minify {
+		minifiedfiles, err := specs.NewMinifier(&specs.OpenApiMinifierOpts{
+			SpecsDir:    cfg.SpecsDir,
+			SubflowsDir: cfg.SubflowsDir,
+		}).Minify()
+		if err != nil {
+			return fmt.Errorf("āŒ ERROR: failed to minify specs files: %w", err)
+		}
+		cfg.SpecsFilesPath = minifiedfiles
+	} else {
+		files, err = common.FindFilesWithExtensions(cfg.SpecsDir, supportFileExtensions)
+		if err != nil {
+			return fmt.Errorf("āŒ ERROR: failed to get supportFiles directory: %w", err)
+		}
+		cfg.SpecsFilesPath = map[string]string{}
+		for _, file := range files {
+			cfg.SpecsFilesPath[file] = file
+			fmt.Printf(" - āœ… Specs file found: %s\n", file)
+		}
 	}
 
 	fmt.Println("šŸ” Looking for schema files...")
@@ -186,8 +200,8 @@ func generateManifests(cfg *DeployUndeployCmdConfig) error {
 		handler.AddResourceAt(filepath.Base(supportFile), filepath.Base(cfg.SchemasDir), specIO)
 	}
 
-	for _, supportFile := range cfg.SpecsFilesPath {
-		specIO, err := common.MustGetFile(supportFile)
+	for supportFile, minifiedFile := range cfg.SpecsFilesPath {
+		specIO, err := common.MustGetFile(minifiedFile)
 		if err != nil {
 			return err
 		}
@@ -234,29 +248,6 @@ func findApplicationPropertiesPath(directoryPath string) string {
 	return filePath
 }
 
-func findSonataFlowFile(extensions []string) (string, error) {
-
-	dir, err := os.Getwd()
-	if err != nil {
-		return "", fmt.Errorf("āŒ ERROR: failed to get current directory: %w", err)
-	}
-
-	var matchingFiles []string
-	for _, ext := range extensions {
-		files, _ := filepath.Glob(filepath.Join(dir, "*."+ext))
-		matchingFiles = append(matchingFiles, files...)
-	}
-
-	switch len(matchingFiles) {
-	case 0:
-		return "", fmt.Errorf("āŒ ERROR: no matching files found")
-	case 1:
-		return matchingFiles[0], nil
-	default:
-		return "", fmt.Errorf("āŒ ERROR: multiple SonataFlow definition files found")
-	}
-}
-
 func setupConfigManifestPath(cfg *DeployUndeployCmdConfig) error {
 
 	if len(cfg.CustomGeneratedManifestDir) == 0 {
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/minify.go b/packages/kn-plugin-workflow/pkg/command/specs/minify.go
new file mode 100644
index 00000000000..ddebb040dd9
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/minify.go
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
+	"github.com/spf13/cobra"
+)
+
+func minifyCommand() *cobra.Command {
+	// add command minify here
+
+	var cmd = &cobra.Command{
+		Use:   "minify",
+		Short: "Minification of OpenAPI specs",
+		Long: `
+	Minification of OpenAPI specs:
+	Minification allows us to reduce the size of an OpenAPI spec file, which is essential given the maximum YAML
+	size supported by Kubernetes is limited to 3,145,728 bytes.
+
+	Note: right now only OpenAPI specs are supported for minification, see examples below.
+	`,
+		Example: `
+	#Minify the workflow project's OpenAPI spec file located in the current project.
+	{{.Name}} specs minify openapi
+		`,
+	}
+
+	cmd.SetHelpFunc(common.DefaultTemplatedHelp)
+	cmd.AddCommand(minifyOpenApi())
+
+	return cmd
+}
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/minify_test.go b/packages/kn-plugin-workflow/pkg/command/specs/minify_test.go
new file mode 100644
index 00000000000..b2c0fd7d7fa
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/minify_test.go
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestMinifyCommand(t *testing.T) {
+	cmd := minifyCommand()
+
+	assert.NotNil(t, cmd)
+
+	assert.Equal(t, "minify", cmd.Use)
+
+	subcommands := cmd.Commands()
+	assert.NotEmpty(t, subcommands)
+	assert.Equal(t, 1, len(subcommands))
+
+	found := false
+	for _, c := range subcommands {
+		if c.Name() == "openapi" {
+			found = true
+			break
+		}
+	}
+	assert.True(t, found, "minify subcommand not found")
+}
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/openapi.go b/packages/kn-plugin-workflow/pkg/command/specs/openapi.go
new file mode 100644
index 00000000000..7518267b05a
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/openapi.go
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"fmt"
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/specs"
+	"github.com/ory/viper"
+	"github.com/spf13/cobra"
+	"os"
+)
+
+func minifyOpenApi() *cobra.Command {
+
+	var cmd = &cobra.Command{
+		Use:   "openapi",
+		Short: "Minify the openAPI spec files to trim operations only used by the workflows",
+		Long: `
+	Minification of OpenAPI specs:
+	Minification allows us to reduce the size of an OpenAPI spec file, which is essential given the maximum YAML
+	size supported by Kubernetes is limited to 3,145,728 bytes.`,
+		Example: `
+	#Minify the workflow project's OpenAPI spec file located in the current project.
+	{{.Name}} specs minify openapi
+
+	# Specify a custom subflows files directory. (default: ./subflows)
+	{{.Name}} specs minify openapi --subflows-dir=<full_directory_path>
+
+	# Specify a custom support specs directory. (default: ./specs)
+	{{.Name}} specs minify openapi --specs-dir=<full_directory_path>
+		`,
+		PreRunE: common.BindEnv("specs-dir", "subflows-dir"),
+	}
+
+	cmd.SetHelpFunc(common.DefaultTemplatedHelp)
+
+	cmd.Flags().StringP("specs-dir", "p", "", "Specify a custom specs files directory")
+	cmd.Flags().StringP("subflows-dir", "s", "", "Specify a custom subflows files directory")
+
+	cmd.RunE = func(cmd *cobra.Command, args []string) error {
+		return runMinifyOpenApi()
+	}
+
+	return cmd
+
+}
+
+func runMinifyOpenApi() error {
+
+	var cfg = &specs.OpenApiMinifierOpts{
+		SpecsDir:    viper.GetString("specs-dir"),
+		SubflowsDir: viper.GetString("subflows-dir"),
+	}
+
+	if len(cfg.SubflowsDir) == 0 {
+		dir, err := os.Getwd()
+		cfg.SubflowsDir = dir + "/subflows"
+		if err != nil {
+			return fmt.Errorf("āŒ ERROR: failed to get default subflows workflow files folder: %w", err)
+		}
+	}
+
+	if len(cfg.SpecsDir) == 0 {
+		dir, err := os.Getwd()
+		cfg.SpecsDir = dir + "/specs"
+		if err != nil {
+			return fmt.Errorf("āŒ ERROR: failed to get default specs files folder: %w", err)
+		}
+	}
+
+	minifier := specs.NewMinifier(cfg)
+	_, err := minifier.Minify()
+	return err
+}
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/openapi_test.go b/packages/kn-plugin-workflow/pkg/command/specs/openapi_test.go
new file mode 100644
index 00000000000..1c5887354a7
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/openapi_test.go
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestOpenApiCommand(t *testing.T) {
+	cmd := minifyOpenApi()
+
+	assert.NotNil(t, cmd)
+
+	assert.Equal(t, "openapi", cmd.Use)
+
+	subcommands := cmd.Commands()
+	assert.Empty(t, subcommands)
+
+	specsDirFlag := cmd.Flags().Lookup("specs-dir")
+	assert.NotNil(t, specsDirFlag)
+	assert.Equal(t, "p", specsDirFlag.Shorthand)
+
+	subflowsDirFlag := cmd.Flags().Lookup("subflows-dir")
+	assert.NotNil(t, subflowsDirFlag)
+	assert.Equal(t, "s", subflowsDirFlag.Shorthand)
+}
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/specs.go b/packages/kn-plugin-workflow/pkg/command/specs/specs.go
new file mode 100644
index 00000000000..3de855042d4
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/specs.go
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
+	"github.com/spf13/cobra"
+)
+
+func SpecsCommand() *cobra.Command {
+	// add command specs here
+
+	var cmd = &cobra.Command{
+		Use:   "specs",
+		Short: "Set of utilities to work with specs",
+		Long: `
+	Minification of OpenAPI specs:
+	Minification allows us to reduce the size of an OpenAPI spec file, which is essential given the maximum YAML
+	size supported by Kubernetes is limited to 3,145,728 bytes.`,
+		Example: `
+	#Minify the workflow project's OpenAPI spec file located in the current project.
+	{{.Name}} specs minify openapi
+		`,
+	}
+
+	cmd.SetHelpFunc(common.DefaultTemplatedHelp)
+
+	cmd.AddCommand(minifyCommand())
+
+	return cmd
+}
diff --git a/packages/kn-plugin-workflow/pkg/command/specs/specs_test.go b/packages/kn-plugin-workflow/pkg/command/specs/specs_test.go
new file mode 100644
index 00000000000..58f0df1ca9a
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/command/specs/specs_test.go
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestSpecsCommand(t *testing.T) {
+	cmd := SpecsCommand()
+
+	assert.NotNil(t, cmd)
+
+	assert.Equal(t, "specs", cmd.Use)
+
+	subcommands := cmd.Commands()
+	assert.NotEmpty(t, subcommands)
+	assert.Equal(t, 1, len(subcommands))
+
+	found := false
+	for _, c := range subcommands {
+		if c.Name() == "minify" {
+			found = true
+			break
+		}
+	}
+	assert.True(t, found, "minify subcommand not found")
+}
diff --git a/packages/kn-plugin-workflow/pkg/common/io.go b/packages/kn-plugin-workflow/pkg/common/io.go
index 85c5ca1dbd4..cd329b85553 100644
--- a/packages/kn-plugin-workflow/pkg/common/io.go
+++ b/packages/kn-plugin-workflow/pkg/common/io.go
@@ -60,6 +60,33 @@ func FindFilesWithExtensions(directoryPath string, extensions []string) ([]strin
 	return filePaths, nil
 }
 
+func FindSonataFlowFile(extensions []string) (string, error) {
+	dir, err := os.Getwd()
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to get current directory: %w", err)
+	}
+
+	matchingFiles := FindSonataFlowFiles(dir, extensions)
+
+	switch len(matchingFiles) {
+	case 0:
+		return "", fmt.Errorf("āŒ ERROR: no matching files found")
+	case 1:
+		return matchingFiles[0], nil
+	default:
+		return "", fmt.Errorf("āŒ ERROR: multiple SonataFlow definition files found")
+	}
+}
+
+func FindSonataFlowFiles(dir string, extensions []string) []string {
+	var matchingFiles []string
+	for _, ext := range extensions {
+		files, _ := filepath.Glob(filepath.Join(dir, "*."+ext))
+		matchingFiles = append(matchingFiles, files...)
+	}
+	return matchingFiles
+}
+
 func MustGetFile(filepath string) (io.Reader, error) {
 	file, err := os.OpenFile(filepath, os.O_RDONLY, os.ModePerm)
 	if err != nil {
diff --git a/packages/kn-plugin-workflow/pkg/root/root.go b/packages/kn-plugin-workflow/pkg/root/root.go
index cc7fe2e8ea8..343b9ecab6e 100644
--- a/packages/kn-plugin-workflow/pkg/root/root.go
+++ b/packages/kn-plugin-workflow/pkg/root/root.go
@@ -21,6 +21,7 @@ package root
 
 import (
 	"fmt"
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/command/specs"
 
 	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/command/quarkus"
 
@@ -76,6 +77,7 @@ func NewRootCommand(cfg RootCmdConfig) *cobra.Command {
 	cmd.AddCommand(command.NewGenManifest())
 	cmd.AddCommand(quarkus.NewQuarkusCommand())
 	cmd.AddCommand(command.NewVersionCommand(cfg.Version))
+	cmd.AddCommand(specs.SpecsCommand())
 
 	cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
 		runRootHelp(cmd, args)
diff --git a/packages/kn-plugin-workflow/pkg/root/root_test.go b/packages/kn-plugin-workflow/pkg/root/root_test.go
index 339897ba570..eb901e24f19 100644
--- a/packages/kn-plugin-workflow/pkg/root/root_test.go
+++ b/packages/kn-plugin-workflow/pkg/root/root_test.go
@@ -46,6 +46,7 @@ func TestNewRootCommand(t *testing.T) {
 			"deploy",
 			"quarkus",
 			"run",
+			"specs",
 			"undeploy",
 			"gen-manifest",
 			"version",
diff --git a/packages/kn-plugin-workflow/pkg/specs/openapi_minifier.go b/packages/kn-plugin-workflow/pkg/specs/openapi_minifier.go
new file mode 100644
index 00000000000..4fe7ef0747c
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/openapi_minifier.go
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
+	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata"
+	"github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api/v1alpha08"
+	"github.com/getkin/kin-openapi/openapi3"
+	"gopkg.in/yaml.v3"
+	"k8s.io/apimachinery/pkg/util/sets"
+	yamlk8s "k8s.io/apimachinery/pkg/util/yaml"
+)
+
+type OpenApiMinifier struct {
+	workflows  []string
+	params     *OpenApiMinifierOpts
+	operations map[string]sets.Set[string]
+}
+
+type OpenApiMinifierOpts struct {
+	RootPath    string
+	SpecsDir    string
+	SubflowsDir string
+}
+
+var workflowExtensionsType = []string{metadata.YAMLSWExtension, metadata.YMLSWExtension, metadata.JSONSWExtension}
+
+var minifiedExtensionsType = []string{metadata.YAMLExtension, metadata.YMLExtension, metadata.JSONExtension}
+
+// k8sFileSizeLimit defines the maximum file size allowed (e.g., Kubernetes ConfigMap size limit is 1MB)
+const k8sFileSizeLimit = 3145728 // 3MB
+
+func NewMinifier(params *OpenApiMinifierOpts) *OpenApiMinifier {
+	return &OpenApiMinifier{params: params, operations: make(map[string]sets.Set[string]), workflows: []string{}}
+}
+
+// Minify removes unused operations from OpenAPI specs based on the functions used in workflows.
+func (m *OpenApiMinifier) Minify() (map[string]string, error) {
+	if err := m.findWorkflowFile(); err != nil {
+		return nil, err
+	}
+
+	m.findSubflowsFiles(m.params)
+
+	if err := m.fetchSpecFromFunctions(); err != nil {
+		return nil, err
+	}
+
+	if err := m.validateSpecsFiles(); err != nil {
+		return nil, err
+	}
+
+	minifySpecsFiles, err := m.minifySpecsFiles()
+	if err != nil {
+		return nil, err
+	}
+
+	return minifySpecsFiles, nil
+}
+
+func (m *OpenApiMinifier) fetchSpecFromFunctions() error {
+	for _, workflowFile := range m.workflows {
+		err := m.fetchSpecFromFunction(workflowFile)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (m *OpenApiMinifier) fetchSpecFromFunction(workflowFile string) error {
+	workflow, err := m.GetWorkflow(workflowFile)
+	if err != nil {
+		return err
+	}
+
+	relativePath := filepath.Base(m.params.SpecsDir)
+
+	if workflow.Functions == nil {
+		return nil
+	}
+
+	for _, function := range workflow.Functions {
+		if strings.HasPrefix(function.Operation, relativePath) {
+			trimmedPrefix := strings.TrimPrefix(function.Operation, relativePath+"/")
+			if !strings.Contains(trimmedPrefix, "#") {
+				return fmt.Errorf("Invalid operation format in function: %s", function.Operation)
+			}
+			parts := strings.SplitN(trimmedPrefix, "#", 2)
+			if len(parts) != 2 {
+				return fmt.Errorf("āŒ ERROR: Invalid operation format: %s", function.Operation)
+			}
+			apiFileName := path.Base(parts[0])
+			operation := parts[1]
+
+			if _, ok := m.operations[apiFileName]; !ok {
+				m.operations[apiFileName] = sets.Set[string]{}
+			}
+			m.operations[apiFileName].Insert(operation)
+		}
+	}
+	return nil
+}
+
+func (m *OpenApiMinifier) validateSpecsFiles() error {
+	for specFile := range m.operations {
+		specFileName := filepath.Join(m.params.SpecsDir, specFile)
+		if _, err := os.Stat(specFileName); err != nil {
+			return fmt.Errorf("āŒ ERROR: file %s not found or can't be open", specFileName)
+		}
+	}
+	return nil
+}
+
+func (m *OpenApiMinifier) minifySpecsFiles() (map[string]string, error) {
+	minifySpecsFiles := map[string]string{}
+	for key, value := range m.operations {
+		minifiedSpecName, err := m.minifySpecsFile(key, value)
+		if err != nil {
+			return nil, err
+		}
+		minifySpecsFiles[key] = minifiedSpecName
+	}
+	return minifySpecsFiles, nil
+}
+
+func (m *OpenApiMinifier) minifySpecsFile(specFileName string, operations sets.Set[string]) (string, error) {
+	specFile := filepath.Join(m.params.SpecsDir, specFileName)
+	data, err := os.ReadFile(specFile)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to read OpenAPI document: %w", err)
+	}
+
+	doc, err := openapi3.NewLoader().LoadFromData(data)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to load OpenAPI document: %w", err)
+	}
+	if doc.Paths == nil {
+		return "", fmt.Errorf("OpenAPI document %s has no paths", specFileName)
+	}
+	for key, value := range doc.Paths.Map() {
+		for method, operation := range value.Operations() {
+			if !operations.Has(operation.OperationID) {
+				value.SetOperation(method, nil)
+			}
+		}
+		if isPathItemEmpty(value) {
+			doc.Paths.Delete(key)
+		}
+	}
+
+	minifiedFile, err := m.writeMinifiedFileToDisk(specFile, doc)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to write minified file of %s : %w", specFile, err)
+	}
+	finalSize, err := validateSpecsFileSize(minifiedFile)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: Minification of %s failed: %w", specFile, err)
+	}
+
+	initialSize, err := os.Stat(specFile)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to get file %s info: %w", specFile, err)
+	}
+
+	fmt.Printf("āœ… Minified file %s created with %d bytes (original size: %d bytes)\n", minifiedFile, finalSize, initialSize.Size())
+	return minifiedFile, nil
+}
+
+func (m *OpenApiMinifier) findWorkflowFile() error {
+	file, err := common.FindSonataFlowFile(workflowExtensionsType)
+	if err != nil {
+		return err
+	}
+	m.workflows = append(m.workflows, file)
+	return nil
+}
+
+func (m *OpenApiMinifier) findSubflowsFiles(cfg *OpenApiMinifierOpts) {
+	files := common.FindSonataFlowFiles(cfg.SubflowsDir, workflowExtensionsType)
+	m.workflows = append(m.workflows, files...)
+}
+
+func (m *OpenApiMinifier) GetWorkflow(workflowFile string) (*v1alpha08.Flow, error) {
+	workflow := &v1alpha08.Flow{}
+	file, err := os.Open(workflowFile)
+	if err != nil {
+		return workflow, err
+	}
+	defer file.Close()
+
+	data, err := io.ReadAll(file)
+	if err != nil {
+		return workflow, fmt.Errorf("failed to read workflow file %s: %w", workflowFile, err)
+	}
+
+	if err = yamlk8s.Unmarshal(data, workflow); err != nil {
+		return workflow, fmt.Errorf("failed to unmarshal workflow file %s: %w", workflowFile, err)
+	}
+	return workflow, nil
+}
+
+func (m *OpenApiMinifier) writeMinifiedFileToDisk(specFile string, doc *openapi3.T) (string, error) {
+	var output []byte
+	var err error
+	if strings.HasSuffix(specFile, metadata.YAMLExtension) || strings.HasSuffix(specFile, metadata.YMLExtension) {
+		var buf bytes.Buffer
+		encoder := yaml.NewEncoder(&buf)
+		encoder.SetIndent(2)
+		err = encoder.Encode(doc)
+		output = buf.Bytes()
+	} else {
+		output, err = json.Marshal(doc)
+	}
+
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to marshal OpenAPI document: %w", err)
+	}
+
+	minifiedSpecFile, err := MinifiedName(specFile)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to get minified file name: %w", err)
+	}
+
+	err = os.WriteFile(minifiedSpecFile, output, 0644)
+	if err != nil {
+		return "", fmt.Errorf("āŒ ERROR: failed to write OpenAPI document: %w", err)
+	}
+	return minifiedSpecFile, nil
+}
+
+func validateSpecsFileSize(specFile string) (int64, error) {
+	file, err := os.Stat(specFile)
+	if err != nil {
+		return -1, fmt.Errorf("āŒ ERROR: failed to get file info: %w", err)
+	}
+	if file.Size() >= k8sFileSizeLimit {
+		return -1, fmt.Errorf("āŒ ERROR: Minified file %s exceeds the size limit of %d bytes", specFile, k8sFileSizeLimit)
+	}
+	return file.Size(), nil
+}
+
+func isPathItemEmpty(pathItem *openapi3.PathItem) bool {
+	return pathItem.Get == nil &&
+		pathItem.Put == nil &&
+		pathItem.Post == nil &&
+		pathItem.Delete == nil &&
+		pathItem.Options == nil &&
+		pathItem.Head == nil &&
+		pathItem.Patch == nil &&
+		pathItem.Trace == nil
+}
+
+func MinifiedName(specFile string) (string, error) {
+	for _, ext := range minifiedExtensionsType {
+		if strings.HasSuffix(specFile, ext) {
+			return strings.TrimSuffix(specFile, ext) + ".min" + ext, nil
+		}
+	}
+	return "", fmt.Errorf("āŒ ERROR: unknown file extension: %s", specFile)
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/openapi_minifier_test.go b/packages/kn-plugin-workflow/pkg/specs/openapi_minifier_test.go
new file mode 100644
index 00000000000..b3be4bfc93e
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/openapi_minifier_test.go
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package specs
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"strings"
+	"testing"
+
+	"github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api/v1alpha08"
+	"github.com/getkin/kin-openapi/openapi3"
+	"github.com/stretchr/testify/assert"
+	"k8s.io/apimachinery/pkg/util/sets"
+	"k8s.io/apimachinery/pkg/util/yaml"
+)
+
+type spec struct {
+	file     string
+	initial  int
+	minified int
+}
+
+type minifyTest struct {
+	workflowFile     string
+	openapiSpecFiles []spec
+	specsDir         string
+	subflowsDir      string
+	subflows         []string
+}
+
+func TestOpenAPIMinify(t *testing.T) {
+	tests := []minifyTest{
+		{
+			workflowFile:     "testdata/workflow.sw.yaml",                   // 4 functions, 2 of them are ref to the same openapi spec
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 3}}, // 5 operations, 3 must left
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow.sw.json",                   // 4 functions, 2 of them are ref to the same openapi spec
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 3}}, // 5 operations, 3 must left
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-json-openapi.sw.json",           // 4 functions, 2 of them are ref to the same openapi spec
+			openapiSpecFiles: []spec{{"testdata/flink-openapi-json.json", 5, 3}}, // 5 operations, 3 must left
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile: "testdata/workflow2.sw.yaml", // 4 functions, 1 per openapi spec file
+			openapiSpecFiles: []spec{
+				{"testdata/flink1-openapi.yaml", 3, 1},
+				{"testdata/flink2-openapi.yaml", 3, 1},
+				{"testdata/flink3-openapi.yaml", 3, 1},
+				{"testdata/flink4-openapi.yaml", 3, 1}},
+			specsDir:    "specs",
+			subflowsDir: "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-empty.sw.yaml", // check don't fail with empty workflow
+			openapiSpecFiles: []spec{},
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-empty.sw.yaml", // check all operations are removed
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 0}},
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-mySpecsDir.sw.yaml", // check all operations are removed, with different specs dir
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 3}},
+			specsDir:         "mySpecsDir",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-mySpecsDir-one-finction.sw.yaml", // check all operations are removed, with different specs dir
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 2}},
+			specsDir:         "mySpecsDir",
+			subflowsDir:      "subflows",
+			subflows:         []string{"testdata/subflow-mySpecsDir.sw.yaml"},
+		},
+		{
+			workflowFile:     "testdata/workflow-empty.sw.yaml", // check all operations are removed, with different subflow dir
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 0}},
+			specsDir:         "mySpecsDir",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-empty2.sw.yaml", // check don't fail with workflow with non openapi functions
+			openapiSpecFiles: []spec{},
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+		},
+		{
+			workflowFile:     "testdata/workflow-empty2.sw.yaml", // check functions is on subflow
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 2}},
+			specsDir:         "specs",
+			subflowsDir:      "subflows",
+			subflows:         []string{"testdata/subflow.sw.yaml"},
+		},
+		{
+			workflowFile:     "testdata/workflow-empty2.sw.yaml", // check functions is on subflow, with different subflow and specs dirs
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 2}},
+			specsDir:         "mySpecsDir",
+			subflowsDir:      "mySubFlowDir",
+			subflows:         []string{"testdata/subflow-mySpecsDir.sw.yaml"},
+		},
+		{
+			workflowFile: 	  "testdata/workflow-greeting.sw.yaml", // check we can process subflows with the same file name but different extensions
+			openapiSpecFiles: []spec{{"testdata/greetingAPI.yaml", 3, 1}},
+			specsDir:         "specs",
+			subflowsDir:      "custom_subflows",
+			subflows:         []string{"testdata/hello.sw.json", "testdata/hello.sw.yaml"}, // 2 subflows, 1 of them has a function that uses the greetingAPI.yaml
+		},
+		{
+			workflowFile: 	  "testdata/workflow-greeting.sw.yaml", // check we can process subflows with the same file name but different extensions
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 2}},
+			specsDir:         "custom_specs",
+			subflowsDir:      "custom_subflows",
+			subflows:         []string{"testdata/subflow-custom.sw.json", "testdata/subflow-custom.sw.yaml"}, // 2 subflows, each one has a function that uses the flink-openapi.yaml
+		},
+		{
+			workflowFile: 	  "testdata/workflow-subflow-custom.sw.yaml", // workflow with a function that uses a subflow with a function that uses the flink-openapi.yaml
+			openapiSpecFiles: []spec{{"testdata/flink-openapi.yaml", 5, 3}},
+			specsDir:         "custom_specs",
+			subflowsDir:      "custom_subflows",
+			subflows:         []string{"testdata/subflow-custom.sw.json", "testdata/subflow-custom.sw.yaml"}, // 2 subflows, each one has a function that uses the flink-openapi.yaml
+		},
+	}
+
+	current, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("Error getting current directory: %v", err)
+	}
+
+	for _, test := range tests {
+		t.Run(test.workflowFile, func(t *testing.T) {
+			if err := os.Mkdir(test.specsDir, 0755); err != nil {
+				t.Fatalf("Error creating specs directory: %v", err)
+			}
+			defer os.RemoveAll(test.specsDir)
+			if err := copyFile(test.workflowFile, path.Base(test.workflowFile)); err != nil {
+				t.Fatalf("Error copying workflow file: %v", err)
+			}
+			defer os.Remove(path.Base(test.workflowFile))
+			if len(test.subflows) > 0 {
+				if err := os.Mkdir(test.subflowsDir, 0755); err != nil {
+					t.Fatalf("Error creating subflows directory: %v", err)
+				}
+				defer os.RemoveAll(test.subflowsDir)
+				for _, subflow := range test.subflows {
+					if err := copyFile(subflow, path.Join(test.subflowsDir, path.Base(subflow))); err != nil {
+						t.Fatalf("Error copying subflow file: %v", err)
+					}
+				}
+			}
+			for _, openapiSpecFile := range test.openapiSpecFiles {
+				if err := copyFile(openapiSpecFile.file, path.Join(test.specsDir, path.Base(openapiSpecFile.file))); err != nil {
+					t.Fatalf("Error copying openapi spec file: %v", err)
+				}
+			}
+
+			minifiedfiles, err := NewMinifier(&OpenApiMinifierOpts{
+				SpecsDir:    path.Join(current, test.specsDir),
+				SubflowsDir: path.Join(current, test.subflowsDir),
+			}).Minify()
+			if err != nil {
+				t.Fatalf("Error minifying openapi specs: %v", err)
+			}
+			checkInitial(t, test)
+			checkResult(t, test, minifiedfiles)
+		})
+	}
+}
+
+// checkInitial checks the initial number of operations in the openapi specs
+func checkInitial(t *testing.T, test minifyTest) {
+	for _, spec := range test.openapiSpecFiles {
+		data, err := os.ReadFile(spec.file)
+		if err != nil {
+			t.Fatalf("Error reading openapi spec file: %v", err)
+		}
+		doc, err := openapi3.NewLoader().LoadFromData(data)
+		if err != nil {
+			t.Fatalf("Error loading openapi spec file: %v", err)
+		}
+		assert.Equalf(t, spec.initial, len(doc.Paths.Map()), "Initial number of operations in %s is not correct", spec.file)
+	}
+}
+
+// checkResult checks the number of operations in the minified openapi specs
+func checkResult(t *testing.T, test minifyTest, minifiedFiles map[string]string) {
+	workflow, err := parseWorkflow(path.Base(test.workflowFile))
+	if err != nil {
+		t.Fatalf("Error parsing workflow file: %v", err)
+	}
+
+	functions := map[string]sets.Set[string]{}
+	parseFunctions(t, functions, workflow, test)
+	for _, subflow := range test.subflows {
+		subflowWorkflow, err := parseWorkflow(subflow)
+		if err != nil {
+			t.Fatalf("Error parsing subflow file: %v", err)
+		}
+		parseFunctions(t, functions, subflowWorkflow, test)
+	}
+
+	countOfOperationInSpecs := map[string]int{}
+
+	for file, operationSet := range functions {
+		minified := minifiedFiles[file]
+		data, err := os.ReadFile(minified)
+		if err != nil {
+			t.Fatalf("Error reading minified file %s: %v", minified, err)
+		}
+		doc, err := openapi3.NewLoader().LoadFromData(data)
+		for _, value := range doc.Paths.Map() {
+			for _, operation := range value.Operations() {
+				assert.True(t, operationSet.Has(operation.OperationID), "Operation %s not found in workflow", operation.OperationID)
+			}
+		}
+		countOfOperationInSpecs[file] = len(doc.Paths.Map())
+		assert.Equal(t, len(operationSet), len(doc.Paths.Map()))
+	}
+	for _, spec := range test.openapiSpecFiles {
+		assert.Equalf(t, spec.minified, countOfOperationInSpecs[path.Base(spec.file)], "Minified number of operations in %s is not correct", spec.file)
+	}
+
+}
+
+func parseFunctions(t *testing.T, functions map[string]sets.Set[string], workflow *v1alpha08.Flow, test minifyTest) {
+	for _, function := range workflow.Functions {
+		if strings.HasPrefix(function.Operation, test.specsDir) {
+			trimmedPrefix := strings.TrimPrefix(function.Operation, test.specsDir+"/")
+			if !strings.Contains(trimmedPrefix, "#") {
+				t.Fatalf("Invalid operation format in function: %s", function.Operation)
+			}
+			parts := strings.SplitN(trimmedPrefix, "#", 2)
+			if len(parts) != 2 {
+				t.Fatalf("Invalid operation format: %s", function.Operation)
+			}
+			apiFileName := path.Base(parts[0])
+			operation := parts[1]
+
+			if _, ok := functions[apiFileName]; !ok {
+				functions[apiFileName] = sets.Set[string]{}
+			}
+			functions[apiFileName].Insert(operation)
+		}
+	}
+}
+
+func parseWorkflow(workflowFile string) (*v1alpha08.Flow, error) {
+	workflow := &v1alpha08.Flow{}
+	file, err := os.Open(workflowFile)
+	if err != nil {
+		return workflow, err
+	}
+	defer file.Close()
+
+	data, err := io.ReadAll(file)
+	if err != nil {
+		return workflow, fmt.Errorf("failed to read workflow file %s: %w", workflowFile, err)
+	}
+
+	if err = yaml.Unmarshal(data, workflow); err != nil {
+		return workflow, fmt.Errorf("failed to unmarshal workflow file %s: %w", workflowFile, err)
+	}
+	return workflow, nil
+}
+
+func copyFile(src, dst string) error {
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer srcFile.Close()
+
+	dstFile, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstFile.Close()
+
+	_, err = io.Copy(dstFile, srcFile)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi-json.json b/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi-json.json
new file mode 100644
index 00000000000..7049ac6b90d
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi-json.json
@@ -0,0 +1,123 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "Flink JobManager REST API",
+    "contact": {
+      "email": "user@flink.apache.org"
+    },
+    "license": {
+      "name": "Apache 2.0",
+      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
+    },
+    "version": "v1/1.20-SNAPSHOT"
+  },
+  "paths": {
+    "/jars": {
+      "get": {
+        "description": "Returns a list of all jars previously uploaded via '/jars/upload'.",
+        "operationId": "getJarList",
+        "responses": {
+          "200": {
+            "description": "The request was successful."
+          }
+        }
+      }
+    },
+    "/jars/{jarid}/run": {
+      "post": {
+        "description": "Submits a job for execution.",
+        "operationId": "submitJobFromJar",
+        "parameters": [
+          {
+            "name": "jarid",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "The request was successful."
+          }
+        }
+      }
+    },
+    "/jobs/{jobid}": {
+      "get": {
+        "description": "Returns details of a job.",
+        "operationId": "getJobDetails",
+        "parameters": [
+          {
+            "name": "jobid",
+            "in": "path",
+            "description": "32-character hexadecimal string value that identifies a job.",
+            "required": true
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "The request was successful."
+          }
+        }
+      },
+      "patch": {
+        "description": "Terminates a job.",
+        "operationId": "cancelJob",
+        "parameters": [
+          {
+            "name": "jobid",
+            "in": "path",
+            "description": "32-character hexadecimal string value that identifies a job.",
+            "required": true
+          },
+          {
+            "name": "mode",
+            "in": "query",
+            "description": "String value that specifies the termination mode. The only supported value is: \"cancel\".",
+            "required": false,
+            "style": "form"
+          }
+        ],
+        "responses": {
+          "202": {
+            "description": "The request was successful."
+          }
+        }
+      }
+    },
+    "/jars/upload": {
+      "post": {
+        "description": "Uploads a jar.",
+        "operationId": "uploadJar",
+        "requestBody": {
+          "content": {
+            "application/x-java-archive": {
+              "schema": {
+                "type": "string",
+                "format": "binary"
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "The request was successful."
+          }
+        }
+      }
+    },
+    "/test": {
+      "get": {
+        "description": "Test endpoint",
+        "operationId": "test",
+        "responses": {
+          "200": {
+            "description": "The request was successful."
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi.yaml
new file mode 100644
index 00000000000..14874d7adbb
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink-openapi.yaml
@@ -0,0 +1,79 @@
+openapi: 3.0.1
+info:
+  title: Flink JobManager REST API
+  contact:
+    email: user@flink.apache.org
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: v1/1.20-SNAPSHOT
+paths:
+  /jars:
+    get:
+      description: Returns a list of all jars previously uploaded via '/jars/upload'.
+      operationId: getJarList
+      responses:
+        "200":
+          description: The request was successful.
+  /jars/{jarid}/run:
+    post:
+      description: Submits a job for execution.
+      operationId: submitJobFromJar
+      parameters:
+        - name: jarid
+          in: path
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: The request was successful.
+  /jobs/{jobid}:
+    get:
+      description: Returns details of a job.
+      operationId: getJobDetails
+      parameters:
+        - name: jobid
+          in: path
+          description: 32-character hexadecimal string value that identifies a job.
+          required: true
+      responses:
+        "200":
+          description: The request was successful.
+    patch:
+      description: Terminates a job.
+      operationId: cancelJob
+      parameters:
+        - name: jobid
+          in: path
+          description: 32-character hexadecimal string value that identifies a job.
+          required: true
+        - name: mode
+          in: query
+          description: "String value that specifies the termination mode. The only supported\
+            \ value is: \"cancel\"."
+          required: false
+          style: form
+      responses:
+        "202":
+          description: The request was successful.
+  /jars/upload:
+    post:
+      description: Uploads a jar.
+      operationId: uploadJar
+      requestBody:
+        content:
+          application/x-java-archive:
+            schema:
+              type: string
+              format: binary
+      responses:
+        "200":
+          description: The request was successful.
+  /test:
+    get:
+      description: Test endpoint
+      operationId: test
+      responses:
+        "200":
+          description: The request was successful.
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink1-openapi.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/flink1-openapi.yaml
new file mode 100644
index 00000000000..585a9cc2ac7
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink1-openapi.yaml
@@ -0,0 +1,37 @@
+openapi: 3.0.1
+info:
+  title: Flink JobManager REST API
+  contact:
+    email: user@flink.apache.org
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: v1/1.20-SNAPSHOT
+paths:
+  /jars:
+    get:
+      description: Returns a list of all jars previously uploaded via '/jars/upload'.
+      operationId: getJarList
+      responses:
+        "200":
+          description: The request was successful.
+  /jars/upload:
+    post:
+      description: Uploads a jar.
+      operationId: uploadJar
+      requestBody:
+        content:
+          application/x-java-archive:
+            schema:
+              type: string
+              format: binary
+      responses:
+        "200":
+          description: The request was successful.
+  /test:
+    get:
+      description: Test endpoint
+      operationId: test
+      responses:
+        "200":
+          description: The request was successful.
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink2-openapi.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/flink2-openapi.yaml
new file mode 100644
index 00000000000..9827c5878b1
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink2-openapi.yaml
@@ -0,0 +1,43 @@
+openapi: 3.0.1
+info:
+  title: Flink JobManager REST API
+  contact:
+    email: user@flink.apache.org
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: v1/1.20-SNAPSHOT
+paths:
+  /jars/{jarid}/run:
+    post:
+      description: Submits a job for execution.
+      operationId: submitJobFromJar
+      parameters:
+        - name: jarid
+          in: path
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: The request was successful.
+  /jars/upload:
+    post:
+      description: Uploads a jar.
+      operationId: uploadJar
+      requestBody:
+        content:
+          application/x-java-archive:
+            schema:
+              type: string
+              format: binary
+      responses:
+        "200":
+          description: The request was successful.
+  /test:
+    get:
+      description: Test endpoint
+      operationId: test
+      responses:
+        "200":
+          description: The request was successful.
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink3-openapi.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/flink3-openapi.yaml
new file mode 100644
index 00000000000..321baa6bae6
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink3-openapi.yaml
@@ -0,0 +1,59 @@
+openapi: 3.0.1
+info:
+  title: Flink JobManager REST API
+  contact:
+    email: user@flink.apache.org
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: v1/1.20-SNAPSHOT
+paths:
+  /jobs/{jobid}:
+    get:
+      description: Returns details of a job.
+      operationId: getJobDetails
+      parameters:
+        - name: jobid
+          in: path
+          description: 32-character hexadecimal string value that identifies a job.
+          required: true
+      responses:
+        "200":
+          description: The request was successful.
+    patch:
+      description: Terminates a job.
+      operationId: cancelJob
+      parameters:
+        - name: jobid
+          in: path
+          description: 32-character hexadecimal string value that identifies a job.
+          required: true
+        - name: mode
+          in: query
+          description: "String value that specifies the termination mode. The only supported\
+            \ value is: \"cancel\"."
+          required: false
+          style: form
+      responses:
+        "202":
+          description: The request was successful.
+  /jars/upload:
+    post:
+      description: Uploads a jar.
+      operationId: uploadJar
+      requestBody:
+        content:
+          application/x-java-archive:
+            schema:
+              type: string
+              format: binary
+      responses:
+        "200":
+          description: The request was successful.
+  /test:
+    get:
+      description: Test endpoint
+      operationId: test
+      responses:
+        "200":
+          description: The request was successful.
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/flink4-openapi.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/flink4-openapi.yaml
new file mode 100644
index 00000000000..585a9cc2ac7
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/flink4-openapi.yaml
@@ -0,0 +1,37 @@
+openapi: 3.0.1
+info:
+  title: Flink JobManager REST API
+  contact:
+    email: user@flink.apache.org
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+  version: v1/1.20-SNAPSHOT
+paths:
+  /jars:
+    get:
+      description: Returns a list of all jars previously uploaded via '/jars/upload'.
+      operationId: getJarList
+      responses:
+        "200":
+          description: The request was successful.
+  /jars/upload:
+    post:
+      description: Uploads a jar.
+      operationId: uploadJar
+      requestBody:
+        content:
+          application/x-java-archive:
+            schema:
+              type: string
+              format: binary
+      responses:
+        "200":
+          description: The request was successful.
+  /test:
+    get:
+      description: Test endpoint
+      operationId: test
+      responses:
+        "200":
+          description: The request was successful.
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/greetingAPI.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/greetingAPI.yaml
new file mode 100644
index 00000000000..6402f4d0a1b
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/greetingAPI.yaml
@@ -0,0 +1,282 @@
+---
+openapi: 3.0.0
+info:
+  title: greeting-flow API
+  version: "1.0"
+paths:
+  /:
+    post:
+      requestBody:
+        content:
+          "*/*":
+            schema:
+              $ref: "#/components/schemas/CloudEvent"
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Response"
+  /hello:
+    get:
+      tags:
+        - Reactive Greeting Resource
+      operationId: hello
+      responses:
+        "200":
+          description: OK
+          content:
+            text/plain:
+              schema:
+                type: string
+  /messaging/topics:
+    get:
+      tags:
+        - Quarkus Topics Information Resource
+      responses:
+        "200":
+          description: OK
+components:
+  schemas:
+    Type:
+      type: object
+      properties:
+        tags:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+    CloudEvent:
+      type: object
+      properties:
+        specVersion:
+          $ref: "#/components/schemas/SpecVersion"
+        id:
+          type: string
+        type:
+          type: string
+        source:
+          format: uri
+          type: string
+        dataContentType:
+          type: string
+        dataSchema:
+          format: uri
+          type: string
+        subject:
+          type: string
+        time:
+          format: date-time
+          type: string
+        attributeNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        extensionNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        data:
+          $ref: "#/components/schemas/CloudEventData"
+    CloudEventData:
+      type: object
+    EntityTag:
+      type: object
+      properties:
+        value:
+          type: string
+        weak:
+          type: boolean
+    Family:
+      enum:
+        - INFORMATIONAL
+        - SUCCESSFUL
+        - REDIRECTION
+        - CLIENT_ERROR
+        - SERVER_ERROR
+        - OTHER
+      type: string
+    Link:
+      type: object
+      properties:
+        uri:
+          format: uri
+          type: string
+        uriBuilder:
+          $ref: "#/components/schemas/UriBuilder"
+        rel:
+          type: string
+        rels:
+          type: array
+          items:
+            type: string
+        title:
+          type: string
+        type:
+          type: string
+        params:
+          type: object
+          additionalProperties:
+            type: string
+    Locale:
+      type: object
+      properties:
+        language:
+          type: string
+        script:
+          type: string
+        country:
+          type: string
+        variant:
+          type: string
+        extensionKeys:
+          uniqueItems: true
+          type: array
+          items:
+            format: byte
+            type: string
+        unicodeLocaleAttributes:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        unicodeLocaleKeys:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        iSO3Language:
+          type: string
+        iSO3Country:
+          type: string
+        displayLanguage:
+          type: string
+        displayScript:
+          type: string
+        displayCountry:
+          type: string
+        displayVariant:
+          type: string
+        displayName:
+          type: string
+    MediaType:
+      type: object
+      properties:
+        type:
+          type: string
+        subtype:
+          type: string
+        parameters:
+          type: object
+          additionalProperties:
+            type: string
+        wildcardType:
+          type: boolean
+        wildcardSubtype:
+          type: boolean
+    MultivaluedMapStringObject:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: object
+    MultivaluedMapStringString:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: string
+    NewCookie:
+      type: object
+      properties:
+        name:
+          type: string
+        value:
+          type: string
+        version:
+          format: int32
+          type: integer
+        path:
+          type: string
+        domain:
+          type: string
+        comment:
+          type: string
+        maxAge:
+          format: int32
+          type: integer
+        expiry:
+          format: date
+          type: string
+        secure:
+          type: boolean
+        httpOnly:
+          type: boolean
+    Response:
+      type: object
+      properties:
+        status:
+          format: int32
+          type: integer
+        statusInfo:
+          $ref: "#/components/schemas/StatusType"
+        entity:
+          type: object
+        mediaType:
+          $ref: "#/components/schemas/MediaType"
+        language:
+          $ref: "#/components/schemas/Locale"
+        length:
+          format: int32
+          type: integer
+        allowedMethods:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        cookies:
+          type: object
+          additionalProperties:
+            $ref: "#/components/schemas/NewCookie"
+        entityTag:
+          $ref: "#/components/schemas/EntityTag"
+        date:
+          format: date
+          type: string
+        lastModified:
+          format: date
+          type: string
+        location:
+          format: uri
+          type: string
+        links:
+          uniqueItems: true
+          type: array
+          items:
+            $ref: "#/components/schemas/Link"
+        metadata:
+          $ref: "#/components/schemas/MultivaluedMapStringObject"
+        headers:
+          $ref: "#/components/schemas/MultivaluedMapStringObject"
+        stringHeaders:
+          $ref: "#/components/schemas/MultivaluedMapStringString"
+    SpecVersion:
+      enum:
+        - V03
+        - V1
+      type: string
+    StatusType:
+      type: object
+      properties:
+        statusCode:
+          format: int32
+          type: integer
+        family:
+          $ref: "#/components/schemas/Family"
+        reasonPhrase:
+          type: string
+    UriBuilder:
+      type: object
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.json b/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.json
new file mode 100644
index 00000000000..bb79e3ff84d
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.json
@@ -0,0 +1,33 @@
+{
+  "id": "helloworldjson",
+  "version": "1.0",
+  "specVersion": "0.8",
+  "name": "Hello World Workflow",
+  "description": "JSON based hello world workflow",
+  "start": "Inject Hello World SubFlow",
+  "functions": [
+    {
+      "name": "HelloFunction",
+      "operation": "specs/greetingAPI.yaml#hello",
+      "type": "rest"
+    }
+  ],
+  "states": [
+    {
+      "name": "Inject Hello World SubFlow",
+      "type": "inject",
+      "data": {
+        "greeting-subflow": "Hello World SubFlow"
+      },
+      "transition": "Inject Mantra SubFlow"
+    },
+    {
+      "name": "Inject Mantra SubFlow",
+      "type": "inject",
+      "data": {
+        "mantra-subflow": "SubFlow Serverless Workflow is awesome!"
+      },
+      "end": true
+    }
+  ]
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.yaml
new file mode 100644
index 00000000000..89577531933
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/hello.sw.yaml
@@ -0,0 +1,12 @@
+id: helloworldyaml
+version: "1.0.0"
+specVersion: "0.8"
+name: Hello World Workflow
+description: Inject Hello World
+start: Hello State
+states:
+  - name: Hello State
+    type: inject
+    data:
+      result: Hello World YAML SubFlow! Eder
+    end: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.json b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.json
new file mode 100644
index 00000000000..aff6964b64f
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.json
@@ -0,0 +1,33 @@
+{
+  "id": "helloworldjson",
+  "version": "1.0",
+  "specVersion": "0.8",
+  "name": "Hello World Workflow",
+  "description": "JSON based hello world workflow",
+  "start": "Inject Hello World SubFlow",
+  "functions": [
+    {
+      "name": "HelloFunction",
+      "operation": "custom_specs/flink-openapi.yaml#getJarList",
+      "type": "rest"
+    }
+  ],
+  "states": [
+    {
+      "name": "Inject Hello World SubFlow",
+      "type": "inject",
+      "data": {
+        "greeting-subflow": "Hello World SubFlow"
+      },
+      "transition": "Inject Mantra SubFlow"
+    },
+    {
+      "name": "Inject Mantra SubFlow",
+      "type": "inject",
+      "data": {
+        "mantra-subflow": "SubFlow Serverless Workflow is awesome!"
+      },
+      "end": true
+    }
+  ]
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.yaml
new file mode 100644
index 00000000000..2dce01fa269
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-custom.sw.yaml
@@ -0,0 +1,22 @@
+---
+id: "helloworldyaml"
+version: "1.0"
+specVersion: "0.8"
+name: "Hello World Workflow"
+description: "JSON based hello world workflow"
+start: "Inject Hello World SubFlow"
+functions:
+  - name: "HelloFunction"
+    operation: "custom_specs/flink-openapi.yaml#submitJobFromJar"
+    type: "rest"
+states:
+  - name: "Inject Hello World SubFlow"
+    type: "inject"
+    data:
+      greeting-subflow: "Hello World SubFlow"
+    transition: "Inject Mantra SubFlow"
+  - name: "Inject Mantra SubFlow"
+    type: "inject"
+    data:
+      mantra-subflow: "SubFlow Serverless Workflow is awesome!"
+    end: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-mySpecsDir.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-mySpecsDir.sw.yaml
new file mode 100644
index 00000000000..d56c3e798d2
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow-mySpecsDir.sw.yaml
@@ -0,0 +1,30 @@
+id: fraudhandling
+name: Fraud Handling
+expressionLang: jsonpath
+start: FraudHandling
+version: "1.0"
+events:
+  - kind: produced
+    name: FraudEvaluation
+    type: fraudEvaluation
+    source: fraudEvaluation
+functions:
+  - name: getFlinkJobs
+    operation: mySpecsDir/flink-openapi.yaml#getJarList
+  - name: runFlinkJob
+    operation: mySpecsDir/flink-openapi.yaml#submitJobFromJar
+states:
+  - name: FraudHandling
+    type: switch
+    dataConditions:
+      - condition: "{{ $.[?(@.total > 1000)] }}"
+        transition: FraudVerificationNeeded
+      - condition: "{{ $.[?(@.total <= 1000)] }}"
+        end: true
+  - name: FraudVerificationNeeded
+    type: inject
+    data:
+      fraudEvaluation: true
+    end:
+      produceEvents:
+        - eventRef: FraudEvaluation
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/subflow.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow.sw.yaml
new file mode 100644
index 00000000000..776924c8455
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/subflow.sw.yaml
@@ -0,0 +1,30 @@
+id: fraudhandling
+name: Fraud Handling
+expressionLang: jsonpath
+start: FraudHandling
+version: "1.0"
+events:
+  - kind: produced
+    name: FraudEvaluation
+    type: fraudEvaluation
+    source: fraudEvaluation
+functions:
+  - name: getFlinkJobs
+    operation: specs/flink-openapi.yaml#getJarList
+  - name: runFlinkJob
+    operation: specs/flink-openapi.yaml#submitJobFromJar
+states:
+  - name: FraudHandling
+    type: switch
+    dataConditions:
+      - condition: "{{ $.[?(@.total > 1000)] }}"
+        transition: FraudVerificationNeeded
+      - condition: "{{ $.[?(@.total <= 1000)] }}"
+        end: true
+  - name: FraudVerificationNeeded
+    type: inject
+    data:
+      fraudEvaluation: true
+    end:
+      produceEvents:
+        - eventRef: FraudEvaluation
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty.sw.yaml
new file mode 100644
index 00000000000..111322b346e
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty.sw.yaml
@@ -0,0 +1,33 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty2.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty2.sw.yaml
new file mode 100644
index 00000000000..bd4c84d6c89
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-empty2.sw.yaml
@@ -0,0 +1,29 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-greeting.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-greeting.sw.yaml
new file mode 100644
index 00000000000..76feeb20c86
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-greeting.sw.yaml
@@ -0,0 +1,18 @@
+id: subworkflows
+version: "1.0.0"
+specVersion: "0.8"
+name: Parallel Execution Workflow
+description: Executes two branches in parallel
+start: ParallelExec
+states:
+  - name: ParallelExec
+    type: parallel
+    completionType: allOf
+    branches:
+      - name: Sub1
+        actions:
+          - subFlowRef: helloworldyaml
+      - name: Sub2
+        actions:
+          - subFlowRef: helloworldjson
+    end: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-json-openapi.sw.json b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-json-openapi.sw.json
new file mode 100644
index 00000000000..600c518e94b
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-json-openapi.sw.json
@@ -0,0 +1,70 @@
+{
+  "id": "flink-workflow",
+  "version": "1.0",
+  "specVersion": "0.8",
+  "name": "flink workflow",
+  "description": "Create a starter flink job management",
+  "functions": [
+    {
+      "name": "getFlinkJobs",
+      "operation": "specs/flink-openapi-json.json#getJarList"
+    },
+    {
+      "name": "runFlinkJob",
+      "operation": "specs/flink-openapi-json.json#submitJobFromJar"
+    },
+    {
+      "name": "stopFlinkJob",
+      "operation": "specs/flink-openapi-json.json#cancelJob"
+    },
+    {
+      "name": "getJars",
+      "operation": "specs/flink-openapi-json.json#getJarList"
+    },
+    {
+      "name": "sysout",
+      "type": "custom",
+      "operation": "sysout"
+    }
+  ],
+  "start": "Get Flink Jars",
+  "states": [
+    {
+      "name": "Get Flink Jars",
+      "type": "operation",
+      "actionMode": "sequential",
+      "actions": [
+        {
+          "name": "Get Flink Jars",
+          "functionRef": {
+            "refName": "getJars"
+          }
+        }
+      ],
+      "transition": "Run Flink Job"
+    },
+    {
+      "name": "Run Flink Job",
+      "type": "operation",
+      "actionMode": "sequential",
+      "actions": [
+        {
+          "actionDataFilter": {
+            "useResults": true
+          },
+          "name": "Run Flink Job",
+          "functionRef": {
+            "refName": "runFlinkJob",
+            "arguments": {
+              "jarid": "72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar",
+              "entry-class": "com.demo.flink.streaming.StreamingJob"
+            }
+          }
+        }
+      ],
+      "end": {
+        "terminate": true
+      }
+    }
+  ]
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir-one-finction.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir-one-finction.sw.yaml
new file mode 100644
index 00000000000..5fdb58a6b5e
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir-one-finction.sw.yaml
@@ -0,0 +1,35 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: getFlinkJobs
+    operation: mySpecsDir/flink-openapi.yaml#getJarList
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir.sw.yaml
new file mode 100644
index 00000000000..4aa6d2cafa4
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-mySpecsDir.sw.yaml
@@ -0,0 +1,41 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: getFlinkJobs
+    operation: mySpecsDir/flink-openapi.yaml#getJarList
+  - name: runFlinkJob
+    operation: mySpecsDir/flink-openapi.yaml#submitJobFromJar
+  - name: stopFlinkJob
+    operation: mySpecsDir/flink-openapi.yaml#cancelJob
+  - name: getJars
+    operation: mySpecsDir/flink-openapi.yaml#getJarList
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-subflow-custom.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-subflow-custom.sw.yaml
new file mode 100644
index 00000000000..ac15349841f
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow-subflow-custom.sw.yaml
@@ -0,0 +1,35 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: stopFlinkJob
+    operation: custom_specs/flink-openapi.yaml#cancelJob
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.json b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.json
new file mode 100644
index 00000000000..54a0ed68408
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.json
@@ -0,0 +1,70 @@
+{
+  "id": "flink-workflow",
+  "version": "1.0",
+  "specVersion": "0.8",
+  "name": "flink workflow",
+  "description": "Create a starter flink job management",
+  "functions": [
+    {
+      "name": "getFlinkJobs",
+      "operation": "specs/flink-openapi.yaml#getJarList"
+    },
+    {
+      "name": "runFlinkJob",
+      "operation": "specs/flink-openapi.yaml#submitJobFromJar"
+    },
+    {
+      "name": "stopFlinkJob",
+      "operation": "specs/flink-openapi.yaml#cancelJob"
+    },
+    {
+      "name": "getJars",
+      "operation": "specs/flink-openapi.yaml#getJarList"
+    },
+    {
+      "name": "sysout",
+      "type": "custom",
+      "operation": "sysout"
+    }
+  ],
+  "start": "Get Flink Jars",
+  "states": [
+    {
+      "name": "Get Flink Jars",
+      "type": "operation",
+      "actionMode": "sequential",
+      "actions": [
+        {
+          "name": "Get Flink Jars",
+          "functionRef": {
+            "refName": "getJars"
+          }
+        }
+      ],
+      "transition": "Run Flink Job"
+    },
+    {
+      "name": "Run Flink Job",
+      "type": "operation",
+      "actionMode": "sequential",
+      "actions": [
+        {
+          "actionDataFilter": {
+            "useResults": true
+          },
+          "name": "Run Flink Job",
+          "functionRef": {
+            "refName": "runFlinkJob",
+            "arguments": {
+              "jarid": "72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar",
+              "entry-class": "com.demo.flink.streaming.StreamingJob"
+            }
+          }
+        }
+      ],
+      "end": {
+        "terminate": true
+      }
+    }
+  ]
+}
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.yaml
new file mode 100644
index 00000000000..45b28a077a5
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow.sw.yaml
@@ -0,0 +1,41 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: getFlinkJobs
+    operation: specs/flink-openapi.yaml#getJarList
+  - name: runFlinkJob
+    operation: specs/flink-openapi.yaml#submitJobFromJar
+  - name: stopFlinkJob
+    operation: specs/flink-openapi.yaml#cancelJob
+  - name: getJars
+    operation: specs/flink-openapi.yaml#getJarList
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true
diff --git a/packages/kn-plugin-workflow/pkg/specs/testdata/workflow2.sw.yaml b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow2.sw.yaml
new file mode 100644
index 00000000000..3232c6bccaa
--- /dev/null
+++ b/packages/kn-plugin-workflow/pkg/specs/testdata/workflow2.sw.yaml
@@ -0,0 +1,41 @@
+id: flink-workflow
+version: "1.0"
+specVersion: "0.8"
+name: flink workflow
+description: Create a starter flink job management
+functions:
+  - name: getFlinkJobs
+    operation: specs/flink1-openapi.yaml#getJarList
+  - name: runFlinkJob
+    operation: specs/flink2-openapi.yaml#submitJobFromJar
+  - name: stopFlinkJob
+    operation: specs/flink3-openapi.yaml#cancelJob
+  - name: getJars
+    operation: specs/flink4-openapi.yaml#getJarList
+  - name: sysout
+    type: custom
+    operation: sysout
+start: Get Flink Jars
+states:
+  - name: Get Flink Jars
+    type: operation
+    actionMode: sequential
+    actions:
+      - name: Get Flink Jars
+        functionRef:
+          refName: getJars
+    transition: Run Flink Job
+  - name: Run Flink Job
+    type: operation
+    actionMode: sequential
+    actions:
+      - actionDataFilter:
+          useResults: true
+        name: Run Flink Job
+        functionRef:
+          refName: runFlinkJob
+          arguments:
+            jarid: 72ecfc25-43ca-4f53-a4ee-1aaf93ac709a_flink-streaming-1.0.jar
+            entry-class: com.demo.flink.streaming.StreamingJob
+    end:
+      terminate: true


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org