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

Issue:
Missing customrun functions for pipelineloop cli
/kind bug

**What steps did you take and what happened:**
[A clear and concise description of what the bug is.]


**What did you expect to happen:**
There are still some missing customrun functions for pipelineloop cli that I have found:
customrun Validation in pipelinespec: https://github.com/kubeflow/kfp-tekton/blob/58b01f9281bdec412d3b73b8e2d36378886c6dfc/tekton-catalog/pipeline-loops/cmd/cli/main.go#L91-L100

We should also update our validation github test to include one customrun example to make sure we can catch any new changes from future customRun spec

**Additional information:**
[Miscellaneous information that will assist in solving the issue.]


**Environment:**

* Python Version (use `python --version`):
* SDK Version: 
* Tekton Version (use `tkn version`):
* Kubernetes Version (use `kubectl version`):
* OS (e.g. from `/etc/os-release`):



Discussion / hints:
/assign @ScrapCodes 

Fix patch:
diff --git a/Makefile b/Makefile
index ee7c4d41af..3febddb4de 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,11 @@ validate-testdata:
 	@cd tekton-catalog/pipeline-loops/ && make validate-testdata-python-sdk
 	@echo "$@: OK"
 
+.PHONY: validate-pipelineloop-examples
+validate-pipelineloop-examples:
+	@cd tekton-catalog/pipeline-loops/ && make validate-examples
+	@echo "$@: OK"
+
 .PHONY: unit_test
 unit_test: venv ## Run compiler unit tests
 	@echo "=================================================================="
diff --git a/tekton-catalog/pipeline-loops/Makefile b/tekton-catalog/pipeline-loops/Makefile
index e5f0138467..064bca249b 100644
--- a/tekton-catalog/pipeline-loops/Makefile
+++ b/tekton-catalog/pipeline-loops/Makefile
@@ -40,6 +40,11 @@ validate-testdata-python-sdk: cli $(info validate-testdata-python-sdk: validate
 		\( -type f -name "*yaml" -not -path "*\test_data\*" -not -name "*component.yaml" \) \
 		-print0 | xargs -0 -n1 ${BIN_DIR}/pipelineloop-cli -f
 
+.PHONY: validate-examples
+validate-examples: cli $(info validate-examples: validate example yamls for pipelineloop custom task. )
+	@find ./examples/ \
+		\( -type f -name "*yaml" \) -print0 | xargs -0 -n1 ${BIN_DIR}/pipelineloop-cli -f
+
 local: update init
 	go build -o=${BIN_DIR}/pipelineloop-controller ./cmd/controller
 	go build -o=${BIN_DIR}/pipelineloop-webhook ./cmd/webhook
diff --git a/tekton-catalog/pipeline-loops/cmd/cli/main.go b/tekton-catalog/pipeline-loops/cmd/cli/main.go
index 2ba74e2fe8..bf25fc9af5 100644
--- a/tekton-catalog/pipeline-loops/cmd/cli/main.go
+++ b/tekton-catalog/pipeline-loops/cmd/cli/main.go
@@ -77,8 +77,9 @@ func main() {
 		if err != nil {
 			fmt.Printf("\nWarn: skipping file:%s, %v\n", inputFileName, err)
 			// os.Exit(2) These are warning because, certain yaml are not k8s resource and we can skip.
-			os.Exit(0)
+			os.Exit(2)
 		}
+		fmt.Printf("Reading file: %s\n", inputFileName)
 		for _, o := range objs {
 			marshalledBytes, err := o.MarshalJSON()
 			if err != nil {
@@ -92,6 +93,8 @@ func main() {
 				// No validation.
 			case "Run":
 				err = validateRun(marshalledBytes)
+			case "CustomRun":
+				err = validateCustomRun(marshalledBytes)
 			case "Pipeline":
 				err = validatePipeline(marshalledBytes)
 			case pipelineloop.PipelineLoopControllerName:
@@ -173,6 +176,23 @@ func validateRun(bytes []byte) error {
 	return nil
 }
 
+func validateCustomRun(bytes []byte) error {
+	customRun := v1beta1.CustomRun{}
+	err := json.Unmarshal(bytes, &customRun)
+	if err != nil {
+		return fmt.Errorf("Error while unmarshal CustomRun:%s\n", err.Error())
+	}
+	// We do not need to validate CustomRun because it is validated by tekton admission webhook
+	// And r.Spec.CustomRef is also validated by tekton.
+	// Here we only need to validate the embedded spec. i.e. r.Spec.Spec
+	if customRun.Spec.CustomSpec != nil && customRun.Spec.CustomSpec.Kind == pipelineloop.PipelineLoopControllerName {
+		if err := validatePipelineLoopEmbedded(customRun.Spec.CustomSpec.Spec.Raw); err != nil {
+			return fmt.Errorf("Found validation errors in CustomRun: %s \n %s", customRun.Name, err.Error())
+		}
+	}
+	return nil
+}
+
 func validatePipelineRun(bytes []byte) error {
 	pr := v1beta1.PipelineRun{}
 	if err := json.Unmarshal(bytes, &pr); err != nil {
@@ -218,11 +238,13 @@ func validatePipelineLoop(bytes []byte) error {
 }
 
 func validateNestedPipelineLoop(pl pipelineloopv1alpha1.PipelineLoop) (error, string) {
-	for _, task := range pl.Spec.PipelineSpec.Tasks {
-		if task.TaskSpec != nil && task.TaskSpec.Kind == pipelineloop.PipelineLoopControllerName {
-			err := validatePipelineLoopEmbedded(task.TaskSpec.Spec.Raw)
-			if err != nil {
-				return err, task.Name
+	if pl.Spec.PipelineSpec != nil {
+		for _, task := range pl.Spec.PipelineSpec.Tasks {
+			if task.TaskSpec != nil && task.TaskSpec.Kind == pipelineloop.PipelineLoopControllerName {
+				err := validatePipelineLoopEmbedded(task.TaskSpec.Spec.Raw)
+				if err != nil {
+					return err, task.Name
+				}
 			}
 		}
 	}


Test patch:
diff --git a/.github/workflows/kfp-tekton-unittests.yml b/.github/workflows/kfp-tekton-unittests.yml
index 5d8de5e47f..7acfca8bec 100644
--- a/.github/workflows/kfp-tekton-unittests.yml
+++ b/.github/workflows/kfp-tekton-unittests.yml
@@ -47,6 +47,8 @@ jobs:
         run: make validate-generated-test-yamls
       - name: "Tekton validation for testdata."
         run: make validate-testdata
+      - name: "Validation for examples data."
+        run: make validate-pipelineloop-examples
   progress-report:
     runs-on: ubuntu-latest
     steps: