diff --git a/docs/pipelines.md b/docs/pipelines.md index 9db48dd7679..a7f62ce0c0f 100644 --- a/docs/pipelines.md +++ b/docs/pipelines.md @@ -604,6 +604,20 @@ references the `outputValue` `Result` emitted by the `calculate-sum` `Task`. For an end-to-end example, see [`Results` in a `PipelineRun`](../examples/v1beta1/pipelineruns/pipelinerun-results.yaml). +A `Pipeline Result` is not emitted if any of the following are true: +- A `PipelineTask` referenced by the `Pipeline Result` failed. The `PipelineRun` will also +have failed. +- A `PipelineTask` referenced by the `Pipeline Result` was skipped. +- A `PipelineTask` referenced by the `Pipeline Result` didn't emit the referenced `Task Result`. This +should be considered a bug in the `Task` and [may fail a `PipelineTask` in future](https://github.com/tektoncd/pipeline/issues/3497). +- The `Pipeline Result` uses a variable that doesn't point to an actual `PipelineTask`. This will +result in an `InvalidTaskResultReference` validation error during `PipelineRun` execution. +- The `Pipeline Result` uses a variable that doesn't point to an actual result in a `PipelineTask`. +This will cause an `InvalidTaskResultReference` validation error during `PipelineRun` execution. + +**Note:** Since a `Pipeline Result` can contain references to multiple `Task Results`, if any of those +`Task Result` references are invalid the entire `Pipeline Result` is not emitted. + ## Configuring the `Task` execution order You can connect `Tasks` in a `Pipeline` so that they execute in a Directed Acyclic Graph (DAG). diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 0f3b0584253..ce2b6412492 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -22,7 +22,6 @@ import ( "path/filepath" "reflect" "strconv" - "strings" "time" "github.com/hashicorp/go-multierror" @@ -176,7 +175,15 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pr *v1beta1.PipelineRun) // and may not have had all of the assumed default specified. pr.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) - c.updatePipelineResults(ctx, pr, getPipelineFunc) + if _, pipelineSpec, err := resources.GetPipelineData(ctx, pr, getPipelineFunc); err != nil { + msg := fmt.Sprintf("Failed to get Pipeline Spec to process Pipeline Results for PipelineRun %s/%s: %v", pr.Namespace, pr.Name, err) + logger.Error(msg) + logger.Warnf("An error processing Pipeline Results overwrites existing Succeeded Condition for PipelineRun %s/%s: %v", pr.Namespace, pr.Name, pr.Status.GetCondition(apis.ConditionSucceeded)) + pr.Status.MarkFailed(ReasonCouldntGetPipeline, msg) + } else { + pr.Status.PipelineResults = resources.ApplyTaskResultsToPipelineResults(pipelineSpec.Results, pr.Status.TaskRuns) + } + if err := artifacts.CleanupArtifactStorage(ctx, pr, c.KubeClientSet); err != nil { logger.Errorf("Failed to delete PVC for PipelineRun %s: %v", pr.Name, err) return c.finishReconcileUpdateEmitEvents(ctx, pr, before, err) @@ -317,21 +324,6 @@ func (c *Reconciler) resolvePipelineState( return pst, nil } -func (c *Reconciler) updatePipelineResults(ctx context.Context, pr *v1beta1.PipelineRun, getPipelineFunc resources.GetPipeline) { - logger := logging.FromContext(ctx) - - _, pipelineSpec, err := resources.GetPipelineData(ctx, pr, getPipelineFunc) - if err != nil { - logger.Errorf("Failed to determine Pipeline spec to use for pipelinerun %s: %v", pr.Name, err) - pr.Status.MarkFailed(ReasonCouldntGetPipeline, - "Error retrieving pipeline for pipelinerun %s/%s: %s", - pr.Namespace, pr.Name, err) - return - } - resolvedResultRefs := resources.ResolvePipelineResultRefs(pr.Status, pipelineSpec.Results) - pr.Status.PipelineResults = getPipelineRunResults(pipelineSpec, resolvedResultRefs) -} - func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun, getPipelineFunc resources.GetPipeline) error { logger := logging.FromContext(ctx) // We may be reading a version of the object that was stored at an older version @@ -622,27 +614,6 @@ func (c *Reconciler) runNextSchedulableTask(ctx context.Context, pr *v1beta1.Pip return nil } -func getPipelineRunResults(pipelineSpec *v1beta1.PipelineSpec, resolvedResultRefs resources.ResolvedResultRefs) []v1beta1.PipelineRunResult { - var results []v1beta1.PipelineRunResult - stringReplacements := map[string]string{} - - for _, resolvedResultRef := range resolvedResultRefs { - replaceTarget := fmt.Sprintf("%s.%s.%s.%s", v1beta1.ResultTaskPart, resolvedResultRef.ResultReference.PipelineTask, v1beta1.ResultResultPart, resolvedResultRef.ResultReference.Result) - stringReplacements[replaceTarget] = resolvedResultRef.Value.StringVal - } - for _, result := range pipelineSpec.Results { - in := result.Value - for k, v := range stringReplacements { - in = strings.Replace(in, fmt.Sprintf("$(%s)", k), v, -1) - } - results = append(results, v1beta1.PipelineRunResult{ - Name: result.Name, - Value: in, - }) - } - return results -} - func (c *Reconciler) updateTaskRunsStatusDirectly(pr *v1beta1.PipelineRun) error { for taskRunName := range pr.Status.TaskRuns { // TODO(dibyom): Add conditionCheck statuses here diff --git a/pkg/reconciler/pipelinerun/resources/apply.go b/pkg/reconciler/pipelinerun/resources/apply.go index 3e026f0a986..5c2f862b6c0 100644 --- a/pkg/reconciler/pipelinerun/resources/apply.go +++ b/pkg/reconciler/pipelinerun/resources/apply.go @@ -18,8 +18,11 @@ package resources import ( "fmt" + "strings" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" ) // ApplyParameters applies the params from a PipelineRun.Params to a PipelineSpec. @@ -84,6 +87,8 @@ func ApplyTaskResults(targets PipelineRunState, resolvedResultRefs ResolvedResul } } +// ApplyWorkspaces replaces workspace variables in the given pipeline spec with their +// concrete values. func ApplyWorkspaces(p *v1beta1.PipelineSpec, pr *v1beta1.PipelineRun) *v1beta1.PipelineSpec { p = p.DeepCopy() replacements := map[string]string{} @@ -124,3 +129,73 @@ func replaceParamValues(params []v1beta1.Param, stringReplacements map[string]st } return params } + +// ApplyTaskResultsToPipelineResults applies the results of completed TasksRuns to a Pipeline's +// list of PipelineResults, returning the computed set of PipelineRunResults. References to +// non-existent TaskResults or failed TaskRuns result in a PipelineResult being considered invalid +// and omitted from the returned slice. A nil slice is returned if no results are passed in or all +// results are invalid. +func ApplyTaskResultsToPipelineResults(results []v1beta1.PipelineResult, taskRunStatuses map[string]*v1beta1.PipelineRunTaskRunStatus) []v1beta1.PipelineRunResult { + taskStatuses := map[string]*v1beta1.PipelineRunTaskRunStatus{} + for _, trStatus := range taskRunStatuses { + taskStatuses[trStatus.PipelineTaskName] = trStatus + } + + var runResults []v1beta1.PipelineRunResult = nil + stringReplacements := map[string]string{} + for _, pipelineResult := range results { + variablesInPipelineResult, _ := v1beta1.GetVarSubstitutionExpressionsForPipelineResult(pipelineResult) + validPipelineResult := true + for _, variable := range variablesInPipelineResult { + if _, isMemoized := stringReplacements[variable]; isMemoized { + continue + } + if resultValue := taskResultValue(variable, taskStatuses); resultValue != nil { + stringReplacements[variable] = *resultValue + } else { + validPipelineResult = false + } + } + if validPipelineResult { + finalValue := pipelineResult.Value + for variable, value := range stringReplacements { + v := fmt.Sprintf("$(%s)", variable) + finalValue = strings.Replace(finalValue, v, value, -1) + } + runResults = append(runResults, v1beta1.PipelineRunResult{ + Name: pipelineResult.Name, + Value: finalValue, + }) + } + } + + return runResults +} + +// taskResultValue returns a pointer to the result value for a given task result variable. A nil +// pointer is returned if the variable is invalid for any reason. +func taskResultValue(variable string, taskStatuses map[string]*v1beta1.PipelineRunTaskRunStatus) *string { + variableParts := strings.Split(variable, ".") + if len(variableParts) != 4 || variableParts[0] != "tasks" || variableParts[2] != "results" { + return nil + } + + taskName, resultName := variableParts[1], variableParts[3] + + status, taskExists := taskStatuses[taskName] + if !taskExists || status.Status == nil { + return nil + } + + cond := status.Status.GetCondition(apis.ConditionSucceeded) + if cond == nil || cond.Status != corev1.ConditionTrue { + return nil + } + + for _, trResult := range status.Status.TaskRunResults { + if trResult.Name == resultName { + return &trResult.Value + } + } + return nil +} diff --git a/pkg/reconciler/pipelinerun/resources/apply_test.go b/pkg/reconciler/pipelinerun/resources/apply_test.go index c27cae71fce..bf0554ad601 100644 --- a/pkg/reconciler/pipelinerun/resources/apply_test.go +++ b/pkg/reconciler/pipelinerun/resources/apply_test.go @@ -25,8 +25,11 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" resourcev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" "github.com/tektoncd/pipeline/test/diff" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/selection" + "knative.dev/pkg/apis" + duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" ) func TestApplyParameters(t *testing.T) { @@ -610,3 +613,273 @@ func TestApplyWorkspaces(t *testing.T) { }) } } + +func TestApplyTaskResultsToPipelineResults(t *testing.T) { + for _, tc := range []struct { + description string + results []v1beta1.PipelineResult + statuses map[string]*v1beta1.PipelineRunTaskRunStatus + expected []v1beta1.PipelineRunResult + }{{ + description: "no-pipeline-results-no-returned-results", + results: []v1beta1.PipelineResult{}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "bar", + }}, + }, + }, + }, + }, + expected: nil, + }, { + description: "invalid-result-variable-no-returned-result", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1_results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "bar", + }}, + }, + }, + }, + }, + expected: nil, + }, { + description: "no-taskrun-results-no-returned-results", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1.results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{}, + }, + }, + }, + }, + expected: nil, + }, { + description: "invalid-taskrun-name-no-returned-result", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1.results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "definitely-not-pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "bar", + }}, + }, + }, + }, + }, + expected: nil, + }, { + description: "invalid-result-name-no-returned-result", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1.results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "definitely-not-foo", + Value: "bar", + }}, + }, + }, + }, + }, + expected: nil, + }, { + description: "unsuccessful-taskrun-no-returned-result", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1.results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionFalse, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "bar", + }}, + }, + }, + }, + }, + expected: nil, + }, { + description: "mixed-success-tasks-some-returned-results", + results: []v1beta1.PipelineResult{{ + Name: "foo", + Value: "$(tasks.pt1.results.foo)", + }, { + Name: "bar", + Value: "$(tasks.pt2.results.bar)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionFalse, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "do", + }}, + }, + }, + }, + "task2": { + PipelineTaskName: "pt2", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "bar", + Value: "rae", + }}, + }, + }, + }, + }, + expected: []v1beta1.PipelineRunResult{{ + Name: "bar", + Value: "rae", + }}, + }, { + description: "multiple-results-multiple-successful-tasks", + results: []v1beta1.PipelineResult{{ + Name: "pipeline-result-1", + Value: "$(tasks.pt1.results.foo)", + }, { + Name: "pipeline-result-2", + Value: "$(tasks.pt1.results.foo), $(tasks.pt2.results.baz), $(tasks.pt1.results.bar), $(tasks.pt2.results.baz), $(tasks.pt1.results.foo)", + }}, + statuses: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "task1": { + PipelineTaskName: "pt1", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "foo", + Value: "do", + }, { + Name: "bar", + Value: "mi", + }}, + }, + }, + }, + "task2": { + PipelineTaskName: "pt2", + Status: &v1beta1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionTrue, + }}, + }, + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{{ + Name: "baz", + Value: "rae", + }}, + }, + }, + }, + }, + expected: []v1beta1.PipelineRunResult{{ + Name: "pipeline-result-1", + Value: "do", + }, { + Name: "pipeline-result-2", + Value: "do, rae, mi, rae, do", + }}, + }} { + t.Run(tc.description, func(t *testing.T) { + received := ApplyTaskResultsToPipelineResults(tc.results, tc.statuses) + if d := cmp.Diff(tc.expected, received); d != "" { + t.Errorf(diff.PrintWantGot(d)) + } + }) + } +} diff --git a/pkg/reconciler/pipelinerun/resources/conditionresolution.go b/pkg/reconciler/pipelinerun/resources/conditionresolution.go index c63de3c861d..a73cd247c3b 100644 --- a/pkg/reconciler/pipelinerun/resources/conditionresolution.go +++ b/pkg/reconciler/pipelinerun/resources/conditionresolution.go @@ -177,6 +177,8 @@ func (rcc *ResolvedConditionCheck) NewConditionCheckStatus() *v1beta1.ConditionC } } +// ToTaskResourceBindings converts pipeline resources in a ResolvedConditionCheck to a list of TaskResourceBinding +// and returns them. func (rcc *ResolvedConditionCheck) ToTaskResourceBindings() []v1beta1.TaskResourceBinding { var trb []v1beta1.TaskResourceBinding diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go index 44a088ae546..fd8c6b51dfd 100644 --- a/pkg/reconciler/pipelinerun/resources/resultrefresolution.go +++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution.go @@ -22,7 +22,6 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" - "knative.dev/pkg/apis" ) // ResolvedResultRefs represents all of the ResolvedResultRef for a pipeline task @@ -51,19 +50,6 @@ func ResolveResultRefs(pipelineRunState PipelineRunState, targets PipelineRunSta return removeDup(allResolvedResultRefs), nil } -// ResolvePipelineResultRefs takes a list of PipelineResults and resolves any references they -// include to Task results in the given PipelineRunStatus -func ResolvePipelineResultRefs(pipelineStatus v1beta1.PipelineRunStatus, pipelineResults []v1beta1.PipelineResult) ResolvedResultRefs { - var allResolvedResultRefs ResolvedResultRefs - for _, result := range pipelineResults { - resolvedResultRefs := convertPipelineResultToResultRefs(pipelineStatus, result) - if resolvedResultRefs != nil { - allResolvedResultRefs = append(allResolvedResultRefs, resolvedResultRefs...) - } - } - return removeDup(allResolvedResultRefs) -} - // extractResultRefs resolves any ResultReference that are found in param or pipeline result // Returns nil if none are found func extractResultRefsForParam(pipelineRunState PipelineRunState, param v1beta1.Param) (ResolvedResultRefs, error) { @@ -74,29 +60,6 @@ func extractResultRefsForParam(pipelineRunState PipelineRunState, param v1beta1. return nil, nil } -// extractResultRefs resolves any ResultReference that are found in param or pipeline result -// Returns nil if none are found -func extractResultRefsForPipelineResult(pipelineStatus v1beta1.PipelineRunStatus, result v1beta1.PipelineResult) (ResolvedResultRefs, error) { - expressions, ok := v1beta1.GetVarSubstitutionExpressionsForPipelineResult(result) - if ok { - return extractResultRefsForPipelineResults(expressions, pipelineStatus) - } - return nil, nil -} - -func extractResultRefsForPipelineResults(expressions []string, pipelineStatus v1beta1.PipelineRunStatus) (ResolvedResultRefs, error) { - resultRefs := v1beta1.NewResultRefs(expressions) - var resolvedResultRefs ResolvedResultRefs - for _, resultRef := range resultRefs { - resolvedResultRef, err := resolveResultRefForPipelineResult(pipelineStatus, resultRef) - if err != nil { - return nil, err - } - resolvedResultRefs = append(resolvedResultRefs, resolvedResultRef) - } - return removeDup(resolvedResultRefs), nil -} - func extractResultRefs(expressions []string, pipelineRunState PipelineRunState) (ResolvedResultRefs, error) { resultRefs := v1beta1.NewResultRefs(expressions) var resolvedResultRefs ResolvedResultRefs @@ -198,15 +161,6 @@ func convertWhenExpressions(whenExpressions []v1beta1.WhenExpression, pipelineRu return resolvedWhenExpressions, nil } -// convertPipelineResultToResultRefs converts all params of the resolved pipeline run task -func convertPipelineResultToResultRefs(pipelineStatus v1beta1.PipelineRunStatus, pipelineResult v1beta1.PipelineResult) ResolvedResultRefs { - resolvedResultRefs, err := extractResultRefsForPipelineResult(pipelineStatus, pipelineResult) - if err != nil { - return nil - } - return resolvedResultRefs -} - func resolveResultRef(pipelineState PipelineRunState, resultRef *v1beta1.ResultRef) (*ResolvedResultRef, error) { referencedPipelineTask := pipelineState.ToMap()[resultRef.PipelineTask] @@ -241,47 +195,6 @@ func resolveResultRef(pipelineState PipelineRunState, resultRef *v1beta1.ResultR }, nil } -func resolveResultRefForPipelineResult(pipelineStatus v1beta1.PipelineRunStatus, resultRef *v1beta1.ResultRef) (*ResolvedResultRef, error) { - taskRunStatus, taskRunName, err := getTaskRunStatus(pipelineStatus, resultRef.PipelineTask) - - if err != nil { - return nil, err - } - result, err := findTaskResultForPipelineResult(taskRunStatus, resultRef) - if err != nil { - return nil, err - } - return &ResolvedResultRef{ - Value: *v1beta1.NewArrayOrString(result.Value), - FromTaskRun: taskRunName, - ResultReference: *resultRef, - }, nil -} - -func getTaskRunStatus(pipelineStatus v1beta1.PipelineRunStatus, pipelineTaskName string) (*v1beta1.TaskRunStatus, string, error) { - for key, taskRun := range pipelineStatus.PipelineRunStatusFields.TaskRuns { - // check if the task run was successful - if taskRun.PipelineTaskName == pipelineTaskName { - c := taskRun.Status.GetCondition(apis.ConditionSucceeded) - if c == nil { - return nil, "", fmt.Errorf("could not find a successful task run status for task %q referenced by result", pipelineTaskName) - } - return taskRun.Status, key, nil - } - } - return nil, "", fmt.Errorf("could not find task run status for task %q referenced by result", pipelineTaskName) -} - -func findTaskResultForPipelineResult(taskStatus *v1beta1.TaskRunStatus, reference *v1beta1.ResultRef) (*v1beta1.TaskRunResult, error) { - results := taskStatus.TaskRunStatusFields.TaskRunResults - for _, result := range results { - if result.Name == reference.Result { - return &result, nil - } - } - return nil, fmt.Errorf("Could not find result with name %s for task run %s", reference.Result, reference.PipelineTask) -} - func findRunResultForParam(run *v1alpha1.Run, reference *v1beta1.ResultRef) (string, error) { results := run.Status.Results for _, result := range results { diff --git a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go index ebe4380e412..28ffbed5ee3 100644 --- a/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/resultrefresolution_test.go @@ -16,7 +16,6 @@ import ( "k8s.io/apimachinery/pkg/selection" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" ) var ( @@ -494,112 +493,3 @@ func TestResolveResultRefs(t *testing.T) { }) } } - -func TestResolvePipelineResultRefs(t *testing.T) { - taskrunStatus := map[string]*v1beta1.PipelineRunTaskRunStatus{} - taskrunStatus["aTaskRun"] = &v1beta1.PipelineRunTaskRunStatus{ - PipelineTaskName: "aTask", - Status: &v1beta1.TaskRunStatus{ - Status: duckv1beta1.Status{ - Conditions: []apis.Condition{{ - Type: apis.ConditionSucceeded, - Status: corev1.ConditionTrue, - }}, - }, - TaskRunStatusFields: v1beta1.TaskRunStatusFields{ - TaskRunResults: []v1beta1.TaskRunResult{ - { - Name: "aResult", - Value: "aResultValue", - }, - }, - }, - }, - } - taskrunStatus["bTaskRun"] = &v1beta1.PipelineRunTaskRunStatus{ - PipelineTaskName: "bTask", - Status: &v1beta1.TaskRunStatus{ - Status: duckv1beta1.Status{ - Conditions: []apis.Condition{{ - Type: apis.ConditionSucceeded, - Status: corev1.ConditionFalse, - }}, - }, - }, - } - taskrunStatus["cTaskRun"] = &v1beta1.PipelineRunTaskRunStatus{ - PipelineTaskName: "cTask", - Status: &v1beta1.TaskRunStatus{ - Status: duckv1beta1.Status{ - Conditions: []apis.Condition{{ - Type: apis.ConditionSucceeded, - Status: corev1.ConditionUnknown, - }}, - }, - }, - } - status := v1beta1.PipelineRunStatus{ - PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ - TaskRuns: taskrunStatus, - }, - } - - tests := []struct { - name string - status v1beta1.PipelineRunStatus - pipelineResults []v1beta1.PipelineResult - want ResolvedResultRefs - }{{ - name: "Test pipeline result from a successful task", - status: status, - pipelineResults: []v1beta1.PipelineResult{{ - Name: "from-a", - Value: "$(tasks.aTask.results.aResult)", - Description: "a result from a", - }}, - want: ResolvedResultRefs{{ - Value: *v1beta1.NewArrayOrString("aResultValue"), - ResultReference: v1beta1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", - }, - FromTaskRun: "aTaskRun", - }}, - }, { - name: "Test results from a task that did not run and one and failed", - status: status, - pipelineResults: []v1beta1.PipelineResult{{ - Name: "from-a", - Value: "$(tasks.aTask.results.aResult)", - Description: "a result from a", - }, { - Name: "from-b", - Value: "$(tasks.bTask.results.bResult)", - Description: "a result from b", - }, { - Name: "from-c", - Value: "$(tasks.cTask.results.cResult)", - Description: "a result from c", - }}, - want: ResolvedResultRefs{{ - Value: *v1beta1.NewArrayOrString("aResultValue"), - ResultReference: v1beta1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", - }, - FromTaskRun: "aTaskRun", - }}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := ResolvePipelineResultRefs(tt.status, tt.pipelineResults) - sort.SliceStable(got, func(i, j int) bool { - return strings.Compare(got[i].FromTaskRun, got[j].FromTaskRun) < 0 - }) - if d := cmp.Diff(tt.want, got); d != "" { - t.Fatalf("ResolveResultRef %s", diff.PrintWantGot(d)) - } - }) - } -}