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:28:00 UTC

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

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