Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change ordering of ResolveResultRefs/ApplyTaskResults #6792

Merged
merged 1 commit into from
Jun 20, 2023

Conversation

EmmaMunley
Copy link
Contributor

@EmmaMunley EmmaMunley commented Jun 7, 2023

Changes

This refactor changes the ordering of when we resolve references to results and apply task results within the reconciler. Prior to this change, we were waiting until RunNextScheduableTask() to resolve and apply task results. This becomes an issue when trying to consume whole array results in a Matrix since the TaskRuns are created prior to RunNextScheduableTask() and the number of TaskRuns before resolving references is nondeterministic [*]. Consuming whole array results is a feature required in order to promote Matrix to beta and will be implemented in a subsequent PR #6603.

In this PR, we move this logic before RunNextScheduableTask() into ResolvePipelineTask() and resolve and apply the task results upfront so that by the time we go to create the TaskRuns, all of the replacements have been applied and we know exactly how many TaskRuns to create. Changing the ordering of the reconciler logic means we also have to change some of the error handling with ResolveResultRefs because we currently fail a PipelineRun if any of the result values are missing, however this could be a valid PipelineRun if it's a skipped Task due to MissingResultsSkip. This PR removes some of the initial errors that would cause the PipelineRun to fail the first time we ResolveResultRefs since some tasks could be missing result references, yet are valid at this point in time and need to be marked as "skipBecauseResultReferencesAreMissing". This enables us to mark all of the task that are supposed to be skipped as "skipBecauseResultReferencesAreMissing" rather than failing the pipelinerun immediately.

We later check for any actual missing result references in the Skipped Tasks and fail the PipelineRun in RunNextSchedulableTask().
An example of this is in TestMissingResultWhenStepErrorIsIgnored()when Task 1 produces Result A successfully and fails to produce Result B, but has onError continue. Task 2 consumes the results from Task 1, which results in the Failed PipelineRun because Task2 cannot reference Result B that was never produced in Task 1. However because On Error: Continue was used, Task 1 succeeded and the PipelineRun needs to now be marked as failed due to "ReasonInvalidTaskResultReference".

For more information on why this is necessary please see the discussion here: #6056 (comment)

/kind feature

Submitter Checklist

As the author of this PR, please check off the items in this checklist:

  • Has Docs if any changes are user facing, including updates to minimum requirements e.g. Kubernetes version bumps
  • Has Tests included if any functionality added or changed
  • Follows the commit message standard
  • Meets the Tekton contributor standards (including functionality, content, code)
  • Has a kind label. You can add one by adding a comment on this PR that contains /kind <type>. Valid types are bug, cleanup, design, documentation, feature, flake, misc, question, tep
  • Release notes block below has been updated with any user facing changes (API changes, bug fixes, changes requiring upgrade notices or deprecation warnings). See some examples of good release notes.
  • Release notes contains the string "action required" if the change requires additional action from users switching to the new release

Release Notes

NONE

@tekton-robot tekton-robot added kind/feature Categorizes issue or PR as related to a new feature. release-note-none Denotes a PR that doesnt merit a release note. labels Jun 7, 2023
@tekton-robot tekton-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 7, 2023
@EmmaMunley EmmaMunley force-pushed the RefactorApplyingTaskResults branch from ac72d98 to 70957d6 Compare June 7, 2023 22:22
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 7, 2023
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.5% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.5% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.5% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.5% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@EmmaMunley EmmaMunley force-pushed the RefactorApplyingTaskResults branch from 9ca533f to 128c2bf Compare June 8, 2023 16:32
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.6% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.6% 91.2% 0.6
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.1% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.3% 91.5% -0.8

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 9, 2023
@EmmaMunley EmmaMunley force-pushed the RefactorApplyingTaskResults branch 2 times, most recently from 47dbfd0 to 7c33032 Compare June 12, 2023 19:10
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 12, 2023
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.7% 89.4% -1.2
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.0% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.7% 89.4% -1.2
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.0% 0.0
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@EmmaMunley EmmaMunley force-pushed the RefactorApplyingTaskResults branch 2 times, most recently from d2ecb93 to dd01206 Compare June 12, 2023 22:33
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.7% 91.1% 0.5
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 95.5% -1.5
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.7% 91.1% 0.5
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 95.5% -1.5
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 90.7% 89.5% -1.2
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 95.5% -1.5
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.2% 91.1% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 93.1% -3.9
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 91.4% -0.8

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.2% 91.1% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.4% 0.3
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 81.4% -10.9

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.2% 91.1% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.4% 0.3
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 81.4% -10.9

) (*ResolvedPipelineTask, error) {
rpt := ResolvedPipelineTask{
PipelineTask: &pipelineTask,
}
rpt.CustomTask = rpt.PipelineTask.TaskRef.IsCustomTask() || rpt.PipelineTask.TaskSpec.IsCustomTask()
numCombinations := 1

// We want to resolve all of the result references and ignore any errors at this point since there could be
// instances where result references are missing here, but will be later skipped or resolved in a subsequent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what circumstances could result references be missing? In these circumstances, will pipelineTask.Matrix.CountCombinations() return the correct number of combinations, and will resolvePipelineTask create the correct number of TaskRuns?

I think we may try to resolve all pipeline tasks immediately, before running any. It seems to me like on the first reconcile loop, ResolvePipelineTask will generate TaskRunNames w/ length 1 for matrixed tasks fanned out from results, and on later reconcile loops will have the correct value.

I think having TaskRunNames in ResolvedPipelineTask doesn't work so well for matrixed pipeline tasks fanned out from array results, and would like to revisit the idea of label selectors. (We could also just merge #6603 if that gets too complicated.) I think this PR is running into a similar problem as #6603 though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The circumstance when result references will be missing is TestMissingResultWhenStepErrorIsIgnored
https://github.com/tektoncd/pipeline/blob/main/pkg/reconciler/pipelinerun/pipelinerun_test.go#L1052-L1090

The reason why we are reordering where we resolve and applyTaskResults in this PR is so that a matrixed pipelinetask that contains references to whole array results will not contain missing result references because the references will have already been resolved before where we try to generate the taskNames based on the number of combination in runNextSchedulableTask() so that we have the accurate number of combinations when fanning out the TaskRun() the first and only time it's called.

I have rebased and applied theses changes in the Add support for consuming whole array results in matrix PR and it's passing all of the tests. #6603

name: "whole array result replacements in matrix.params",
pName: "p-dag-3",
p: parse.MustParseV1beta1Pipeline(t, fmt.Sprintf(`
metadata:
name: %s
namespace: foo
spec:
tasks:
- name: pt-with-result
params:
- name: platforms
type: array
taskRef:
name: taskwithresults
- name: echo-platforms
matrix:
params:
- name: platform
value: $(tasks.pt-with-result.results.platforms[*])
taskRef:
name: mytask
`, "p-dag-3")),
tr: mustParseTaskRunWithObjectMeta(t,
taskRunObjectMeta("pr-pt-with-result", "foo",
"pr", "p-dag-3", "pt-with-result", false),
`
spec:
serviceAccountName: test-sa
taskRef:
name: taskwithresults
status:
conditions:
- type: Succeeded
status: "True"
reason: Succeeded
message: All Tasks have completed executing
taskResults:
- name: platforms
value:
- linux
- mac
- windows
`),
expectedTaskRuns: []*v1beta1.TaskRun{
mustParseTaskRunWithObjectMeta(t,
taskRunObjectMeta("pr-echo-platforms-0", "foo",
"pr", "p-dag-3", "echo-platforms", false),
`
spec:
params:
- name: platform
value: linux
serviceAccountName: test-sa
taskRef:
name: mytask
kind: Task
labels:
tekton.dev/memberOf: tasks
tekton.dev/pipeline: p-dag-3
`),
mustParseTaskRunWithObjectMeta(t,
taskRunObjectMeta("pr-echo-platforms-1", "foo",
"pr", "p-dag-3", "echo-platforms", false),
`
spec:
params:
- name: platform
value: mac
serviceAccountName: test-sa
taskRef:
name: mytask
kind: Task
labels:
tekton.dev/memberOf: tasks
tekton.dev/pipeline: p-dag-3
`),
mustParseTaskRunWithObjectMeta(t,
taskRunObjectMeta("pr-echo-platforms-2", "foo",
"pr", "p-dag-3", "echo-platforms", false),
`
spec:
params:
- name: platform
value: windows
serviceAccountName: test-sa
taskRef:
name: mytask
kind: Task
labels:
tekton.dev/memberOf: tasks
tekton.dev/pipeline: p-dag-3
`),
},
expectedPipelineRun: parse.MustParseV1beta1PipelineRun(t, `
metadata:
name: pr
namespace: foo
annotations: {}
labels:
tekton.dev/pipeline: p-dag-3
spec:
serviceAccountName: test-sa
pipelineRef:
name: p-dag-3
status:
pipelineSpec:
tasks:
- name: pt-with-result
params:
- name: platforms
type: array
taskRef:
name: taskwithresults
kind: Task
- name: echo-platforms
taskRef:
name: mytask
kind: Task
matrix:
params:
- name: platform
value: $(tasks.pt-with-result.results.platforms[*])
conditions:
- type: Succeeded
status: "Unknown"
reason: "Running"
message: "Tasks Completed: 1 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 0"
childReferences:
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
name: pr-pt-with-result
pipelineTaskName: pt-with-result
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
name: pr-echo-platforms-0
pipelineTaskName: echo-platforms
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
name: pr-echo-platforms-1
pipelineTaskName: echo-platforms
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
name: pr-echo-platforms-2
pipelineTaskName: echo-platforms
provenance:
featureFlags:
RunningInEnvWithInjectedSidecars: true
EnableTektonOCIBundles: true
EnableAPIFields: "alpha"
AwaitSidecarReadiness: true
VerificationNoMatchPolicy: "ignore"
EnableProvenanceInStatus: true
ResultExtractionMethod: "termination-message"
MaxResultSize: 4096
`),
}}
for _, tt := range tests {
t.Run(tt.pName, func(t *testing.T) {
pr := parse.MustParseV1beta1PipelineRun(t, fmt.Sprintf(`
metadata:
name: pr
namespace: foo
spec:
serviceAccountName: test-sa
pipelineRef:
name: %s
`, tt.pName))
d := test.Data{
PipelineRuns: []*v1beta1.PipelineRun{pr},
Pipelines: []*v1beta1.Pipeline{tt.p},
Tasks: []*v1beta1.Task{task, taskwithresults},
ConfigMaps: cms,
}
if tt.tr != nil {
d.TaskRuns = []*v1beta1.TaskRun{tt.tr}
}
prt := newPipelineRunTest(t, d)
defer prt.Cancel()
pipelineRun, clients := prt.reconcileRun(pr.Namespace, pr.Name, []string{} /* wantEvents*/, false /* permanentError*/)
taskRuns := getTaskRunsForPipelineTask(prt.TestAssets.Ctx, t, clients, pr.Namespace, pr.Name, "echo-platforms")
validateTaskRunsCount(t, taskRuns, len(tt.expectedTaskRuns))
for _, expectedTaskRun := range tt.expectedTaskRuns {
trName := expectedTaskRun.Name
actual := getTaskRunByName(t, taskRuns, trName)
if d := cmp.Diff(expectedTaskRun, actual, ignoreResourceVersion, ignoreTypeMeta); d != "" {
t.Errorf("expected to see TaskRun %v created. Diff %s", expectedTaskRun.Name, diff.PrintWantGot(d))
}
}
if d := cmp.Diff(tt.expectedPipelineRun, pipelineRun, ignoreResourceVersion, ignoreTypeMeta, ignoreLastTransitionTime, ignoreStartTime, ignoreFinallyStartTime, cmpopts.EquateEmpty()); d != "" {
t.Errorf("expected PipelineRun was not created. Diff %s", diff.PrintWantGot(d))
}
})
}
}

Let me know if that answers your question/concern.

Copy link
Member

@dibyom dibyom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really well written clear PR description. Thanks!! Have a couple of minor comments but the logic sounds good to me.


// We want to resolve all of the result references and ignore any errors at this point since there could be
// instances where result references are missing here, but will be later skipped or resolved in a subsequent
// TaskRun. The final validation is handled in skipBecauseResultReferencesAreMissing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: instead of passing in the pipelinerunState struct to ResolvePipelineTask, could we resolve the references right after we call ResolvedPipelineTask but before we append it to the pipelinerun state i.e. after line 379

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 16, 2023
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 20, 2023
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 95.2% 3.0

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 95.2% 3.0

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 92.4% 0.1

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 92.4% 0.1

@tekton-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dibyom

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 20, 2023
// TaskRun. The final validation is handled in skipBecauseResultReferencesAreMissing.
resolvedResultRefs, _, _ := ResolveResultRefs(pst, PipelineRunState{&rpt})
if err := validateArrayResultsIndex(resolvedResultRefs); err != nil {
return nil, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (not a block for the PR): I think this line is not covered?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this PR the coverage for ValidateArrayResultsIndex() exists within resolutionrefresolution_test.go.

func TestValidateArrayResultsIndex(t *testing.T) {

However I do have a pipelinerun.go unit test that covers an invalid array result index in the whole array results implementation https://github.com/tektoncd/pipeline/blob/c164f71ab448c4ac263d0113bf1b58d1c0199be3/pkg/reconciler/pipelinerun/pipelinerun_test.go#LL10603C6-L10603C66

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test in TestValidateArrayResultsIndex only tests the validateArrayResultsIndex but not tests the ResolvePipelineTask where we call the function.

The 2nd link makes sense! The validation happened in pipelinerun.go before but in this PR we moved it to the ResolvePipelineTask, I think it should be ok to rely on that test.

This line is red in the coverage report but I think that's fine.

Comment on lines 763 to 766
// CheckMissingResultReferences returns an error if it is missing any result references
// validates any array result indexes to ensure the reference is in bounds.
// Missing result references can occur if task fails to produce a result but has
// OnError: continue (ie TestMissingResultWhenStepErrorIsIgnored)
func CheckMissingResultReferences(pipelineRunState PipelineRunState, targets PipelineRunState) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a block for the PR: the docstrings says "validates any array result indexes to ensure the reference is in bounds.", is it referring to validateArrayResultsIndex. Can we call validateArrayResultsIndex inside this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Yongxuanzhang Good catch. I forgot I updated this so that validateArrayResultIndex() is called outside of this function
so that we are able to return an error that immediately fails the pipeline run. Removed this from the doc string.

if err := validateArrayResultsIndex(resolvedResultRefs); err != nil {

@@ -3823,6 +3809,7 @@ func TestResolvePipelineRunTask_WithMatrix(t *testing.T) {
name string
pt v1.PipelineTask
want *ResolvedPipelineTask
pst PipelineRunState
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this pst used in the tests? I cannot find it used in the 2 test cases

Copy link
Contributor Author

@EmmaMunley EmmaMunley Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think it's relevant to these test cases since we aren't dealing with results so removed it altogether, but have added it with whole array result examples in the subsequent PR: https://github.com/tektoncd/pipeline/blob/c164f71ab448c4ac263d0113bf1b58d1c0199be3/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go#L3822-L#3888

This refactor changes the ordering of when we resolve references to results and apply task results within the reconciler. Prior to this change, we were waiting until `RunNextScheduableTask()` to resolve and apply task results. This becomes an issue when trying to consume whole array results in a Matrix since the TaskRuns are created prior to `RunNextScheduableTask()` and the number of TaskRuns before resolving references is nondeterministic [*]. Consuming whole array results is a feature required in order to promote Matrix to beta and will be implemented in a subsequent PR.

In this commit, we move this logic before `RunNextScheduableTask()` into `ResolvePipelineTask()` and resolve and apply the task results upfront so that by the time we go to create the TaskRuns, all of the replacements have been applied and we know exactly how many TaskRuns to create. Changing the ordering of the reconciler logic means we also have to change some of the error handling with ResolveResultRefs because we currently fail a PipelineRun if any of the result values are missing, however this could be a valid PR if it's a skipped Task due to `MissingResultsSkip`. This commit removes some of the initial errors that would cause the PipelineRun to fail the first time we ResolveResultRefs since some tasks could be missing result references, yet are valid at this point in time and need to be marked as "skipBecauseResultReferencesAreMissing". This enables us to mark all of the task that are supposed to be skipped as "skipBecauseResultReferencesAreMissing" rather than failing the pipelinerun immediately.

We later check for any actual missing result references in the Skipped Tasks and fail the PipelineRun in RunNextSchedulableTask().
An example of this is in TestMissingResultWhenStepErrorIsIgnored()when Task 1 produces Result A successfully and fails to produce Result B, but has onError continue. Task 2 consumes the results from Task 1, which results in the Failed PipelineRun because Task2 cannot reference Result B that was never produced in Task 1. However because On Error: Continue was used, Task 1 succeeded and the PipelineRun needs to now be marked as failed due to "ReasonInvalidTaskResultReference".
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 92.4% 0.1

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/reconciler/pipelinerun/pipelinerun.go 91.3% 91.3% -0.0
pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go 97.0% 97.2% 0.2
pkg/reconciler/pipelinerun/resources/resultrefresolution.go 92.2% 92.4% 0.1

Copy link
Member

@Yongxuanzhang Yongxuanzhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
Thanks Emma!

// TaskRun. The final validation is handled in skipBecauseResultReferencesAreMissing.
resolvedResultRefs, _, _ := ResolveResultRefs(pst, PipelineRunState{&rpt})
if err := validateArrayResultsIndex(resolvedResultRefs); err != nil {
return nil, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test in TestValidateArrayResultsIndex only tests the validateArrayResultsIndex but not tests the ResolvePipelineTask where we call the function.

The 2nd link makes sense! The validation happened in pipelinerun.go before but in this PR we moved it to the ResolvePipelineTask, I think it should be ok to rely on that test.

This line is red in the coverage report but I think that's fine.

name: "Valid: successful result references resolution - params",
pipelineRunState: pipelineRunState,
targets: PipelineRunState{
pipelineRunState[1],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not related to this PR, I think it's hard to review this kind of test. Maybe one solution is to separate them into different vars with meaningful names?😂

@tekton-robot tekton-robot added the lgtm Indicates that a PR is ready to be merged. label Jun 20, 2023
@tekton-robot tekton-robot merged commit b6f84fd into tektoncd:main Jun 20, 2023
@EmmaMunley EmmaMunley deleted the RefactorApplyingTaskResults branch June 21, 2023 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/feature Categorizes issue or PR as related to a new feature. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesnt merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants