From 0b0774c25731533a90dbdda7ca9dc5a6df0da012 Mon Sep 17 00:00:00 2001 From: Sky Tao Date: Wed, 5 Jun 2024 15:47:25 +0800 Subject: [PATCH] feat(matrix): Fix matrix param type mismatch problem for ref array result from customrun scenario Adjust `resolveCustomResultRef` implementation in Tekton to handle array results from CustomRun tasks correctly. This change resolves a type mismatch issue when using array results as matrix parameters, ensuring compatibility and proper functioning in scenarios where previous CustomRun emits array results. --- .../resources/resultrefresolution.go | 18 ++++++- .../resources/resultrefresolution_test.go | 50 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go index 73d7f9cf29a..5fa2217072d 100644 --- a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go +++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "encoding/json" "errors" "fmt" "sort" @@ -164,13 +165,28 @@ func resolveCustomResultRef(customRuns []*v1beta1.CustomRun, resultRef *v1.Resul return nil, err } return &ResolvedResultRef{ - Value: *v1.NewStructuredValues(runValue), + Value: *paramValueFromCustomRunResult(runValue), FromTaskRun: "", FromRun: runName, ResultReference: *resultRef, }, nil } +func paramValueFromCustomRunResult(result string) *v1.ParamValue { + var arrayResult []string + // for fan out array result, which is represented as string, we should make it to array type param value + if err := json.Unmarshal([]byte(result), &arrayResult); err == nil && len(arrayResult) > 0 { + if len(arrayResult) > 1 { + return v1.NewStructuredValues(arrayResult[0], arrayResult[1:]...) + } + return &v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{arrayResult[0]}, + } + } + return v1.NewStructuredValues(result) +} + func resolveResultRef(taskRuns []*v1.TaskRun, resultRef *v1.ResultRef) (*ResolvedResultRef, error) { taskRun := taskRuns[0] taskRunName := taskRun.Name diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go index ef18e506b13..284bf5704ae 100644 --- a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go @@ -841,3 +841,53 @@ func TestValidateArrayResultsIndex(t *testing.T) { }) } } + +func TestParamValueFromCustomRunResult(t *testing.T) { + type args struct { + result string + } + tests := []struct { + name string + args args + want *v1.ParamValue + }{ + { + name: "multiple array elements result", + args: args{ + result: `["amd64", "arm64"]`, + }, + want: &v1.ParamValue{ + Type: "array", + ArrayVal: []string{"amd64", "arm64"}, + }, + }, + { + name: "single array elements result", + args: args{ + result: `[ "amd64" ]`, + }, + want: &v1.ParamValue{ + Type: "array", + ArrayVal: []string{"amd64"}, + }, + }, + { + name: "simple string result", + args: args{ + result: "amd64", + }, + want: &v1.ParamValue{ + Type: "string", + StringVal: "amd64", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := paramValueFromCustomRunResult(tt.args.result) + if d := cmp.Diff(tt.want, got); d != "" { + t.Fatalf("paramValueFromCustomRunResult %s", diff.PrintWantGot(d)) + } + }) + } +}