diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 522923bb03..087f5a38cb 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -16,6 +16,7 @@ package pipelinerun import ( "context" "fmt" + "reflect" signing "github.com/tektoncd/chains/pkg/chains" "github.com/tektoncd/chains/pkg/chains/objects" @@ -72,8 +73,27 @@ func (r *Reconciler) FinalizeKind(ctx context.Context, pr *v1beta1.PipelineRun) // Get TaskRun names depending on whether embeddedstatus feature is set or not var trs []string - for _, cr := range pr.Status.ChildReferences { - trs = append(trs, cr.Name) + if len(pr.Status.ChildReferences) == 0 { + fieldName := "TaskRuns" + value := reflect.ValueOf(pr.Status) + field := value.FieldByName(fieldName) + if field.IsValid() { + taskRuns := pr.Status.TaskRuns //nolint:golangci-lint //incompatible with pipelines v0.45 + for trName, ptrs := range taskRuns { + // TaskRuns within a PipelineRun may not have been finalized yet if the PipelineRun timeout + // has exceeded. Wait to process the PipelineRun on the next update, see + // https://github.com/tektoncd/pipeline/issues/4916 + if ptrs.Status == nil || ptrs.Status.CompletionTime == nil { + logging.FromContext(ctx).Infof("taskrun %s within pipelinerun is not yet finalized: embedded status is not complete", trName) + return nil + } + trs = append(trs, trName) + } + } + } else { + for _, cr := range pr.Status.ChildReferences { + trs = append(trs, cr.Name) + } } // Signing both taskruns and pipelineruns causes a race condition when using oci storage diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 3ea31e4455..46ff8630f3 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -162,7 +162,52 @@ func TestReconciler_handlePipelineRun(t *testing.T) { shouldSign: false, }, { - name: "taskruns completed", + name: "taskruns completed with full status spec", + pr: &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinerun", + Namespace: "default", + Annotations: map[string]string{}, + }, + Status: v1beta1.PipelineRunStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{Type: apis.ConditionSucceeded}}, + }, + PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ + TaskRuns: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "taskrun1": { + PipelineTaskName: "task1", + Status: &v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + CompletionTime: &metav1.Time{}, + }, + }, + }, + }, + }, + }, + }, + taskruns: []*v1beta1.TaskRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "taskrun1", + Namespace: "default", + Annotations: map[string]string{ + "chains.tekton.dev/signed": "true", + }, + }, + Status: v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + CompletionTime: &v1.Time{Time: time.Date(1995, time.December, 24, 6, 12, 12, 24, time.UTC)}, + }, + }, + }, + }, + shouldSign: true, + wantErr: false, + }, + { + name: "taskruns completed with child references", pr: &v1beta1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{ Name: "pipelinerun", @@ -204,6 +249,43 @@ func TestReconciler_handlePipelineRun(t *testing.T) { }, { name: "taskruns not yet completed", + pr: &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinerun", + Namespace: "default", + Annotations: map[string]string{}, + }, + Status: v1beta1.PipelineRunStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{Type: apis.ConditionSucceeded}}, + }, + PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ + TaskRuns: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "taskrun1": { + PipelineTaskName: "task1", + Status: &v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + CompletionTime: &metav1.Time{}, + }, + }, + }, + }, + }, + }, + }, + taskruns: []*v1beta1.TaskRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "taskrun1", + Namespace: "default", + }, + }, + }, + shouldSign: false, + wantErr: true, + }, + { + name: "taskruns not yet completed with child references", pr: &v1beta1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{ Name: "pipelinerun", @@ -237,6 +319,35 @@ func TestReconciler_handlePipelineRun(t *testing.T) { }, { name: "missing taskrun", + pr: &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinerun", + Namespace: "default", + Annotations: map[string]string{}, + }, + Status: v1beta1.PipelineRunStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{Type: apis.ConditionSucceeded}}, + }, + PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ + TaskRuns: map[string]*v1beta1.PipelineRunTaskRunStatus{ + "taskrun1": { + PipelineTaskName: "task1", + Status: &v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + CompletionTime: &metav1.Time{}, + }, + }, + }, + }, + }, + }, + }, + shouldSign: false, + wantErr: false, + }, + { + name: "missing taskrun with child references", pr: &v1beta1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{ Name: "pipelinerun",