From 6d684d683acc55219de503026c4a89b490e110fa Mon Sep 17 00:00:00 2001
From: Zoran Regvart <zoran@regvart.com>
Date: Mon, 29 Jul 2024 14:53:26 +0200
Subject: [PATCH] Refine check if the result is from a matrix task

Given a matrix run of a TaskRun with cardinality of 1, the result from
it will not be converted to an array but kept as a string, i.e. as if
the TaskRun was not configured to run with matrix.

This causes issues for consumers of the TaskRun's results as they will
be configured to consume array results. As a result making the passed
value equal to expression value instead.

Resolves: #8157
---
 .../resources/resultrefresolution.go          |  2 +-
 .../resources/resultrefresolution_test.go     | 53 +++++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go
index 73d7f9cf29a..790f5c6c105 100644
--- a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go
+++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go
@@ -134,7 +134,7 @@ func convertToResultRefs(pipelineRunState PipelineRunState, target *ResolvedPipe
 			resolvedResultRefs = append(resolvedResultRefs, resolved)
 		default:
 			// Matrixed referenced Pipeline Task
-			if len(referencedPipelineTask.TaskRuns) > 1 {
+			if referencedPipelineTask.PipelineTask.IsMatrixed() {
 				arrayValues, err := findResultValuesForMatrix(referencedPipelineTask, resultRef)
 				if err != nil {
 					return nil, resultRef.PipelineTask, err
diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go
index ca2f54be49f..8dc2b1b60de 100644
--- a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go
+++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go
@@ -363,6 +363,42 @@ var pipelineRunState = PipelineRunState{{
 			Value: *v1.NewStructuredValues("$(tasks.lTask.results.aResult)"),
 		}},
 	},
+}, {
+	TaskRunNames: []string{"nTaskRun"},
+	TaskRuns: []*v1.TaskRun{{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "nTaskRun",
+		},
+		Status: v1.TaskRunStatus{
+			Status: duckv1.Status{
+				Conditions: duckv1.Conditions{successCondition},
+			},
+			TaskRunStatusFields: v1.TaskRunStatusFields{
+				Results: []v1.TaskRunResult{{
+					Name:  "nResult",
+					Value: *v1.NewStructuredValues("one"),
+				}},
+			},
+		},
+	}},
+	PipelineTask: &v1.PipelineTask{
+		Name:    "nTask",
+		TaskRef: &v1.TaskRef{Name: "nTask"},
+		Matrix: &v1.Matrix{
+			Include: v1.IncludeParamsList{v1.IncludeParams{}},
+		},
+	},
+}, {
+	TaskRunNames: []string{"oTaskRun"},
+	TaskRuns:     []*v1.TaskRun{},
+	PipelineTask: &v1.PipelineTask{
+		Name:    "oTask",
+		TaskRef: &v1.TaskRef{Name: "oTask"},
+		Params: []v1.Param{{
+			Name:  "oParam",
+			Value: *v1.NewStructuredValues("$(tasks.nTask.results.nResult)"),
+		}},
+	},
 }}
 
 func TestResolveResultRefs(t *testing.T) {
@@ -551,6 +587,23 @@ func TestResolveResultRefs(t *testing.T) {
 		},
 		wantPt:  "kTask",
 		wantErr: true,
+	}, {
+		name:             "Test result lookup single element matrix",
+		pipelineRunState: pipelineRunState,
+		targets: PipelineRunState{
+			pipelineRunState[21],
+		},
+		want: ResolvedResultRefs{{
+			Value: v1.ParamValue{
+				Type:     v1.ParamTypeArray,
+				ArrayVal: []string{"one"},
+			},
+			ResultReference: v1.ResultRef{
+				PipelineTask: "nTask",
+				Result:       "nResult",
+			},
+			FromTaskRun: "nTaskRun",
+		}},
 	}} {
 		t.Run(tt.name, func(t *testing.T) {
 			got, pt, err := ResolveResultRefs(tt.pipelineRunState, tt.targets)