You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cd...@apache.org on 2023/07/06 19:27:58 UTC

[camel-k] branch main updated (0908a2949 -> 21b968948)

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

cdeppisch pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git


    from 0908a2949 chore(deps): bump golang.org/x/oauth2 from 0.9.0 to 0.10.0
     new ffa53139c fix(#592): Introduce build order strategy
     new 21b968948 fix(#592): Introduce "dependencies" build order strategy

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 config/crd/bases/camel.apache.org_builds.yaml      |  14 +
 .../bases/camel.apache.org_integrationkits.yaml    |   4 +
 .../camel.apache.org_integrationplatforms.yaml     |  22 ++
 .../crd/bases/camel.apache.org_integrations.yaml   |   4 +
 .../bases/camel.apache.org_kameletbindings.yaml    |   4 +
 config/crd/bases/camel.apache.org_pipes.yaml       |   4 +
 docs/modules/ROOT/pages/architecture/cr/build.adoc |  10 +
 .../ROOT/pages/installation/advanced/advanced.adoc |   1 +
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  24 ++
 docs/modules/traits/pages/builder.adoc             |   4 +
 e2e/builder/build_test.go                          | 151 +++++++-
 e2e/common/traits/builder_test.go                  |  61 +++-
 .../build_order_strategy_test.go                   | 175 +++++++++
 ...er-kamelet-usage.groovy => timer-source.groovy} |   3 +-
 e2e/commonwithcustominstall/local_platform_test.go |   1 +
 helm/camel-k/crds/crd-build.yaml                   |  14 +
 helm/camel-k/crds/crd-integration-kit.yaml         |   4 +
 helm/camel-k/crds/crd-integration-platform.yaml    |  22 ++
 helm/camel-k/crds/crd-integration.yaml             |   4 +
 helm/camel-k/crds/crd-kamelet-binding.yaml         |   4 +
 helm/camel-k/crds/crd-pipe.yaml                    |   4 +
 pkg/apis/camel/v1/build_types_support.go           | 105 ++++++
 pkg/apis/camel/v1/common_types.go                  |  23 ++
 pkg/apis/camel/v1/common_types_support.go          |   1 +
 pkg/apis/camel/v1/trait/builder.go                 |   2 +
 .../camel/v1/buildconfiguration.go                 |  23 +-
 pkg/cmd/install.go                                 |  22 ++
 pkg/cmd/install_test.go                            |   7 +
 pkg/controller/build/build_controller.go           |   3 +-
 pkg/controller/build/build_monitor.go              |  62 +++-
 pkg/controller/build/build_monitor_test.go         | 405 ++++++++++++++++++++-
 pkg/controller/integrationkit/build.go             |  13 +-
 pkg/platform/defaults.go                           |   9 +
 pkg/platform/defaults_test.go                      |  37 +-
 pkg/resources/resources.go                         |  28 +-
 pkg/trait/builder.go                               |  43 ++-
 resources/traits.yaml                              |   4 +
 37 files changed, 1247 insertions(+), 74 deletions(-)
 create mode 100644 e2e/commonwithcustominstall/build_order_strategy_test.go
 copy e2e/commonwithcustominstall/files/{timer-kamelet-usage.groovy => timer-source.groovy} (90%)


[camel-k] 01/02: fix(#592): Introduce build order strategy

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdeppisch pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit ffa53139cd78270b2f3b3bd1e850f49099b73266
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Thu Jun 1 15:08:13 2023 +0200

    fix(#592): Introduce build order strategy
    
    - Run builds on same operator namespace with user defined strategy
    - Default strategy is "sequential" running only one single build at a time
    - Also support "fifo" strategy where builds are run/queued based on their creation timestamp. This strategy allows parallel builds as long as individual build dependency lists are not colliding
    - Users may adjust/overwrite the build order strategy via install command option, in the (local) integration platform settings or via the builder trait option
    - Max number of running builds limitation is not affected by the build order strategy (ensure to always obey the limitation)
---
 config/crd/bases/camel.apache.org_builds.yaml      |  12 ++
 .../bases/camel.apache.org_integrationkits.yaml    |   4 +
 .../camel.apache.org_integrationplatforms.yaml     |  20 +++
 .../crd/bases/camel.apache.org_integrations.yaml   |   4 +
 .../bases/camel.apache.org_kameletbindings.yaml    |   4 +
 config/crd/bases/camel.apache.org_pipes.yaml       |   4 +
 docs/modules/ROOT/pages/architecture/cr/build.adoc |   9 ++
 .../ROOT/pages/installation/advanced/advanced.adoc |   1 +
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  24 +++
 docs/modules/traits/pages/builder.adoc             |   4 +
 e2e/builder/build_test.go                          |  77 ++++++++-
 e2e/common/traits/builder_test.go                  |  35 ++++-
 e2e/commonwithcustominstall/local_platform_test.go |   1 +
 helm/camel-k/crds/crd-build.yaml                   |  12 ++
 helm/camel-k/crds/crd-integration-kit.yaml         |   4 +
 helm/camel-k/crds/crd-integration-platform.yaml    |  20 +++
 helm/camel-k/crds/crd-integration.yaml             |   4 +
 helm/camel-k/crds/crd-kamelet-binding.yaml         |   4 +
 helm/camel-k/crds/crd-pipe.yaml                    |   4 +
 pkg/apis/camel/v1/build_types_support.go           |  25 +++
 pkg/apis/camel/v1/common_types.go                  |  18 +++
 pkg/apis/camel/v1/common_types_support.go          |   1 +
 pkg/apis/camel/v1/trait/builder.go                 |   2 +
 .../camel/v1/buildconfiguration.go                 |  23 ++-
 pkg/cmd/install.go                                 |  22 +++
 pkg/cmd/install_test.go                            |   7 +
 pkg/controller/build/build_controller.go           |   3 +-
 pkg/controller/build/build_monitor.go              |  43 ++---
 pkg/controller/build/build_monitor_test.go         | 173 ++++++++++++++++++++-
 pkg/controller/integrationkit/build.go             |  13 +-
 pkg/platform/defaults.go                           |   9 ++
 pkg/platform/defaults_test.go                      |  37 ++++-
 pkg/resources/resources.go                         |  28 ++--
 pkg/trait/builder.go                               |  43 ++++-
 resources/traits.yaml                              |   4 +
 35 files changed, 634 insertions(+), 64 deletions(-)

diff --git a/config/crd/bases/camel.apache.org_builds.yaml b/config/crd/bases/camel.apache.org_builds.yaml
index 9e525152b..44ee86332 100644
--- a/config/crd/bases/camel.apache.org_builds.yaml
+++ b/config/crd/bases/camel.apache.org_builds.yaml
@@ -97,6 +97,12 @@ spec:
                     description: The namespace where to run the builder Pod (must
                       be the same of the operator in charge of this Build reconciliation).
                     type: string
+                  orderStrategy:
+                    description: the build order strategy to adopt
+                    enum:
+                    - fifo
+                    - sequential
+                    type: string
                   requestCPU:
                     description: The minimum amount of CPU required. Only used for
                       `pod` strategy
@@ -206,6 +212,12 @@ spec:
                                 Pod (must be the same of the operator in charge of
                                 this Build reconciliation).
                               type: string
+                            orderStrategy:
+                              description: the build order strategy to adopt
+                              enum:
+                              - fifo
+                              - sequential
+                              type: string
                             requestCPU:
                               description: The minimum amount of CPU required. Only
                                 used for `pod` strategy
diff --git a/config/crd/bases/camel.apache.org_integrationkits.yaml b/config/crd/bases/camel.apache.org_integrationkits.yaml
index 8ff5668a5..39fccd088 100644
--- a/config/crd/bases/camel.apache.org_integrationkits.yaml
+++ b/config/crd/bases/camel.apache.org_integrationkits.yaml
@@ -211,6 +211,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index 080b76618..1d716f3e6 100644
--- a/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -116,6 +116,12 @@ spec:
                         description: The namespace where to run the builder Pod (must
                           be the same of the operator in charge of this Build reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only used
                           for `pod` strategy
@@ -462,6 +468,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
@@ -1753,6 +1763,12 @@ spec:
                         description: The namespace where to run the builder Pod (must
                           be the same of the operator in charge of this Build reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only used
                           for `pod` strategy
@@ -2147,6 +2163,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index 0912bebc7..6106dc086 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -6194,6 +6194,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 93b4eba21..2ffcbaff3 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -6469,6 +6469,10 @@ spec:
                             description: When using `pod` strategy, the maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided to the
                               build task
diff --git a/config/crd/bases/camel.apache.org_pipes.yaml b/config/crd/bases/camel.apache.org_pipes.yaml
index 6b166be6b..4da7c6ade 100644
--- a/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/config/crd/bases/camel.apache.org_pipes.yaml
@@ -6466,6 +6466,10 @@ spec:
                             description: When using `pod` strategy, the maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided to the
                               build task
diff --git a/docs/modules/ROOT/pages/architecture/cr/build.adoc b/docs/modules/ROOT/pages/architecture/cr/build.adoc
index 306fb22bf..f331906f1 100644
--- a/docs/modules/ROOT/pages/architecture/cr/build.adoc
+++ b/docs/modules/ROOT/pages/architecture/cr/build.adoc
@@ -36,6 +36,15 @@ At the moment the available strategies are:
 - buildStrategy: pod (each build is run in a separate pod, the operator monitors the pod state)
 - buildStrategy: routine (each build is run as a go routine inside the operator pod)
 
+[[build-order-strategy]]
+== Build order strategy
+
+You can choose from different build order strategies. The strategy defines in which order queued builds are run.
+At the moment the available strategies are:
+
+- buildOrderStrategy: sequential (runs builds strictly sequential so that only one single build per operator namespace is running at a time.)
+- buildOrderStrategy: fifo (performs the builds with first in first out strategy based on the creation timestamp. The strategy allows builds to run in parallel to each other but oldest builds will be run first.)
+
 [[build-queue]]
 == Build queues
 
diff --git a/docs/modules/ROOT/pages/installation/advanced/advanced.adoc b/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
index c34e804d6..595f9ccef 100644
--- a/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
+++ b/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
@@ -26,6 +26,7 @@ We have several configuration used to influence the building of an integration:
 --build-publish-strategy string               Set the build publish strategy
 --build-publish-strategy-option stringArray   Add a build publish strategy option, as <name=value>
 --build-strategy string                       Set the build strategy
+--build-order-strategy string                 Set the build order strategy
 --build-timeout string                        Set how long the build process can last
 ```
 A very important set of configuration you can provide is related to Maven:
diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index 169451c07..aa0730185 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -533,6 +533,13 @@ The namespace where to run the builder Pod (must be the same of the operator in
 
 the strategy to adopt
 
+|`orderStrategy` +
+*xref:#_camel_apache_org_v1_BuildOrderStrategy[BuildOrderStrategy]*
+|
+
+
+the build order strategy to adopt
+
 |`requestCPU` +
 string
 |
@@ -564,6 +571,16 @@ The maximum amount of memory required. Only used for `pod` strategy
 
 |===
 
+[#_camel_apache_org_v1_BuildOrderStrategy]
+=== BuildOrderStrategy(`string` alias)
+
+*Appears on:*
+
+* <<#_camel_apache_org_v1_BuildConfiguration, BuildConfiguration>>
+
+BuildOrderStrategy specifies how builds are reconciled and queued.
+
+
 [#_camel_apache_org_v1_BuildPhase]
 === BuildPhase(`string` alias)
 
@@ -5390,6 +5407,13 @@ string
 
 The strategy to use, either `pod` or `routine` (default routine)
 
+|`orderStrategy` +
+string
+|
+
+
+The build order strategy to use, either `fifo` or `sequential` (default sequential)
+
 |`requestCPU` +
 string
 |
diff --git a/docs/modules/traits/pages/builder.adoc b/docs/modules/traits/pages/builder.adoc
index 3ae0a7f40..298d7afba 100755
--- a/docs/modules/traits/pages/builder.adoc
+++ b/docs/modules/traits/pages/builder.adoc
@@ -40,6 +40,10 @@ The following configuration options are available:
 | string
 | The strategy to use, either `pod` or `routine` (default routine)
 
+| builder.order-strategy
+| string
+| The build order strategy to use, either `fifo` or `sequential` (default sequential)
+
 | builder.request-cpu
 | string
 | When using `pod` strategy, the minimum amount of CPU required by the pod builder.
diff --git a/e2e/builder/build_test.go b/e2e/builder/build_test.go
index ae4835f13..ccb266706 100644
--- a/e2e/builder/build_test.go
+++ b/e2e/builder/build_test.go
@@ -45,8 +45,9 @@ func TestKitMaxBuildLimit(t *testing.T) {
 		createOperator(ns, "8m0s", "--global", "--force")
 
 		pl := Platform(ns)()
-		// set maximum number of running builds
+		// set maximum number of running builds and order strategy
 		pl.Spec.Build.MaxRunningBuilds = 2
+		pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategySequential
 		if err := TestClient().Update(TestContext, pl); err != nil {
 			t.Error(err)
 			t.FailNow()
@@ -139,6 +140,80 @@ func TestKitMaxBuildLimit(t *testing.T) {
 	})
 }
 
+func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) {
+	WithNewTestNamespace(t, func(ns string) {
+		createOperator(ns, "8m0s", "--global", "--force")
+
+		pl := Platform(ns)()
+		// set maximum number of running builds and order strategy
+		pl.Spec.Build.MaxRunningBuilds = 2
+		pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategyFIFO
+		if err := TestClient().Update(TestContext, pl); err != nil {
+			t.Error(err)
+			t.FailNow()
+		}
+
+		buildA := "integration-a"
+		buildB := "integration-b"
+		buildC := "integration-c"
+
+		doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:timer", "camel:log",
+			},
+			traits: []string{
+				"builder.properties=build-property=A",
+			},
+		}, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+		doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:timer", "camel:log",
+			},
+			traits: []string{
+				"builder.properties=build-property=B",
+			},
+		}, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+		doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:timer", "camel:log",
+			},
+			traits: []string{
+				"builder.properties=build-property=C",
+			},
+		}, v1.BuildPhaseScheduling, v1.IntegrationKitPhaseNone)
+
+		var notExceedsMaxBuildLimit = func(runningBuilds int) bool {
+			return runningBuilds <= 2
+		}
+
+		limit := 0
+		for limit < 5 && BuildPhase(ns, buildA)() == v1.BuildPhaseRunning {
+			// verify that number of running builds does not exceed max build limit
+			Consistently(BuildsRunning(BuildPhase(ns, buildA), BuildPhase(ns, buildB), BuildPhase(ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit))
+			limit++
+		}
+
+		// make sure we have verified max build limit at least once
+		if limit == 0 {
+			t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), buildA)))
+			t.FailNow()
+		}
+
+		// verify that all builds are successful
+		Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+		Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+		Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+	})
+}
+
 func TestKitTimerToLogFullBuild(t *testing.T) {
 	doKitFullBuild(t, "timer-to-log", "8m0s", TestTimeoutLong, kitOptions{
 		dependencies: []string{
diff --git a/e2e/common/traits/builder_test.go b/e2e/common/traits/builder_test.go
index f876a2445..d940aad83 100644
--- a/e2e/common/traits/builder_test.go
+++ b/e2e/common/traits/builder_test.go
@@ -37,9 +37,8 @@ import (
 func TestBuilderTrait(t *testing.T) {
 	RegisterTestingT(t)
 
-	name := "java"
-
 	t.Run("Run build strategy routine", func(t *testing.T) {
+		name := "java"
 		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
 			"--name", name,
 			"-t", "builder.strategy=routine").Execute()).To(Succeed())
@@ -51,6 +50,33 @@ func TestBuilderTrait(t *testing.T) {
 		integrationKitName := IntegrationKit(ns, name)()
 		builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName)
 		Eventually(BuildConfig(ns, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine))
+		Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential))
+		// Default resource CPU Check
+		Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal(""))
+
+		Eventually(BuilderPod(ns, builderKitName), TestTimeoutShort).Should(BeNil())
+
+		// We need to remove the kit as well
+		Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Run build order strategy fifo", func(t *testing.T) {
+		name := "java-fifo-strategy"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			"-t", "builder.order-strategy=fifo").Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		integrationKitName := IntegrationKit(ns, name)()
+		builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName)
+		Eventually(BuildConfig(ns, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine))
+		Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyFIFO))
 		// Default resource CPU Check
 		Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal(""))
 		Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal(""))
@@ -64,6 +90,7 @@ func TestBuilderTrait(t *testing.T) {
 	})
 
 	t.Run("Run build resources configuration", func(t *testing.T) {
+		name := "java-resource-config"
 		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
 			"--name", name,
 			"-t", "builder.request-cpu=500m",
@@ -81,6 +108,7 @@ func TestBuilderTrait(t *testing.T) {
 		builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName)
 
 		Eventually(BuildConfig(ns, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyPod))
+		Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential))
 		Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("500m"))
 		Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("1000m"))
 		Eventually(BuildConfig(ns, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("2Gi"))
@@ -98,6 +126,7 @@ func TestBuilderTrait(t *testing.T) {
 	})
 
 	t.Run("Run custom pipeline task", func(t *testing.T) {
+		name := "java-pipeline"
 		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
 			"--name", name,
 			"-t", "builder.tasks=custom1;alpine;tree",
@@ -141,8 +170,8 @@ func TestBuilderTrait(t *testing.T) {
 		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 	})
 
-	name = "java-error"
 	t.Run("Run custom pipeline task error", func(t *testing.T) {
+		name := "java-error"
 		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
 			"--name", name,
 			"-t", "builder.tasks=custom1;alpine;cat missingfile.txt",
diff --git a/e2e/commonwithcustominstall/local_platform_test.go b/e2e/commonwithcustominstall/local_platform_test.go
index 05ce8c3b7..2f924ac20 100644
--- a/e2e/commonwithcustominstall/local_platform_test.go
+++ b/e2e/commonwithcustominstall/local_platform_test.go
@@ -82,6 +82,7 @@ func TestLocalPlatform(t *testing.T) {
 			local := Platform(ns1)()
 			Expect(local.Status.Build.PublishStrategy).To(Equal(pl.Status.Build.PublishStrategy))
 			Expect(local.Status.Build.BuildConfiguration.Strategy).To(Equal(pl.Status.Build.BuildConfiguration.Strategy))
+			Expect(local.Status.Build.BuildConfiguration.OrderStrategy).To(Equal(pl.Status.Build.BuildConfiguration.OrderStrategy))
 			Expect(local.Status.Build.Maven.LocalRepository).To(Equal(pl.Status.Build.Maven.LocalRepository))
 			Expect(local.Status.Build.Maven.CLIOptions).To(ContainElements(pl.Status.Build.Maven.CLIOptions))
 			Expect(local.Status.Build.Maven.Extension).To(BeEmpty())
diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml
index 9e525152b..44ee86332 100644
--- a/helm/camel-k/crds/crd-build.yaml
+++ b/helm/camel-k/crds/crd-build.yaml
@@ -97,6 +97,12 @@ spec:
                     description: The namespace where to run the builder Pod (must
                       be the same of the operator in charge of this Build reconciliation).
                     type: string
+                  orderStrategy:
+                    description: the build order strategy to adopt
+                    enum:
+                    - fifo
+                    - sequential
+                    type: string
                   requestCPU:
                     description: The minimum amount of CPU required. Only used for
                       `pod` strategy
@@ -206,6 +212,12 @@ spec:
                                 Pod (must be the same of the operator in charge of
                                 this Build reconciliation).
                               type: string
+                            orderStrategy:
+                              description: the build order strategy to adopt
+                              enum:
+                              - fifo
+                              - sequential
+                              type: string
                             requestCPU:
                               description: The minimum amount of CPU required. Only
                                 used for `pod` strategy
diff --git a/helm/camel-k/crds/crd-integration-kit.yaml b/helm/camel-k/crds/crd-integration-kit.yaml
index 8ff5668a5..39fccd088 100644
--- a/helm/camel-k/crds/crd-integration-kit.yaml
+++ b/helm/camel-k/crds/crd-integration-kit.yaml
@@ -211,6 +211,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml
index 080b76618..1d716f3e6 100644
--- a/helm/camel-k/crds/crd-integration-platform.yaml
+++ b/helm/camel-k/crds/crd-integration-platform.yaml
@@ -116,6 +116,12 @@ spec:
                         description: The namespace where to run the builder Pod (must
                           be the same of the operator in charge of this Build reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only used
                           for `pod` strategy
@@ -462,6 +468,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
@@ -1753,6 +1763,12 @@ spec:
                         description: The namespace where to run the builder Pod (must
                           be the same of the operator in charge of this Build reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only used
                           for `pod` strategy
@@ -2147,6 +2163,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index 0912bebc7..6106dc086 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -6194,6 +6194,10 @@ spec:
                         description: When using `pod` strategy, the maximum amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either `fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to the build
                           task
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 93b4eba21..2ffcbaff3 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -6469,6 +6469,10 @@ spec:
                             description: When using `pod` strategy, the maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided to the
                               build task
diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml
index 6b166be6b..4da7c6ade 100644
--- a/helm/camel-k/crds/crd-pipe.yaml
+++ b/helm/camel-k/crds/crd-pipe.yaml
@@ -6466,6 +6466,10 @@ spec:
                             description: When using `pod` strategy, the maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided to the
                               build task
diff --git a/pkg/apis/camel/v1/build_types_support.go b/pkg/apis/camel/v1/build_types_support.go
index 6131f909b..8c05f66e7 100644
--- a/pkg/apis/camel/v1/build_types_support.go
+++ b/pkg/apis/camel/v1/build_types_support.go
@@ -201,3 +201,28 @@ func (c BuildCondition) GetReason() string {
 func (c BuildCondition) GetMessage() string {
 	return c.Message
 }
+
+func (bl BuildList) HasRunningBuilds() bool {
+	for _, b := range bl.Items {
+		if b.Status.Phase == BuildPhasePending || b.Status.Phase == BuildPhaseRunning {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (bl BuildList) HasScheduledBuildsBefore(build *Build) bool {
+	for _, b := range bl.Items {
+		if b.Name == build.Name {
+			continue
+		}
+
+		if (b.Status.Phase == BuildPhaseInitialization || b.Status.Phase == BuildPhaseScheduling) &&
+			b.CreationTimestamp.Before(&build.CreationTimestamp) {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 4a4aaa2cf..979cd2a87 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -43,6 +43,8 @@ type BuildConfiguration struct {
 	BuilderPodNamespace string `json:"operatorNamespace,omitempty"`
 	// the strategy to adopt
 	Strategy BuildStrategy `property:"strategy" json:"strategy,omitempty"`
+	// the build order strategy to adopt
+	OrderStrategy BuildOrderStrategy `property:"order-strategy" json:"orderStrategy,omitempty"`
 	// The minimum amount of CPU required. Only used for `pod` strategy
 	RequestCPU string `property:"request-cpu" json:"requestCPU,omitempty"`
 	// The minimum amount of memory required. Only used for `pod` strategy
@@ -70,6 +72,12 @@ const (
 	// mitigated by the presence of a Maven proxy.
 	// Available for both Quarkus JVM and Native mode.
 	BuildStrategyPod BuildStrategy = "pod"
+
+	// BuildOrderStrategyFIFO performs the builds with first in first out strategy based on the creation timestamp.
+	// The strategy allows builds to run in parallel to each other but oldest builds will be run first.
+	BuildOrderStrategyFIFO BuildOrderStrategy = "fifo"
+	// BuildOrderStrategySequential runs builds strictly sequential so that only one single build per operator namespace is running at a time.
+	BuildOrderStrategySequential BuildOrderStrategy = "sequential"
 )
 
 // BuildStrategies is a list of strategies allowed for the build
@@ -78,6 +86,16 @@ var BuildStrategies = []BuildStrategy{
 	BuildStrategyPod,
 }
 
+// BuildOrderStrategy specifies how builds are reconciled and queued.
+// +kubebuilder:validation:Enum=fifo;sequential
+type BuildOrderStrategy string
+
+// BuildOrderStrategies is a list of order strategies allowed for the build
+var BuildOrderStrategies = []BuildOrderStrategy{
+	BuildOrderStrategyFIFO,
+	BuildOrderStrategySequential,
+}
+
 // ConfigurationSpec represents a generic configuration specification
 type ConfigurationSpec struct {
 	// represents the type of configuration, ie: property, configmap, secret, ...
diff --git a/pkg/apis/camel/v1/common_types_support.go b/pkg/apis/camel/v1/common_types_support.go
index b66dca9a8..6b48170d3 100644
--- a/pkg/apis/camel/v1/common_types_support.go
+++ b/pkg/apis/camel/v1/common_types_support.go
@@ -159,6 +159,7 @@ var _ json.Unmarshaler = (*RawMessage)(nil)
 // IsEmpty -- .
 func (bc *BuildConfiguration) IsEmpty() bool {
 	return bc.Strategy == "" &&
+		bc.OrderStrategy == "" &&
 		bc.RequestCPU == "" &&
 		bc.RequestMemory == "" &&
 		bc.LimitCPU == "" &&
diff --git a/pkg/apis/camel/v1/trait/builder.go b/pkg/apis/camel/v1/trait/builder.go
index 6bfe96546..86e682ab3 100644
--- a/pkg/apis/camel/v1/trait/builder.go
+++ b/pkg/apis/camel/v1/trait/builder.go
@@ -29,6 +29,8 @@ type BuilderTrait struct {
 	Properties []string `property:"properties" json:"properties,omitempty"`
 	// The strategy to use, either `pod` or `routine` (default routine)
 	Strategy string `property:"strategy" json:"strategy,omitempty"`
+	// The build order strategy to use, either `fifo` or `sequential` (default sequential)
+	OrderStrategy string `property:"order-strategy" json:"orderStrategy,omitempty"`
 	// When using `pod` strategy, the minimum amount of CPU required by the pod builder.
 	RequestCPU string `property:"request-cpu" json:"requestCPU,omitempty"`
 	// When using `pod` strategy, the minimum amount of memory required by the pod builder.
diff --git a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
index 581db6aa5..7aa865add 100644
--- a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
+++ b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
@@ -26,13 +26,14 @@ import (
 // BuildConfigurationApplyConfiguration represents an declarative configuration of the BuildConfiguration type for use
 // with apply.
 type BuildConfigurationApplyConfiguration struct {
-	ToolImage           *string           `json:"toolImage,omitempty"`
-	BuilderPodNamespace *string           `json:"operatorNamespace,omitempty"`
-	Strategy            *v1.BuildStrategy `json:"strategy,omitempty"`
-	RequestCPU          *string           `json:"requestCPU,omitempty"`
-	RequestMemory       *string           `json:"requestMemory,omitempty"`
-	LimitCPU            *string           `json:"limitCPU,omitempty"`
-	LimitMemory         *string           `json:"limitMemory,omitempty"`
+	ToolImage           *string                `json:"toolImage,omitempty"`
+	BuilderPodNamespace *string                `json:"operatorNamespace,omitempty"`
+	Strategy            *v1.BuildStrategy      `json:"strategy,omitempty"`
+	OrderStrategy       *v1.BuildOrderStrategy `json:"orderStrategy,omitempty"`
+	RequestCPU          *string                `json:"requestCPU,omitempty"`
+	RequestMemory       *string                `json:"requestMemory,omitempty"`
+	LimitCPU            *string                `json:"limitCPU,omitempty"`
+	LimitMemory         *string                `json:"limitMemory,omitempty"`
 }
 
 // BuildConfigurationApplyConfiguration constructs an declarative configuration of the BuildConfiguration type for use with
@@ -65,6 +66,14 @@ func (b *BuildConfigurationApplyConfiguration) WithStrategy(value v1.BuildStrate
 	return b
 }
 
+// WithOrderStrategy sets the OrderStrategy field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the OrderStrategy field is set to the value of the last call.
+func (b *BuildConfigurationApplyConfiguration) WithOrderStrategy(value v1.BuildOrderStrategy) *BuildConfigurationApplyConfiguration {
+	b.OrderStrategy = &value
+	return b
+}
+
 // WithRequestCPU sets the RequestCPU field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the RequestCPU field is set to the value of the last call.
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index cf68324c8..6a4f3bd08 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -107,6 +107,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) (*cobra.Command, *installCmdO
 	cmd.Flags().String("operator-image", "", "Set the operator Image used for the operator deployment")
 	cmd.Flags().String("operator-image-pull-policy", "", "Set the operator ImagePullPolicy used for the operator deployment")
 	cmd.Flags().String("build-strategy", "", "Set the build strategy")
+	cmd.Flags().String("build-order-strategy", "", "Set the build order strategy")
 	cmd.Flags().String("build-publish-strategy", "", "Set the build publish strategy")
 	cmd.Flags().StringArray("build-publish-strategy-option", nil, "Add a build publish strategy option, as <name=value>")
 	cmd.Flags().String("build-timeout", "", "Set how long the build process can last")
@@ -181,6 +182,7 @@ type installCmdOptions struct {
 	OperatorImage               string   `mapstructure:"operator-image"`
 	OperatorImagePullPolicy     string   `mapstructure:"operator-image-pull-policy"`
 	BuildStrategy               string   `mapstructure:"build-strategy"`
+	BuildOrderStrategy          string   `mapstructure:"build-order-strategy"`
 	BuildPublishStrategy        string   `mapstructure:"build-publish-strategy"`
 	BuildPublishStrategyOptions []string `mapstructure:"build-publish-strategy-options"`
 	BuildTimeout                string   `mapstructure:"build-timeout"`
@@ -524,6 +526,9 @@ func (o *installCmdOptions) setupIntegrationPlatform(c client.Client, namespace
 	if o.BuildStrategy != "" {
 		platform.Spec.Build.BuildConfiguration.Strategy = v1.BuildStrategy(o.BuildStrategy)
 	}
+	if o.BuildOrderStrategy != "" {
+		platform.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategy(o.BuildOrderStrategy)
+	}
 	if o.BuildPublishStrategy != "" {
 		platform.Spec.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategy(o.BuildPublishStrategy)
 	}
@@ -749,6 +754,23 @@ func (o *installCmdOptions) validate(_ *cobra.Command, _ []string) error {
 		}
 	}
 
+	if o.BuildOrderStrategy != "" {
+		found := false
+		for _, s := range v1.BuildOrderStrategies {
+			if string(s) == o.BuildOrderStrategy {
+				found = true
+				break
+			}
+		}
+		if !found {
+			var strategies []string
+			for _, s := range v1.BuildOrderStrategies {
+				strategies = append(strategies, string(s))
+			}
+			return fmt.Errorf("unknown build order strategy: %s. One of [%s] is expected", o.BuildOrderStrategy, strings.Join(strategies, ", "))
+		}
+	}
+
 	if o.BuildPublishStrategy != "" {
 		found := false
 		for _, s := range v1.IntegrationPlatformBuildPublishStrategies {
diff --git a/pkg/cmd/install_test.go b/pkg/cmd/install_test.go
index fcfdb8ecd..aacc8824b 100644
--- a/pkg/cmd/install_test.go
+++ b/pkg/cmd/install_test.go
@@ -107,6 +107,13 @@ func TestInstallBuildStrategyFlag(t *testing.T) {
 	assert.Equal(t, "someString", installCmdOptions.BuildStrategy)
 }
 
+func TestInstallBuildOrderStrategyFlag(t *testing.T) {
+	installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t)
+	_, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-order-strategy", "someString")
+	assert.Nil(t, err)
+	assert.Equal(t, "someString", installCmdOptions.BuildOrderStrategy)
+}
+
 func TestInstallBuildTimeoutFlag(t *testing.T) {
 	installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t)
 	_, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-timeout", "10")
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 33fe525d8..75439a3d2 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -147,7 +147,8 @@ func (r *reconcileBuild) Reconcile(ctx context.Context, request reconcile.Reques
 		return reconcile.Result{}, err
 	}
 	buildMonitor := Monitor{
-		maxRunningBuilds: ip.Status.Build.MaxRunningBuilds,
+		maxRunningBuilds:   ip.Status.Build.MaxRunningBuilds,
+		buildOrderStrategy: ip.Status.Build.BuildConfiguration.OrderStrategy,
 	}
 
 	switch instance.BuilderConfiguration().Strategy {
diff --git a/pkg/controller/build/build_monitor.go b/pkg/controller/build/build_monitor.go
index 521dd6b86..a60ce1b3a 100644
--- a/pkg/controller/build/build_monitor.go
+++ b/pkg/controller/build/build_monitor.go
@@ -33,7 +33,8 @@ import (
 var runningBuilds sync.Map
 
 type Monitor struct {
-	maxRunningBuilds int32
+	maxRunningBuilds   int32
+	buildOrderStrategy v1.BuildOrderStrategy
 }
 
 func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Build) (bool, error) {
@@ -43,15 +44,15 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
 		return true
 	})
 
-	if runningBuildsTotal >= bm.maxRunningBuilds {
-		requestName := build.Name
-		requestNamespace := build.Namespace
-		buildCreator := kubernetes.GetCamelCreator(build)
-		if buildCreator != nil {
-			requestName = buildCreator.Name
-			requestNamespace = buildCreator.Namespace
-		}
+	requestName := build.Name
+	requestNamespace := build.Namespace
+	buildCreator := kubernetes.GetCamelCreator(build)
+	if buildCreator != nil {
+		requestName = buildCreator.Name
+		requestNamespace = buildCreator.Namespace
+	}
 
+	if runningBuildsTotal >= bm.maxRunningBuilds {
 		Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "max-running-builds-limit", runningBuildsTotal).
 			ForBuild(build).Infof("Maximum number of running builds (%d) exceeded - the build gets enqueued", runningBuildsTotal)
 
@@ -84,18 +85,22 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
 		return false, err
 	}
 
-	// Emulate a serialized working queue to only allow one build to run at a given time.
-	// This is currently necessary for the incremental build to work as expected.
-	// We may want to explicitly manage build priority as opposed to relying on
-	// the reconciliation loop to handle the queuing.
-	for _, b := range builds.Items {
-		if b.Status.Phase == v1.BuildPhasePending || b.Status.Phase == v1.BuildPhaseRunning {
-			// Let's requeue the build in case one is already running
-			return false, nil
-		}
+	var allowed bool
+	switch bm.buildOrderStrategy {
+	case v1.BuildOrderStrategyFIFO:
+		// Check on builds that have been created before the current build and grant precedence if any.
+		allowed = !builds.HasScheduledBuildsBefore(build)
+	case v1.BuildOrderStrategySequential:
+		// Emulate a serialized working queue to only allow one build to run at a given time.
+		// Let's requeue the build in case one is already running
+		allowed = !builds.HasRunningBuilds()
+	default:
+		Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "order-strategy", bm.buildOrderStrategy).
+			ForBuild(build).Infof("Unsupported build order strategy (%s) - the build gets enqueued", bm.buildOrderStrategy)
+		allowed = false
 	}
 
-	return true, nil
+	return allowed, nil
 }
 
 func monitorRunningBuild(build *v1.Build) {
diff --git a/pkg/controller/build/build_monitor_test.go b/pkg/controller/build/build_monitor_test.go
index 0dd4ee2d3..b44cd0533 100644
--- a/pkg/controller/build/build_monitor_test.go
+++ b/pkg/controller/build/build_monitor_test.go
@@ -30,7 +30,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-func TestMonitorBuilds(t *testing.T) {
+func TestMonitorSequentialBuilds(t *testing.T) {
 	testcases := []struct {
 		name     string
 		running  []*v1.Build
@@ -49,7 +49,7 @@ func TestMonitorBuilds(t *testing.T) {
 			name:     "allowNewNativeBuild",
 			running:  []*v1.Build{},
 			finished: []*v1.Build{},
-			build:    newNativeBuild("ns", "my-build"),
+			build:    newNativeBuild("ns", "my-native-build"),
 			allowed:  true,
 		},
 		{
@@ -69,7 +69,7 @@ func TestMonitorBuilds(t *testing.T) {
 				newNativeBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
 				newNativeBuildInPhase("ns", "my-build-failed", v1.BuildPhaseFailed),
 			},
-			build:   newNativeBuild("ns", "my-build"),
+			build:   newNativeBuild("ns", "my-native-build"),
 			allowed: true,
 		},
 		{
@@ -144,7 +144,8 @@ func TestMonitorBuilds(t *testing.T) {
 			assert.Nil(t, err)
 
 			bm := Monitor{
-				maxRunningBuilds: 3,
+				maxRunningBuilds:   3,
+				buildOrderStrategy: v1.BuildOrderStrategySequential,
 			}
 
 			// reset running builds in memory cache
@@ -167,7 +168,8 @@ func TestAllowBuildRequeue(t *testing.T) {
 	assert.Nil(t, err)
 
 	bm := Monitor{
-		maxRunningBuilds: 3,
+		maxRunningBuilds:   3,
+		buildOrderStrategy: v1.BuildOrderStrategySequential,
 	}
 
 	runningBuild := newBuild("some-ns", "my-build-1")
@@ -191,6 +193,165 @@ func TestAllowBuildRequeue(t *testing.T) {
 	assert.True(t, allowed)
 }
 
+func TestMonitorFIFOBuilds(t *testing.T) {
+	testcases := []struct {
+		name    string
+		running []*v1.Build
+		builds  []*v1.Build
+		build   *v1.Build
+		allowed bool
+	}{
+		{
+			name:    "allowNewBuild",
+			running: []*v1.Build{},
+			builds:  []*v1.Build{},
+			build:   newBuild("ns", "my-build"),
+			allowed: true,
+		},
+		{
+			name:    "allowNewNativeBuild",
+			running: []*v1.Build{},
+			builds:  []*v1.Build{},
+			build:   newNativeBuild("ns1", "my-build"),
+			allowed: true,
+		},
+		{
+			name:    "allowNewBuildWhenOthersFinished",
+			running: []*v1.Build{},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+				newBuildInPhase("ns", "my-build-failed", v1.BuildPhaseFailed),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: true,
+		},
+		{
+			name:    "allowNewNativeBuildWhenOthersFinished",
+			running: []*v1.Build{},
+			builds: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+				newNativeBuildInPhase("ns", "my-build-failed", v1.BuildPhaseFailed),
+			},
+			build:   newNativeBuild("ns", "my-build"),
+			allowed: true,
+		},
+		{
+			name: "limitMaxRunningBuilds",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1"),
+				newBuild("other-ns", "my-build-2"),
+				newBuild("another-ns", "my-build-3"),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: false,
+		},
+		{
+			name: "limitMaxRunningNativeBuilds",
+			running: []*v1.Build{
+				newBuildInPhase("some-ns", "my-build-1", v1.BuildPhaseRunning),
+				newNativeBuildInPhase("other-ns", "my-build-2", v1.BuildPhaseRunning),
+				newNativeBuildInPhase("another-ns", "my-build-3", v1.BuildPhaseRunning),
+			},
+			builds: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+			},
+			build:   newNativeBuildInPhase("ns", "my-build", v1.BuildPhaseInitialization),
+			allowed: false,
+		},
+		{
+			name: "allowParallelBuildsWithDifferentLayout",
+			running: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-1", v1.BuildPhaseRunning),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: true,
+		},
+		{
+			name: "allowParallelBuildsInSameNamespace",
+			running: []*v1.Build{
+				newBuild("ns", "my-build-1"),
+				newBuild("other-ns", "my-build-2"),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+				newBuildInPhase("other-ns", "my-build-new", v1.BuildPhaseScheduling),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: true,
+		},
+		{
+			name: "queueBuildWhenOlderBuildIsAlreadyInitialized",
+			running: []*v1.Build{
+				newBuild("ns", "my-build-1"),
+				newBuild("other-ns", "my-build-2"),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+				newBuildInPhase("ns", "my-build-new", v1.BuildPhaseInitialization),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: false,
+		},
+		{
+			name: "queueBuildWhenOlderBuildIsAlreadyScheduled",
+			running: []*v1.Build{
+				newBuild("ns", "my-build-1"),
+				newBuild("other-ns", "my-build-2"),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+				newBuildInPhase("ns", "my-build-new", v1.BuildPhaseScheduling),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: false,
+		},
+		{
+			name: "allowBuildsInNewNamespace",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1"),
+				newBuild("other-ns", "my-build-2"),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded),
+			},
+			build:   newBuild("ns", "my-build"),
+			allowed: true,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			var initObjs []runtime.Object
+			for _, build := range append(tc.running, tc.builds...) {
+				initObjs = append(initObjs, build)
+			}
+
+			c, err := test.NewFakeClient(initObjs...)
+
+			assert.Nil(t, err)
+
+			bm := Monitor{
+				maxRunningBuilds:   3,
+				buildOrderStrategy: v1.BuildOrderStrategyFIFO,
+			}
+
+			// reset running builds in memory cache
+			cleanRunningBuildsMonitor()
+			for _, build := range tc.running {
+				monitorRunningBuild(build)
+			}
+
+			allowed, err := bm.canSchedule(context.TODO(), c, tc.build)
+
+			assert.Nil(t, err)
+			assert.Equal(t, tc.allowed, allowed)
+		})
+	}
+}
+
 func cleanRunningBuildsMonitor() {
 	runningBuilds.Range(func(key interface{}, v interface{}) bool {
 		runningBuilds.Delete(key)
@@ -226,6 +387,7 @@ func newBuildWithLayoutInPhase(namespace string, name string, layout string, pha
 			Labels: map[string]string{
 				v1.IntegrationKitLayoutLabel: layout,
 			},
+			CreationTimestamp: metav1.NewTime(time.Now()),
 		},
 		Spec: v1.BuildSpec{
 			Tasks: []v1.Task{
@@ -233,6 +395,7 @@ func newBuildWithLayoutInPhase(namespace string, name string, layout string, pha
 					Builder: &v1.BuilderTask{
 						Configuration: v1.BuildConfiguration{
 							Strategy:            v1.BuildStrategyRoutine,
+							OrderStrategy:       v1.BuildOrderStrategySequential,
 							ToolImage:           "camel:latest",
 							BuilderPodNamespace: "ns",
 						},
diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go
index 75228c041..d4b49fa97 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -113,9 +113,16 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
 		if buildConfig.IsEmpty() {
 			// default to IntegrationPlatform configuration
 			buildConfig = &env.Platform.Status.Build.BuildConfiguration
-		} else if buildConfig.Strategy == "" {
-			// we always need to define a strategy, so we default to platform if none
-			buildConfig.Strategy = env.Platform.Status.Build.BuildConfiguration.Strategy
+		} else {
+			if buildConfig.Strategy == "" {
+				// we always need to define a strategy, so we default to platform if none
+				buildConfig.Strategy = env.Platform.Status.Build.BuildConfiguration.Strategy
+			}
+
+			if buildConfig.OrderStrategy == "" {
+				// we always need to define an order strategy, so we default to platform if none
+				buildConfig.OrderStrategy = env.Platform.Status.Build.BuildConfiguration.OrderStrategy
+			}
 		}
 
 		// nolint: contextcheck
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index 7504c195b..a7711e4cc 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -97,6 +97,11 @@ func ConfigureDefaults(ctx context.Context, c client.Client, p *v1.IntegrationPl
 		log.Debugf("Integration Platform %s [%s]: setting build strategy %s", p.Name, p.Namespace, p.Status.Build.BuildConfiguration.Strategy)
 	}
 
+	if p.Status.Build.BuildConfiguration.OrderStrategy == "" {
+		p.Status.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategySequential
+		log.Debugf("Integration Platform %s [%s]: setting build order strategy %s", p.Name, p.Namespace, p.Status.Build.BuildConfiguration.OrderStrategy)
+	}
+
 	err := setPlatformDefaults(p, verbose)
 	if err != nil {
 		return err
@@ -237,6 +242,10 @@ func applyPlatformSpec(source *v1.IntegrationPlatform, target *v1.IntegrationPla
 		target.Status.Build.BuildConfiguration.Strategy = source.Status.Build.BuildConfiguration.Strategy
 	}
 
+	if target.Status.Build.BuildConfiguration.OrderStrategy == "" {
+		target.Status.Build.BuildConfiguration.OrderStrategy = source.Status.Build.BuildConfiguration.OrderStrategy
+	}
+
 	if target.Status.Build.RuntimeVersion == "" {
 		log.Debugf("Integration Platform %s [%s]: setting runtime version", target.Name, target.Namespace)
 		target.Status.Build.RuntimeVersion = source.Status.Build.RuntimeVersion
diff --git a/pkg/platform/defaults_test.go b/pkg/platform/defaults_test.go
index b2a51fb22..d73b99af2 100644
--- a/pkg/platform/defaults_test.go
+++ b/pkg/platform/defaults_test.go
@@ -28,9 +28,35 @@ import (
 	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
 	"github.com/apache/camel-k/v2/pkg/builder"
+	"github.com/apache/camel-k/v2/pkg/util/defaults"
 	"github.com/apache/camel-k/v2/pkg/util/test"
 )
 
+func TestIntegrationPlatformDefaults(t *testing.T) {
+	ip := v1.IntegrationPlatform{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      DefaultPlatformName,
+			Namespace: "ns",
+		},
+	}
+
+	c, err := test.NewFakeClient(&ip)
+	assert.Nil(t, err)
+
+	err = ConfigureDefaults(context.TODO(), c, &ip, false)
+	assert.Nil(t, err)
+
+	assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, ip.Status.Cluster)
+	assert.Equal(t, v1.TraitProfile(""), ip.Status.Profile)
+	assert.Equal(t, v1.BuildStrategyRoutine, ip.Status.Build.BuildConfiguration.Strategy)
+	assert.Equal(t, v1.BuildOrderStrategySequential, ip.Status.Build.BuildConfiguration.OrderStrategy)
+	assert.Equal(t, defaults.BaseImage(), ip.Status.Build.BaseImage)
+	assert.Equal(t, defaults.LocalRepository, ip.Status.Build.Maven.LocalRepository)
+	assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for build strategy routine
+	assert.Equal(t, 3, len(ip.Status.Build.Maven.CLIOptions))
+	assert.NotNil(t, ip.Status.Traits)
+}
+
 func TestApplyGlobalPlatformSpec(t *testing.T) {
 	global := v1.IntegrationPlatform{
 		ObjectMeta: metav1.ObjectMeta{
@@ -40,7 +66,8 @@ func TestApplyGlobalPlatformSpec(t *testing.T) {
 		Spec: v1.IntegrationPlatformSpec{
 			Build: v1.IntegrationPlatformBuildSpec{
 				BuildConfiguration: v1.BuildConfiguration{
-					Strategy: v1.BuildStrategyRoutine,
+					Strategy:      v1.BuildStrategyRoutine,
+					OrderStrategy: v1.BuildOrderStrategyFIFO,
 				},
 				Maven: v1.MavenSpec{
 					Properties: map[string]string{
@@ -83,6 +110,7 @@ func TestApplyGlobalPlatformSpec(t *testing.T) {
 	assert.Equal(t, v1.IntegrationPlatformClusterOpenShift, ip.Status.Cluster)
 	assert.Equal(t, v1.TraitProfileOpenShift, ip.Status.Profile)
 	assert.Equal(t, v1.BuildStrategyRoutine, ip.Status.Build.BuildConfiguration.Strategy)
+	assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy)
 	assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for build strategy routine
 	assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), len(ip.Status.Build.Maven.CLIOptions))
 	assert.Equal(t, global.Status.Build.Maven.CLIOptions, ip.Status.Build.Maven.CLIOptions)
@@ -187,7 +215,8 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
 		Spec: v1.IntegrationPlatformSpec{
 			Build: v1.IntegrationPlatformBuildSpec{
 				BuildConfiguration: v1.BuildConfiguration{
-					Strategy: v1.BuildStrategyRoutine,
+					Strategy:      v1.BuildStrategyRoutine,
+					OrderStrategy: v1.BuildOrderStrategySequential,
 				},
 				Maven: v1.MavenSpec{
 					Properties: map[string]string{
@@ -224,7 +253,8 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
 		Spec: v1.IntegrationPlatformSpec{
 			Build: v1.IntegrationPlatformBuildSpec{
 				BuildConfiguration: v1.BuildConfiguration{
-					Strategy: v1.BuildStrategyPod,
+					Strategy:      v1.BuildStrategyPod,
+					OrderStrategy: v1.BuildOrderStrategyFIFO,
 				},
 				MaxRunningBuilds: 1,
 				Maven: v1.MavenSpec{
@@ -251,6 +281,7 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
 	assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, ip.Status.Cluster)
 	assert.Equal(t, v1.TraitProfileKnative, ip.Status.Profile)
 	assert.Equal(t, v1.BuildStrategyPod, ip.Status.Build.BuildConfiguration.Strategy)
+	assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy)
 	assert.True(t, ip.Status.Build.MaxRunningBuilds == 1)
 	assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), len(ip.Status.Build.Maven.CLIOptions))
 	assert.Equal(t, global.Status.Build.Maven.CLIOptions, ip.Status.Build.Maven.CLIOptions)
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 8911750c1..582168091 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -117,9 +117,9 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_builds.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_builds.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 44155,
+			uncompressedSize: 44653,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb9\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x69\xbd\xb9\x23\x5e\x6c\x0d\xf1\xd1\xdd\xe8\x2f\x34\x1a\xc0\x29\x8c\x9e\xae\x9c\x9c\xc2\x3b\x9e\xa0\xd0\x98\x82\x91\x60\x96\x08\x97\x05\x4b\x96\x08\x53\x39\x37\x6b\xa6\x10\xde\xc8\x52\xa4\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb5\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x6a\xbd\xb9\x23\x5e\x6c\x71\xf0\xd1\xdd\x68\xf4\x17\x1a\xc0\x29\x8c\x0e\x57\x4e\x4e\xe1\x1d\x4f\x50\x68\x4c\xc1\x48\x30\x0b\x84\xab\x82\x25\x0b\x84\x89\x9c\x99\x15\x53\x08\x6f\x64\x29\x52\x [...]
 		},
 		"/crd/bases/camel.apache.org_camelcatalogs.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_camelcatalogs.yaml",
@@ -131,30 +131,30 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_integrationkits.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrationkits.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 20532,
+			uncompressedSize: 20753,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xdb\x38\x92\xef\xfa\x15\x5d\xf1\x43\xec\x2a\x49\xde\xb9\x9b\x9a\xba\xf2\xee\x6d\x95\xd7\x49\x66\x5d\x71\x12\x5f\xe4\xcc\xdc\x54\xcd\x83\x5b\x64\x4b\xc2\x88\x04\xb8\x00\x28\x59\x77\x75\xff\xfd\x0a\x0d\x80\xa2\x24\x92\x62\xe4\xf8\x6e\x1f\xc2\x97\x44\x24\xd0\xe8\xef\x0f\xa0\xe1\x33\x18\x7d\xbb\x67\x70\x06\x77\x22\x21\x69\x28\x05\xab\xc0\x2e\x08\xae\x0b\x4c\x16\x04\x13\x35\xb3\x6b\xd4\x04\xef\x54\x29\x53\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7c\x5f\x6f\xdb\xb8\x96\xf8\xbb\x3f\xc5\x41\xf3\xd0\x04\xb0\x9d\x3b\xbf\xdf\x60\xb0\xc8\xbd\x7b\x81\xdc\xb4\x9d\x1b\x34\x6d\xb3\x75\x3a\xb3\x03\xcc\x43\x8e\xa5\x63\x9b\x63\x89\xd4\x90\x94\x1d\xef\x62\xbf\xfb\x82\x87\xa4\x2c\xdb\x92\xac\x3a\xcd\xee\x3e\x54\x2f\xad\x25\xf2\xf0\xfc\xff\x43\x1e\xe6\x0c\x46\xdf\xee\x19\x9c\xc1\x9d\x48\x48\x1a\x4a\xc1\x2a\xb0\x0b\x82\xeb\x02\x93\x05\xc1\x44\xcd\xec\x1a\x35\xc1\x3b\x55\x [...]
 		},
 		"/crd/bases/camel.apache.org_integrationplatforms.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrationplatforms.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 182031,
+			uncompressedSize: 182959,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x [...]
 		},
 		"/crd/bases/camel.apache.org_integrations.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrations.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 495936,
+			uncompressedSize: 496157,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x [...]
 		},
 		"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_kameletbindings.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 575715,
+			uncompressedSize: 575952,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x [...]
 		},
 		"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_kamelets.yaml",
@@ -166,9 +166,9 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_pipes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_pipes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 542983,
+			uncompressedSize: 543220,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x [...]
 		},
 		"/manager": &vfsgen۰DirInfo{
 			name:    "manager",
@@ -625,9 +625,9 @@ var assets = func() http.FileSystem {
 		"/traits.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "traits.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 66742,
+			uncompressedSize: 66891,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x [...]
 		},
 	}
 	fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index e8b72419f..2d997210e 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -181,9 +181,10 @@ func (t *builderTrait) builderTask(e *Environment) (*v1.BuilderTask, error) {
 		}
 		// The builder trait must define certain resources requirements when we have a native build
 		if ok && pointer.BoolDeref(quarkus.Enabled, true) && (isNativeIntegration || isNativeKit) {
-			// Force the build to run in a separate Pod
+			// Force the build to run in a separate Pod and strictly sequential
 			t.L.Info("This is a Quarkus native build: setting build configuration with build Pod strategy, 1 CPU core and 4 GiB memory. Make sure your cluster can handle it.")
 			t.Strategy = string(v1.BuildStrategyPod)
+			t.OrderStrategy = string(v1.BuildOrderStrategySequential)
 			t.RequestCPU = "1000m"
 			t.RequestMemory = "4Gi"
 		}
@@ -198,13 +199,39 @@ func (t *builderTrait) builderTask(e *Environment) (*v1.BuilderTask, error) {
 
 	if t.Strategy != "" {
 		t.L.Infof("User defined build strategy %s", t.Strategy)
-		switch t.Strategy {
-		case string(v1.BuildStrategyPod):
-			buildConfig.Strategy = v1.BuildStrategyPod
-		case string(v1.BuildStrategyRoutine):
-			buildConfig.Strategy = v1.BuildStrategyRoutine
-		default:
-			return nil, fmt.Errorf("must specify either pod or routine build strategy, unknown %s", t.Strategy)
+		found := false
+		for _, s := range v1.BuildStrategies {
+			if string(s) == t.Strategy {
+				found = true
+				buildConfig.Strategy = s
+				break
+			}
+		}
+		if !found {
+			var strategies []string
+			for _, s := range v1.BuildStrategies {
+				strategies = append(strategies, string(s))
+			}
+			return nil, fmt.Errorf("unknown build strategy: %s. One of [%s] is expected", t.Strategy, strings.Join(strategies, ", "))
+		}
+	}
+
+	if t.OrderStrategy != "" {
+		t.L.Infof("User defined build order strategy %s", t.OrderStrategy)
+		found := false
+		for _, s := range v1.BuildOrderStrategies {
+			if string(s) == t.OrderStrategy {
+				found = true
+				buildConfig.OrderStrategy = s
+				break
+			}
+		}
+		if !found {
+			var strategies []string
+			for _, s := range v1.BuildOrderStrategies {
+				strategies = append(strategies, string(s))
+			}
+			return nil, fmt.Errorf("unknown build order strategy: %s. One of [%s] is expected", t.OrderStrategy, strings.Join(strategies, ", "))
 		}
 	}
 
diff --git a/resources/traits.yaml b/resources/traits.yaml
index 9a8f278c9..af06f964c 100755
--- a/resources/traits.yaml
+++ b/resources/traits.yaml
@@ -212,6 +212,10 @@ traits:
   - name: strategy
     type: string
     description: The strategy to use, either `pod` or `routine` (default routine)
+  - name: order-strategy
+    type: string
+    description: The build order strategy to use, either `fifo` or `sequential` (default
+      sequential)
   - name: request-cpu
     type: string
     description: When using `pod` strategy, the minimum amount of CPU required by


[camel-k] 02/02: fix(#592): Introduce "dependencies" build order strategy

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdeppisch pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 21b968948cca207a10cc39dad7084cc9d4abcd9e
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Mon Jul 3 21:51:23 2023 +0200

    fix(#592): Introduce "dependencies" build order strategy
    
    - Introduce new build order strategy "dependencies"
    - Strategy looks at the list of dependencies required by an Integration and queues builds that may reuse base images produced by other scheduled builds in order to leverage the incremental build option
    - The strategy allows non-matching builds to run in parallel to each other
---
 config/crd/bases/camel.apache.org_builds.yaml      |   2 +
 .../bases/camel.apache.org_integrationkits.yaml    |   4 +-
 .../camel.apache.org_integrationplatforms.yaml     |  10 +-
 .../crd/bases/camel.apache.org_integrations.yaml   |   4 +-
 .../bases/camel.apache.org_kameletbindings.yaml    |   4 +-
 config/crd/bases/camel.apache.org_pipes.yaml       |   4 +-
 docs/modules/ROOT/pages/architecture/cr/build.adoc |   1 +
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |   2 +-
 docs/modules/traits/pages/builder.adoc             |   2 +-
 e2e/builder/build_test.go                          |  74 +++++++
 e2e/common/traits/builder_test.go                  |  26 +++
 .../build_order_strategy_test.go                   | 175 ++++++++++++++++
 .../files/timer-source.groovy                      |  20 ++
 helm/camel-k/crds/crd-build.yaml                   |   2 +
 helm/camel-k/crds/crd-integration-kit.yaml         |   4 +-
 helm/camel-k/crds/crd-integration-platform.yaml    |  10 +-
 helm/camel-k/crds/crd-integration.yaml             |   4 +-
 helm/camel-k/crds/crd-kamelet-binding.yaml         |   4 +-
 helm/camel-k/crds/crd-pipe.yaml                    |   4 +-
 pkg/apis/camel/v1/build_types_support.go           |  86 +++++++-
 pkg/apis/camel/v1/common_types.go                  |   7 +-
 pkg/apis/camel/v1/trait/builder.go                 |   2 +-
 pkg/controller/build/build_monitor.go              |  31 ++-
 pkg/controller/build/build_monitor_test.go         | 232 ++++++++++++++++++++-
 pkg/resources/resources.go                         |  28 +--
 resources/traits.yaml                              |   4 +-
 26 files changed, 684 insertions(+), 62 deletions(-)

diff --git a/config/crd/bases/camel.apache.org_builds.yaml b/config/crd/bases/camel.apache.org_builds.yaml
index 44ee86332..f7947276d 100644
--- a/config/crd/bases/camel.apache.org_builds.yaml
+++ b/config/crd/bases/camel.apache.org_builds.yaml
@@ -100,6 +100,7 @@ spec:
                   orderStrategy:
                     description: the build order strategy to adopt
                     enum:
+                    - dependencies
                     - fifo
                     - sequential
                     type: string
@@ -215,6 +216,7 @@ spec:
                             orderStrategy:
                               description: the build order strategy to adopt
                               enum:
+                              - dependencies
                               - fifo
                               - sequential
                               type: string
diff --git a/config/crd/bases/camel.apache.org_integrationkits.yaml b/config/crd/bases/camel.apache.org_integrationkits.yaml
index 39fccd088..c86813bc5 100644
--- a/config/crd/bases/camel.apache.org_integrationkits.yaml
+++ b/config/crd/bases/camel.apache.org_integrationkits.yaml
@@ -212,8 +212,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index 1d716f3e6..6f3b9d984 100644
--- a/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -119,6 +119,7 @@ spec:
                       orderStrategy:
                         description: the build order strategy to adopt
                         enum:
+                        - dependencies
                         - fifo
                         - sequential
                         type: string
@@ -469,8 +470,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
@@ -1766,6 +1767,7 @@ spec:
                       orderStrategy:
                         description: the build order strategy to adopt
                         enum:
+                        - dependencies
                         - fifo
                         - sequential
                         type: string
@@ -2164,8 +2166,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index 6106dc086..8f460495d 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -6195,8 +6195,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 2ffcbaff3..ef1cdf18e 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -6470,8 +6470,8 @@ spec:
                               of memory required by the pod builder.
                             type: string
                           orderStrategy:
-                            description: The build order strategy to use, either `fifo`
-                              or `sequential` (default sequential)
+                            description: The build order strategy to use, either `dependencies`,
+                              `fifo` or `sequential` (default sequential)
                             type: string
                           properties:
                             description: A list of properties to be provided to the
diff --git a/config/crd/bases/camel.apache.org_pipes.yaml b/config/crd/bases/camel.apache.org_pipes.yaml
index 4da7c6ade..bc442ac3a 100644
--- a/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/config/crd/bases/camel.apache.org_pipes.yaml
@@ -6467,8 +6467,8 @@ spec:
                               of memory required by the pod builder.
                             type: string
                           orderStrategy:
-                            description: The build order strategy to use, either `fifo`
-                              or `sequential` (default sequential)
+                            description: The build order strategy to use, either `dependencies`,
+                              `fifo` or `sequential` (default sequential)
                             type: string
                           properties:
                             description: A list of properties to be provided to the
diff --git a/docs/modules/ROOT/pages/architecture/cr/build.adoc b/docs/modules/ROOT/pages/architecture/cr/build.adoc
index f331906f1..e2e6a0557 100644
--- a/docs/modules/ROOT/pages/architecture/cr/build.adoc
+++ b/docs/modules/ROOT/pages/architecture/cr/build.adoc
@@ -43,6 +43,7 @@ You can choose from different build order strategies. The strategy defines in wh
 At the moment the available strategies are:
 
 - buildOrderStrategy: sequential (runs builds strictly sequential so that only one single build per operator namespace is running at a time.)
+- buildOrderStrategy: dependencies (strategy looks at the list of dependencies required by an Integration and queues builds that may reuse base images produced by other scheduled builds in order to leverage the incremental build option. The strategy allows non-matching builds to run in parallel to each other.)
 - buildOrderStrategy: fifo (performs the builds with first in first out strategy based on the creation timestamp. The strategy allows builds to run in parallel to each other but oldest builds will be run first.)
 
 [[build-queue]]
diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index aa0730185..1a2554c09 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -5412,7 +5412,7 @@ string
 |
 
 
-The build order strategy to use, either `fifo` or `sequential` (default sequential)
+The build order strategy to use, either `dependencies`, `fifo` or `sequential` (default sequential)
 
 |`requestCPU` +
 string
diff --git a/docs/modules/traits/pages/builder.adoc b/docs/modules/traits/pages/builder.adoc
index 298d7afba..e2254e9ce 100755
--- a/docs/modules/traits/pages/builder.adoc
+++ b/docs/modules/traits/pages/builder.adoc
@@ -42,7 +42,7 @@ The following configuration options are available:
 
 | builder.order-strategy
 | string
-| The build order strategy to use, either `fifo` or `sequential` (default sequential)
+| The build order strategy to use, either `dependencies`, `fifo` or `sequential` (default sequential)
 
 | builder.request-cpu
 | string
diff --git a/e2e/builder/build_test.go b/e2e/builder/build_test.go
index ccb266706..1b11797db 100644
--- a/e2e/builder/build_test.go
+++ b/e2e/builder/build_test.go
@@ -214,6 +214,80 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) {
 	})
 }
 
+func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) {
+	WithNewTestNamespace(t, func(ns string) {
+		createOperator(ns, "8m0s", "--global", "--force")
+
+		pl := Platform(ns)()
+		// set maximum number of running builds and order strategy
+		pl.Spec.Build.MaxRunningBuilds = 2
+		pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategyDependencies
+		if err := TestClient().Update(TestContext, pl); err != nil {
+			t.Error(err)
+			t.FailNow()
+		}
+
+		buildA := "integration-a"
+		buildB := "integration-b"
+		buildC := "integration-c"
+
+		doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:timer", "camel:log",
+			},
+			traits: []string{
+				"builder.properties=build-property=A",
+			},
+		}, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+		doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:cron", "camel:log", "camel:joor",
+			},
+			traits: []string{
+				"builder.properties=build-property=B",
+			},
+		}, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+		doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{
+			operatorID: fmt.Sprintf("camel-k-%s", ns),
+			dependencies: []string{
+				"camel:timer", "camel:log", "camel:joor", "camel:http",
+			},
+			traits: []string{
+				"builder.properties=build-property=C",
+			},
+		}, v1.BuildPhaseScheduling, v1.IntegrationKitPhaseNone)
+
+		var notExceedsMaxBuildLimit = func(runningBuilds int) bool {
+			return runningBuilds <= 2
+		}
+
+		limit := 0
+		for limit < 5 && BuildPhase(ns, buildA)() == v1.BuildPhaseRunning {
+			// verify that number of running builds does not exceed max build limit
+			Consistently(BuildsRunning(BuildPhase(ns, buildA), BuildPhase(ns, buildB), BuildPhase(ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit))
+			limit++
+		}
+
+		// make sure we have verified max build limit at least once
+		if limit == 0 {
+			t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), buildA)))
+			t.FailNow()
+		}
+
+		// verify that all builds are successful
+		Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+		Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+		Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+	})
+}
+
 func TestKitTimerToLogFullBuild(t *testing.T) {
 	doKitFullBuild(t, "timer-to-log", "8m0s", TestTimeoutLong, kitOptions{
 		dependencies: []string{
diff --git a/e2e/common/traits/builder_test.go b/e2e/common/traits/builder_test.go
index d940aad83..26b39c035 100644
--- a/e2e/common/traits/builder_test.go
+++ b/e2e/common/traits/builder_test.go
@@ -63,6 +63,32 @@ func TestBuilderTrait(t *testing.T) {
 		Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed())
 	})
 
+	t.Run("Run build order strategy dependencies", func(t *testing.T) {
+		name := "java-fifo-strategy"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			"-t", "builder.order-strategy=dependencies").Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		integrationKitName := IntegrationKit(ns, name)()
+		builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName)
+		Eventually(BuildConfig(ns, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine))
+		Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyDependencies))
+		// Default resource CPU Check
+		Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal(""))
+		Eventually(BuildConfig(ns, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal(""))
+
+		Eventually(BuilderPod(ns, builderKitName), TestTimeoutShort).Should(BeNil())
+
+		// We need to remove the kit as well
+		Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed())
+	})
+
 	t.Run("Run build order strategy fifo", func(t *testing.T) {
 		name := "java-fifo-strategy"
 		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
diff --git a/e2e/commonwithcustominstall/build_order_strategy_test.go b/e2e/commonwithcustominstall/build_order_strategy_test.go
new file mode 100644
index 000000000..529ad5e7d
--- /dev/null
+++ b/e2e/commonwithcustominstall/build_order_strategy_test.go
@@ -0,0 +1,175 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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 commonwithcustominstall
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/v2/e2e/support"
+	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/v2/pkg/util/defaults"
+)
+
+func TestRunBuildOrderStrategyMatchingDependencies(t *testing.T) {
+	WithNewTestNamespace(t, func(ns string) {
+		operatorID := "camel-k-build-order-deps"
+		Expect(KamelInstallWithID(operatorID, ns, "--build-order-strategy", string(v1.BuildOrderStrategyDependencies)).Execute()).To(Succeed())
+		Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
+
+		Expect(CreateTimerKamelet(ns, "timer-source")()).To(Succeed())
+
+		integrationA := "java-a"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", integrationA,
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationKit(ns, integrationA), TestTimeoutMedium).ShouldNot(BeEmpty())
+		integrationKitNameA := IntegrationKit(ns, integrationA)()
+		Eventually(Build(ns, integrationKitNameA), TestTimeoutMedium).ShouldNot(BeNil())
+
+		integrationB := "java-b"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", integrationB,
+			"-d", "camel:joor",
+		).Execute()).To(Succeed())
+
+		integrationC := "java-c"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", integrationC,
+			"-d", "camel:joor",
+			"-d", "camel:zipfile",
+		).Execute()).To(Succeed())
+
+		integrationZ := "groovy-z"
+		Expect(KamelRunWithID(operatorID, ns, "files/timer-source.groovy",
+			"--name", integrationZ,
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationKit(ns, integrationB), TestTimeoutMedium).ShouldNot(BeEmpty())
+		Eventually(IntegrationKit(ns, integrationC), TestTimeoutMedium).ShouldNot(BeEmpty())
+		Eventually(IntegrationKit(ns, integrationZ), TestTimeoutMedium).ShouldNot(BeEmpty())
+
+		integrationKitNameB := IntegrationKit(ns, integrationB)()
+		integrationKitNameC := IntegrationKit(ns, integrationC)()
+		integrationKitNameZ := IntegrationKit(ns, integrationZ)()
+
+		Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
+
+		Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameB)().Status.BaseImage).Should(ContainSubstring(integrationKitNameA))
+
+		Eventually(BuildPhase(ns, integrationKitNameC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationC), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationC, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationC), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameC)().Status.BaseImage).Should(ContainSubstring(integrationKitNameB))
+
+		Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
+
+		buildA := Build(ns, integrationKitNameA)()
+		buildB := Build(ns, integrationKitNameB)()
+		buildC := Build(ns, integrationKitNameC)()
+		buildZ := Build(ns, integrationKitNameZ)()
+
+		Expect(buildA.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue())
+		Expect(buildA.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue())
+		Expect(buildB.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue())
+		Expect(buildZ.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue())
+		Expect(buildZ.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+}
+
+func TestRunBuildOrderStrategyFIFO(t *testing.T) {
+	WithNewTestNamespace(t, func(ns string) {
+		operatorID := "camel-k-build-order-fifo"
+		Expect(KamelInstallWithID(operatorID, ns, "--build-order-strategy", string(v1.BuildOrderStrategyFIFO)).Execute()).To(Succeed())
+		Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
+
+		Expect(CreateTimerKamelet(ns, "timer-source")()).To(Succeed())
+
+		integrationA := "java-a"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", integrationA,
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPhase(ns, integrationA)).Should(Equal(v1.IntegrationPhaseBuildingKit))
+
+		integrationB := "java-b"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", integrationB,
+			"-d", "camel:joor",
+		).Execute()).To(Succeed())
+
+		integrationZ := "groovy-z"
+		Expect(KamelRunWithID(operatorID, ns, "files/timer-source.groovy",
+			"--name", integrationZ,
+		).Execute()).To(Succeed())
+
+		integrationKitNameA := IntegrationKit(ns, integrationA)()
+		Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning))
+
+		Eventually(IntegrationPhase(ns, integrationB)).Should(Equal(v1.IntegrationPhaseBuildingKit))
+		integrationKitNameB := IntegrationKit(ns, integrationB)()
+		Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning))
+
+		Eventually(IntegrationPhase(ns, integrationZ)).Should(Equal(v1.IntegrationPhaseBuildingKit))
+		integrationKitNameZ := IntegrationKit(ns, integrationZ)()
+		Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning))
+
+		Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
+
+		Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameB)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
+
+		Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+		Eventually(IntegrationPodPhase(ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(Kit(ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+}
diff --git a/e2e/commonwithcustominstall/files/timer-source.groovy b/e2e/commonwithcustominstall/files/timer-source.groovy
new file mode 100644
index 000000000..9c2901ba2
--- /dev/null
+++ b/e2e/commonwithcustominstall/files/timer-source.groovy
@@ -0,0 +1,20 @@
+// camel-k: language=groovy
+/*
+ * 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.
+ */
+
+from('kamelet:timer-source?message=Magicstring!&period=3000')
+    .to('log:info?showAll=false')
diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml
index 44ee86332..f7947276d 100644
--- a/helm/camel-k/crds/crd-build.yaml
+++ b/helm/camel-k/crds/crd-build.yaml
@@ -100,6 +100,7 @@ spec:
                   orderStrategy:
                     description: the build order strategy to adopt
                     enum:
+                    - dependencies
                     - fifo
                     - sequential
                     type: string
@@ -215,6 +216,7 @@ spec:
                             orderStrategy:
                               description: the build order strategy to adopt
                               enum:
+                              - dependencies
                               - fifo
                               - sequential
                               type: string
diff --git a/helm/camel-k/crds/crd-integration-kit.yaml b/helm/camel-k/crds/crd-integration-kit.yaml
index 39fccd088..c86813bc5 100644
--- a/helm/camel-k/crds/crd-integration-kit.yaml
+++ b/helm/camel-k/crds/crd-integration-kit.yaml
@@ -212,8 +212,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml
index 1d716f3e6..6f3b9d984 100644
--- a/helm/camel-k/crds/crd-integration-platform.yaml
+++ b/helm/camel-k/crds/crd-integration-platform.yaml
@@ -119,6 +119,7 @@ spec:
                       orderStrategy:
                         description: the build order strategy to adopt
                         enum:
+                        - dependencies
                         - fifo
                         - sequential
                         type: string
@@ -469,8 +470,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
@@ -1766,6 +1767,7 @@ spec:
                       orderStrategy:
                         description: the build order strategy to adopt
                         enum:
+                        - dependencies
                         - fifo
                         - sequential
                         type: string
@@ -2164,8 +2166,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index 6106dc086..8f460495d 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -6195,8 +6195,8 @@ spec:
                           of memory required by the pod builder.
                         type: string
                       orderStrategy:
-                        description: The build order strategy to use, either `fifo`
-                          or `sequential` (default sequential)
+                        description: The build order strategy to use, either `dependencies`,
+                          `fifo` or `sequential` (default sequential)
                         type: string
                       properties:
                         description: A list of properties to be provided to the build
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 2ffcbaff3..ef1cdf18e 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -6470,8 +6470,8 @@ spec:
                               of memory required by the pod builder.
                             type: string
                           orderStrategy:
-                            description: The build order strategy to use, either `fifo`
-                              or `sequential` (default sequential)
+                            description: The build order strategy to use, either `dependencies`,
+                              `fifo` or `sequential` (default sequential)
                             type: string
                           properties:
                             description: A list of properties to be provided to the
diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml
index 4da7c6ade..bc442ac3a 100644
--- a/helm/camel-k/crds/crd-pipe.yaml
+++ b/helm/camel-k/crds/crd-pipe.yaml
@@ -6467,8 +6467,8 @@ spec:
                               of memory required by the pod builder.
                             type: string
                           orderStrategy:
-                            description: The build order strategy to use, either `fifo`
-                              or `sequential` (default sequential)
+                            description: The build order strategy to use, either `dependencies`,
+                              `fifo` or `sequential` (default sequential)
                             type: string
                           properties:
                             description: A list of properties to be provided to the
diff --git a/pkg/apis/camel/v1/build_types_support.go b/pkg/apis/camel/v1/build_types_support.go
index 8c05f66e7..396997fa1 100644
--- a/pkg/apis/camel/v1/build_types_support.go
+++ b/pkg/apis/camel/v1/build_types_support.go
@@ -60,6 +60,25 @@ func (build *Build) BuilderConfiguration() *BuildConfiguration {
 
 }
 
+// BuilderDependencies returns the list of dependencies configured on by the builder task for this Build.
+func (build *Build) BuilderDependencies() []string {
+	if builder, ok := FindBuilderTask(build.Spec.Tasks); ok {
+		return builder.Dependencies
+	}
+
+	return []string{}
+}
+
+// FindBuilderTask returns the 1st builder task from the task list.
+func FindBuilderTask(tasks []Task) (*BuilderTask, bool) {
+	for _, t := range tasks {
+		if t.Builder != nil {
+			return t.Builder, true
+		}
+	}
+	return nil, false
+}
+
 // BuilderConfigurationTasks returns the builder configuration from the task list.
 func BuilderConfigurationTasks(tasks []Task) *BuildConfiguration {
 	for _, t := range tasks {
@@ -106,6 +125,11 @@ func (in *BuildStatus) Failed(err error) BuildStatus {
 	return *in
 }
 
+func (in *BuildStatus) IsFinished() bool {
+	return in.Phase == BuildPhaseSucceeded || in.Phase == BuildPhaseFailed ||
+		in.Phase == BuildPhaseInterrupted || in.Phase == BuildPhaseError
+}
+
 func (in *BuildStatus) SetCondition(condType BuildConditionType, status corev1.ConditionStatus, reason string, message string) {
 	in.SetConditions(BuildCondition{
 		Type:               condType,
@@ -212,7 +236,7 @@ func (bl BuildList) HasRunningBuilds() bool {
 	return false
 }
 
-func (bl BuildList) HasScheduledBuildsBefore(build *Build) bool {
+func (bl BuildList) HasScheduledBuildsBefore(build *Build) (bool, *Build) {
 	for _, b := range bl.Items {
 		if b.Name == build.Name {
 			continue
@@ -220,9 +244,65 @@ func (bl BuildList) HasScheduledBuildsBefore(build *Build) bool {
 
 		if (b.Status.Phase == BuildPhaseInitialization || b.Status.Phase == BuildPhaseScheduling) &&
 			b.CreationTimestamp.Before(&build.CreationTimestamp) {
-			return true
+			return true, &b
 		}
 	}
 
-	return false
+	return false, nil
+}
+
+// HasMatchingBuild visit all items in the list of builds and search for a scheduled build that matches the given build's dependencies.
+func (bl BuildList) HasMatchingBuild(build *Build) (bool, *Build) {
+	required := build.BuilderDependencies()
+	if len(required) == 0 {
+		return false, nil
+	}
+
+	for _, b := range bl.Items {
+		if b.Name == build.Name || b.Status.IsFinished() {
+			continue
+		}
+
+		dependencies := b.BuilderDependencies()
+		dependencyMap := make(map[string]int, len(dependencies))
+		for i, item := range dependencies {
+			dependencyMap[item] = i
+		}
+
+		allMatching := true
+		missing := 0
+		for _, item := range required {
+			if _, ok := dependencyMap[item]; !ok {
+				allMatching = false
+				missing++
+			}
+		}
+
+		// Heuristic approach: if there are too many unrelated libraries then this image is
+		// not suitable to be used as base image
+		if !allMatching && missing >= len(required)/2 {
+			continue
+		}
+
+		// handle suitable build that has started already
+		if b.Status.Phase == BuildPhasePending || b.Status.Phase == BuildPhaseRunning {
+			return true, &b
+		}
+
+		// handle suitable scheduled build
+		if b.Status.Phase == BuildPhaseInitialization || b.Status.Phase == BuildPhaseScheduling {
+			if allMatching && len(required) == len(dependencies) {
+				// seems like both builds require exactly the same list of dependencies
+				// additionally check for the creation timestamp
+				if b.CreationTimestamp.Before(&build.CreationTimestamp) {
+					return true, &b
+				}
+			} else if missing > 0 {
+				// found another suitable scheduled build with fewer dependencies that should build first in order to reuse the produced image
+				return true, &b
+			}
+		}
+	}
+
+	return false, nil
 }
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 979cd2a87..e535e45bb 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -76,6 +76,10 @@ const (
 	// BuildOrderStrategyFIFO performs the builds with first in first out strategy based on the creation timestamp.
 	// The strategy allows builds to run in parallel to each other but oldest builds will be run first.
 	BuildOrderStrategyFIFO BuildOrderStrategy = "fifo"
+	// BuildOrderStrategyDependencies runs builds ordered by its required dependencies.
+	// Strategy looks at the list of dependencies required by an Integration and queues builds that may reuse base images produced by other
+	// scheduled builds in order to leverage the incremental build option. The strategy allows non-matching builds to run in parallel to each other.
+	BuildOrderStrategyDependencies BuildOrderStrategy = "dependencies"
 	// BuildOrderStrategySequential runs builds strictly sequential so that only one single build per operator namespace is running at a time.
 	BuildOrderStrategySequential BuildOrderStrategy = "sequential"
 )
@@ -87,12 +91,13 @@ var BuildStrategies = []BuildStrategy{
 }
 
 // BuildOrderStrategy specifies how builds are reconciled and queued.
-// +kubebuilder:validation:Enum=fifo;sequential
+// +kubebuilder:validation:Enum=dependencies;fifo;sequential
 type BuildOrderStrategy string
 
 // BuildOrderStrategies is a list of order strategies allowed for the build
 var BuildOrderStrategies = []BuildOrderStrategy{
 	BuildOrderStrategyFIFO,
+	BuildOrderStrategyDependencies,
 	BuildOrderStrategySequential,
 }
 
diff --git a/pkg/apis/camel/v1/trait/builder.go b/pkg/apis/camel/v1/trait/builder.go
index 86e682ab3..044b9a39c 100644
--- a/pkg/apis/camel/v1/trait/builder.go
+++ b/pkg/apis/camel/v1/trait/builder.go
@@ -29,7 +29,7 @@ type BuilderTrait struct {
 	Properties []string `property:"properties" json:"properties,omitempty"`
 	// The strategy to use, either `pod` or `routine` (default routine)
 	Strategy string `property:"strategy" json:"strategy,omitempty"`
-	// The build order strategy to use, either `fifo` or `sequential` (default sequential)
+	// The build order strategy to use, either `dependencies`, `fifo` or `sequential` (default sequential)
 	OrderStrategy string `property:"order-strategy" json:"orderStrategy,omitempty"`
 	// When using `pod` strategy, the minimum amount of CPU required by the pod builder.
 	RequestCPU string `property:"request-cpu" json:"requestCPU,omitempty"`
diff --git a/pkg/controller/build/build_monitor.go b/pkg/controller/build/build_monitor.go
index a60ce1b3a..44c1fcff5 100644
--- a/pkg/controller/build/build_monitor.go
+++ b/pkg/controller/build/build_monitor.go
@@ -19,6 +19,7 @@ package build
 
 import (
 	"context"
+	"fmt"
 	"sync"
 
 	"k8s.io/apimachinery/pkg/labels"
@@ -54,7 +55,7 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
 
 	if runningBuildsTotal >= bm.maxRunningBuilds {
 		Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "max-running-builds-limit", runningBuildsTotal).
-			ForBuild(build).Infof("Maximum number of running builds (%d) exceeded - the build gets enqueued", runningBuildsTotal)
+			ForBuild(build).Infof("Maximum number of running builds (%d) exceeded - the build (%s) gets enqueued", runningBuildsTotal, build.Name)
 
 		// max number of running builds limit exceeded
 		return false, nil
@@ -85,21 +86,39 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
 		return false, err
 	}
 
-	var allowed bool
+	var reason string
+	allowed := true
 	switch bm.buildOrderStrategy {
 	case v1.BuildOrderStrategyFIFO:
 		// Check on builds that have been created before the current build and grant precedence if any.
-		allowed = !builds.HasScheduledBuildsBefore(build)
+		if hasScheduledBuildsBefore, otherBuild := builds.HasScheduledBuildsBefore(build); hasScheduledBuildsBefore {
+			reason = fmt.Sprintf("Waiting for build (%s) because it has been created before", otherBuild.Name)
+			allowed = false
+		}
+	case v1.BuildOrderStrategyDependencies:
+		// Check on the Integration dependencies and see if we should queue the build in order to leverage incremental builds
+		// because there is already another build in the making that matches the requirements
+		if hasMatchingBuild, otherBuild := builds.HasMatchingBuild(build); hasMatchingBuild {
+			reason = fmt.Sprintf("Waiting for build (%s) to finish in order to use incremental image builds", otherBuild.Name)
+			allowed = false
+		}
 	case v1.BuildOrderStrategySequential:
 		// Emulate a serialized working queue to only allow one build to run at a given time.
 		// Let's requeue the build in case one is already running
-		allowed = !builds.HasRunningBuilds()
+		if hasRunningBuilds := builds.HasRunningBuilds(); hasRunningBuilds {
+			reason = "Found a running build in this namespace"
+			allowed = false
+		}
 	default:
-		Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "order-strategy", bm.buildOrderStrategy).
-			ForBuild(build).Infof("Unsupported build order strategy (%s) - the build gets enqueued", bm.buildOrderStrategy)
+		reason = fmt.Sprintf("Unsupported build order strategy (%s)", bm.buildOrderStrategy)
 		allowed = false
 	}
 
+	if !allowed {
+		Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "order-strategy", bm.buildOrderStrategy).
+			ForBuild(build).Infof("%s - the build (%s) gets enqueued", reason, build.Name)
+	}
+
 	return allowed, nil
 }
 
diff --git a/pkg/controller/build/build_monitor_test.go b/pkg/controller/build/build_monitor_test.go
index b44cd0533..1cde7301e 100644
--- a/pkg/controller/build/build_monitor_test.go
+++ b/pkg/controller/build/build_monitor_test.go
@@ -352,6 +352,219 @@ func TestMonitorFIFOBuilds(t *testing.T) {
 	}
 }
 
+func TestMonitorDependencyMatchingBuilds(t *testing.T) {
+	deps := []string{"camel:core", "camel:timer", "camel:log", "mvn:org.apache.camel.k:camel-k-runtime"}
+
+	testcases := []struct {
+		name    string
+		running []*v1.Build
+		builds  []*v1.Build
+		build   *v1.Build
+		allowed bool
+	}{
+		{
+			name:    "allowNewBuild",
+			running: []*v1.Build{},
+			builds:  []*v1.Build{},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name:    "allowNewNativeBuild",
+			running: []*v1.Build{},
+			builds:  []*v1.Build{},
+			build:   newNativeBuild("ns1", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name:    "allowNewBuildWhenOthersFinished",
+			running: []*v1.Build{},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-failed", v1.BuildPhaseFailed, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name:    "allowNewNativeBuildWhenOthersFinished",
+			running: []*v1.Build{},
+			builds: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newNativeBuildInPhase("ns", "my-build-failed", v1.BuildPhaseFailed, deps...),
+			},
+			build:   newNativeBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name: "limitMaxRunningBuilds",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+				newBuild("another-ns", "my-build-3", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: false,
+		},
+		{
+			name: "limitMaxRunningNativeBuilds",
+			running: []*v1.Build{
+				newBuildInPhase("some-ns", "my-build-1", v1.BuildPhaseRunning, deps...),
+				newNativeBuildInPhase("other-ns", "my-build-2", v1.BuildPhaseRunning, deps...),
+				newNativeBuildInPhase("another-ns", "my-build-3", v1.BuildPhaseRunning, deps...),
+			},
+			builds: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+			},
+			build:   newNativeBuildInPhase("ns", "my-build", v1.BuildPhaseInitialization, deps...),
+			allowed: false,
+		},
+		{
+			name: "allowParallelBuildsWithDifferentLayout",
+			running: []*v1.Build{
+				newNativeBuildInPhase("ns", "my-build-1", v1.BuildPhaseRunning, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name: "allowParallelBuildsInSameNamespaceWithTooManyMissingDependencies",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("other-ns", "my-build-new", v1.BuildPhaseScheduling, deps...),
+			},
+			build:   newBuild("ns", "my-build", append(deps, "camel:test", "camel:foo")...),
+			allowed: true,
+		},
+		{
+			name: "allowParallelBuildsInSameNamespaceWithLessDependencies",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-scheduled", v1.BuildPhaseScheduling, append(deps, "camel:test")...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+		{
+			name: "queueBuildWhenSuitableBuildHasOnlyOneSingleMissingDependency",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-new", v1.BuildPhaseScheduling, deps...),
+			},
+			build:   newBuild("ns", "my-build", append(deps, "camel:test")...),
+			allowed: false,
+		},
+		{
+			name: "queueBuildWhenSuitableBuildIsAlreadyRunning",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-running", v1.BuildPhaseRunning, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: false,
+		},
+		{
+			name: "queueBuildWhenSuitableBuildIsAlreadyPending",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-pending", v1.BuildPhasePending, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: false,
+		},
+		{
+			name: "queueBuildWhenSuitableBuildWithSupersetDependenciesIsAlreadyRunning",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-running", v1.BuildPhaseRunning, append(deps, "camel:test")...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: false,
+		},
+		{
+			name: "queueBuildWhenSuitableBuildWithSameDependenciesIsAlreadyScheduled",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+				newBuildInPhase("ns", "my-build-existing", v1.BuildPhaseScheduling, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: false,
+		},
+		{
+			name: "allowBuildsInNewNamespace",
+			running: []*v1.Build{
+				newBuild("some-ns", "my-build-1", deps...),
+				newBuild("other-ns", "my-build-2", deps...),
+			},
+			builds: []*v1.Build{
+				newBuildInPhase("ns", "my-build-x", v1.BuildPhaseSucceeded, deps...),
+			},
+			build:   newBuild("ns", "my-build", deps...),
+			allowed: true,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			var initObjs []runtime.Object
+			for _, build := range append(tc.running, tc.builds...) {
+				initObjs = append(initObjs, build)
+			}
+
+			c, err := test.NewFakeClient(initObjs...)
+
+			assert.Nil(t, err)
+
+			bm := Monitor{
+				maxRunningBuilds:   3,
+				buildOrderStrategy: v1.BuildOrderStrategyDependencies,
+			}
+
+			// reset running builds in memory cache
+			cleanRunningBuildsMonitor()
+			for _, build := range tc.running {
+				monitorRunningBuild(build)
+			}
+
+			allowed, err := bm.canSchedule(context.TODO(), c, tc.build)
+
+			assert.Nil(t, err)
+			assert.Equal(t, tc.allowed, allowed)
+		})
+	}
+}
+
 func cleanRunningBuildsMonitor() {
 	runningBuilds.Range(func(key interface{}, v interface{}) bool {
 		runningBuilds.Delete(key)
@@ -359,23 +572,23 @@ func cleanRunningBuildsMonitor() {
 	})
 }
 
-func newBuild(namespace string, name string) *v1.Build {
-	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutFastJar, v1.BuildPhasePending)
+func newBuild(namespace string, name string, dependencies ...string) *v1.Build {
+	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutFastJar, v1.BuildPhasePending, dependencies...)
 }
 
-func newNativeBuild(namespace string, name string) *v1.Build {
-	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutNative, v1.BuildPhasePending)
+func newNativeBuild(namespace string, name string, dependencies ...string) *v1.Build {
+	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutNative, v1.BuildPhasePending, dependencies...)
 }
 
-func newBuildInPhase(namespace string, name string, phase v1.BuildPhase) *v1.Build {
-	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutFastJar, phase)
+func newBuildInPhase(namespace string, name string, phase v1.BuildPhase, dependencies ...string) *v1.Build {
+	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutFastJar, phase, dependencies...)
 }
 
-func newNativeBuildInPhase(namespace string, name string, phase v1.BuildPhase) *v1.Build {
-	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutNative, phase)
+func newNativeBuildInPhase(namespace string, name string, phase v1.BuildPhase, dependencies ...string) *v1.Build {
+	return newBuildWithLayoutInPhase(namespace, name, v1.IntegrationKitLayoutNative, phase, dependencies...)
 }
 
-func newBuildWithLayoutInPhase(namespace string, name string, layout string, phase v1.BuildPhase) *v1.Build {
+func newBuildWithLayoutInPhase(namespace string, name string, layout string, phase v1.BuildPhase, dependencies ...string) *v1.Build {
 	return &v1.Build{
 		TypeMeta: metav1.TypeMeta{
 			APIVersion: v1.SchemeGroupVersion.String(),
@@ -399,6 +612,7 @@ func newBuildWithLayoutInPhase(namespace string, name string, layout string, pha
 							ToolImage:           "camel:latest",
 							BuilderPodNamespace: "ns",
 						},
+						Dependencies: dependencies,
 					},
 				},
 			},
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 582168091..7b1b35409 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -117,9 +117,9 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_builds.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_builds.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 44653,
+			uncompressedSize: 44733,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb5\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x6a\xbd\xb9\x23\x5e\x6c\x71\xf0\xd1\xdd\x68\xf4\x17\x1a\xc0\x29\x8c\x0e\x57\x4e\x4e\xe1\x1d\x4f\x50\x68\x4c\xc1\x48\x30\x0b\x84\xab\x82\x25\x0b\x84\x89\x9c\x99\x15\x53\x08\x6f\x64\x29\x52\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb5\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x6a\xbd\xb9\x23\x5e\x6c\x71\xf0\xd1\xdd\xe8\x2f\x34\x1a\xc0\x29\x8c\x0e\x57\x4e\x4e\xe1\x1d\x4f\x50\x68\x4c\xc1\x48\x30\x0b\x84\xab\x82\x25\x0b\x84\x89\x9c\x99\x15\x53\x08\x6f\x64\x29\x52\x [...]
 		},
 		"/crd/bases/camel.apache.org_camelcatalogs.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_camelcatalogs.yaml",
@@ -131,30 +131,30 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_integrationkits.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrationkits.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 20753,
+			uncompressedSize: 20769,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7c\x5f\x6f\xdb\xb8\x96\xf8\xbb\x3f\xc5\x41\xf3\xd0\x04\xb0\x9d\x3b\xbf\xdf\x60\xb0\xc8\xbd\x7b\x81\xdc\xb4\x9d\x1b\x34\x6d\xb3\x75\x3a\xb3\x03\xcc\x43\x8e\xa5\x63\x9b\x63\x89\xd4\x90\x94\x1d\xef\x62\xbf\xfb\x82\x87\xa4\x2c\xdb\x92\xac\x3a\xcd\xee\x3e\x54\x2f\xad\x25\xf2\xf0\xfc\xff\x43\x1e\xe6\x0c\x46\xdf\xee\x19\x9c\xc1\x9d\x48\x48\x1a\x4a\xc1\x2a\xb0\x0b\x82\xeb\x02\x93\x05\xc1\x44\xcd\xec\x1a\x35\xc1\x3b\x55\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7c\x5f\x6f\xdb\xb8\x96\xf8\xbb\x3f\xc5\x41\xf3\xd0\x04\xb0\x9d\x3b\xbf\xdf\x60\xb0\xc8\xbd\x7b\x81\xdc\xb4\x9d\x1b\x34\x6d\xb3\x75\x3a\xb3\x03\xcc\x43\x8e\xa5\x63\x9b\x63\x89\xd4\x90\x94\x1d\xef\x62\xbf\xfb\x82\x87\xa4\x2c\xdb\x92\xac\x3a\xcd\xee\x3e\x54\x2f\xad\x25\xf2\xf0\xfc\xff\x43\x1e\xe6\x0c\x46\xdf\xee\x19\x9c\xc1\x9d\x48\x48\x1a\x4a\xc1\x2a\xb0\x0b\x82\xeb\x02\x93\x05\xc1\x44\xcd\xec\x1a\x35\xc1\x3b\x55\x [...]
 		},
 		"/crd/bases/camel.apache.org_integrationplatforms.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrationplatforms.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 182959,
+			uncompressedSize: 183069,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x [...]
 		},
 		"/crd/bases/camel.apache.org_integrations.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_integrations.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 496157,
+			uncompressedSize: 496173,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x [...]
 		},
 		"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_kameletbindings.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 575952,
+			uncompressedSize: 575968,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x [...]
 		},
 		"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_kamelets.yaml",
@@ -166,9 +166,9 @@ var assets = func() http.FileSystem {
 		"/crd/bases/camel.apache.org_pipes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "camel.apache.org_pipes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 543220,
+			uncompressedSize: 543236,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x [...]
 		},
 		"/manager": &vfsgen۰DirInfo{
 			name:    "manager",
@@ -625,9 +625,9 @@ var assets = func() http.FileSystem {
 		"/traits.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "traits.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 66891,
+			uncompressedSize: 66907,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x [...]
 		},
 	}
 	fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
diff --git a/resources/traits.yaml b/resources/traits.yaml
index af06f964c..8be71a81d 100755
--- a/resources/traits.yaml
+++ b/resources/traits.yaml
@@ -214,8 +214,8 @@ traits:
     description: The strategy to use, either `pod` or `routine` (default routine)
   - name: order-strategy
     type: string
-    description: The build order strategy to use, either `fifo` or `sequential` (default
-      sequential)
+    description: The build order strategy to use, either `dependencies`, `fifo` or
+      `sequential` (default sequential)
   - name: request-cpu
     type: string
     description: When using `pod` strategy, the minimum amount of CPU required by