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

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

commit 4d7fd196cc494e48d23182d4799fe8b569051eb1
Author: Pranjul Kalsi <[email protected]>
AuthorDate: Sat Dec 13 00:40:43 2025 +0530

    feat(ctrl): dry build - support Pipe BuildComplete phase
---
 e2e/common/cli/deploy_test.go       | 21 ++++++++++++++++++
 pkg/apis/camel/v1/pipe_types.go     |  2 ++
 pkg/controller/pipe/monitor.go      | 13 ++++++++++-
 pkg/controller/pipe/monitor_test.go | 44 +++++++++++++++++++++++++++++++++++++
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/e2e/common/cli/deploy_test.go b/e2e/common/cli/deploy_test.go
index 88f407fcf..4f7a907b5 100644
--- a/e2e/common/cli/deploy_test.go
+++ b/e2e/common/cli/deploy_test.go
@@ -68,3 +68,24 @@ func TestBuildDontRun(t *testing.T) {
                })
        })
 }
+
+func TestPipeBuildDontRun(t *testing.T) {
+       t.Parallel()
+       WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) {
+               name := RandomizedSuffixName("pipe-deploy")
+               t.Run("build and dont run pipe", func(t *testing.T) {
+                       g.Expect(KamelBind(t, ctx, ns, 
"timer-source?message=HelloPipe", "log-sink",
+                               "--name", name,
+                               "--annotation", 
"camel.apache.org/dont-run-after-build=true",
+                       ).Execute()).To(Succeed())
+                       g.Eventually(IntegrationPhase(t, ctx, ns, name), 
TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseBuildComplete))
+                       g.Eventually(PipePhase(t, ctx, ns, name), 
TestTimeoutMedium).Should(Equal(v1.PipePhaseBuildComplete))
+                       g.Consistently(IntegrationPhase(t, ctx, ns, name), 
10*time.Second).Should(Equal(v1.IntegrationPhaseBuildComplete))
+                       g.Consistently(PipePhase(t, ctx, ns, name), 
10*time.Second).Should(Equal(v1.PipePhaseBuildComplete))
+                       g.Eventually(Deployment(t, ctx, ns, 
name)).Should(BeNil())
+                       // Pipe condition should indicate build is complete
+                       g.Eventually(PipeCondition(t, ctx, ns, name, 
v1.PipeConditionReady), TestTimeoutShort).Should(
+                               WithTransform(PipeConditionReason, 
Equal("BuildComplete")))
+               })
+       })
+}
diff --git a/pkg/apis/camel/v1/pipe_types.go b/pkg/apis/camel/v1/pipe_types.go
index a61eca0ce..ccdb7ff19 100644
--- a/pkg/apis/camel/v1/pipe_types.go
+++ b/pkg/apis/camel/v1/pipe_types.go
@@ -159,6 +159,8 @@ const (
        PipePhaseError PipePhase = "Error"
        // PipePhaseReady --.
        PipePhaseReady PipePhase = "Ready"
+       // PipePhaseBuildComplete --.
+       PipePhaseBuildComplete PipePhase = "Build Complete"
 )
 
 // +kubebuilder:object:root=true
diff --git a/pkg/controller/pipe/monitor.go b/pkg/controller/pipe/monitor.go
index 8d16d4aa7..f75e5af7d 100644
--- a/pkg/controller/pipe/monitor.go
+++ b/pkg/controller/pipe/monitor.go
@@ -48,7 +48,8 @@ func (action *monitorAction) Name() string {
 func (action *monitorAction) CanHandle(pipe *v1.Pipe) bool {
        return pipe.Status.Phase == v1.PipePhaseCreating ||
                pipe.Status.Phase == v1.PipePhaseError ||
-               pipe.Status.Phase == v1.PipePhaseReady
+               pipe.Status.Phase == v1.PipePhaseReady ||
+               pipe.Status.Phase == v1.PipePhaseBuildComplete
 }
 
 func (action *monitorAction) Handle(ctx context.Context, pipe *v1.Pipe) 
(*v1.Pipe, error) {
@@ -128,6 +129,16 @@ func (action *monitorAction) Handle(ctx context.Context, 
pipe *v1.Pipe) (*v1.Pip
                target.Status.Phase = v1.PipePhaseError
                setPipeReadyCondition(target, &it)
 
+       case v1.IntegrationPhaseBuildComplete:
+               target.Status.Phase = v1.PipePhaseBuildComplete
+               c := v1.PipeCondition{
+                       Type:    v1.PipeConditionReady,
+                       Status:  corev1.ConditionFalse,
+                       Reason:  "BuildComplete",
+                       Message: fmt.Sprintf("Integration %q build completed 
successfully", it.GetName()),
+               }
+               target.Status.SetConditions(c)
+
        default:
                target.Status.Phase = v1.PipePhaseCreating
 
diff --git a/pkg/controller/pipe/monitor_test.go 
b/pkg/controller/pipe/monitor_test.go
index 543a918f9..ba2269b2b 100644
--- a/pkg/controller/pipe/monitor_test.go
+++ b/pkg/controller/pipe/monitor_test.go
@@ -376,3 +376,47 @@ func TestPipeIntegrationPipeTraitAnnotations(t *testing.T) 
{
        assert.Equal(t, corev1.ConditionFalse, 
handledPipe.Status.GetCondition(v1.PipeConditionReady).Status)
        assert.Equal(t, "Integration \"my-pipe\" is in \"Creating\" phase", 
handledPipe.Status.GetCondition(v1.PipeConditionReady).Message)
 }
+
+func TestPipeIntegrationBuildComplete(t *testing.T) {
+       pipe := &v1.Pipe{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.PipeKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-pipe",
+               },
+               Spec: v1.PipeSpec{
+                       Source: v1.Endpoint{
+                               URI: ptr.To("timer:tick"),
+                       },
+                       Sink: v1.Endpoint{
+                               URI: ptr.To("log:info"),
+                       },
+               },
+               Status: v1.PipeStatus{
+                       Phase: v1.PipePhaseCreating,
+               },
+       }
+
+       c, err := internal.NewFakeClient(pipe)
+       require.NoError(t, err)
+       it, err := CreateIntegrationFor(context.TODO(), c, pipe)
+       require.NoError(t, err)
+       it.Status.Phase = v1.IntegrationPhaseBuildComplete
+       c, err = internal.NewFakeClient(pipe, it)
+       require.NoError(t, err)
+
+       a := NewMonitorAction()
+       a.InjectLogger(log.Log)
+       a.InjectClient(c)
+       assert.Equal(t, "monitor", a.Name())
+       assert.True(t, a.CanHandle(pipe))
+       handledPipe, err := a.Handle(context.TODO(), pipe)
+       require.NoError(t, err)
+       assert.Equal(t, v1.PipePhaseBuildComplete, handledPipe.Status.Phase)
+       assert.Equal(t, corev1.ConditionFalse, 
handledPipe.Status.GetCondition(v1.PipeConditionReady).Status)
+       assert.Equal(t, "BuildComplete", 
handledPipe.Status.GetCondition(v1.PipeConditionReady).Reason)
+       assert.Equal(t, "Integration \"my-pipe\" build completed successfully", 
handledPipe.Status.GetCondition(v1.PipeConditionReady).Message)
+}

Reply via email to