diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md
index 5a07522b52b..3ae4c3e31ee 100644
--- a/docs/pipeline-api.md
+++ b/docs/pipeline-api.md
@@ -1454,6 +1454,17 @@ string
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the TaskRun or Run’s UID
+ |
+
Combination
@@ -2266,6 +2277,17 @@ CustomRunStatus
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the Run’s UID
+ |
+
PipelineRunSpec
@@ -2648,6 +2670,17 @@ TaskRunStatus
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the TaskRun’s UID
+ |
+
PipelineSpec
@@ -9782,6 +9815,17 @@ string
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the TaskRun or Run’s UID
+ |
+
CloudEventCondition
@@ -11073,6 +11117,17 @@ CustomRunStatus
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the Run’s UID
+ |
+
PipelineRunSpec
@@ -11535,6 +11590,17 @@ TaskRunStatus
WhenExpressions is the list of checks guarding the execution of the PipelineTask
+
+
+uid
+
+k8s.io/apimachinery/pkg/types.UID
+
+ |
+
+ UID is the TaskRun’s UID
+ |
+
PipelineSpec
diff --git a/pkg/apis/pipeline/v1/openapi_generated.go b/pkg/apis/pipeline/v1/openapi_generated.go
index b5e5f19fa0a..4a8cf216536 100644
--- a/pkg/apis/pipeline/v1/openapi_generated.go
+++ b/pkg/apis/pipeline/v1/openapi_generated.go
@@ -514,6 +514,13 @@ func schema_pkg_apis_pipeline_v1_ChildStatusReference(ref common.ReferenceCallba
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the TaskRun or Run's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
@@ -1285,6 +1292,13 @@ func schema_pkg_apis_pipeline_v1_PipelineRunRunStatus(ref common.ReferenceCallba
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the Run's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
@@ -1713,6 +1727,13 @@ func schema_pkg_apis_pipeline_v1_PipelineRunTaskRunStatus(ref common.ReferenceCa
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the TaskRun's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
diff --git a/pkg/apis/pipeline/v1/pipelinerun_types.go b/pkg/apis/pipeline/v1/pipelinerun_types.go
index 9c9bcd85566..b252161623a 100644
--- a/pkg/apis/pipeline/v1/pipelinerun_types.go
+++ b/pkg/apis/pipeline/v1/pipelinerun_types.go
@@ -494,6 +494,9 @@ type ChildStatusReference struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+
+ // UID is the TaskRun or Run's UID
+ UID types.UID `json:"uid,omitempty"`
}
// PipelineRunStatusFields holds the fields of PipelineRunStatus' status.
@@ -598,6 +601,8 @@ type PipelineRunTaskRunStatus struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+ // UID is the TaskRun's UID
+ UID types.UID `json:"uid,omitempty"`
}
// PipelineRunRunStatus contains the name of the PipelineTask for this Run and the Run's Status
@@ -611,6 +616,8 @@ type PipelineRunRunStatus struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+ // UID is the Run's UID
+ UID types.UID `json:"uid,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/pkg/apis/pipeline/v1/swagger.json b/pkg/apis/pipeline/v1/swagger.json
index 04538db544b..21a9517ac26 100644
--- a/pkg/apis/pipeline/v1/swagger.json
+++ b/pkg/apis/pipeline/v1/swagger.json
@@ -207,6 +207,10 @@
"description": "PipelineTaskName is the name of the PipelineTask this is referencing.",
"type": "string"
},
+ "uid": {
+ "description": "UID is the TaskRun or Run's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
@@ -621,6 +625,10 @@
"description": "Status is the RunStatus for the corresponding Run",
"$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.run.v1beta1.CustomRunStatus"
},
+ "uid": {
+ "description": "UID is the Run's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
@@ -841,6 +849,10 @@
"description": "Status is the TaskRunStatus for the corresponding TaskRun",
"$ref": "#/definitions/v1.TaskRunStatus"
},
+ "uid": {
+ "description": "UID is the TaskRun's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go
index 75817a84c3a..1a333240ab3 100644
--- a/pkg/apis/pipeline/v1beta1/openapi_generated.go
+++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go
@@ -538,6 +538,13 @@ func schema_pkg_apis_pipeline_v1beta1_ChildStatusReference(ref common.ReferenceC
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the TaskRun or Run's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
@@ -1930,6 +1937,13 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunRunStatus(ref common.ReferenceC
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the Run's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
@@ -2444,6 +2458,13 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunTaskRunStatus(ref common.Refere
},
},
},
+ "uid": {
+ SchemaProps: spec.SchemaProps{
+ Description: "UID is the TaskRun's UID",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
},
},
diff --git a/pkg/apis/pipeline/v1beta1/pipelinerun_conversion.go b/pkg/apis/pipeline/v1beta1/pipelinerun_conversion.go
index 4e9ebf2ac90..3410226a506 100644
--- a/pkg/apis/pipeline/v1beta1/pipelinerun_conversion.go
+++ b/pkg/apis/pipeline/v1beta1/pipelinerun_conversion.go
@@ -332,6 +332,7 @@ func (st *SkippedTask) convertFrom(ctx context.Context, source v1.SkippedTask) {
func (csr ChildStatusReference) convertTo(ctx context.Context, sink *v1.ChildStatusReference) {
sink.TypeMeta = csr.TypeMeta
sink.Name = csr.Name
+ sink.UID = csr.UID
sink.DisplayName = csr.DisplayName
sink.PipelineTaskName = csr.PipelineTaskName
sink.WhenExpressions = nil
@@ -345,6 +346,7 @@ func (csr ChildStatusReference) convertTo(ctx context.Context, sink *v1.ChildSta
func (csr *ChildStatusReference) convertFrom(ctx context.Context, source v1.ChildStatusReference) {
csr.TypeMeta = source.TypeMeta
csr.Name = source.Name
+ csr.UID = source.UID
csr.DisplayName = source.DisplayName
csr.PipelineTaskName = source.PipelineTaskName
csr.WhenExpressions = nil
diff --git a/pkg/apis/pipeline/v1beta1/pipelinerun_conversion_test.go b/pkg/apis/pipeline/v1beta1/pipelinerun_conversion_test.go
index 04397c0708b..a830025810f 100644
--- a/pkg/apis/pipeline/v1beta1/pipelinerun_conversion_test.go
+++ b/pkg/apis/pipeline/v1beta1/pipelinerun_conversion_test.go
@@ -35,6 +35,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
+ "k8s.io/apimachinery/pkg/types"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
@@ -43,6 +44,7 @@ var (
childRefTaskRuns = []v1beta1.ChildStatusReference{{
TypeMeta: runtime.TypeMeta{Kind: "TaskRun", APIVersion: "tekton.dev/v1beta1"},
Name: "tr-0",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
DisplayName: "TR 0",
PipelineTaskName: "ptn",
WhenExpressions: []v1beta1.WhenExpression{{Input: "default-value", Operator: "in", Values: []string{"val"}}},
@@ -50,12 +52,14 @@ var (
childRefRuns = []v1beta1.ChildStatusReference{{
TypeMeta: runtime.TypeMeta{Kind: "Run", APIVersion: "tekton.dev/v1alpha1"},
Name: "r-0",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
DisplayName: "R 0",
PipelineTaskName: "ptn-0",
WhenExpressions: []v1beta1.WhenExpression{{Input: "default-value-0", Operator: "in", Values: []string{"val-0", "val-1"}}},
}}
trs = &v1beta1.PipelineRunTaskRunStatus{
PipelineTaskName: "ptn",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
Status: &v1beta1.TaskRunStatus{
TaskRunStatusFields: v1beta1.TaskRunStatusFields{
PodName: "pod-name",
@@ -88,13 +92,14 @@ var (
},
},
},
- Sidecars: []v1beta1.SidecarState{{ContainerState: corev1.ContainerState{
- Terminated: &corev1.ContainerStateTerminated{
- ExitCode: 1,
- Reason: "Error",
- Message: "Error",
+ Sidecars: []v1beta1.SidecarState{{
+ ContainerState: corev1.ContainerState{
+ Terminated: &corev1.ContainerStateTerminated{
+ ExitCode: 1,
+ Reason: "Error",
+ Message: "Error",
+ },
},
- },
Name: "error",
ImageID: "image-id",
ContainerName: "sidecar-error",
@@ -109,6 +114,7 @@ var (
}
rrs = &v1beta1.PipelineRunRunStatus{
PipelineTaskName: "ptn-0",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
Status: &runv1beta1.CustomRunStatus{
CustomRunStatusFields: runv1beta1.CustomRunStatusFields{
Results: []runv1beta1.CustomRunResult{{
@@ -268,17 +274,21 @@ func TestPipelineRunConversion(t *testing.T) {
},
HostNetwork: false,
},
- StepOverrides: []v1beta1.TaskRunStepOverride{{
- Name: "test-so",
- Resources: corev1.ResourceRequirements{
- Requests: corev1.ResourceList{corev1.ResourceMemory: corev1resources.MustParse("1Gi")},
- }},
+ StepOverrides: []v1beta1.TaskRunStepOverride{
+ {
+ Name: "test-so",
+ Resources: corev1.ResourceRequirements{
+ Requests: corev1.ResourceList{corev1.ResourceMemory: corev1resources.MustParse("1Gi")},
+ },
+ },
},
- SidecarOverrides: []v1beta1.TaskRunSidecarOverride{{
- Name: "test-so",
- Resources: corev1.ResourceRequirements{
- Requests: corev1.ResourceList{corev1.ResourceMemory: corev1resources.MustParse("1Gi")},
- }},
+ SidecarOverrides: []v1beta1.TaskRunSidecarOverride{
+ {
+ Name: "test-so",
+ Resources: corev1.ResourceRequirements{
+ Requests: corev1.ResourceList{corev1.ResourceMemory: corev1resources.MustParse("1Gi")},
+ },
+ },
},
Metadata: &v1beta1.PipelineTaskMetadata{
Labels: map[string]string{
@@ -315,7 +325,8 @@ func TestPipelineRunConversion(t *testing.T) {
Value: *v1beta1.NewObject(map[string]string{
"pkey1": "val1",
"pkey2": "rae",
- })}, {
+ }),
+ }, {
Name: "pipeline-result-2",
Value: *v1beta1.NewObject(map[string]string{
"pkey1": "val2",
@@ -349,6 +360,7 @@ func TestPipelineRunConversion(t *testing.T) {
TypeMeta: runtime.TypeMeta{Kind: "TaskRun"},
Name: "t1",
PipelineTaskName: "task-1",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
WhenExpressions: []v1beta1.WhenExpression{{
Input: "foo",
Operator: "notin",
@@ -358,6 +370,7 @@ func TestPipelineRunConversion(t *testing.T) {
{
TypeMeta: runtime.TypeMeta{Kind: "Run"},
Name: "t2",
+ UID: types.UID("22222222-2222-2222-2222-222222222222"),
PipelineTaskName: "task-2",
},
},
diff --git a/pkg/apis/pipeline/v1beta1/pipelinerun_types.go b/pkg/apis/pipeline/v1beta1/pipelinerun_types.go
index c3a111a978b..82c33e61e1a 100644
--- a/pkg/apis/pipeline/v1beta1/pipelinerun_types.go
+++ b/pkg/apis/pipeline/v1beta1/pipelinerun_types.go
@@ -442,6 +442,9 @@ type ChildStatusReference struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+
+ // UID is the TaskRun or Run's UID
+ UID types.UID `json:"uid,omitempty"`
}
// PipelineRunStatusFields holds the fields of PipelineRunStatus' status.
@@ -562,6 +565,8 @@ type PipelineRunTaskRunStatus struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+ // UID is the TaskRun's UID
+ UID types.UID `json:"uid,omitempty"`
}
// PipelineRunRunStatus contains the name of the PipelineTask for this CustomRun or Run and the CustomRun or Run's Status
@@ -575,6 +580,8 @@ type PipelineRunRunStatus struct {
// +optional
// +listType=atomic
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
+ // UID is the Run's UID
+ UID types.UID `json:"uid,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json
index 00322afb0e1..ad1ab8d4fe2 100644
--- a/pkg/apis/pipeline/v1beta1/swagger.json
+++ b/pkg/apis/pipeline/v1beta1/swagger.json
@@ -207,6 +207,10 @@
"description": "PipelineTaskName is the name of the PipelineTask this is referencing.",
"type": "string"
},
+ "uid": {
+ "description": "UID is the TaskRun or Run's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
@@ -962,6 +966,10 @@
"description": "Status is the CustomRunStatus for the corresponding CustomRun or Run",
"$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.run.v1beta1.CustomRunStatus"
},
+ "uid": {
+ "description": "UID is the Run's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
@@ -1225,6 +1233,10 @@
"description": "Status is the TaskRunStatus for the corresponding TaskRun",
"$ref": "#/definitions/v1beta1.TaskRunStatus"
},
+ "uid": {
+ "description": "UID is the TaskRun's UID",
+ "type": "string"
+ },
"whenExpressions": {
"description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask",
"type": "array",
diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go
index 8756c1282f4..c50f266c191 100644
--- a/pkg/reconciler/pipelinerun/pipelinerun.go
+++ b/pkg/reconciler/pipelinerun/pipelinerun.go
@@ -66,6 +66,7 @@ import (
k8slabels "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/kubernetes"
"k8s.io/utils/clock"
@@ -111,7 +112,7 @@ var (
ReasonFailedValidation = v1.PipelineRunReasonFailedValidation.String()
// ReasonInvalidGraph indicates that the reason for the failure status is that the
// associated Pipeline is an invalid graph (a.k.a wrong order, cycle, …)
- ReasonInvalidGraph = v1.PipelineRunReasonInvalidGraph.String()
+ RewasonInvalidGraph = v1.PipelineRunReasonInvalidGraph.String()
// ReasonCancelled indicates that a PipelineRun was cancelled.
ReasonCancelled = v1.PipelineRunReasonCancelled.String()
// ReasonPending indicates that a PipelineRun is pending.
@@ -338,7 +339,8 @@ func (c *Reconciler) resolvePipelineState(
tasks []v1.PipelineTask,
pipelineMeta *metav1.ObjectMeta,
pr *v1.PipelineRun,
- pst resources.PipelineRunState) (resources.PipelineRunState, error) {
+ pst resources.PipelineRunState,
+) (resources.PipelineRunState, error) {
ctx, span := c.tracerProvider.Tracer(TracerName).Start(ctx, "resolvePipelineState")
defer span.End()
// Resolve each task individually because they each could have a different reference context (remote or local).
@@ -385,9 +387,12 @@ func (c *Reconciler) resolvePipelineState(
"Pipeline %s/%s can't be Run; it contains Tasks that don't exist: %s",
pipelineMeta.Namespace, pipelineMeta.Name, nfErr)
} else {
+ if !strings.Contains(err.Error(), "mismatched UID") {
+ err = pipelineErrors.WrapUserError(err)
+ }
pr.Status.MarkFailed(v1.PipelineRunReasonFailedValidation.String(),
"PipelineRun %s/%s can't be Run; couldn't resolve all references: %s",
- pipelineMeta.Namespace, pr.Name, pipelineErrors.WrapUserError(err))
+ pipelineMeta.Namespace, pr.Name, err)
}
return nil, controller.NewPermanentError(err)
}
@@ -1512,11 +1517,12 @@ func filterTaskRunsForPipelineRunStatus(logger *zap.SugaredLogger, pr *v1.Pipeli
}
// filterCustomRunsForPipelineRunStatus filters the given slice of customRuns, returning information only those owned by the given PipelineRun.
-func filterCustomRunsForPipelineRunStatus(logger *zap.SugaredLogger, pr *v1.PipelineRun, customRuns []*v1beta1.CustomRun) ([]string, []string, []schema.GroupVersionKind, []*v1beta1.CustomRunStatus) {
+func filterCustomRunsForPipelineRunStatus(logger *zap.SugaredLogger, pr *v1.PipelineRun, customRuns []*v1beta1.CustomRun) ([]string, []string, []schema.GroupVersionKind, []*v1beta1.CustomRunStatus, []types.UID) {
var names []string
var taskLabels []string
var gvks []schema.GroupVersionKind
var statuses []*v1beta1.CustomRunStatus
+ var uids []types.UID
// Loop over all the customRuns associated to Tasks
for _, cr := range customRuns {
@@ -1529,13 +1535,14 @@ func filterCustomRunsForPipelineRunStatus(logger *zap.SugaredLogger, pr *v1.Pipe
names = append(names, cr.GetObjectMeta().GetName())
taskLabels = append(taskLabels, cr.GetObjectMeta().GetLabels()[pipeline.PipelineTaskLabelKey])
+ uids = append(uids, cr.GetObjectMeta().GetUID())
statuses = append(statuses, &cr.Status)
// We can't just get the gvk from the customRun's TypeMeta because that isn't populated for resources created through the fake client.
gvks = append(gvks, v1beta1.SchemeGroupVersion.WithKind(customRun))
}
- return names, taskLabels, gvks, statuses
+ return names, taskLabels, gvks, statuses, uids
}
func updatePipelineRunStatusFromChildRefs(logger *zap.SugaredLogger, pr *v1.PipelineRun, trs []*v1.TaskRun, customRuns []*v1beta1.CustomRun) {
@@ -1572,18 +1579,20 @@ func updatePipelineRunStatusFromChildRefs(logger *zap.SugaredLogger, pr *v1.Pipe
},
Name: tr.Name,
PipelineTaskName: pipelineTaskName,
+ UID: tr.UID,
}
}
}
// Get the names, their task label values, and their group/version/kind info for all CustomRuns or Runs associated with the PipelineRun
- names, taskLabels, gvks, _ := filterCustomRunsForPipelineRunStatus(logger, pr, customRuns)
+ names, taskLabels, gvks, _, uids := filterCustomRunsForPipelineRunStatus(logger, pr, customRuns)
// Loop over that data and populate the child references
for idx := range names {
name := names[idx]
taskLabel := taskLabels[idx]
gvk := gvks[idx]
+ uid := uids[idx]
if _, ok := childRefByName[name]; !ok {
// This run was missing from the status.
@@ -1598,6 +1607,7 @@ func updatePipelineRunStatusFromChildRefs(logger *zap.SugaredLogger, pr *v1.Pipe
},
Name: name,
PipelineTaskName: taskLabel,
+ UID: uid,
}
}
}
diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go
index 71d1e776f1c..dc62daf9cb8 100644
--- a/pkg/reconciler/pipelinerun/pipelinerun_test.go
+++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go
@@ -332,7 +332,8 @@ spec:
type: string
- name: contextRetriesParam
type: string
-`)}
+`),
+ }
clusterTasks := []*v1beta1.ClusterTask{
parse.MustParseClusterTask(t, `
metadata:
@@ -347,7 +348,8 @@ spec:
type: string
- name: contextPipelineParam
type: string
-`)}
+`),
+ }
d := test.Data{
PipelineRuns: prs,
@@ -713,7 +715,8 @@ spec:
`, v1.ParamTypeObject)),
}
- ps := []*v1.Pipeline{parse.MustParseV1Pipeline(t, `
+ ps := []*v1.Pipeline{
+ parse.MustParseV1Pipeline(t, `
metadata:
name: pipeline-missing-tasks
namespace: foo
@@ -793,6 +796,7 @@ spec:
for _, tc := range []struct {
name string
pipelineRun *v1.PipelineRun
+ taskRuns []*v1.TaskRun
reason string
hasNoDefaultLabels bool
permanentError bool
@@ -1020,14 +1024,62 @@ spec:
"Normal Started",
"Warning Failed [User error] PipelineRun foo/pipeline-invalid-final-graph's Pipeline DAG is invalid for finally clause: task final-task-1 is already present in Graph, can't add it again: duplicate pipeline task",
},
+ }, {
+ name: "mismatched-taskrun-uid",
+ pipelineRun: parse.MustParseV1PipelineRun(t, `
+metadata:
+ name: pipeline-with-mismatched-taskrun-uid
+ namespace: foo
+spec:
+ pipelineSpec:
+ tasks:
+ - name: hello-world-task-1
+ taskSpec:
+ steps:
+ - image: myimage
+ name: mystep
+status:
+ conditions:
+ - status: Unknown
+ type: Succeeded
+ startTime: "2021-12-31T23:58:59Z"
+ childReferences:
+ - apiVersion: tekton.dev/v1beta1
+ kind: TaskRun
+ name: mismatched-taskrun-uid-task
+ pipelineTaskName: hello-world-task-1
+ uid: 11111111-1111-1111-1111-111111111111
+`),
+ taskRuns: []*v1.TaskRun{mustParseTaskRunWithObjectMeta(t,
+ taskRunObjectMetaWithUID("mismatched-taskrun-uid-task", "foo",
+ "pipeline-with-mismatched-taskrun-uid", "", "hello-world-task-1", true,
+ "22222222-2222-2222-2222-222222222222"),
+ `
+spec:
+ taskSpec:
+ steps:
+ - image: otherImage
+ name: otherStep
+status:
+ conditions:
+ - status: "Unknown"
+ type: Succeeded
+`)},
+ reason: ReasonFailedValidation,
+ permanentError: true,
+ wantEvents: []string{
+ "Warning Failed PipelineRun foo/pipeline-with-mismatched-taskrun-uid can't be Run; couldn't resolve all references: mismatched UID for TaskRun mismatched-taskrun-uid-task; expected 11111111-1111-1111-1111-111111111111, found 22222222-2222-2222-2222-222222222222",
+ },
}} {
t.Run(tc.name, func(t *testing.T) {
+ tc := tc
cms := []*corev1.ConfigMap{withEnabledAlphaAPIFields(newFeatureFlagsConfigMap())}
d := test.Data{
PipelineRuns: []*v1.PipelineRun{tc.pipelineRun},
Pipelines: ps,
Tasks: ts,
+ TaskRuns: tc.taskRuns,
ConfigMaps: cms,
}
prt := newPipelineRunTest(t, d)
@@ -1192,8 +1244,7 @@ status:
value: 123
`)}
- expectedPipelineRun :=
- parse.MustParseV1PipelineRun(t, `
+ expectedPipelineRun := parse.MustParseV1PipelineRun(t, `
metadata:
name: test-pipeline-missing-results
namespace: foo
@@ -2199,14 +2250,15 @@ status:
"hello-world",
corev1.ConditionTrue,
)},
- initialChildReferences: []v1.ChildStatusReference{{
- TypeMeta: runtime.TypeMeta{
- APIVersion: v1.SchemeGroupVersion.String(),
- Kind: "TaskRun",
+ initialChildReferences: []v1.ChildStatusReference{
+ {
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: "TaskRun",
+ },
+ Name: "test-pipeline-run-stopped-run-finally-hello-world",
+ PipelineTaskName: "hello-world-1",
},
- Name: "test-pipeline-run-stopped-run-finally-hello-world",
- PipelineTaskName: "hello-world-1",
- },
},
expectedEvents: []string{"Warning Failed PipelineRun \"test-pipeline-run-stopped-run-finally\" was cancelled"},
hasNilCompletionTime: false,
@@ -2876,7 +2928,8 @@ spec:
taskRef:
name: hello-world
kind: Task
-`)}
+`),
+ }
oneStartedTRs := []*v1.TaskRun{
getTaskRun(
t,
@@ -3159,7 +3212,8 @@ spec:
taskRef:
name: hello-world
kind: Task
-`)},
+`),
+ },
ps: []*v1.Pipeline{pipelineFinalTask},
pr: parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
metadata:
@@ -4102,7 +4156,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -4293,7 +4346,6 @@ spec:
LabelSelector: fmt.Sprintf("tekton.dev/pipelineTask=%s,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", taskName),
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRuns %s", err)
}
@@ -4451,7 +4503,6 @@ status:
LabelSelector: "tekton.dev/pipelineTask=c-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRuns %s", err)
}
@@ -4596,7 +4647,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -4762,7 +4812,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=f-c-task,tekton.dev/pipelineRun=test-pipeline-run-different-final-task-when",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -5820,7 +5869,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -6178,7 +6226,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-variable-substitution",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -6777,7 +6824,7 @@ metadata:
resolvedObjectMeta *resolutionutil.ResolvedObjectMeta
}
- var tests = []struct {
+ tests := []struct {
name string
reconcile1Args *args
reconcile2Args *args
@@ -7631,7 +7678,8 @@ func TestReconcilePipeline_FinalTasks(t *testing.T) {
// checkTaskRunStatusFromChildRefs checks the status of taskruns from ChildReferences to be expected.
func checkTaskRunStatusFromChildRefs(ctx context.Context, t *testing.T, namespace string, clients test.Clients,
- childRefs []v1.ChildStatusReference, expectedTaskRuns map[string]*v1.PipelineRunTaskRunStatus) {
+ childRefs []v1.ChildStatusReference, expectedTaskRuns map[string]*v1.PipelineRunTaskRunStatus,
+) {
t.Helper()
taskrunsToCheck := len(expectedTaskRuns)
if taskrunsToCheck == 0 {
@@ -7960,7 +8008,8 @@ spec:
params:
- name: pipelineRun-tasks-task1
type: string
-`)}
+`),
+ }
trs := []*v1.TaskRun{mustParseTaskRunWithObjectMeta(t,
taskRunObjectMeta(pipelineRunName+"-task1-xxyy", "foo", pipelineRunName, pipelineName, "task1", false),
@@ -8006,7 +8055,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=finaltask,tekton.dev/pipelineRun=" + pipelineRunName,
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -8212,7 +8260,6 @@ spec:
LabelSelector: "tekton.dev/pipelineTask=final-task-1,tekton.dev/pipelineRun=test-pipeline-run-final-task-results",
Limit: 1,
})
-
if err != nil {
t.Fatalf("Failure to list TaskRun's %s", err)
}
@@ -8781,7 +8828,7 @@ spec:
}
// Mock a successful resolution
- var pipelineBytes = []byte(`
+ pipelineBytes := []byte(`
kind: Pipeline
apiVersion: tekton.dev/v1
metadata:
@@ -9046,6 +9093,12 @@ func baseObjectMeta(name, ns string) metav1.ObjectMeta {
}
}
+func taskRunObjectMetaWithUID(trName, ns, prName, pipelineName, pipelineTaskName string, skipMemberOfLabel bool, uid string) metav1.ObjectMeta {
+ om := taskRunObjectMeta(trName, ns, prName, pipelineName, pipelineTaskName, skipMemberOfLabel)
+ om.UID = types.UID(uid)
+ return om
+}
+
func taskRunObjectMeta(trName, ns, prName, pipelineName, pipelineTaskName string, skipMemberOfLabel bool) metav1.ObjectMeta {
om := metav1.ObjectMeta{
Name: trName,
@@ -9138,6 +9191,7 @@ spec:
status:
startTime: %s`, prName, specStatus, now.Format(time.RFC3339)))
}
+
func verifyTaskRunStatusesCount(t *testing.T, prStatus v1.PipelineRunStatus, taskCount int) {
t.Helper()
@@ -9145,6 +9199,7 @@ func verifyTaskRunStatusesCount(t *testing.T, prStatus v1.PipelineRunStatus, tas
t.Errorf("Expected PipelineRun status ChildReferences to have %d tasks, but was %d", taskCount, len(filterChildRefsForKind(prStatus.ChildReferences, taskRun)))
}
}
+
func verifyTaskRunStatusesNames(t *testing.T, prStatus v1.PipelineRunStatus, taskNames ...string) {
t.Helper()
@@ -9258,9 +9313,10 @@ func TestGetTaskrunWorkspaces_Failure(t *testing.T) {
name string
pr *v1.PipelineRun
expectedError string
- }{{
- name: "failure declaring workspace with different name",
- pr: parse.MustParseV1PipelineRun(t, `
+ }{
+ {
+ name: "failure declaring workspace with different name",
+ pr: parse.MustParseV1PipelineRun(t, `
metadata:
name: pipeline
spec:
@@ -9274,8 +9330,8 @@ spec:
workspaces:
- name: not-source
`),
- expectedError: `expected workspace "not-source" to be provided by pipelinerun for pipeline task "resolved-pipelinetask"`,
- },
+ expectedError: `expected workspace "not-source" to be provided by pipelinerun for pipeline task "resolved-pipelinetask"`,
+ },
{
name: "failure mapping workspace with different name",
pr: parse.MustParseV1PipelineRun(t, `
@@ -9367,24 +9423,25 @@ func TestGetTaskrunWorkspaces_Success(t *testing.T) {
name string
pr *v1.PipelineRun
rprt *resources.ResolvedPipelineTask
- }{{
- name: "valid declaration of workspace names",
- pr: parse.MustParseV1PipelineRun(t, `
+ }{
+ {
+ name: "valid declaration of workspace names",
+ pr: parse.MustParseV1PipelineRun(t, `
metadata:
name: pipeline
spec:
workspaces:
- name: source`),
- rprt: &resources.ResolvedPipelineTask{
- PipelineTask: &v1.PipelineTask{
- Name: "resolved-pipelinetask",
- Workspaces: []v1.WorkspacePipelineTaskBinding{{
- Name: "my-task-workspace",
- Workspace: "source",
- }},
+ rprt: &resources.ResolvedPipelineTask{
+ PipelineTask: &v1.PipelineTask{
+ Name: "resolved-pipelinetask",
+ Workspaces: []v1.WorkspacePipelineTaskBinding{{
+ Name: "my-task-workspace",
+ Workspace: "source",
+ }},
+ },
},
},
- },
{
name: "valid mapping with same workspace names",
pr: parse.MustParseV1PipelineRun(t, `
@@ -9460,7 +9517,6 @@ spec:
KubeClientSet: fakek8s.NewSimpleClientset(),
}
_, _, err := c.getTaskrunWorkspaces(context.Background(), tt.pr, tt.rprt)
-
if err != nil {
t.Errorf("Pipeline.getTaskrunWorkspaces() returned error for valid pipeline: %v", err)
}
@@ -10470,6 +10526,7 @@ labels:
})
}
}
+
func TestReconciler_PipelineTaskIncludeParams(t *testing.T) {
names.TestingSeed()
@@ -11102,10 +11159,11 @@ spec:
p *v1.Pipeline
tr *v1.TaskRun
expectedPipelineRun *v1.PipelineRun
- }{{
- name: "p-dag",
- memberOf: "tasks",
- p: parse.MustParseV1Pipeline(t, fmt.Sprintf(`
+ }{
+ {
+ name: "p-dag",
+ memberOf: "tasks",
+ p: parse.MustParseV1Pipeline(t, fmt.Sprintf(`
metadata:
name: %s
namespace: foo
@@ -11135,7 +11193,7 @@ spec:
- name: DOCKERFILE
value: path/to/Dockerfile3
`, "p-dag")),
- expectedPipelineRun: parse.MustParseV1PipelineRun(t, `
+ expectedPipelineRun: parse.MustParseV1PipelineRun(t, `
metadata:
name: pr
namespace: foo
@@ -11196,7 +11254,7 @@ status:
displayName: build-3
pipelineTaskName: matrix-include
`),
- },
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -13666,12 +13724,11 @@ spec:
if tt.tr != nil {
d.TaskRuns = []*v1.TaskRun{tt.tr}
}
- wantEvents :=
- []string{
- "Normal Started",
- "Warning Failed [User error] PipelineRun foo/pr can't be Run; couldn't resolve all references: array Result Index 3 for Task pt-with-result Result platforms is out of bound of size 3",
- "Warning InternalError 1 error occurred:",
- }
+ wantEvents := []string{
+ "Normal Started",
+ "Warning Failed [User error] PipelineRun foo/pr can't be Run; couldn't resolve all references: array Result Index 3 for Task pt-with-result Result platforms is out of bound of size 3",
+ "Warning InternalError 1 error occurred:",
+ }
prt := newPipelineRunTest(t, d)
defer prt.Cancel()
pipelineRun, clients := prt.reconcileRun(pr.Namespace, pr.Name, wantEvents /* wantEvents*/, true /* permanentError*/)
@@ -15526,6 +15583,7 @@ spec:
})
}
}
+
func TestReconcile_SetDefaults(t *testing.T) {
names.TestingSeed()
@@ -15757,7 +15815,8 @@ spec:
expectedComputeResources: []corev1.ResourceRequirements{{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1"),
- corev1.ResourceMemory: resource.MustParse("1Gi")},
+ corev1.ResourceMemory: resource.MustParse("1Gi"),
+ },
Limits: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("2")},
}},
}}
@@ -15848,6 +15907,7 @@ spec:
t.Fatalf("Should have filtered chains.tekton.dev/* and results.tekton.dev/* annotations and only have one annotations, got %v", tr.ObjectMeta.Annotations)
}
}
+
func TestReconcile_CancelUnscheduled(t *testing.T) {
pipelineRunName := "cancel-test-run"
prs := []*v1.PipelineRun{parse.MustParseV1PipelineRun(t, `metadata:
@@ -15969,7 +16029,8 @@ spec:
},
Spec: v1alpha1.VerificationPolicySpec{
Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}},
- }}}
+ },
+ }}
// warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run
warnPolicy := []*v1alpha1.VerificationPolicy{{
ObjectMeta: metav1.ObjectMeta{
@@ -15979,7 +16040,8 @@ spec:
Spec: v1alpha1.VerificationPolicySpec{
Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}},
Mode: v1alpha1.ModeWarn,
- }}}
+ },
+ }}
prs := parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
metadata:
@@ -16010,27 +16072,28 @@ spec:
noMatchPolicy string
verificationPolicies []*v1alpha1.VerificationPolicy
wantTrustedResourcesCondition *apis.Condition
- }{{
- name: "ignore no match policy",
- noMatchPolicy: config.IgnoreNoMatchPolicy,
- verificationPolicies: noMatchPolicy,
- wantTrustedResourcesCondition: nil,
- }, {
- name: "warn no match policy",
- noMatchPolicy: config.WarnNoMatchPolicy,
- verificationPolicies: noMatchPolicy,
- wantTrustedResourcesCondition: failNoMatchCondition,
- }, {
- name: "pass enforce policy",
- noMatchPolicy: config.FailNoMatchPolicy,
- verificationPolicies: vps,
- wantTrustedResourcesCondition: passCondition,
- }, {
- name: "only fail warn policy",
- noMatchPolicy: config.FailNoMatchPolicy,
- verificationPolicies: warnPolicy,
- wantTrustedResourcesCondition: failNoKeysCondition,
- },
+ }{
+ {
+ name: "ignore no match policy",
+ noMatchPolicy: config.IgnoreNoMatchPolicy,
+ verificationPolicies: noMatchPolicy,
+ wantTrustedResourcesCondition: nil,
+ }, {
+ name: "warn no match policy",
+ noMatchPolicy: config.WarnNoMatchPolicy,
+ verificationPolicies: noMatchPolicy,
+ wantTrustedResourcesCondition: failNoMatchCondition,
+ }, {
+ name: "pass enforce policy",
+ noMatchPolicy: config.FailNoMatchPolicy,
+ verificationPolicies: vps,
+ wantTrustedResourcesCondition: passCondition,
+ }, {
+ name: "only fail warn policy",
+ noMatchPolicy: config.FailNoMatchPolicy,
+ verificationPolicies: warnPolicy,
+ wantTrustedResourcesCondition: failNoKeysCondition,
+ },
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -16303,7 +16366,8 @@ spec:
},
Spec: v1alpha1.VerificationPolicySpec{
Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}},
- }}}
+ },
+ }}
// warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run
warnPolicy := []*v1alpha1.VerificationPolicy{{
ObjectMeta: metav1.ObjectMeta{
@@ -16313,7 +16377,8 @@ spec:
Spec: v1alpha1.VerificationPolicySpec{
Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}},
Mode: v1alpha1.ModeWarn,
- }}}
+ },
+ }}
prs := parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
metadata:
@@ -16344,27 +16409,28 @@ spec:
noMatchPolicy string
verificationPolicies []*v1alpha1.VerificationPolicy
wantTrustedResourcesCondition *apis.Condition
- }{{
- name: "ignore no match policy",
- noMatchPolicy: config.IgnoreNoMatchPolicy,
- verificationPolicies: noMatchPolicy,
- wantTrustedResourcesCondition: nil,
- }, {
- name: "warn no match policy",
- noMatchPolicy: config.WarnNoMatchPolicy,
- verificationPolicies: noMatchPolicy,
- wantTrustedResourcesCondition: failNoMatchCondition,
- }, {
- name: "pass enforce policy",
- noMatchPolicy: config.FailNoMatchPolicy,
- verificationPolicies: vps,
- wantTrustedResourcesCondition: passCondition,
- }, {
- name: "only fail warn policy",
- noMatchPolicy: config.FailNoMatchPolicy,
- verificationPolicies: warnPolicy,
- wantTrustedResourcesCondition: failNoKeysCondition,
- },
+ }{
+ {
+ name: "ignore no match policy",
+ noMatchPolicy: config.IgnoreNoMatchPolicy,
+ verificationPolicies: noMatchPolicy,
+ wantTrustedResourcesCondition: nil,
+ }, {
+ name: "warn no match policy",
+ noMatchPolicy: config.WarnNoMatchPolicy,
+ verificationPolicies: noMatchPolicy,
+ wantTrustedResourcesCondition: failNoMatchCondition,
+ }, {
+ name: "pass enforce policy",
+ noMatchPolicy: config.FailNoMatchPolicy,
+ verificationPolicies: vps,
+ wantTrustedResourcesCondition: passCondition,
+ }, {
+ name: "only fail warn policy",
+ noMatchPolicy: config.FailNoMatchPolicy,
+ verificationPolicies: warnPolicy,
+ wantTrustedResourcesCondition: failNoKeysCondition,
+ },
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -16638,7 +16704,8 @@ spec:
echo "hello world"
workspaces:
- name: source
-`)}
+`),
+ }
trs := []*v1.TaskRun{}
@@ -17075,7 +17142,8 @@ status:
type: string
value: bar-value
startTime: "2023-10-03T10:55:12Z"
-`)}
+`),
+ }
d := test.Data{
PipelineRuns: prs,
diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go
index 6f1cadc34af..440f72fc27b 100644
--- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go
+++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go
@@ -33,6 +33,7 @@ import (
"github.com/tektoncd/pipeline/pkg/remote"
"github.com/tektoncd/pipeline/pkg/substitution"
kerrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
"knative.dev/pkg/apis"
"knative.dev/pkg/kmeta"
)
@@ -590,9 +591,42 @@ func ResolvePipelineTask(
}
}
}
+
+ existingPipelineTaskUIDs := getPipelineTaskUIDs(pipelineRun.Status)
+
+ for _, run := range rpt.CustomRuns {
+ if run == nil {
+ continue
+ }
+ if existingUID, ok := existingPipelineTaskUIDs[run.GetObjectMeta().GetName()]; ok && existingUID != run.GetObjectMeta().GetUID() && existingUID != "" {
+ return nil, fmt.Errorf("mismatched UID for Run %s; expected %s, found %s", run.GetObjectMeta().GetName(), existingUID, run.GetObjectMeta().GetUID())
+ }
+ }
+
+ for _, tr := range rpt.TaskRuns {
+ if tr == nil {
+ continue
+ }
+ if existingUID, ok := existingPipelineTaskUIDs[tr.Name]; ok && existingUID != tr.UID && existingUID != "" {
+ return nil, fmt.Errorf("mismatched UID for TaskRun %s; expected %s, found %s", tr.Name, existingUID, tr.UID)
+ }
+ }
+
return &rpt, nil
}
+func getPipelineTaskUIDs(prs v1.PipelineRunStatus) map[string]types.UID {
+ m := make(map[string]types.UID)
+
+ if len(prs.ChildReferences) > 0 {
+ for _, cr := range prs.ChildReferences {
+ m[cr.Name] = cr.UID
+ }
+ return m
+ }
+ return m
+}
+
// setTaskRunsAndResolvedTask fetches the named TaskRun using the input function getTaskRun,
// and the resolved Task spec of the Pipeline Task using the input function getTask.
// It updates the ResolvedPipelineTask with the ResolvedTask and a pointer to the fetched TaskRun.
diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go
index a1633b68ea6..9f1fefc6ba4 100644
--- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go
+++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go
@@ -35,6 +35,7 @@ import (
"github.com/tektoncd/pipeline/pkg/trustedresources"
"github.com/tektoncd/pipeline/test/diff"
"github.com/tektoncd/pipeline/test/names"
+ "github.com/tektoncd/pipeline/test/parse"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -48,9 +49,11 @@ import (
func nopGetCustomRun(string) (*v1beta1.CustomRun, error) {
return nil, errors.New("GetRun should not be called")
}
+
func nopGetTask(context.Context, string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) {
return nil, nil, nil, errors.New("GetTask should not be called")
}
+
func nopGetTaskRun(string) (*v1.TaskRun, error) {
return nil, errors.New("GetTaskRun should not be called")
}
@@ -128,14 +131,16 @@ var pts = []v1.PipelineTask{{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}, {
Name: "mytask17",
Matrix: &v1.Matrix{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}, {
Name: "mytask18",
TaskRef: &v1.TaskRef{Name: "task"},
@@ -144,7 +149,8 @@ var pts = []v1.PipelineTask{{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}, {
Name: "mytask19",
TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "customtask"},
@@ -152,7 +158,8 @@ var pts = []v1.PipelineTask{{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}, {
Name: "mytask20",
TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "customtask"},
@@ -160,7 +167,8 @@ var pts = []v1.PipelineTask{{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}, {
Name: "mytask21",
TaskRef: &v1.TaskRef{Name: "task"},
@@ -169,7 +177,8 @@ var pts = []v1.PipelineTask{{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}}
var p = &v1.Pipeline{
@@ -243,12 +252,14 @@ var matrixedPipelineTask = &v1.PipelineTask{
Image: "bash:latest",
Script: `#!/usr/bin/env bash\necho -n "$(params.browser)" | sha256sum | tee $(results.BROWSER.path)"`,
}},
- }},
+ },
+ },
Matrix: &v1.Matrix{
Params: v1.Params{{
Name: "browser",
Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}},
- }}},
+ }},
+ },
}
func makeScheduled(tr v1.TaskRun) *v1.TaskRun {
@@ -1137,7 +1148,8 @@ func TestIsSkipped(t *testing.T) {
Type: v1.ParamTypeArray,
ArrayVal: []string{"foo", "bar"},
},
- }}},
+ }},
+ },
},
TaskRunNames: []string{"pipelinerun-matrix-empty-params"},
TaskRuns: nil,
@@ -1156,7 +1168,8 @@ func TestIsSkipped(t *testing.T) {
Type: v1.ParamTypeArray,
ArrayVal: []string{},
},
- }}},
+ }},
+ },
},
TaskRunNames: []string{"pipelinerun-matrix-empty-params"},
TaskRuns: nil,
@@ -1181,7 +1194,8 @@ func TestIsSkipped(t *testing.T) {
Type: v1.ParamTypeArray,
ArrayVal: []string{},
},
- }}},
+ }},
+ },
},
TaskRunNames: []string{"pipelinerun-matrix-empty-params"},
TaskRuns: nil,
@@ -2317,7 +2331,8 @@ func TestSkipBecauseParentTaskWasSkipped(t *testing.T) {
}
func getExpectedMessage(runName string, specStatus v1.PipelineRunSpecStatus, status corev1.ConditionStatus,
- successful, incomplete, skipped, failed, cancelled int) string {
+ successful, incomplete, skipped, failed, cancelled int,
+) string {
if status == corev1.ConditionFalse &&
(specStatus == v1.PipelineRunSpecStatusCancelledRunFinally ||
specStatus == v1.PipelineRunSpecStatusStoppedRunFinally) {
@@ -2475,7 +2490,8 @@ func TestResolvePipelineRun_TaskDoesntExist(t *testing.T) {
Name: "bar",
Value: *v1.NewStructuredValues("b", "a", "r"),
}},
- }}}
+ },
+ }}
// Return an error when the Task is retrieved, as if it didn't exist
getTask := func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) {
@@ -2518,7 +2534,8 @@ func TestResolvePipelineRun_VerificationFailed(t *testing.T) {
Name: "bar",
Value: *v1.NewStructuredValues("b", "a", "r"),
}},
- }}}
+ },
+ }}
verificationResult := &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationError, Err: trustedresources.ErrResourceVerificationFailed}
getTask := func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) {
return task, nil, verificationResult, nil
@@ -2537,6 +2554,71 @@ func TestResolvePipelineRun_VerificationFailed(t *testing.T) {
}
}
+func TestResolvePipelineRun_MismatchedTaskRunUID(t *testing.T) {
+ names.TestingSeed()
+
+ p := &v1.Pipeline{
+ ObjectMeta: metav1.ObjectMeta{Name: "pipelines"},
+ Spec: v1.PipelineSpec{
+ Tasks: []v1.PipelineTask{
+ {
+ Name: "mytask1",
+ TaskSpec: &v1.EmbeddedTask{
+ TaskSpec: v1.TaskSpec{
+ Steps: []v1.Step{{Name: "step1"}},
+ },
+ },
+ },
+ },
+ },
+ }
+
+ pr := v1.PipelineRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "pipelinerun",
+ },
+ Status: v1.PipelineRunStatus{
+ PipelineRunStatusFields: v1.PipelineRunStatusFields{
+ ChildReferences: []v1.ChildStatusReference{{
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.Version,
+ Kind: "TaskRun",
+ },
+ Name: "mytask1-1",
+ PipelineTaskName: "mytask1",
+ UID: "11111111-1111-1111-1111-111111111111",
+ }},
+ },
+ },
+ }
+ // The Task "task" doesn't actually take any inputs or outputs, but validating
+ // that is not done as part of Run resolution
+ getTask := func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) {
+ return nil, nil, nil, nil
+ }
+ getTaskRun := func(name string) (*v1.TaskRun, error) {
+ return parse.MustParseV1TaskRun(t, `
+metadata:
+ name: mytask1-1
+ uid: 22222222-2222-2222-2222-222222222222
+spec:
+ steps:
+ - name: mystep
+ image: myimage
+`), nil
+ }
+
+ _, err := ResolvePipelineTask(context.Background(), pr, getTask, getTaskRun, nopGetCustomRun, p.Spec.Tasks[0], nil)
+ if err == nil {
+ t.Fatalf("Expected error getting tasks for fake pipeline %s, but did not get one", p.ObjectMeta.Name)
+ }
+
+ expectedErrStr := "mismatched UID for TaskRun mytask1-1; expected 11111111-1111-1111-1111-111111111111, found 22222222-2222-2222-2222-222222222222"
+ if err.Error() != expectedErrStr {
+ t.Fatalf("Expected error %s, but got %s", expectedErrStr, err.Error())
+ }
+}
+
func TestValidateWorkspaceBindingsWithValidWorkspaces(t *testing.T) {
for _, tc := range []struct {
name string
@@ -2984,7 +3066,8 @@ func TestResolvedPipelineRunTask_IsFinallySkipped(t *testing.T) {
Params: v1.Params{{
Name: "platform",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{}},
- }}},
+ }},
+ },
},
}}
@@ -3206,7 +3289,8 @@ func TestResolvedPipelineRunTask_IsFinallySkippedByCondition(t *testing.T) {
},
},
},
- }},
+ },
+ },
want: TaskSkipStatus{
IsSkipped: false,
SkippingReason: v1.None,
@@ -3271,23 +3355,24 @@ func TestResolvedPipelineRunTask_IsFinalTask(t *testing.T) {
},
}
- state := PipelineRunState{{
- TaskRunNames: []string{"dag-task"},
- TaskRuns: []*v1.TaskRun{tr},
- PipelineTask: &v1.PipelineTask{
- Name: "dag-task",
- TaskRef: &v1.TaskRef{Name: "task"},
- },
- }, {
- PipelineTask: &v1.PipelineTask{
- Name: "final-task",
- TaskRef: &v1.TaskRef{Name: "task"},
- Params: v1.Params{{
- Name: "commit",
- Value: *v1.NewStructuredValues("$(tasks.dag-task.results.commit)"),
- }},
+ state := PipelineRunState{
+ {
+ TaskRunNames: []string{"dag-task"},
+ TaskRuns: []*v1.TaskRun{tr},
+ PipelineTask: &v1.PipelineTask{
+ Name: "dag-task",
+ TaskRef: &v1.TaskRef{Name: "task"},
+ },
+ }, {
+ PipelineTask: &v1.PipelineTask{
+ Name: "final-task",
+ TaskRef: &v1.TaskRef{Name: "task"},
+ Params: v1.Params{{
+ Name: "commit",
+ Value: *v1.NewStructuredValues("$(tasks.dag-task.results.commit)"),
+ }},
+ },
},
- },
}
tasks := v1.PipelineTaskList([]v1.PipelineTask{*state[0].PipelineTask})
@@ -3575,7 +3660,8 @@ func TestIsMatrixed(t *testing.T) {
Params: v1.Params{{
Name: "platform",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}},
- }}},
+ }},
+ },
},
want: true,
}, {
@@ -3597,7 +3683,8 @@ func TestIsMatrixed(t *testing.T) {
Params: v1.Params{{
Name: "platform",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}},
- }}},
+ }},
+ },
},
want: true,
}, {
@@ -3665,7 +3752,8 @@ func TestResolvePipelineRunTask_WithMatrix(t *testing.T) {
Params: v1.Params{{
Name: "platform",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}},
- }}},
+ }},
+ },
}, {
Name: "pipelinetask",
TaskRef: &v1.TaskRef{
@@ -3699,7 +3787,7 @@ func TestResolvePipelineRunTask_WithMatrix(t *testing.T) {
}}},
}
- var pipelineRunState = PipelineRunState{{
+ pipelineRunState := PipelineRunState{{
TaskRunNames: []string{"get-platforms"},
TaskRuns: []*v1.TaskRun{{
ObjectMeta: metav1.ObjectMeta{
@@ -3824,7 +3912,8 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) {
Params: v1.Params{{
Name: "platform",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}},
- }}},
+ }},
+ },
}, {
Name: "pipelinetask",
TaskRef: &v1.TaskRef{
@@ -3839,7 +3928,8 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) {
}, {
Name: "browsers",
Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"chrome", "safari", "firefox"}},
- }}},
+ }},
+ },
}, {
Name: "customTask-with-whole-array-results",
TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "aTask"},
@@ -3849,7 +3939,7 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) {
}},
}}
- var pipelineRunState = PipelineRunState{{
+ pipelineRunState := PipelineRunState{{
TaskRunNames: []string{"get-platforms"},
TaskRuns: []*v1.TaskRun{{
ObjectMeta: metav1.ObjectMeta{
@@ -4997,25 +5087,26 @@ func TestEvaluateCEL_invalid(t *testing.T) {
for _, tc := range []struct {
name string
rpt *ResolvedPipelineTask
- }{{
- name: "compile error - token unrecogniezd",
- rpt: &ResolvedPipelineTask{
- PipelineTask: &v1.PipelineTask{
- When: v1.WhenExpressions{{
- CEL: "$(params.foo)=='foo'",
- }},
+ }{
+ {
+ name: "compile error - token unrecogniezd",
+ rpt: &ResolvedPipelineTask{
+ PipelineTask: &v1.PipelineTask{
+ When: v1.WhenExpressions{{
+ CEL: "$(params.foo)=='foo'",
+ }},
+ },
},
- },
- }, {
- name: "CEL result is not true or false",
- rpt: &ResolvedPipelineTask{
- PipelineTask: &v1.PipelineTask{
- When: v1.WhenExpressions{{
- CEL: "{'blue': '0x000080', 'red': '0xFF0000'}['red']",
- }},
+ }, {
+ name: "CEL result is not true or false",
+ rpt: &ResolvedPipelineTask{
+ PipelineTask: &v1.PipelineTask{
+ When: v1.WhenExpressions{{
+ CEL: "{'blue': '0x000080', 'red': '0xFF0000'}['red']",
+ }},
+ },
},
},
- },
} {
t.Run(tc.name, func(t *testing.T) {
err := tc.rpt.EvaluateCEL()