Repository: kubeflow/kfp-tekton (language: python)

Issue:
[KFP-Tekton v2] Merge DAG drivers and publishers into a sub-dag controller to reduce Tekton graph complexity.
/kind feature

**Description:**
When adding driver and publisher tasks into the sub-dag, we are introducing a new layer of complexity to the Tekton graph because the driver needs to connect with all the root nodes and publisher needs to connect with all the leave node. Because driver always runs before the main sub-dag(pipelinerun in Tekton) and publisher runs after the sub-dag is done, we can have our controller handles those logic instead of embedding drivers and publishers into the Tekton pipeline graph.

This will require we implement the status-IR first as right now we don't have a way to update sub-dag and root dag pipeline status in MLMD and reflect them on the UI.


<img width="1158" alt="Screenshot 2023-11-22 at 9 27 59 AM" src="https://github.com/kubeflow/kfp-tekton/assets/10889249/bf577411-89b3-41b4-82bc-281b5c33e138">


**Additional information:**
[Miscellaneous information that will assist in solving the issue.]



Discussion / hints:

Fix patch:
diff --git a/backend/src/v2/compiler/tektoncompiler/container.go b/backend/src/v2/compiler/tektoncompiler/container.go
index 2c6fb094f6..4c7505c8d9 100644
--- a/backend/src/v2/compiler/tektoncompiler/container.go
+++ b/backend/src/v2/compiler/tektoncompiler/container.go
@@ -189,6 +189,7 @@ func (c *pipelinerunCompiler) Container(taskName, compRef string,
 		containerDef:     container,
 		exitHandler:      exitHandler,
 		kubernetesConfig: kubernetesConfigPlaceholder,
+		inLoopDag:        c.HasLoopName(c.CurrentDag()),
 	})
 }
 
@@ -211,6 +212,7 @@ type containerDriverInputs struct {
 	iterationIndex   string // optional, when this is an iteration task
 	exitHandler      bool
 	kubernetesConfig string
+	inLoopDag        bool
 }
 
 func (i *containerDriverInputs) getParentDagID(isExitHandler bool) string {
@@ -219,6 +221,8 @@ func (i *containerDriverInputs) getParentDagID(isExitHandler bool) string {
 	}
 	if isExitHandler && i.parentDag == compiler.RootComponentName {
 		return fmt.Sprintf("$(params.%s)", paramParentDagID)
+	} else if i.inLoopDag {
+		return fmt.Sprintf("$(params.%s)", paramNameDagExecutionId)
 	} else {
 		return taskOutputParameter(getDAGDriverTaskName(i.parentDag), paramExecutionID)
 	}
diff --git a/backend/src/v2/compiler/tektoncompiler/dag.go b/backend/src/v2/compiler/tektoncompiler/dag.go
index fd4159c587..2e6f7580b2 100644
--- a/backend/src/v2/compiler/tektoncompiler/dag.go
+++ b/backend/src/v2/compiler/tektoncompiler/dag.go
@@ -47,10 +47,6 @@ func (c *pipelinerunCompiler) LoopDAG(taskName, compRef string, task *pipelinesp
 		return err
 	}
 
-	if err := c.addDagPubTask(newTaskName, dagSpec, c.spec, true, false); err != nil {
-		return err
-	}
-
 	// add the Loop DAG into DAG Stack
 	c.PushDagStack(newTaskName)
 	return nil
@@ -70,6 +66,16 @@ func (c *pipelinerunCompiler) EmbedLoopDAG(taskName, compRef string, task *pipel
 		return fmt.Errorf("unable to Marshal pipelineSpec:%v", err)
 	}
 
+	componentSpecStr, err := c.useComponentSpec(compRef)
+	if err != nil {
+		return err
+	}
+
+	taskSpecJson, err := stablyMarshalJSON(task)
+	if err != nil {
+		return err
+	}
+
 	pipelinelooptask := pipelineapi.PipelineTask{
 		Name: taskName + subfixPipelineLoop,
 		Params: []pipelineapi.Param{
@@ -78,6 +84,51 @@ func (c *pipelinerunCompiler) EmbedLoopDAG(taskName, compRef string, task *pipel
 			{Name: "from", Value: pipelineapi.ParamValue{Type: "string", StringVal: "0"}},
 			{Name: "step", Value: pipelineapi.ParamValue{Type: "string", StringVal: "1"}},
 			{Name: "to", Value: pipelineapi.ParamValue{Type: "string", StringVal: taskOutputParameter(getDAGDriverTaskName(taskName), paramIterationCount)}},
+			// "--type"
+			{
+				Name:  paramNameType,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: "DAG"},
+			},
+			// "--pipeline-name"
+			{
+				Name:  paramNamePipelineName,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: c.spec.GetPipelineInfo().GetName()},
+			},
+			// "--run-id"
+			{
+				Name:  paramRunId,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: runID()},
+			},
+			// "--dag-execution-id"
+			{
+				Name:  paramNameDagExecutionId,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: taskOutputParameter(getDAGDriverTaskName(taskName), paramExecutionID)},
+			},
+			// "--component"
+			{
+				Name:  paramComponent,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: componentSpecStr},
+			},
+			// "--task"
+			{
+				Name:  paramTask,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: taskSpecJson},
+			},
+			// "--runtime-config"
+			{
+				Name:  paramNameRuntimeConfig,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: ""},
+			},
+			// "--mlmd-server-address"
+			{
+				Name:  paramNameMLMDServerHost,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: GetMLMDHost()},
+			},
+			// "--mlmd_server_port"
+			{
+				Name:  paramNameMLMDServerPort,
+				Value: pipelineapi.ParamValue{Type: "string", StringVal: GetMLMDPort()},
+			},
 		},
 		TaskSpec: &pipelineapi.EmbeddedTask{
 			TypeMeta: runtime.TypeMeta{
@@ -149,18 +200,20 @@ func (c *pipelinerunCompiler) addDagTask(name, compRef string, task *pipelinespe
 		inputs.task = taskSpecJson
 		inputs.deps = task.GetDependentTasks()
 		inputs.parentDagID = c.CurrentDag()
+		inputs.inLoopDag = c.HasLoopName(c.CurrentDag())
 	}
 
 	if loopDag {
 		inputs.iterationIndex = inputValue(paramIterationIndex)
 		inputs.loopDag = true
+		c.AddLoopName(name)
+	} else {
+		driver, err := c.dagDriverTask(driverTaskName, &inputs)
+		if err != nil {
+			return err
+		}
+		c.addPipelineTask(driver)
 	}
-
-	driver, err := c.dagDriverTask(driverTaskName, &inputs)
-	if err != nil {
-		return err
-	}
-	c.addPipelineTask(driver)
 	return nil
 }
 
@@ -206,7 +259,7 @@ func (c *pipelinerunCompiler) createPipelineLoop() *pipelineloopapi.PipelineLoop
 		Spec: pipelineloopapi.PipelineLoopSpec{
 			PipelineSpec: &pipelineapi.PipelineSpec{
 				Params: []pipelineapi.ParamSpec{
-					{Name: paramParentDagID, Type: "string"},
+					{Name: paramNameDagExecutionId, Type: "string"},
 					{Name: paramIterationIndex, Type: "string"},
 				}},
 			IterateNumeric: paramIterationIndex,
@@ -359,6 +412,7 @@ type dagDriverInputs struct {
 	iterationIndex string                                  // optional, iterator passes iteration index to iteration tasks
 	deps           []string
 	loopDag        bool
+	inLoopDag      bool
 }
 
 type pubDagDriverInputs struct {
@@ -388,8 +442,8 @@ func (i *dagDriverInputs) getParentDagID(isExitHandler bool) string {
 	}
 	if isExitHandler && i.parentDagID == compiler.RootComponentName {
 		return fmt.Sprintf("$(params.%s)", paramParentDagID)
-	} else if i.loopDag {
-		return fmt.Sprintf("$(params.%s)", paramParentDagID)
+	} else if i.loopDag || i.inLoopDag {
+		return fmt.Sprintf("$(params.%s)", paramNameDagExecutionId)
 	} else {
 		return taskOutputParameter(getDAGDriverTaskName(i.parentDagID), paramExecutionID)
 	}
diff --git a/backend/src/v2/compiler/tektoncompiler/tekton.go b/backend/src/v2/compiler/tektoncompiler/tekton.go
index b3ae4a6717..eb8646c980 100644
--- a/backend/src/v2/compiler/tektoncompiler/tekton.go
+++ b/backend/src/v2/compiler/tektoncompiler/tekton.go
@@ -368,6 +368,7 @@ type pipelinerunCompiler struct {
 	pr               *pipelineapi.PipelineRun
 	exithandler      *ehv1alpha1.ExitHandler
 	loops            []*pipelineloopapi.PipelineLoop
+	loopNames        map[string]string
 	launcherImage    string
 	dagStack         []string
 	exitHandlerScope bool
@@ -481,6 +482,24 @@ func (c *pipelinerunCompiler) PushLoop(loop *pipelineloopapi.PipelineLoop) {
 	c.loops = append(c.loops, loop)
 }
 
+func (c *pipelinerunCompiler) AddLoopName(name string) {
+	if c.loopNames == nil {
+		c.loopNames = make(map[string]string)
+	}
+	if name == "" {
+		return
+	}
+	c.loopNames[name] = "true"
+}
+
+func (c *pipelinerunCompiler) HasLoopName(name string) bool {
+	if c.loopNames == nil {
+		return false
+	}
+	_, ok := c.loopNames[name]
+	return ok
+}
+
 func (c *pipelinerunCompiler) PopLoop() *pipelineloopapi.PipelineLoop {
 	lsize := len(c.loops)
 	if lsize > 0 {
diff --git a/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/201-clusterrole.yaml b/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/201-clusterrole.yaml
index 40e18c7253..34281f8b89 100644
--- a/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/201-clusterrole.yaml
+++ b/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/201-clusterrole.yaml
@@ -15,7 +15,7 @@ rules:
     resources: ["runs/status", "customruns/status", "taskruns/status", "pipelineruns/status", "runs/finalizers", "customruns/finalizers",]
     verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
   - apiGroups: ["custom.tekton.dev"]
-    resources: ["pipelineloops"]
+    resources: ["pipelineloops", "kfptasks"]
     verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
   - apiGroups: ["apps"]
     resources: ["deployments", "deployments/finalizers"]
diff --git a/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/500-controller.yaml b/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/500-controller.yaml
index 9361b0a856..e58fc23b97 100644
--- a/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/500-controller.yaml
+++ b/manifests/kustomize/third-party/tekton-custom-task/pipeline-loops/500-controller.yaml
@@ -42,6 +42,8 @@ spec:
       - name: tekton-pipelineloop-controller
         image: quay.io/aipipeline/pipelineloop-controller:nightly
         env:
+        - name: KFPV2
+          value: "true"
         - name: SYSTEM_NAMESPACE
           valueFrom:
             fieldRef:


Test patch:
diff --git a/backend/src/v2/compiler/tektoncompiler/testdata/loop_static.yaml b/backend/src/v2/compiler/tektoncompiler/testdata/loop_static.yaml
index 123d60e9f0..0bb2b7db31 100644
--- a/backend/src/v2/compiler/tektoncompiler/testdata/loop_static.yaml
+++ b/backend/src/v2/compiler/tektoncompiler/testdata/loop_static.yaml
@@ -23,6 +23,25 @@ spec:
         value: "1"
       - name: to
         value: $(tasks.for-loop-2-dag-driver.results.iteration-count)
+      - name: type
+        value: DAG
+      - name: pipeline-name
+        value: pipeline-with-loop-static
+      - name: run-id
+        value: $(context.pipelineRun.uid)
+      - name: dag-execution-id
+        value: $(tasks.for-loop-2-dag-driver.results.execution-id)
+      - name: component
+        value: '{"dag":{"tasks":{"concat-op":{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-concat-op"},"inputs":{"parameters":{"a":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"a\"]"},"b":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"b\"]"}}},"taskInfo":{"name":"concat-op"}},"print-op-2":{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-print-op-2"},"dependentTasks":["concat-op"],"inputs":{"parameters":{"text":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"concat-op"}}}},"taskInfo":{"name":"print-op-2"}}}},"inputDefinitions":{"parameters":{"pipelinechannel--loop-item-param-1":{"parameterType":"STRUCT"}}}}'
+      - name: task
+        value: '{"componentRef":{"name":"comp-for-loop-2"},"parameterIterator":{"itemInput":"pipelinechannel--loop-item-param-1","items":{"raw":"[{\"a\":
+          \"1\", \"b\": \"2\"}, {\"a\": \"10\", \"b\": \"20\"}]"}},"taskInfo":{"name":"for-loop-2"}}'
+      - name: runtime-config
+        value: ""
+      - name: mlmd-server-address
+        value: metadata-grpc-service.kubeflow.svc.cluster.local
+      - name: mlmd-server-port
+        value: "8080"
       taskSpec:
         apiVersion: custom.tekton.dev/v1alpha1
         kind: PipelineLoop
@@ -32,56 +51,11 @@ spec:
           iterateParam: ""
           pipelineSpec:
             params:
-            - name: parent-dag-id
+            - name: dag-execution-id
               type: string
             - name: iteration-index
               type: string
             tasks:
-            - name: for-loop-2-loop-dag-driver
-              params:
-              - name: type
-                value: DAG
-              - name: pipeline-name
-                value: pipeline-with-loop-static
-              - name: run-id
-                value: $(context.pipelineRun.uid)
-              - name: dag-execution-id
-                value: $(params.parent-dag-id)
-              - name: component
-                value: '{"dag":{"tasks":{"concat-op":{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-concat-op"},"inputs":{"parameters":{"a":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"a\"]"},"b":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"b\"]"}}},"taskInfo":{"name":"concat-op"}},"print-op-2":{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-print-op-2"},"dependentTasks":["concat-op"],"inputs":{"parameters":{"text":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"concat-op"}}}},"taskInfo":{"name":"print-op-2"}}}},"inputDefinitions":{"parameters":{"pipelinechannel--loop-item-param-1":{"parameterType":"STRUCT"}}}}'
-              - name: task
-                value: '{"componentRef":{"name":"comp-for-loop-2"},"parameterIterator":{"itemInput":"pipelinechannel--loop-item-param-1","items":{"raw":"[{\"a\":
-                  \"1\", \"b\": \"2\"}, {\"a\": \"10\", \"b\": \"20\"}]"}},"taskInfo":{"name":"for-loop-2"}}'
-              - name: runtime-config
-                value: ""
-              - name: iteration-index
-                value: $(params.iteration-index)
-              - name: mlmd-server-address
-                value: metadata-grpc-service.kubeflow.svc.cluster.local
-              - name: mlmd-server-port
-                value: "8080"
-              taskRef:
-                apiVersion: custom.tekton.dev/v1alpha1
-                kind: KFPTask
-            - name: for-loop-2-loop-dag-pub-driver
-              params:
-              - name: type
-                value: DAG_PUB
-              - name: pipeline-name
-                value: pipeline-with-loop-static
-              - name: run-id
-                value: $(context.pipelineRun.uid)
-              - name: dag-execution-id
-                value: $(tasks.for-loop-2-loop-dag-driver.results.execution-id)
-              - name: mlmd-server-address
-                value: metadata-grpc-service.kubeflow.svc.cluster.local
-              - name: mlmd-server-port
-                value: "8080"
-              runAfter:
-              - print-op-2
-              taskRef:
-                apiVersion: custom.tekton.dev/v1alpha1
-                kind: KFPTask
             - name: concat-op
               params:
               - name: type
@@ -91,7 +65,7 @@ spec:
               - name: run-id
                 value: $(context.pipelineRun.uid)
               - name: dag-execution-id
-                value: $(tasks.for-loop-2-loop-dag-driver.results.execution-id)
+                value: $(params.dag-execution-id)
               - name: task
                 value: '{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-concat-op"},"inputs":{"parameters":{"a":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"a\"]"},"b":{"componentInputParameter":"pipelinechannel--loop-item-param-1","parameterExpressionSelector":"parseJson(string_value)[\"b\"]"}}},"taskInfo":{"name":"concat-op"}}'
               - name: container
@@ -232,7 +206,7 @@ spec:
               - name: run-id
                 value: $(context.pipelineRun.uid)
               - name: dag-execution-id
-                value: $(tasks.for-loop-2-loop-dag-driver.results.execution-id)
+                value: $(params.dag-execution-id)
               - name: task
                 value: '{"cachingOptions":{"enableCache":true},"componentRef":{"name":"comp-print-op-2"},"dependentTasks":["concat-op"],"inputs":{"parameters":{"text":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"concat-op"}}}},"taskInfo":{"name":"print-op-2"}}'
               - name: container
diff --git a/backend/src/v2/compiler/tektoncompiler/testdata/nestedloop.yaml b/backend/src/v2/compiler/tektoncompiler/testdata/nestedloop.yaml
index 500b566ace..b37660ec8d 100644
--- a/backend/src/v2/compiler/tektoncompiler/testdata/nestedloop.yaml
+++ b/backend/src/v2/compiler/tektoncompiler/testdata/nestedloop.yaml
@@ -168,6 +168,26 @@ spec:
         value: "1"
       - name: to
         value: $(tasks.for-loop-2-dag-driver.results.iteration-count)
+      - name: type
+        value: DAG
+      - name: pipeline-name
+        value: tutorial-control-flows
+      - name: run-id
+        value: $(context.pipelineRun.uid)
+      - name: dag-execution-id
+        value: $(tasks.for-loop-2-dag-driver.results.execution-id)
+      - name: component
+        value: '{"dag":{"tasks":{"condition-3":{"componentRef":{"name":"comp-condition-3"},"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"componentInputParameter":"pipelinechannel--flip-coin-op-Output"},"pipelinechannel--loop-item-param-1":{"componentInputParameter":"pipelinechannel--loop-item-param-1"}}},"taskInfo":{"name":"condition-3"},"triggerPolicy":{"condition":"inputs.parameter_values[''pipelinechannel--loop-item-param-1'']
+          == inputs.parameter_values[''pipelinechannel--flip-coin-op-Output'']"}}}},"inputDefinitions":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"parameterType":"STRING"},"pipelinechannel--loop-item-param-1":{"parameterType":"STRING"}}}}'
+      - name: task
+        value: '{"componentRef":{"name":"comp-for-loop-2"},"dependentTasks":["flip-coin-op"],"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"flip-coin-op"}}}},"iteratorPolicy":{"parallelismLimit":2},"parameterIterator":{"itemInput":"pipelinechannel--loop-item-param-1","items":{"raw":"[\"heads\",
+          \"tails\"]"}},"taskInfo":{"name":"for-loop-2"}}'
+      - name: runtime-config
+        value: ""
+      - name: mlmd-server-address
+        value: metadata-grpc-service.kubeflow.svc.cluster.local
+      - name: mlmd-server-port
+        value: "8080"
       runAfter:
       - flip-coin-op
       taskSpec:
@@ -180,58 +200,11 @@ spec:
           parallelism: 2
           pipelineSpec:
             params:
-            - name: parent-dag-id
+            - name: dag-execution-id
               type: string
             - name: iteration-index
               type: string
             tasks:
-            - name: for-loop-2-loop-dag-driver
-              params:
-              - name: type
-                value: DAG
-              - name: pipeline-name
-                value: tutorial-control-flows
-              - name: run-id
-                value: $(context.pipelineRun.uid)
-              - name: dag-execution-id
-                value: $(params.parent-dag-id)
-              - name: component
-                value: '{"dag":{"tasks":{"condition-3":{"componentRef":{"name":"comp-condition-3"},"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"componentInputParameter":"pipelinechannel--flip-coin-op-Output"},"pipelinechannel--loop-item-param-1":{"componentInputParameter":"pipelinechannel--loop-item-param-1"}}},"taskInfo":{"name":"condition-3"},"triggerPolicy":{"condition":"inputs.parameter_values[''pipelinechannel--loop-item-param-1'']
-                  == inputs.parameter_values[''pipelinechannel--flip-coin-op-Output'']"}}}},"inputDefinitions":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"parameterType":"STRING"},"pipelinechannel--loop-item-param-1":{"parameterType":"STRING"}}}}'
-              - name: task
-                value: '{"componentRef":{"name":"comp-for-loop-2"},"dependentTasks":["flip-coin-op"],"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"flip-coin-op"}}}},"iteratorPolicy":{"parallelismLimit":2},"parameterIterator":{"itemInput":"pipelinechannel--loop-item-param-1","items":{"raw":"[\"heads\",
-                  \"tails\"]"}},"taskInfo":{"name":"for-loop-2"}}'
-              - name: runtime-config
-                value: ""
-              - name: iteration-index
-                value: $(params.iteration-index)
-              - name: mlmd-server-address
-                value: metadata-grpc-service.kubeflow.svc.cluster.local
-              - name: mlmd-server-port
-                value: "8080"
-              taskRef:
-                apiVersion: custom.tekton.dev/v1alpha1
-                kind: KFPTask
-            - name: for-loop-2-loop-dag-pub-driver
-              params:
-              - name: type
-                value: DAG_PUB
-              - name: pipeline-name
-                value: tutorial-control-flows
-              - name: run-id
-                value: $(context.pipelineRun.uid)
-              - name: dag-execution-id
-                value: $(tasks.for-loop-2-loop-dag-driver.results.execution-id)
-              - name: mlmd-server-address
-                value: metadata-grpc-service.kubeflow.svc.cluster.local
-              - name: mlmd-server-port
-                value: "8080"
-              runAfter:
-              - print-op
-              - print-op-2
-              taskRef:
-                apiVersion: custom.tekton.dev/v1alpha1
-                kind: KFPTask
             - name: print-op
               params:
               - name: type
@@ -784,7 +757,7 @@ spec:
               - name: run-id
                 value: $(context.pipelineRun.uid)
               - name: dag-execution-id
-                value: $(tasks.for-loop-2-loop-dag-driver.results.execution-id)
+                value: $(params.dag-execution-id)
               - name: component
                 value: '{"dag":{"tasks":{"condition-4":{"componentRef":{"name":"comp-condition-4"},"dependentTasks":["get-random-int-op"],"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"componentInputParameter":"pipelinechannel--flip-coin-op-Output"},"pipelinechannel--get-random-int-op-Output":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"get-random-int-op"}},"pipelinechannel--loop-item-param-1":{"componentInputParameter":"pipelinechannel--loop-item-param-1"}}},"taskInfo":{"name":"condition-4"},"triggerPolicy":{"condition":"int(inputs.parameter_values[''pipelinechannel--get-random-int-op-Output''])
                   \u003e 5"}},"condition-5":{"componentRef":{"name":"comp-condition-5"},"dependentTasks":["get-random-int-op"],"inputs":{"parameters":{"pipelinechannel--flip-coin-op-Output":{"componentInputParameter":"pipelinechannel--flip-coin-op-Output"},"pipelinechannel--get-random-int-op-Output":{"taskOutputParameter":{"outputParameterKey":"Output","producerTask":"get-random-int-op"}},"pipelinechannel--loop-item-param-1":{"componentInputParameter":"pipelinechannel--loop-item-param-1"}}},"taskInfo":{"name":"condition-5"},"triggerPolicy":{"condition":"int(inputs.parameter_values[''pipelinechannel--get-random-int-op-Output''])
@@ -818,8 +791,8 @@ spec:
               - name: mlmd-server-port
                 value: "8080"
               runAfter:
-              - print-op
               - print-op-2
+              - print-op
               taskRef:
                 apiVersion: custom.tekton.dev/v1alpha1
                 kind: KFPTask