Skip to content

Commit b42df6a

Browse files
committed
pipelinetask metadata
Adding metadata to TaskSpec in PipelineTask to allow specifying metadata. This metadata will be propogated to taskRun and then to the pods. ``` apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: pipelinerun-with-taskspec-to-echo-greetings spec: pipelineSpec: tasks: - name: echo-greetings taskSpec: metadata: labels: [ …] steps: ... ``` Metadata is already supported as part of Tasks and Pipelines while respective CRDs are created. But was not possible to specify with embedded resources.
1 parent 44f22a0 commit b42df6a

12 files changed

+369
-47
lines changed

examples/v1beta1/pipelineruns/pipelinerun-with-pipelinespec-and-taskspec.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ spec:
77
tasks:
88
- name: echo-good-morning
99
taskSpec:
10+
metadata:
11+
labels:
12+
app: "example"
1013
steps:
1114
- name: echo
1215
image: ubuntu

internal/builder/v1beta1/pipeline.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,20 @@ func PipelineRunResult(name, value string) PipelineRunStatusOp {
179179
// PipelineTaskSpec sets the TaskSpec on a PipelineTask.
180180
func PipelineTaskSpec(spec *v1beta1.TaskSpec) PipelineTaskOp {
181181
return func(pt *v1beta1.PipelineTask) {
182-
pt.TaskSpec = spec
182+
if pt.TaskSpec == nil {
183+
pt.TaskSpec = &v1beta1.EmbeddedTask{}
184+
}
185+
pt.TaskSpec.TaskSpec = spec
186+
}
187+
}
188+
189+
// PipelineTaskMetadata sets the Metadata on a PipelineTask.
190+
func PipelineTaskMetadata(metadata metav1.ObjectMeta) PipelineTaskOp {
191+
return func(pt *v1beta1.PipelineTask) {
192+
if pt.TaskSpec == nil {
193+
pt.TaskSpec = &v1beta1.EmbeddedTask{}
194+
}
195+
pt.TaskSpec.Metadata = metadata
183196
}
184197
}
185198

internal/builder/v1beta1/pipeline_test.go

+62-7
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,14 @@ func TestPipeline(t *testing.T) {
137137
Timeout: &metav1.Duration{Duration: 5 * time.Second},
138138
}, {
139139
Name: "foo",
140-
TaskSpec: &v1beta1.TaskSpec{
141-
Steps: []v1beta1.Step{{Container: corev1.Container{
142-
Name: "step",
143-
Image: "myimage",
144-
}}},
145-
},
146-
}},
140+
TaskSpec: &v1beta1.EmbeddedTask{
141+
TaskSpec: &v1beta1.TaskSpec{
142+
Steps: []v1beta1.Step{{Container: corev1.Container{
143+
Name: "step",
144+
Image: "myimage",
145+
}}},
146+
},
147+
}}},
147148
Workspaces: []v1beta1.PipelineWorkspaceDeclaration{{
148149
Name: "workspace1",
149150
}},
@@ -393,3 +394,57 @@ func TestPipelineRunWithPipelineSpec(t *testing.T) {
393394
t.Fatalf("PipelineRun diff -want, +got: %s", diff)
394395
}
395396
}
397+
398+
func TestPipelineRunWithTaskSpec_TaskMetadata(t *testing.T) {
399+
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"),
400+
tb.PipelineRunSpec("", tb.PipelineRunPipelineSpec(
401+
tb.PipelineTask("a-task", "",
402+
tb.PipelineTaskMetadata(metav1.ObjectMeta{
403+
Name: "a-task-name",
404+
Labels: map[string]string{"label": "labelvalue"},
405+
Annotations: map[string]string{"annotation": "annotationvalue"}},
406+
),
407+
tb.PipelineTaskSpec(&v1beta1.TaskSpec{
408+
Steps: []v1beta1.Step{{Container: corev1.Container{
409+
Name: "step",
410+
Image: "myimage",
411+
}}},
412+
},
413+
))),
414+
tb.PipelineRunServiceAccountName("sa"),
415+
))
416+
417+
expectedPipelineRun := &v1beta1.PipelineRun{
418+
ObjectMeta: metav1.ObjectMeta{
419+
Name: "pear",
420+
Namespace: "foo",
421+
},
422+
Spec: v1beta1.PipelineRunSpec{
423+
PipelineRef: nil,
424+
PipelineSpec: &v1beta1.PipelineSpec{
425+
Tasks: []v1beta1.PipelineTask{{
426+
Name: "a-task",
427+
TaskSpec: &v1beta1.EmbeddedTask{
428+
Metadata: metav1.ObjectMeta{
429+
Name: "a-task-name",
430+
Labels: map[string]string{"label": "labelvalue"},
431+
Annotations: map[string]string{"annotation": "annotationvalue"},
432+
},
433+
TaskSpec: &v1beta1.TaskSpec{
434+
Steps: []v1beta1.Step{{Container: corev1.Container{
435+
Name: "step",
436+
Image: "myimage",
437+
}}},
438+
},
439+
},
440+
}},
441+
},
442+
ServiceAccountName: "sa",
443+
Timeout: &metav1.Duration{Duration: 1 * time.Hour},
444+
},
445+
}
446+
447+
if diff := cmp.Diff(expectedPipelineRun, pipelineRun); diff != "" {
448+
t.Fatalf("PipelineRun diff -want, +got: %s", diff)
449+
}
450+
}

pkg/apis/pipeline/v1alpha1/pipeline_conversion.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"context"
2222
"fmt"
2323

24+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
2426
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
2527
"knative.dev/pkg/apis"
2628
)
@@ -61,8 +63,8 @@ func (source *PipelineTask) ConvertTo(ctx context.Context, sink *v1beta1.Pipelin
6163
sink.Name = source.Name
6264
sink.TaskRef = source.TaskRef
6365
if source.TaskSpec != nil {
64-
sink.TaskSpec = &v1beta1.TaskSpec{}
65-
if err := source.TaskSpec.ConvertTo(ctx, sink.TaskSpec); err != nil {
66+
sink.TaskSpec = &v1beta1.EmbeddedTask{v1.ObjectMeta{}, &v1beta1.TaskSpec{}}
67+
if err := source.TaskSpec.ConvertTo(ctx, sink.TaskSpec.TaskSpec); err != nil {
6668
return err
6769
}
6870
}
@@ -112,7 +114,7 @@ func (sink *PipelineTask) ConvertFrom(ctx context.Context, source v1beta1.Pipeli
112114
sink.TaskRef = source.TaskRef
113115
if source.TaskSpec != nil {
114116
sink.TaskSpec = &TaskSpec{}
115-
if err := sink.TaskSpec.ConvertFrom(ctx, source.TaskSpec); err != nil {
117+
if err := sink.TaskSpec.ConvertFrom(ctx, source.TaskSpec.TaskSpec); err != nil {
116118
return err
117119
}
118120
}

pkg/apis/pipeline/v1beta1/pipeline_defaults_test.go

+32-18
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
"testing"
2222

23+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
2325
"github.com/tektoncd/pipeline/test/diff"
2426

2527
"github.com/google/go-cmp/cmp"
@@ -85,41 +87,53 @@ func TestPipelineSpec_SetDefaults(t *testing.T) {
8587
desc: "pipeline task with taskSpec - default param type must be " + string(v1beta1.ParamTypeString),
8688
ps: &v1beta1.PipelineSpec{
8789
Tasks: []v1beta1.PipelineTask{{
88-
Name: "foo", TaskSpec: &v1beta1.TaskSpec{
89-
Params: []v1beta1.ParamSpec{{
90-
Name: "string-param",
91-
}},
90+
Name: "foo", TaskSpec: &v1beta1.EmbeddedTask{
91+
Metadata: v1.ObjectMeta{},
92+
TaskSpec: &v1beta1.TaskSpec{
93+
Params: []v1beta1.ParamSpec{{
94+
Name: "string-param",
95+
}},
96+
},
9297
},
9398
}},
9499
},
95100
want: &v1beta1.PipelineSpec{
96101
Tasks: []v1beta1.PipelineTask{{
97-
Name: "foo", TaskSpec: &v1beta1.TaskSpec{
98-
Params: []v1beta1.ParamSpec{{
99-
Name: "string-param",
100-
Type: v1beta1.ParamTypeString,
101-
}},
102+
Name: "foo", TaskSpec: &v1beta1.EmbeddedTask{
103+
Metadata: v1.ObjectMeta{},
104+
TaskSpec: &v1beta1.TaskSpec{
105+
Params: []v1beta1.ParamSpec{{
106+
Name: "string-param",
107+
Type: v1beta1.ParamTypeString,
108+
}},
109+
},
102110
},
103111
}},
104112
},
105113
}, {
106114
desc: "final pipeline task with taskSpec - default param type must be " + string(v1beta1.ParamTypeString),
107115
ps: &v1beta1.PipelineSpec{
108116
Finally: []v1beta1.PipelineTask{{
109-
Name: "foo", TaskSpec: &v1beta1.TaskSpec{
110-
Params: []v1beta1.ParamSpec{{
111-
Name: "string-param",
112-
}},
117+
Name: "foo", TaskSpec: &v1beta1.EmbeddedTask{
118+
Metadata: v1.ObjectMeta{},
119+
TaskSpec: &v1beta1.TaskSpec{
120+
Params: []v1beta1.ParamSpec{{
121+
Name: "string-param",
122+
}},
123+
},
113124
},
114125
}},
115126
},
116127
want: &v1beta1.PipelineSpec{
117128
Finally: []v1beta1.PipelineTask{{
118-
Name: "foo", TaskSpec: &v1beta1.TaskSpec{
119-
Params: []v1beta1.ParamSpec{{
120-
Name: "string-param",
121-
Type: v1beta1.ParamTypeString,
122-
}},
129+
Name: "foo", TaskSpec: &v1beta1.EmbeddedTask{
130+
Metadata: v1.ObjectMeta{},
131+
TaskSpec: &v1beta1.TaskSpec{
132+
Params: []v1beta1.ParamSpec{{
133+
Name: "string-param",
134+
Type: v1beta1.ParamTypeString,
135+
}},
136+
},
123137
},
124138
}},
125139
},

pkg/apis/pipeline/v1beta1/pipeline_types.go

+25-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
"github.com/tektoncd/pipeline/pkg/apis/validate"
2021
"github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag"
2122
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"knative.dev/pkg/apis"
2224
)
2325

2426
// +genclient
@@ -90,6 +92,15 @@ type PipelineResult struct {
9092
Value string `json:"value"`
9193
}
9294

95+
type EmbeddedTask struct {
96+
// +optional
97+
Metadata metav1.ObjectMeta `json:"metadata,omitempty"`
98+
99+
// TaskSpec is a specification of a task
100+
// +optional
101+
*TaskSpec `json:",inline,omitempty"`
102+
}
103+
93104
// PipelineTask defines a task in a Pipeline, passing inputs from both
94105
// Params and from the output of previous tasks.
95106
type PipelineTask struct {
@@ -104,7 +115,7 @@ type PipelineTask struct {
104115

105116
// TaskSpec is a specification of a task
106117
// +optional
107-
TaskSpec *TaskSpec `json:"taskSpec,omitempty"`
118+
TaskSpec *EmbeddedTask `json:"taskSpec,inline,omitempty"`
108119

109120
// Conditions is a list of conditions that need to be true for the task to run
110121
// +optional
@@ -139,6 +150,19 @@ type PipelineTask struct {
139150
Timeout *metav1.Duration `json:"timeout,omitempty"`
140151
}
141152

153+
func (pt *PipelineTask) TaskSpecMetadata() metav1.ObjectMeta {
154+
return pt.TaskSpec.Metadata
155+
}
156+
157+
func (pt *PipelineTask) ValidateTaskSpecMetadata() *apis.FieldError {
158+
if pt.TaskSpec != nil {
159+
if err := validate.ObjectMetadata(pt.TaskSpec.Metadata.GetObjectMeta()); err != nil {
160+
return err.ViaField("[tasks|finally].taskSpec.metadata")
161+
}
162+
}
163+
return nil
164+
}
165+
142166
func (pt PipelineTask) HashKey() string {
143167
return pt.Name
144168
}

pkg/apis/pipeline/v1beta1/pipeline_validation.go

+3
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ func validatePipelineTaskName(ctx context.Context, prefix string, i int, t Pipel
251251
if err := t.TaskSpec.Validate(ctx); err != nil {
252252
return err
253253
}
254+
if err := t.ValidateTaskSpecMetadata(); err != nil {
255+
return err
256+
}
254257
}
255258
if t.TaskRef != nil && t.TaskRef.Name != "" {
256259
// Task names are appended to the container name, which must exist and

0 commit comments

Comments
 (0)