Skip to content

Commit

Permalink
don't return validation error when taskrun failed/skipped
Browse files Browse the repository at this point in the history
This commit aims to fix tektoncd#6383, tektoncd#6139 and supports tektoncd#3749. This commits
skip the validation if the taskrun is not successful (e.g. failed or skipped) and
omit the pipelinerun coresponding result. This way the skipped taskrun
won't get validation error for pipelinerun. And the pipelinerun error
won't be overwritten by the validation error.

Signed-off-by: Yongxuan Zhang yongxuanzhang@google.com
  • Loading branch information
Yongxuanzhang committed Apr 24, 2023
1 parent 8e8c163 commit 474d88c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 23 deletions.
45 changes: 45 additions & 0 deletions examples/v1beta1/pipelineruns/6139-regression.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pipelinerun-test
spec:
pipelineSpec:
params:
- name: say-hello
default: 'false'
tasks:
- name: hello
taskSpec:
results:
- name: result-one
steps:
- image: alpine
script: |
#!/bin/sh
echo "Hello world!"
echo -n "RES1" > $(results.result-one.path)
- name: goodbye
runAfter:
- hello
taskSpec:
results:
- name: result-two
steps:
- image: alpine
script: |
#!/bin/sh
echo "Goodbye world!"
echo -n "RES2" > $(results.result-two.path)
when:
- input: $(params.say-hello)
operator: in
values: ["true"]

results:
- name: result-hello
description: Result one
value: '$(tasks.hello.results.result-one)'
- name: result-goodbye
description: Result two
value: '$(tasks.goodbye.results.result-two)'
2 changes: 1 addition & 1 deletion pkg/reconciler/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun, get
pr.Status.SkippedTasks = pipelineRunFacts.GetSkippedTasks()
if after.Status == corev1.ConditionTrue || after.Status == corev1.ConditionFalse {
pr.Status.PipelineResults, err = resources.ApplyTaskResultsToPipelineResults(ctx, pipelineSpec.Results,
pipelineRunFacts.State.GetTaskRunsResults(), pipelineRunFacts.State.GetRunsResults(), pr.Status.SkippedTasks)
pipelineRunFacts.State.GetTaskRunsResults(), pipelineRunFacts.State.GetRunsResults(), pipelineRunFacts.GetPipelineTaskStatus())
if err != nil {
pr.Status.MarkFailed(ReasonFailedValidation, err.Error())
return err
Expand Down
26 changes: 16 additions & 10 deletions pkg/reconciler/pipelinerun/resources/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,9 @@ func ApplyTaskResultsToPipelineResults(
results []v1beta1.PipelineResult,
taskRunResults map[string][]v1beta1.TaskRunResult,
customTaskResults map[string][]v1beta1.CustomRunResult,
skippedTasks []v1beta1.SkippedTask) ([]v1beta1.PipelineRunResult, error) {
taskstatus map[string]string) ([]v1beta1.PipelineRunResult, error) {
var runResults []v1beta1.PipelineRunResult
var invalidPipelineResults []string
skippedTaskNames := map[string]bool{}
for _, t := range skippedTasks {
skippedTaskNames[t.Name] = true
}

stringReplacements := map[string]string{}
arrayReplacements := map[string][]string{}
Expand All @@ -366,11 +362,7 @@ func ApplyTaskResultsToPipelineResults(
continue
}
variableParts := strings.Split(variable, ".")
// if the referenced task is skipped, we should also skip the results replacements
if _, ok := skippedTaskNames[variableParts[1]]; ok {
validPipelineResult = false
continue
}

if (variableParts[0] != v1beta1.ResultTaskPart && variableParts[0] != v1beta1.ResultFinallyPart) || variableParts[2] != v1beta1.ResultResultPart {
validPipelineResult = false
invalidPipelineResults = append(invalidPipelineResults, pipelineResult.Name)
Expand Down Expand Up @@ -406,6 +398,13 @@ func ApplyTaskResultsToPipelineResults(
} else if resultValue := runResultValue(taskName, resultName, customTaskResults); resultValue != nil {
stringReplacements[variable] = *resultValue
} else {
// if the task is not successful (e.g. skipped or failed) and the results is missing, don't return error
if status, ok := taskstatus[PipelineTaskStatusPrefix+taskName+PipelineTaskStatusSuffix]; ok {
if status != v1beta1.TaskRunReasonSuccessful.String() {
validPipelineResult = false
continue
}
}
// referred result name is not existent
invalidPipelineResults = append(invalidPipelineResults, pipelineResult.Name)
validPipelineResult = false
Expand All @@ -423,6 +422,13 @@ func ApplyTaskResultsToPipelineResults(
validPipelineResult = false
}
} else {
// if the task is not successful (e.g. skipped or failed) and the results is missing, don't return error
if status, ok := taskstatus[PipelineTaskStatusPrefix+taskName+PipelineTaskStatusSuffix]; ok {
if status != v1beta1.TaskRunReasonSuccessful.String() {
validPipelineResult = false
continue
}
}
// referred result name is not existent
invalidPipelineResults = append(invalidPipelineResults, pipelineResult.Name)
validPipelineResult = false
Expand Down
51 changes: 39 additions & 12 deletions pkg/reconciler/pipelinerun/resources/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3512,6 +3512,7 @@ func TestApplyTaskResultsToPipelineResults_Success(t *testing.T) {
results []v1beta1.PipelineResult
taskResults map[string][]v1beta1.TaskRunResult
runResults map[string][]v1beta1.CustomRunResult
taskstatus map[string]string
skippedTasks []v1beta1.SkippedTask
expectedResults []v1beta1.PipelineRunResult
}{{
Expand Down Expand Up @@ -3789,13 +3790,47 @@ func TestApplyTaskResultsToPipelineResults_Success(t *testing.T) {
Value: *v1beta1.NewStructuredValues("rae"),
}},
},
skippedTasks: []v1beta1.SkippedTask{{
Name: "skippedTask",
taskstatus: map[string]string{resources.PipelineTaskStatusPrefix + "skippedTask" + resources.PipelineTaskStatusSuffix: resources.PipelineTaskStateNone},
expectedResults: nil,
}, {
description: "unsuccessful-taskrun-no-results",
results: []v1beta1.PipelineResult{{
Name: "foo",
Value: *v1beta1.NewStructuredValues("$(tasks.pt1.results.foo)"),
}},
taskResults: map[string][]v1beta1.TaskRunResult{},
taskstatus: map[string]string{resources.PipelineTaskStatusPrefix + "pt1" + resources.PipelineTaskStatusSuffix: v1beta1.TaskRunReasonFailed.String()},
expectedResults: nil,
}, {
description: "unsuccessful-taskrun-no-returned-result-object-ref",
results: []v1beta1.PipelineResult{{
Name: "foo",
Value: *v1beta1.NewStructuredValues("$(tasks.pt1.results.foo.key1)"),
}},
taskResults: map[string][]v1beta1.TaskRunResult{},
taskstatus: map[string]string{resources.PipelineTaskStatusPrefix + "pt1" + resources.PipelineTaskStatusSuffix: v1beta1.TaskRunReasonFailed.String()},
expectedResults: nil,
}, {
description: "unsuccessful-taskrun-with-results",
results: []v1beta1.PipelineResult{{
Name: "foo",
Value: *v1beta1.NewStructuredValues("$(tasks.pt1.results.foo[*])"),
}},
taskResults: map[string][]v1beta1.TaskRunResult{
"pt1": {
{
Name: "foo",
Value: *v1beta1.NewStructuredValues("do", "rae", "mi"),
},
}},
taskstatus: map[string]string{resources.PipelineTaskStatusPrefix + "pt1" + resources.PipelineTaskStatusSuffix: v1beta1.TaskRunReasonFailed.String()},
expectedResults: []v1beta1.PipelineRunResult{{
Name: "foo",
Value: *v1beta1.NewStructuredValues("do", "rae", "mi"),
}},
}} {
t.Run(tc.description, func(t *testing.T) {
received, err := resources.ApplyTaskResultsToPipelineResults(context.Background(), tc.results, tc.taskResults, tc.runResults, tc.skippedTasks)
received, err := resources.ApplyTaskResultsToPipelineResults(context.Background(), tc.results, tc.taskResults, tc.runResults, tc.taskstatus)
if err != nil {
t.Errorf("Got unecpected error:%v", err)
}
Expand Down Expand Up @@ -3921,15 +3956,6 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) {
},
expectedResults: nil,
expectedError: fmt.Errorf("invalid pipelineresults [foo], the referred results don't exist"),
}, {
description: "unsuccessful-taskrun-no-returned-result",
results: []v1beta1.PipelineResult{{
Name: "foo",
Value: *v1beta1.NewStructuredValues("$(tasks.pt1.results.foo)"),
}},
taskResults: map[string][]v1beta1.TaskRunResult{},
expectedResults: nil,
expectedError: fmt.Errorf("invalid pipelineresults [foo], the referred results don't exist"),
}, {
description: "mixed-success-tasks-some-returned-results",
results: []v1beta1.PipelineResult{{
Expand Down Expand Up @@ -4014,6 +4040,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) {
received, err := resources.ApplyTaskResultsToPipelineResults(context.Background(), tc.results, tc.taskResults, tc.runResults, nil /*skipped tasks*/)
if err == nil {
t.Errorf("Expect error but got nil")
return
}

if d := cmp.Diff(tc.expectedError.Error(), err.Error()); d != "" {
Expand Down

0 comments on commit 474d88c

Please sign in to comment.