Skip to content

Commit 94a02f7

Browse files
committed
Adding support to enable pipelineSpec
Its now possible to embed the whole pipeline specification into Pipeline Run using pipelineSpec, for example: apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: pipelinerun-echo-greetings spec: pipelineRef: name: pipeline-echo-greetings Can be specified as: apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: pipelinerun-echo-greetings spec: pipelineSpec: tasks: - name: echo-good-morning ... params: ...
1 parent 454ddec commit 94a02f7

17 files changed

+455
-41
lines changed

docs/pipelineruns.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ following fields:
3333
`PipelineRun` resource object, for example a `name`.
3434
- [`spec`][kubernetes-overview] - Specifies the configuration information for
3535
your `PipelineRun` resource object.
36-
- `pipelineRef` - Specifies the [`Pipeline`](pipelines.md) you want to run.
36+
- [`pipelineRef` or `pipelineSpec`](#specifiying-a-pipeline) - Specifies the [`Pipeline`](pipelines.md) you want to run.
3737
- Optional:
3838

3939
- [`resources`](#resources) - Specifies which
@@ -55,6 +55,48 @@ following fields:
5555
[kubernetes-overview]:
5656
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
5757

58+
### Specifying a pipeline
59+
60+
Since a `PipelineRun` is an invocation of a [`Pipeline`](pipelines.md), you must sepcify
61+
what `Pipeline` to invoke.
62+
63+
You can do this by providing a reference to an existing `Pipeline`:
64+
65+
```yaml
66+
spec:
67+
pipelineRef:
68+
name: myPipeline
69+
70+
```
71+
72+
Or you can embed the spec of the `Pipeline` directly in the `PipelineRun`:
73+
74+
```yaml
75+
spec:
76+
pipelineSpec:
77+
tasks:
78+
- name: task1
79+
taskRef:
80+
name: myTask
81+
```
82+
83+
[Here](../examples/pipelineruns/pipelinerun-with-pipelinespec.yaml) is a sample `PipelineRun` to display different
84+
greetings while embedding the spec of the `Pipeline` directly in the `PipelineRun`.
85+
86+
87+
After creating such `PipelineRun`, logs from a pod displaying morning greetings:
88+
89+
```bash
90+
kubectl logs $(kubectl get pods -o name | grep pipelinerun-echo-greetings-echo-good-morning)
91+
Good Morning, Bob!
92+
```
93+
94+
And logs from a pod displaying morning greetings:
95+
```bash
96+
kubectl logs $(kubectl get pods -o name | grep pipelinerun-echo-greetings-echo-good-night)
97+
Good Night, Bob!
98+
```
99+
58100
### Resources
59101

60102
When running a [`Pipeline`](pipelines.md), you will need to specify the
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
apiVersion: tekton.dev/v1alpha1
2+
kind: Task
3+
metadata:
4+
name: task-echo-message
5+
spec:
6+
inputs:
7+
params:
8+
- name: MESSAGE
9+
type: string
10+
default: "Hello World"
11+
steps:
12+
- name: echo
13+
image: ubuntu
14+
command:
15+
- echo
16+
args:
17+
- "$(inputs.params.MESSAGE)"
18+
---
19+
20+
apiVersion: tekton.dev/v1alpha1
21+
kind: PipelineRun
22+
metadata:
23+
name: pipelinerun-echo-greetings
24+
spec:
25+
pipelineSpec:
26+
params:
27+
- name: MORNING_GREETINGS
28+
description: "morning greetings, default is Good Morning!"
29+
type: string
30+
default: "Good Morning!"
31+
- name: NIGHT_GREETINGS
32+
description: "Night greetings, default is Good Night!"
33+
type: string
34+
default: "Good Night!"
35+
tasks:
36+
# Task to display morning greetings
37+
- name: echo-good-morning
38+
taskRef:
39+
name: task-echo-message
40+
params:
41+
- name: MESSAGE
42+
value: $(params.MORNING_GREETINGS)
43+
# Task to display night greetings
44+
- name: echo-good-night
45+
taskRef:
46+
name: task-echo-message
47+
params:
48+
- name: MESSAGE
49+
value: $(params.NIGHT_GREETINGS)
50+
params:
51+
- name: MORNING_GREETINGS
52+
value: "Good Morning, Bob!"
53+
- name: NIGHT_GREETINGS
54+
value: "Good Night, Bob!"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
Copyright 2019 The Tekton Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20+
21+
// PipelineInterface is implemented by Pipeline and ClusterPipeline
22+
type PipelineInterface interface {
23+
PipelineMetadata() metav1.ObjectMeta
24+
PipelineSpec() PipelineSpec
25+
Copy() PipelineInterface
26+
}

pkg/apis/pipeline/v1alpha1/pipeline_types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ type Pipeline struct {
7373
Status PipelineStatus `json:"status"`
7474
}
7575

76+
func (p *Pipeline) PipelineMetadata() metav1.ObjectMeta {
77+
return p.ObjectMeta
78+
}
79+
80+
func (p *Pipeline) PipelineSpec() PipelineSpec {
81+
return p.Spec
82+
}
83+
84+
func (p *Pipeline) Copy() PipelineInterface {
85+
return p.DeepCopy()
86+
}
87+
7688
// PipelineTask defines a task in a Pipeline, passing inputs from both
7789
// Params and from the output of previous tasks.
7890
type PipelineTask struct {

pkg/apis/pipeline/v1alpha1/pipelinerun_types.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ var _ apis.Defaultable = (*PipelineRun)(nil)
4242

4343
// PipelineRunSpec defines the desired state of PipelineRun
4444
type PipelineRunSpec struct {
45-
PipelineRef PipelineRef `json:"pipelineRef"`
45+
// +optional
46+
PipelineRef PipelineRef `json:"pipelineRef,omitempty"`
47+
// +optional
48+
PipelineSpec *PipelineSpec `json:"pipelineSpec,omitempty"`
4649
// Resources is a list of bindings specifying which actual instances of
4750
// PipelineResources to use for the resources the Pipeline has declared
4851
// it needs.

pkg/apis/pipeline/v1alpha1/pipelinerun_validation.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,22 @@ func (ps *PipelineRunSpec) Validate(ctx context.Context) *apis.FieldError {
3737
if equality.Semantic.DeepEqual(ps, &PipelineRunSpec{}) {
3838
return apis.ErrMissingField("spec")
3939
}
40-
// pipeline reference should be present for pipelinerun
41-
if ps.PipelineRef.Name == "" {
42-
return apis.ErrMissingField("pipelinerun.spec.Pipelineref.Name")
40+
41+
// can't have both pipelinekRef and pipelineSpec at the same time
42+
if ps.PipelineRef.Name != "" && ps.PipelineSpec != nil {
43+
return apis.ErrDisallowedFields("spec.pipelineRef", "spec.pipelineSpec")
44+
}
45+
46+
// Check that one of PipelineRef and PipelineSpec is present
47+
if ps.PipelineRef.Name == "" && ps.PipelineSpec == nil {
48+
return apis.ErrMissingField("spec.pipelineRef.name", "spec.pipelineSpec")
49+
}
50+
51+
// Validate PipelineSpec if it's present
52+
if ps.PipelineSpec != nil {
53+
if err := ps.PipelineSpec.Validate(ctx); err != nil {
54+
return err
55+
}
4356
}
4457

4558
// check for results

pkg/apis/pipeline/v1alpha1/pipelinerun_validation_test.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func TestPipelineRun_Invalidate(t *testing.T) {
6363
ServiceAccount: "foo",
6464
},
6565
},
66-
want: apis.ErrMissingField("pipelinerun.spec.Pipelineref.Name"),
66+
want: apis.ErrMissingField("spec.pipelineRef.name, spec.pipelineSpec"),
6767
}, {
6868
name: "negative pipeline timeout",
6969
pr: v1alpha1.PipelineRun{
@@ -136,3 +136,70 @@ func TestPipelineRun_Validate(t *testing.T) {
136136
})
137137
}
138138
}
139+
140+
func TestPipelineRunSpec_Invalidate(t *testing.T) {
141+
tests := []struct {
142+
name string
143+
spec v1alpha1.PipelineRunSpec
144+
wantErr *apis.FieldError
145+
}{{
146+
name: "Empty pipelineSpec",
147+
spec: v1alpha1.PipelineRunSpec{},
148+
wantErr: apis.ErrMissingField("spec"),
149+
}, {
150+
name: "pipelineRef without Pipeline Name",
151+
spec: v1alpha1.PipelineRunSpec{
152+
PipelineRef: v1alpha1.PipelineRef{},
153+
},
154+
wantErr: apis.ErrMissingField("spec"),
155+
}, {
156+
name: "pipelineRef and pipelineSpec together",
157+
spec: v1alpha1.PipelineRunSpec{
158+
PipelineRef: v1alpha1.PipelineRef{
159+
Name: "pipelinerefname",
160+
},
161+
PipelineSpec: &v1alpha1.PipelineSpec{
162+
Tasks: []v1alpha1.PipelineTask{{
163+
Name: "mytask",
164+
TaskRef: v1alpha1.TaskRef{
165+
Name: "mytask",
166+
},
167+
}}},
168+
},
169+
wantErr: apis.ErrDisallowedFields("spec.pipelineSpec", "spec.pipelineRef"),
170+
}}
171+
for _, ps := range tests {
172+
t.Run(ps.name, func(t *testing.T) {
173+
err := ps.spec.Validate(context.Background())
174+
if d := cmp.Diff(ps.wantErr.Error(), err.Error()); d != "" {
175+
t.Errorf("PipelineRunSpec.Validate/%s (-want, +got) = %v", ps.name, d)
176+
}
177+
})
178+
}
179+
}
180+
181+
func TestPipelineRunSpec_Validate(t *testing.T) {
182+
tests := []struct {
183+
name string
184+
spec v1alpha1.PipelineRunSpec
185+
}{{
186+
name: "PipelineRun without pipelineRef",
187+
spec: v1alpha1.PipelineRunSpec{
188+
PipelineSpec: &v1alpha1.PipelineSpec{
189+
Tasks: []v1alpha1.PipelineTask{{
190+
Name: "mytask",
191+
TaskRef: v1alpha1.TaskRef{
192+
Name: "mytask",
193+
},
194+
}},
195+
},
196+
},
197+
}}
198+
for _, ps := range tests {
199+
t.Run(ps.name, func(t *testing.T) {
200+
if err := ps.spec.Validate(context.Background()); err != nil {
201+
t.Errorf("PipelineRunSpec.Validate/%s (-want, +got) = %v", ps.name, err)
202+
}
203+
})
204+
}
205+
}

pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)