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) +}
