Skip to content

Commit 7aa21eb

Browse files
committed
implementing finally at the pipeline level
We can now specify a list of tasks needs to be executed just before pipeline exits (either after finishing all non-final tasks successfully or after a single failure) Most useful for tasks such as report test results, cleanup cluster resources, etc ``` apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: pipeline-with-final-tasks spec: tasks: - name: pre-work taskRef: Name: some-pre-work - name: unit-test taskRef: Name: run-unit-test runAfter: - pre-work - name: integration-test taskRef: Name: run-integration-test runAfter: - unit-test finally: - name: cleanup-test taskRef: Name: cleanup-cluster - name: report-results taskRef: Name: report-test-results ```
1 parent a68d753 commit 7aa21eb

21 files changed

+1457
-188
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# Task producing success by exiting with 0
2+
apiVersion: tekton.dev/v1beta1
3+
kind: Task
4+
metadata:
5+
name: successful-task
6+
spec:
7+
steps:
8+
- name: success
9+
image: ubuntu
10+
script: |
11+
exit 0
12+
---
13+
14+
apiVersion: tekton.dev/v1beta1
15+
kind: Pipeline
16+
metadata:
17+
name: pipeline-with-final-tasks
18+
spec:
19+
tasks:
20+
- name: pre-work
21+
taskRef:
22+
Name: successful-task
23+
- name: unit-test
24+
taskRef:
25+
Name: successful-task
26+
runAfter:
27+
- pre-work
28+
- name: integration-test
29+
taskRef:
30+
Name: successful-task
31+
runAfter:
32+
- unit-test
33+
finally:
34+
- name: cleanup-test
35+
taskRef:
36+
Name: successful-task
37+
- name: report-results
38+
taskRef:
39+
Name: successful-task
40+
---
41+
42+
apiVersion: tekton.dev/v1beta1
43+
kind: PipelineRun
44+
metadata:
45+
name: pipelinerun-with-final-tasks
46+
spec:
47+
pipelineRef:
48+
name: pipeline-with-final-tasks
49+
---
50+
51+
apiVersion: tekton.dev/v1beta1
52+
kind: Task
53+
metadata:
54+
name: sum-two-ints
55+
annotations:
56+
description: |
57+
A simple task that sums the two provided integers
58+
spec:
59+
params:
60+
- name: a
61+
type: string
62+
default: "1"
63+
description: The first integer
64+
- name: b
65+
type: string
66+
default: "1"
67+
description: The second integer
68+
results:
69+
- name: sum-result
70+
description: The sum of the two provided integers
71+
steps:
72+
- name: sum
73+
image: bash:latest
74+
script: |
75+
#!/usr/bin/env bash
76+
echo -n $(( "$(params.a)" + "$(params.b)" )) | tee $(results.sum-result.path)
77+
---
78+
79+
apiVersion: tekton.dev/v1beta1
80+
kind: Task
81+
metadata:
82+
name: format-result
83+
spec:
84+
params:
85+
- name: result
86+
type: string
87+
default: "0"
88+
steps:
89+
- name: print-sum
90+
image: ubuntu
91+
script: echo "*** Result = $(params.result) ***"
92+
---
93+
94+
apiVersion: tekton.dev/v1beta1
95+
kind: Pipeline
96+
metadata:
97+
name: sum-and-print-pipeline
98+
spec:
99+
params:
100+
- name: a
101+
type: string
102+
default: "1"
103+
- name: b
104+
type: string
105+
default: "1"
106+
tasks:
107+
- name: sum-inputs
108+
taskRef:
109+
name: sum-two-ints
110+
params:
111+
- name: a
112+
value: "$(params.a)"
113+
- name: b
114+
value: "$(params.b)"
115+
finally:
116+
- name: print-sum
117+
taskRef:
118+
name: format-result
119+
params:
120+
- name: result
121+
value: "$(tasks.sum-inputs.results.sum-result)"
122+
---
123+
124+
apiVersion: tekton.dev/v1beta1
125+
kind: PipelineRun
126+
metadata:
127+
name: sum-and-print-pipeline-run
128+
spec:
129+
pipelineRef:
130+
name: sum-and-print-pipeline
131+
params:
132+
- name: a
133+
value: "100"
134+
- name: b
135+
value: "1000"
136+
---
137+
138+
apiVersion: v1
139+
kind: PersistentVolumeClaim
140+
metadata:
141+
name: shared-workspace
142+
spec:
143+
resources:
144+
requests:
145+
storage: 16Mi
146+
volumeMode: Filesystem
147+
accessModes:
148+
- ReadWriteOnce
149+
---
150+
151+
apiVersion: tekton.dev/v1alpha1
152+
kind: Task
153+
metadata:
154+
name: clone-app-repo-to-workspace
155+
spec:
156+
workspaces:
157+
- name: shared-workspace
158+
resources:
159+
inputs:
160+
- name: app-git
161+
type: git
162+
targetPath: application
163+
steps:
164+
- name: clone-app-repo-to-workspace
165+
image: ubuntu
166+
script: |
167+
#!/usr/bin/env bash
168+
set -xe
169+
cp -avr $(resources.inputs.app-git.path)/ $(workspaces.shared-workspace.path)/
170+
---
171+
172+
apiVersion: tekton.dev/v1alpha1
173+
kind: Task
174+
metadata:
175+
name: cleanup-workspace
176+
spec:
177+
workspaces:
178+
- name: shared-workspace
179+
steps:
180+
- name: cleanup-workspace
181+
image: ubuntu
182+
script: |
183+
#!/usr/bin/env bash
184+
set -xe
185+
rm -rf $(workspaces.shared-workspace.path)/application/
186+
---
187+
188+
apiVersion: tekton.dev/v1alpha1
189+
kind: Pipeline
190+
metadata:
191+
name: clone-into-workspace-and-cleanup-workspace
192+
spec:
193+
resources:
194+
- name: app-git
195+
type: git
196+
workspaces:
197+
- name: shared-workspace
198+
tasks:
199+
- name: clone-app-source
200+
taskRef:
201+
name: clone-app-repo-to-workspace
202+
workspaces:
203+
- name: shared-workspace
204+
workspace: shared-workspace
205+
resources:
206+
inputs:
207+
- name: app-git
208+
resource: app-git
209+
finally:
210+
- name: cleanup-workspace
211+
taskRef:
212+
name: cleanup-workspace
213+
workspaces:
214+
- name: shared-workspace
215+
workspace: shared-workspace
216+
---
217+
218+
apiVersion: tekton.dev/v1alpha1
219+
kind: PipelineRun
220+
metadata:
221+
name: write-and-cleanup-workspace
222+
spec:
223+
pipelineRef:
224+
name: clone-into-workspace-and-cleanup-workspace
225+
workspaces:
226+
- name: shared-workspace
227+
persistentVolumeClaim:
228+
claimName: shared-workspace
229+
resources:
230+
- name: app-git
231+
resourceSpec:
232+
type: git
233+
params:
234+
- name: url
235+
value: https://github.com/tektoncd/pipeline.git
236+
---

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.13
44

55
require (
66
cloud.google.com/go v0.47.0 // indirect
7+
cloud.google.com/go/storage v1.0.0
78
contrib.go.opencensus.io/exporter/stackdriver v0.12.8 // indirect
89
github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher v0.0.0-20191203181535-308b93ad1f39
910
github.com/cloudevents/sdk-go/v2 v2.0.0-preview8

pkg/apis/pipeline/v1alpha1/pipeline_conversion.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ func (source *PipelineSpec) ConvertTo(ctx context.Context, sink *v1beta1.Pipelin
5151
}
5252
}
5353
}
54+
if len(source.Finally) > 0 {
55+
sink.Finally = make([]v1beta1.PipelineTask, len(source.Finally))
56+
for i := range source.Finally {
57+
if err := source.Finally[i].ConvertTo(ctx, &sink.Finally[i]); err != nil {
58+
return err
59+
}
60+
}
61+
}
5462
return nil
5563
}
5664

@@ -96,6 +104,14 @@ func (sink *PipelineSpec) ConvertFrom(ctx context.Context, source v1beta1.Pipeli
96104
}
97105
}
98106
}
107+
if len(source.Finally) > 0 {
108+
sink.Finally = make([]PipelineTask, len(source.Finally))
109+
for i := range source.Finally {
110+
if err := sink.Finally[i].ConvertFrom(ctx, source.Finally[i]); err != nil {
111+
return err
112+
}
113+
}
114+
}
99115
return nil
100116
}
101117

pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,38 @@ func TestPipelineConversion(t *testing.T) {
109109
}},
110110
RunAfter: []string{"task1"},
111111
}},
112+
Finally: []PipelineTask{{
113+
Name: "finaltask1",
114+
TaskRef: &TaskRef{
115+
Name: "finaltaskref",
116+
},
117+
Retries: 10,
118+
Resources: &PipelineTaskResources{
119+
Inputs: []v1beta1.PipelineTaskInputResource{{
120+
Name: "input1",
121+
Resource: "resource1",
122+
}},
123+
Outputs: []v1beta1.PipelineTaskOutputResource{{
124+
Name: "output1",
125+
Resource: "resource2",
126+
}},
127+
},
128+
Params: []Param{{
129+
Name: "finalparam1",
130+
Value: v1beta1.ArrayOrString{StringVal: "str", Type: v1beta1.ParamTypeString},
131+
}},
132+
Workspaces: []WorkspacePipelineTaskBinding{{
133+
Name: "w1",
134+
Workspace: "workspace1",
135+
}},
136+
}, {
137+
Name: "finaltask2",
138+
TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{
139+
Steps: []v1beta1.Step{{Container: corev1.Container{
140+
Image: "foo",
141+
}}},
142+
}},
143+
}},
112144
},
113145
},
114146
}, {
@@ -147,6 +179,27 @@ func TestPipelineConversion(t *testing.T) {
147179
}},
148180
RunAfter: []string{"task1"},
149181
}},
182+
Finally: []PipelineTask{{
183+
Name: "finaltask",
184+
TaskSpec: &TaskSpec{
185+
TaskSpec: v1beta1.TaskSpec{
186+
Steps: []v1beta1.Step{{Container: corev1.Container{
187+
Image: "foo",
188+
}}},
189+
Resources: &v1beta1.TaskResources{
190+
Inputs: []v1beta1.TaskResource{{ResourceDeclaration: v1beta1.ResourceDeclaration{
191+
Name: "input-1",
192+
Type: resource.PipelineResourceTypeGit,
193+
}}},
194+
},
195+
},
196+
Inputs: &Inputs{
197+
Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{
198+
Name: "input-1",
199+
Type: resource.PipelineResourceTypeGit,
200+
}}},
201+
}},
202+
}},
150203
},
151204
},
152205
wantErr: true,

pkg/apis/pipeline/v1alpha1/pipeline_defaults.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,12 @@ func (ps *PipelineSpec) SetDefaults(ctx context.Context) {
4242
for i := range ps.Params {
4343
ps.Params[i].SetDefaults(ctx)
4444
}
45+
for _, ft := range ps.Finally {
46+
if ft.TaskRef.Kind == "" {
47+
ft.TaskRef.Kind = NamespacedTaskKind
48+
}
49+
if ft.TaskSpec != nil {
50+
ft.TaskSpec.SetDefaults(ctx)
51+
}
52+
}
4553
}

pkg/apis/pipeline/v1alpha1/pipeline_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ type PipelineSpec struct {
4343
// Results are values that this pipeline can output once run
4444
// +optional
4545
Results []PipelineResult `json:"results,omitempty"`
46+
// Finally declares the list of Tasks that execute just before leaving the Pipeline
47+
// i.e. either after all Tasks are finished executing successfully
48+
// or after a failure which would result in ending the Pipeline
49+
Finally []PipelineTask `json:"finally,omitempty"`
4650
}
4751

4852
// PipelineResult used to describe the results of a pipeline

0 commit comments

Comments
 (0)