screwdriver-api 7.0.170 → 7.0.172
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,1180 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
Pipeline template abstracts entire pipeline configuration into reusable modules which can be imported (screwdriver.yaml) and extended to build individual pipelines.
|
|
3
|
+
|
|
4
|
+
Github: https://github.com/screwdriver-cd/screwdriver/issues/2135
|
|
5
|
+
|
|
6
|
+
## Table of Contents
|
|
7
|
+
|
|
8
|
+
- [Requirements](#requirements)
|
|
9
|
+
- [Design](#design)
|
|
10
|
+
- [Template Management](#template-management)
|
|
11
|
+
- [Template Configuration Schema](#template-configuration-schema)
|
|
12
|
+
- [API](#api)
|
|
13
|
+
- [DB Model](#db-model)
|
|
14
|
+
- [Domain Model](#domain-model)
|
|
15
|
+
- [Config Parser](#config-parser)
|
|
16
|
+
- [Template Validator](#template-validator)
|
|
17
|
+
- [Data Access Object/Layer (DAO)](#data-access-objectlayer-dao)
|
|
18
|
+
- [Endpoints](#endpoints)
|
|
19
|
+
- [SD CLI](#sd-cli)
|
|
20
|
+
- [UI](#ui)
|
|
21
|
+
- [Template Usage](#template-usage-1)
|
|
22
|
+
- [Pipeline configuration](#pipeline-configuration)
|
|
23
|
+
- [API](#api-1)
|
|
24
|
+
- [DB Model](#db-model-1)
|
|
25
|
+
- [Domain Model](#domain-model-1)
|
|
26
|
+
- [Config Parser](#config-parser-1)
|
|
27
|
+
- [UI](#ui-1)
|
|
28
|
+
|
|
29
|
+
# Requirements
|
|
30
|
+
## Template Management
|
|
31
|
+
1. Ability to validate a pipeline template configuration
|
|
32
|
+
1. Ability to create/store versioned pipeline template configuration from the screwdriver pipeline which owns the template
|
|
33
|
+
1. Ability to create/update tags referring to a version of the template from a screwdriver pipeline which owns the template
|
|
34
|
+
1. A Screwdriver admin should be able to mark a pipeline template as trusted or not
|
|
35
|
+
a. Capture the version since it was marked as trusted
|
|
36
|
+
b. Clear the version, when a template is no longer marked as trusted which was previously trusted
|
|
37
|
+
1. All users should be able to view all the pipeline templates available in the system
|
|
38
|
+
1. All users should be able to view all the versions of a pipeline template
|
|
39
|
+
1. All Users should be able to view the configuration a specific version of a pipeline template
|
|
40
|
+
1. Below users should be allowed to delete a specific version and all of its associated tags
|
|
41
|
+
a. Screwdriver admin
|
|
42
|
+
b. Screwdriver pipeline owning the template
|
|
43
|
+
c. Admins of the SCM repo hosting the template configuration
|
|
44
|
+
1. Below users should be allowed to delete a template and all of its associated versions and tags
|
|
45
|
+
a. Screwdriver admin
|
|
46
|
+
b. Screwdriver pipeline owning the template
|
|
47
|
+
c. Admins of the SCM repo hosting the template configuration
|
|
48
|
+
|
|
49
|
+
## Template Usage
|
|
50
|
+
To be updated
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Design
|
|
54
|
+
## Template Management
|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
### Template Configuration Schema
|
|
59
|
+
|
|
60
|
+

|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
__Basic Configuration:__
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
namespace: myNamespace
|
|
68
|
+
name: template_name
|
|
69
|
+
version: '1.3.2'
|
|
70
|
+
description: template for testing
|
|
71
|
+
maintainer: foo@bar.com
|
|
72
|
+
|
|
73
|
+
config:
|
|
74
|
+
jobs:
|
|
75
|
+
main:
|
|
76
|
+
image:
|
|
77
|
+
steps:
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
__Advanced Configuration:__
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
namespace: myNamespace
|
|
85
|
+
name: template_name
|
|
86
|
+
version: '1.3.2'
|
|
87
|
+
description: template for testing
|
|
88
|
+
maintainer: foo@bar.com
|
|
89
|
+
config:
|
|
90
|
+
shared:
|
|
91
|
+
image:
|
|
92
|
+
environment:
|
|
93
|
+
SD_SONAR_OPTS:
|
|
94
|
+
steps:
|
|
95
|
+
annotations:
|
|
96
|
+
|
|
97
|
+
parameters:
|
|
98
|
+
FOO: bar
|
|
99
|
+
|
|
100
|
+
jobs:
|
|
101
|
+
main:
|
|
102
|
+
requires:
|
|
103
|
+
image:
|
|
104
|
+
template:
|
|
105
|
+
steps:
|
|
106
|
+
parameters:
|
|
107
|
+
secrets:
|
|
108
|
+
settings:
|
|
109
|
+
email:
|
|
110
|
+
slack:
|
|
111
|
+
annotations:
|
|
112
|
+
sourcePaths:
|
|
113
|
+
test:
|
|
114
|
+
....
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Field | Sub Field | Schema | Description |
|
|
119
|
+
| ---------- | ------------- |------------- |------------- |
|
|
120
|
+
| namespace | | Same as Job template `namespace` [schema][schema-namespace] | Required |
|
|
121
|
+
| name | | Same as Job template `name` [schema][schema-name] | Required |
|
|
122
|
+
| maintainer | | Same as Job template `maintainer` [schema][schema-maintainer] | Required |
|
|
123
|
+
| version | | Same as Job template `version` [schema][schema-version] | Required |
|
|
124
|
+
| description | | Same as Job template `description` [schema][schema-description] | Required |
|
|
125
|
+
| config | shared | Same as Pipeline `shared` [schema][schema-shared] | Optional |
|
|
126
|
+
| | jobs | Same as Pipeline `jobs` [schema][schema-jobs] | Required |
|
|
127
|
+
| | parameters | Same as Pipeline `parameters` [schema][schema-params] | Optional |
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
## API
|
|
131
|
+
|
|
132
|
+
### DB Model
|
|
133
|
+
|
|
134
|
+
**Pipeline Template**
|
|
135
|
+
|
|
136
|
+
Approach 1 - Add Pipeline template data to existing template table:
|
|
137
|
+
|
|
138
|
+
- Add new column `templateType` that takes 2 values -> `PIPELINE` and `JOB`
|
|
139
|
+
- `images` column should have NULL when `templateType` = `PIPELINE`
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
Approach 2 - Create new tables
|
|
143
|
+
|
|
144
|
+
Add two new tables to persist pipeline template
|
|
145
|
+
- templateMeta
|
|
146
|
+
- metadata about pipeline template: `name`, `namespace`, `maintainer`, etc.
|
|
147
|
+
- pipelineTemplateVersions
|
|
148
|
+
- configuration associated with individual versions
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
***templateMeta***
|
|
153
|
+
|
|
154
|
+
| Column | Type | Nullable | Description |
|
|
155
|
+
| ---------- | ------------- |------------- |------------- |
|
|
156
|
+
| id | Sequelize.INTEGER.UNSIGNED | No | |
|
|
157
|
+
| pipelineId | Sequelize.DOUBLE | No | Identifier of the Screwdriver pipeline which owns the template |
|
|
158
|
+
| namespace | Sequelize.STRING(64) | No | |
|
|
159
|
+
| name | Sequelize.STRING(64) | No | |
|
|
160
|
+
| maintainer | Sequelize.STRING(64) | No | |
|
|
161
|
+
| trustedSinceVersion | Sequelize.STRING(32) | Yes | |
|
|
162
|
+
| latestVersion | Sequelize.STRING(16) | Yes | |
|
|
163
|
+
| createTime | Sequelize.STRING(32) | No | |
|
|
164
|
+
| updateTime | Sequelize.STRING(32) | No | |
|
|
165
|
+
| templateType | Sequelize.STRING(16) | No | Allowed values: ‘JOB’, ‘PIPELINE’ |
|
|
166
|
+
|
|
167
|
+
_Constraints_
|
|
168
|
+
|
|
169
|
+
- Add composite unique constraint on name, namespace, and templateType
|
|
170
|
+
|
|
171
|
+
_Indexes_
|
|
172
|
+
|
|
173
|
+
- Add index on name
|
|
174
|
+
- Add index on namespace
|
|
175
|
+
|
|
176
|
+
***pipelineTemplateVersions***
|
|
177
|
+
|
|
178
|
+
| Column | Type | Nullable | Description |
|
|
179
|
+
| ---------- | ------------- |------------- |------------- |
|
|
180
|
+
| id | Sequelize.INTEGER.UNSIGNED | No | |
|
|
181
|
+
| templateId | Sequelize.DOUBLE | No | Identifier of the Screwdriver pipeline which owns the template |
|
|
182
|
+
| description | Sequelize.STRING(64) | No | |
|
|
183
|
+
| version | Sequelize.STRING(64) | No | |
|
|
184
|
+
| config | Sequelize.STRING(64) | No | |
|
|
185
|
+
| createTime | Sequelize.STRING(32) | Yes | |
|
|
186
|
+
|
|
187
|
+
_Constraints_
|
|
188
|
+
|
|
189
|
+
- Composite unique constraint on templateId and version
|
|
190
|
+
|
|
191
|
+
_Indexes_
|
|
192
|
+
|
|
193
|
+
- Add index on templateId
|
|
194
|
+
- Add index on version
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
**Conclusion**
|
|
198
|
+
|
|
199
|
+
Proceeding with approach #2
|
|
200
|
+
- Normalizes the data to reduce redundancy
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
**Pipeline Template Tags**
|
|
206
|
+
|
|
207
|
+
We can reuse the existing `templateTags` table to store the tags associated with pipeline templates by adding a new column `templateType`
|
|
208
|
+
|
|
209
|
+
***Existing Columns***
|
|
210
|
+
| Column | Type | Nullable | Description |
|
|
211
|
+
| ---------- | ------------- |------------- |------------- |
|
|
212
|
+
| id | Sequelize.INTEGER.UNSIGNED | No | |
|
|
213
|
+
| createTime | Sequelize.STRING(32) | No | Created during API call |
|
|
214
|
+
| namespace | Sequelize.STRING(64) | No | |
|
|
215
|
+
| name | Sequelize.STRING(64)| No | |
|
|
216
|
+
| tag | Sequelize.STRING(30) | No | |
|
|
217
|
+
| version | Sequelize.STRING(16) | No | |
|
|
218
|
+
|
|
219
|
+
***New Columns***
|
|
220
|
+
| Column | Type | Nullable | Description |
|
|
221
|
+
| ---------- | ------------- |------------- |------------- |
|
|
222
|
+
| templateType | Sequelize.STRING(16) | No | Allowed values: ‘JOB’, ‘PIPELINE’ & Default value: ‘JOB’ |
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
_Constraints_
|
|
226
|
+
- Drop unique constraint on `name`, `namespace` and `tag` columns
|
|
227
|
+
- Add unique constraint on `name`, `namespace`, ‘type’ and `tag` columns
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
### Domain Model
|
|
233
|
+
|
|
234
|
+
**PipelineTemplate**
|
|
235
|
+
|
|
236
|
+
| Field | Sub Field | Schema | Description |
|
|
237
|
+
| ---------- | ------------- |------------- |------------- |
|
|
238
|
+
| id | | Same as Job template `id` [schema][schema-domain-id] | |
|
|
239
|
+
| name | | Same as this [schema][schema-domain-name] | |
|
|
240
|
+
| namespace | | Same as this [schema][schema-domain-namespace] | |
|
|
241
|
+
| maintainer | | Same as this [schema][schema-domain-maintainer] | |
|
|
242
|
+
| trustedSinceVersion | | Same as this [schema][schema-domain-trustedSinceVersion] | |
|
|
243
|
+
| latestVersion | | Same as this [schema][schema-domain-latestVersion] | |
|
|
244
|
+
| pipelineId | | Same as this [schema][schema-domain-pipelineId] | |
|
|
245
|
+
|
|
246
|
+
**PipelineTemplateVersion**
|
|
247
|
+
|
|
248
|
+
| Field | Sub Field | Schema | Description |
|
|
249
|
+
| ---------- | ------------- |------------- |------------- |
|
|
250
|
+
| id | | Same as Job template `id` [schema][schema-domain-id] | |
|
|
251
|
+
| description | | Same as this [schema][schema-domain-description] | |
|
|
252
|
+
| version | | Same as this [schema][schema-domain-version] | |
|
|
253
|
+
| config | shared | Same as this [schema][schema-domain-shared] | |
|
|
254
|
+
| | jobs | Same as this [schema][schema-domain-jobs] | Required |
|
|
255
|
+
| | parameters | Same as this [schema][schema-domain-params] | |
|
|
256
|
+
| createTime | | Same as this [schema][schema-domain-createTime] | |
|
|
257
|
+
| templateId | | Same as this [schema][schema-domain-id] | |
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
### Config Parser
|
|
261
|
+
|
|
262
|
+
No change needed
|
|
263
|
+
|
|
264
|
+
### Template Validator
|
|
265
|
+
|
|
266
|
+
Add a new function that takes the parsed template (Javascript) object as input and validates it against the [schema][schema-template-validator].
|
|
267
|
+
|
|
268
|
+
### Data Access Object/Layer (DAO)
|
|
269
|
+
|
|
270
|
+
Provides an interface to integrate with the database.
|
|
271
|
+
|
|
272
|
+
***TemplateMeta***
|
|
273
|
+
|
|
274
|
+
The `TemplateMeta` module will extend the `BaseModel` class to expose methods to update or delete pipeline/job templates. For pipeline templates:
|
|
275
|
+
|
|
276
|
+
_remove(templateVersionFactory, templateTagFactory)_
|
|
277
|
+
- Deletes template metadata by removing the entry from `templateMeta` table
|
|
278
|
+
- Get the configurations associated with all the versions of this template using templateVersionFactory
|
|
279
|
+
- Call remove(templateTagFactory) on each version from step #2
|
|
280
|
+
|
|
281
|
+
_update()_
|
|
282
|
+
Default implementation
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
***TemplateMetaFactory***
|
|
286
|
+
|
|
287
|
+
The `TemplateMetaFactory` module will extend the `BaseFactory` class to expose methods to create or fetch pipeline templates.
|
|
288
|
+
|
|
289
|
+
_list(config)_
|
|
290
|
+
|
|
291
|
+
Fetch and return entries from `templateMeta` table for the criteria specified in the config.
|
|
292
|
+
|
|
293
|
+
Arguments:
|
|
294
|
+
| Argument | Description |
|
|
295
|
+
| ---------- | ------------- |
|
|
296
|
+
| config.params.id | Identifier of the template |
|
|
297
|
+
| config.params.name | |
|
|
298
|
+
| config.params.namespace | |
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
_get(config)_
|
|
302
|
+
|
|
303
|
+
Fetch and return the template configuration from `PipelineTemplate` matching the criteria specified in the config
|
|
304
|
+
|
|
305
|
+
Arguments:
|
|
306
|
+
| Argument | Description |
|
|
307
|
+
| ---------- | ------------- |
|
|
308
|
+
| config.params.id | |
|
|
309
|
+
| config.params.name | |
|
|
310
|
+
| config.params.namespace | |
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
_create(config)_
|
|
315
|
+
|
|
316
|
+
Calls getTemplateType() method to update `templateType` field in templateMeta table
|
|
317
|
+
|
|
318
|
+
Arguments:
|
|
319
|
+
| Argument | Description |
|
|
320
|
+
| ---------- | ------------- |
|
|
321
|
+
| config.<?> |`?` refers to the fields mentioned in template configuration schema |
|
|
322
|
+
| config.pipelineId | Identifier of the Screwdriver pipeline that is publishing the template |
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
***PipelineTemplate***
|
|
327
|
+
|
|
328
|
+
The `PipelineTemplate` module will extend the `TemplateMeta` class.
|
|
329
|
+
|
|
330
|
+
***PipelineTemplateFactory***
|
|
331
|
+
|
|
332
|
+
The `PipelineTemplateFactory` module will extend the `TemplateMetaFactory` class to expose methods to create or fetch pipeline templates.
|
|
333
|
+
|
|
334
|
+
_getTemplateType()_
|
|
335
|
+
Return the type of template as ‘PIPELINE’
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
***PipelineTemplateVersion***
|
|
339
|
+
|
|
340
|
+
The `PipelineTemplateVersion` module will extend the `BaseModel` class to expose methods to update or delete pipeline template versions.
|
|
341
|
+
|
|
342
|
+
_remove(templateTagFactory)_
|
|
343
|
+
- Removes the entry from `pipelineTemplateVersions` table
|
|
344
|
+
- Get all the associated tags using templateTagFactory.list(config)
|
|
345
|
+
- Call remove() on each tag from step #2
|
|
346
|
+
|
|
347
|
+
_update()_
|
|
348
|
+
Default implementation
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
***PipelineTemplateVersionFactory***
|
|
352
|
+
|
|
353
|
+
The `PipelineTemplateVersionFactory` module will extend the `BaseFactory` class to expose methods to create or fetch template versions.
|
|
354
|
+
|
|
355
|
+
_create(config)_
|
|
356
|
+
1. If template does not exist in `templateMeta`,
|
|
357
|
+
- adds a new entry in `templateMeta` table to persist metadata associated with the template
|
|
358
|
+
- Adds an entry in `pipelineTemplateVersions` table to persist version and configuration for the new template by calling templateVersionFactory.create()
|
|
359
|
+
|
|
360
|
+
1. If template exists in `templateMeta`,
|
|
361
|
+
- adds entry in `pipelineTemplateVersions` table with latest details to persist version and configuration for the new template by calling templateVersionFactory.create()
|
|
362
|
+
|
|
363
|
+
Arguments:
|
|
364
|
+
| Argument | Description |
|
|
365
|
+
| ---------- | ------------- |
|
|
366
|
+
| config.<?> |`?` refers to the fields of PipelineTemplateVersion |
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
_list(config)_
|
|
370
|
+
|
|
371
|
+
Fetch and return entries from `pipelineTemplateVersions` table for the criteria specified in the config.
|
|
372
|
+
|
|
373
|
+
Arguments:
|
|
374
|
+
| Argument | Description |
|
|
375
|
+
| ---------- | ------------- |
|
|
376
|
+
| config.params.templateId| |
|
|
377
|
+
| config.params.name | |
|
|
378
|
+
| config.params.namespace | |
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
_get(config)_
|
|
382
|
+
|
|
383
|
+
Fetch and return the template configuration from `pipelineTemplateVersions` matching the criteria specified in the config
|
|
384
|
+
|
|
385
|
+
Arguments:
|
|
386
|
+
| Argument | Description |
|
|
387
|
+
| ---------- | ------------- |
|
|
388
|
+
| config.params.templateId | Filter result by templateId. Template name and templateId are mutually exclusive |
|
|
389
|
+
| config.params.name | |
|
|
390
|
+
| config.params.namespace | |
|
|
391
|
+
| config.params.version | |
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
_getWithMetadata(config)_
|
|
395
|
+
|
|
396
|
+
Fetch and return the template configuration from `pipelineTemplateVersions` matching the criteria specified in the config and also include the corresponding metadata from the `templateMeta` table
|
|
397
|
+
|
|
398
|
+
Arguments:
|
|
399
|
+
| Argument | Description |
|
|
400
|
+
| ---------- | ------------- |
|
|
401
|
+
| config.params.templateId | Filter result by templateId |
|
|
402
|
+
| config.params.name | |
|
|
403
|
+
| config.params.namespace | |
|
|
404
|
+
| config.params.version | |
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
***TemplateTagFactory***
|
|
408
|
+
|
|
409
|
+
As we are utilizing the current templateTags table and introducing a new column called `templateType`, we will modify the existing templateTagsFactory module to incorporate the `templateType` field.
|
|
410
|
+
|
|
411
|
+
_listPipelineTemplateTags(config)_
|
|
412
|
+
|
|
413
|
+
This will add `templateType`: ‘PIPELINE’ to `config.params`
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
Arguments:
|
|
417
|
+
| Argument | Description |
|
|
418
|
+
| ---------- | ------------- |
|
|
419
|
+
| config.templateName | |
|
|
420
|
+
| config.templateNamespace | |
|
|
421
|
+
| config.params.version | |
|
|
422
|
+
|
|
423
|
+
Will set `config.params.templateType` = 'PIPELINE’
|
|
424
|
+
|
|
425
|
+
_createPipelineTag(config)_
|
|
426
|
+
|
|
427
|
+
This will add `templateType: ‘PIPELINE’` to `config` and then call `create(config)`
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
Arguments:
|
|
431
|
+
| Argument | Description |
|
|
432
|
+
| ---------- | ------------- |
|
|
433
|
+
| config.templateName | |
|
|
434
|
+
| config.templateNamespace | |
|
|
435
|
+
| config.params.version | |
|
|
436
|
+
|
|
437
|
+
Will set `config.params.templateType` = 'PIPELINE’
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
***PipelineTemplateTagFactory***
|
|
441
|
+
The PipelineTemplateTagFactory module will extend the TemplateTagFactory class to expose methods to get template types.
|
|
442
|
+
|
|
443
|
+
_getTemplateType()_
|
|
444
|
+
Return `templateType` as ‘PIPELINE’
|
|
445
|
+
|
|
446
|
+
***JobTemplateTagFactory***
|
|
447
|
+
The JobTemplateTagFactory module will extend the TemplateTagFactory class to expose methods to get template types.
|
|
448
|
+
|
|
449
|
+
_getTemplateType()_
|
|
450
|
+
Return `templateType` as ‘JOB’
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
### Endpoints
|
|
455
|
+
|
|
456
|
+
***1. Validate a template***
|
|
457
|
+
|
|
458
|
+
This endpoint parses the template yaml file and confirms its validity so that it can be used for publishing with no errors.
|
|
459
|
+
|
|
460
|
+
**Request:**
|
|
461
|
+
|
|
462
|
+
- **Method**: POST
|
|
463
|
+
- **Path** : ‘/pipeline/template/validate’
|
|
464
|
+
- **Payload:**
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
{
|
|
468
|
+
"namespace": "myNamespace",
|
|
469
|
+
"name": "template_name",
|
|
470
|
+
"version": "1.3",
|
|
471
|
+
"description": "template for testing",
|
|
472
|
+
"maintainer": "foo@bar.com",
|
|
473
|
+
"config": {
|
|
474
|
+
"jobs": {
|
|
475
|
+
"main": {
|
|
476
|
+
"image": "node:18",
|
|
477
|
+
"steps": "abc",
|
|
478
|
+
"requires": "xyz"
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Response:**
|
|
485
|
+
|
|
486
|
+
JSON containing the property ‘valid’ indicating if the template is valid or not.
|
|
487
|
+
|
|
488
|
+
```
|
|
489
|
+
{
|
|
490
|
+
"valid": "true"
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
***2. Validate and Publish a template***
|
|
496
|
+
|
|
497
|
+
This endpoint accepts template configuration as input, validates it and publishes it so that it can be used to create pipelines.
|
|
498
|
+
|
|
499
|
+
**Request:**
|
|
500
|
+
|
|
501
|
+
- **Method**: POST
|
|
502
|
+
- **Path** : ‘validator/pipelineTemplate’
|
|
503
|
+
- **Payload:**
|
|
504
|
+
|
|
505
|
+
```
|
|
506
|
+
{
|
|
507
|
+
"namespace": "myNamespace",
|
|
508
|
+
"name": "template_name",
|
|
509
|
+
"version": "1.3",
|
|
510
|
+
"description": "template for testing",
|
|
511
|
+
"maintainer": "foo@bar.com",
|
|
512
|
+
"config": {
|
|
513
|
+
"jobs": {
|
|
514
|
+
"main": {
|
|
515
|
+
"image": "node:18",
|
|
516
|
+
"steps": "abc",
|
|
517
|
+
"requires": "xyz"
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Response:**
|
|
524
|
+
|
|
525
|
+
JSON object representing the template version along with the metadata which was created by the API.
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
{
|
|
529
|
+
"id": 3,
|
|
530
|
+
"templateId": 123,
|
|
531
|
+
"pipelineId": 3,
|
|
532
|
+
"namespace": "myNamespace",
|
|
533
|
+
"name": "template_name",
|
|
534
|
+
"version": "1.3.2",
|
|
535
|
+
"description": "template for testing",
|
|
536
|
+
"maintainer": "foo@bar.com",
|
|
537
|
+
"config": {
|
|
538
|
+
"jobs": {
|
|
539
|
+
"main": {
|
|
540
|
+
"image": "node:18",
|
|
541
|
+
"steps": "abc",
|
|
542
|
+
"requires": "xyz"
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
"createTime": "2023-06-12T21:52:22.706Z"
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
***3. Create/Update template tag***
|
|
552
|
+
|
|
553
|
+
This endpoint accepts the version as input and creates/updates a tag for the template name and namespace specified in the endpoint path.
|
|
554
|
+
|
|
555
|
+
**Request:**
|
|
556
|
+
|
|
557
|
+
- **Method**: PUT
|
|
558
|
+
- **Path** : ‘/pipeline/template/{templateNamespace}/{templateName}/tags/{tagName}’
|
|
559
|
+
- **Payload:**
|
|
560
|
+
|
|
561
|
+
```
|
|
562
|
+
{
|
|
563
|
+
|
|
564
|
+
"version": "1.3.2"
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Response:**
|
|
569
|
+
|
|
570
|
+
JSON object representing the template tag details and status code.
|
|
571
|
+
|
|
572
|
+
```
|
|
573
|
+
{
|
|
574
|
+
"id": 2,
|
|
575
|
+
"createTime": "2023-06-12T21:52:22.706Z"
|
|
576
|
+
"namespace": "tempNameSpace"
|
|
577
|
+
"name": "templateName",
|
|
578
|
+
"tag": "tagName",
|
|
579
|
+
"version": "1.3.2",
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
***4. List all the templates***
|
|
585
|
+
|
|
586
|
+
Returns an array template meta for all the pipeline templates
|
|
587
|
+
|
|
588
|
+
**Request:**
|
|
589
|
+
|
|
590
|
+
- **Method**: GET
|
|
591
|
+
- **Path** : ‘/pipeline/templates’
|
|
592
|
+
|
|
593
|
+
**Response:**
|
|
594
|
+
|
|
595
|
+
JSON object consisting of a list of objects having template metadata for each template.
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
Status Code: 200 (OK)
|
|
599
|
+
Response Body:
|
|
600
|
+
[
|
|
601
|
+
{
|
|
602
|
+
"id": 123,
|
|
603
|
+
"pipelineId": 3,
|
|
604
|
+
"name": "example-template",
|
|
605
|
+
"namespace": "my-namespace",
|
|
606
|
+
"description": "An example template",
|
|
607
|
+
"maintainer": "example123@gmail.com",
|
|
608
|
+
“trustedSinceVersion”: “true”,
|
|
609
|
+
“latestVersion”: “1.3.2”,
|
|
610
|
+
"createTime": "2023-06-12T21:52:22.706Z",
|
|
611
|
+
"updateTime": "2023-06-29T11:23:45.706Z"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
…
|
|
615
|
+
},
|
|
616
|
+
…
|
|
617
|
+
]
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
***5. Get a specific template by id***
|
|
621
|
+
|
|
622
|
+
Returns an array of details for a specific template when its id is provided in the endpoint.
|
|
623
|
+
|
|
624
|
+
**Request:**
|
|
625
|
+
|
|
626
|
+
- **Method**: GET
|
|
627
|
+
- **Path** : ‘/pipeline/template/{templateId}`
|
|
628
|
+
|
|
629
|
+
**Response:**
|
|
630
|
+
|
|
631
|
+
JSON object consisting template details for the given Id.
|
|
632
|
+
|
|
633
|
+
```
|
|
634
|
+
Status Code: 200 (OK)
|
|
635
|
+
Response Body:
|
|
636
|
+
{
|
|
637
|
+
"id": 123,
|
|
638
|
+
"pipelineId": 3,
|
|
639
|
+
"namespace": "my-namespace",
|
|
640
|
+
"name": "example-template",
|
|
641
|
+
"description": "An example template",
|
|
642
|
+
"maintainer": "example@gmail.com",
|
|
643
|
+
“trustedSinceVersion”: “1.2.3”,
|
|
644
|
+
"latestVersion": "1.3.2",
|
|
645
|
+
"createTime": "2023-06-12T21:52:22.706Z",
|
|
646
|
+
"updateTime": "2023-06-29T11:23:45.706Z"
|
|
647
|
+
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
***6. Get a specific template by namespace and name***
|
|
652
|
+
|
|
653
|
+
Returns template meta for the specified namespace and name
|
|
654
|
+
|
|
655
|
+
**Request:**
|
|
656
|
+
|
|
657
|
+
- **Method**: GET
|
|
658
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}`
|
|
659
|
+
|
|
660
|
+
**Response:**
|
|
661
|
+
|
|
662
|
+
JSON object consisting template details for the given template namespace and name combination.
|
|
663
|
+
|
|
664
|
+
```
|
|
665
|
+
Status Code: 200 (OK)
|
|
666
|
+
Response Body:
|
|
667
|
+
{
|
|
668
|
+
"id": 123,
|
|
669
|
+
"pipelineId": 3,
|
|
670
|
+
"namespace": "my-namespace",
|
|
671
|
+
"name": "example-template",
|
|
672
|
+
"description": "An example template",
|
|
673
|
+
"maintainer": "example@gmail.com",
|
|
674
|
+
“trustedSinceVersion”: “1.2.3”,
|
|
675
|
+
"latestVersion": "1.3.2",
|
|
676
|
+
"createTime": "2023-06-12T21:52:22.706Z",
|
|
677
|
+
"updateTime": "2023-06-29T11:23:45.706Z"
|
|
678
|
+
|
|
679
|
+
}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
***7. List all the versions for a template namespace and name***
|
|
683
|
+
|
|
684
|
+
Returns fields from the pipelineTemplateVersions table for the specified namespace and name.
|
|
685
|
+
|
|
686
|
+
**Request:**
|
|
687
|
+
|
|
688
|
+
- **Method**: GET
|
|
689
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}/versions`
|
|
690
|
+
|
|
691
|
+
**Response:**
|
|
692
|
+
|
|
693
|
+
JSON object consisting list of template records, representing all versions of the specified template name.
|
|
694
|
+
|
|
695
|
+
```
|
|
696
|
+
Status Code: 200 (OK)
|
|
697
|
+
Response Body:
|
|
698
|
+
[
|
|
699
|
+
{
|
|
700
|
+
"id": 1,
|
|
701
|
+
"templateId": 123,
|
|
702
|
+
"description": "An example template",
|
|
703
|
+
"version": "1.0.0",
|
|
704
|
+
"config": {
|
|
705
|
+
"jobs": {
|
|
706
|
+
"main": {
|
|
707
|
+
"image": "node:18",
|
|
708
|
+
"steps": {
|
|
709
|
+
"printLine": "echo 'Testing template creation V1'"
|
|
710
|
+
},
|
|
711
|
+
"requires": "[~pr, ~commit]"
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
"createTime": "2023-06-12T21:52:22.706Z"
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
"id": 2,
|
|
719
|
+
"templateId": 123,
|
|
720
|
+
"description": "An example template",
|
|
721
|
+
"version": "1.1.0",
|
|
722
|
+
"config": {
|
|
723
|
+
"jobs": {
|
|
724
|
+
"main": {
|
|
725
|
+
"image": "node:18",
|
|
726
|
+
"steps": {
|
|
727
|
+
"printLine": "echo 'Testing template creation V1.1'"
|
|
728
|
+
},
|
|
729
|
+
"requires": "[~pr, ~commit]"
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
"createTime": "2023-06-12T21:52:22.706Z" }
|
|
734
|
+
]
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
***8. List all the tags for a template namespace and name***
|
|
738
|
+
|
|
739
|
+
Returns fields from pipeline template tag table for specified namespace and name.
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
**Request:**
|
|
743
|
+
|
|
744
|
+
- **Method**: GET
|
|
745
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}/tags`
|
|
746
|
+
|
|
747
|
+
**Response:**
|
|
748
|
+
|
|
749
|
+
JSON object consisting list of template tags, representing all the tags associated with the specified template name and namespace.
|
|
750
|
+
|
|
751
|
+
```
|
|
752
|
+
Status Code: 200 (OK)
|
|
753
|
+
Response Body:
|
|
754
|
+
[
|
|
755
|
+
{
|
|
756
|
+
"id": 1,
|
|
757
|
+
"createTime": "2023-06-12T22:52:22.706Z",
|
|
758
|
+
"namespace": "namespace123",
|
|
759
|
+
"name": "testTemplate",
|
|
760
|
+
"tag": "stable",
|
|
761
|
+
"version": "1.0.0"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
"id": 2,
|
|
765
|
+
"createTime": "2023-06-12T24:45:22.706Z",
|
|
766
|
+
"namespace": "namespace123",
|
|
767
|
+
"name": "testTemplate",
|
|
768
|
+
"tag": "latest"
|
|
769
|
+
"version": "1.1.0"
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
***9. Get a specific template version details by version number or tag***
|
|
775
|
+
|
|
776
|
+
Returns fields from both template meta and version table associated with the specified pipeline template namespace, name and version/tag
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
**Request:**
|
|
780
|
+
|
|
781
|
+
- **Method**: GET
|
|
782
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}/{versionOrTag}’
|
|
783
|
+
|
|
784
|
+
**Response:**
|
|
785
|
+
|
|
786
|
+
JSON object consisting of the template details for the given version number or tag.
|
|
787
|
+
|
|
788
|
+
```
|
|
789
|
+
Status Code: 200 (OK)
|
|
790
|
+
Response Body:
|
|
791
|
+
[
|
|
792
|
+
{
|
|
793
|
+
"id":1",
|
|
794
|
+
"templateId": 123,
|
|
795
|
+
"pipelineId": 3,
|
|
796
|
+
"namespace": "myNamespace",
|
|
797
|
+
"name": "template_name",
|
|
798
|
+
"version": "1.3.2",
|
|
799
|
+
"description": "template for testing",
|
|
800
|
+
"maintainer": "example@gmail.com",
|
|
801
|
+
"config": {
|
|
802
|
+
"jobs": {
|
|
803
|
+
"main": {
|
|
804
|
+
"image": "node:18",
|
|
805
|
+
"steps": {
|
|
806
|
+
"printLine": "echo 'Testing template creation V1'"
|
|
807
|
+
},
|
|
808
|
+
"requires": "[~pr, ~commit]"
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
"createTime": "2023-06-12T21:52:22.706Z"
|
|
813
|
+
}
|
|
814
|
+
]
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
***10. Remove template and associated versions and tags***
|
|
818
|
+
|
|
819
|
+
Deletes the template and its corresponding versions and tags
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
**Request:**
|
|
823
|
+
|
|
824
|
+
- **Method**: DELETE
|
|
825
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}`
|
|
826
|
+
|
|
827
|
+
**Response:**
|
|
828
|
+
|
|
829
|
+
HTTP status code 204 (No Content)
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
***11. Remove template tag***
|
|
833
|
+
|
|
834
|
+
Deletes the template tag for a specific template from the `templateTags` table where `templateType` is ‘PIPELINE’
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
**Request:**
|
|
838
|
+
|
|
839
|
+
- **Method**: DELETE
|
|
840
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}/tags/{tagName}’
|
|
841
|
+
|
|
842
|
+
**Response:**
|
|
843
|
+
|
|
844
|
+
HTTP status code 204 (No Content)
|
|
845
|
+
|
|
846
|
+
***12. Remove template version and associated tags***
|
|
847
|
+
|
|
848
|
+
Deletes the specific template tag and then removes the associated versions
|
|
849
|
+
|
|
850
|
+
**Request:**
|
|
851
|
+
|
|
852
|
+
- **Method**: DELETE
|
|
853
|
+
- **Path** : ‘/pipeline/templates/{templateNamespace}/{templateName}/versions/{version}`
|
|
854
|
+
|
|
855
|
+
**Response:**
|
|
856
|
+
|
|
857
|
+
HTTP status code 204 (No Content)
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
### SD CLI
|
|
861
|
+
|
|
862
|
+
We will introduce new commands to validate, publish and tag pipeline templates because using the existing commands will not allow us to easily differentiate between the two types of templates (job template and pipeline template)
|
|
863
|
+
|
|
864
|
+
CLI can be installed using below command:
|
|
865
|
+
|
|
866
|
+
``` $ npm install sd-template-main ```
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
***1. Validate***
|
|
870
|
+
|
|
871
|
+
We will add a new command `pipeline-template-validate`.
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
The default path to the template.yaml file is `./sd-template.yaml` unless specified in the environment variable `SD_TEMPLATE_PATH`
|
|
875
|
+
|
|
876
|
+
This command will
|
|
877
|
+
- read the content of ‘template.yaml’ and parse it into Javascript object
|
|
878
|
+
- make a POST request ‘/pipeline/template/validate’ endpoint
|
|
879
|
+
|
|
880
|
+
Note: This command does accept any arguments
|
|
881
|
+
|
|
882
|
+
Usage:
|
|
883
|
+
|
|
884
|
+
```$ ./node_modules/.bin/pipeline-template-validate --json```
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
***2. Publish***
|
|
888
|
+
|
|
889
|
+
We will add a new command `pipeline-template-publish`.
|
|
890
|
+
|
|
891
|
+
This command will
|
|
892
|
+
- Read the content of `template.yaml` and parse it into Javascript object
|
|
893
|
+
- Make a POST request to `/pipelineTemplates` endpoint to create a new template
|
|
894
|
+
- Make a PUT request to `/pipeline/template/{templateName}/tags/{tagName}` endpoint to create/update the tag for the newly created template
|
|
895
|
+
|
|
896
|
+
The default path to the template.yaml file is `./sd-template.yaml` unless specified in the environment variable `SD_TEMPLATE_PATH`
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
Arguments:
|
|
900
|
+
| Argument | Optional | Description |
|
|
901
|
+
| ---------- | ------------- | ------------- |
|
|
902
|
+
| tag| Yes | Specifies the name of the tag to be created/updated after the template is created. Uses `latest` as the tag name if not specified.
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
Usage:
|
|
906
|
+
|
|
907
|
+
```
|
|
908
|
+
$ ./node_modules/.bin/pipeline-template-publish --json
|
|
909
|
+
|
|
910
|
+
#takes custom tag name "stable"
|
|
911
|
+
$ ./node_modules/.bin/pipeline-template-publish --json --tag stable
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
***3. Create/Update Tag***
|
|
916
|
+
|
|
917
|
+
We will add a new command `pipeline-template-tag`.
|
|
918
|
+
|
|
919
|
+
This command will
|
|
920
|
+
- Take template details (`name`, `namespace` and `version`) and name of the tag as input
|
|
921
|
+
- Make a PUT request to ‘/pipeline/template/{templateName}/tags/{tagName}’ endpoint to create or update the tag to the specified template
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
Arguments:
|
|
926
|
+
| Argument | Description |
|
|
927
|
+
| ---------- | ------------- |
|
|
928
|
+
| namespace| Specifies template namespace |
|
|
929
|
+
| name| Specifies template name |
|
|
930
|
+
| version| Specifies version of the template |
|
|
931
|
+
| tag| Specifies tag name |
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
Usage:
|
|
935
|
+
|
|
936
|
+
```
|
|
937
|
+
$ ./node_modules/.bin/pipeline-template-tag --json --namespace template123 –name 123 --version 4.0.0 --tag stable
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
***4. Remove a Template***
|
|
941
|
+
|
|
942
|
+
We will add a new command `pipeline-template-remove`.
|
|
943
|
+
|
|
944
|
+
This command will
|
|
945
|
+
- Remove a template and associated versions and tags by making a DELETE request to the ‘/pipeline/templates/{templateName}’ API endpoint
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
Arguments:
|
|
950
|
+
| Argument | Description |
|
|
951
|
+
| ---------- | ------------- |
|
|
952
|
+
| namespace| Specifies template namespace |
|
|
953
|
+
| name| Specifies template name |
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
Usage:
|
|
957
|
+
|
|
958
|
+
```
|
|
959
|
+
$ ./node_modules/.bin/pipeline-template-remove --json --namespace template123 –name 123
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
***5. Remove a Template Tag***
|
|
965
|
+
|
|
966
|
+
We will add a new command `pipeline-template-remove-tag`.
|
|
967
|
+
|
|
968
|
+
This command will
|
|
969
|
+
- Take template details (`name` and `namespace`) and name of the tag as input
|
|
970
|
+
- Make a DELETE request ‘/pipeline/templates/{templateName}/tags/{tagName}’ endpoint to remove the tag for the specified template
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
Arguments:
|
|
976
|
+
| Argument | Description |
|
|
977
|
+
| ---------- | ------------- |
|
|
978
|
+
| namespace| Specifies template namespace |
|
|
979
|
+
| name| Specifies template name |
|
|
980
|
+
| tag| Specifies tag name |
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
Usage:
|
|
984
|
+
|
|
985
|
+
```
|
|
986
|
+
$ ./node_modules/.bin/pipeline-template-remove-tag --json --namespace template123 –name 123 --tag stable
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
***6. Remove a Template Version***
|
|
990
|
+
|
|
991
|
+
We will add a new command `pipeline-template-remove-version`.
|
|
992
|
+
|
|
993
|
+
This command will
|
|
994
|
+
- Take template name, namespace and version as input
|
|
995
|
+
- Make a DELETE request ‘/pipeline/templates/{templateName}versions/{version}’ endpoint to delete the config and tags associated with the specified version
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
Arguments:
|
|
999
|
+
| Argument | Description |
|
|
1000
|
+
| ---------- | ------------- |
|
|
1001
|
+
| namespace| Specifies template namespace |
|
|
1002
|
+
| name| Specifies template name |
|
|
1003
|
+
| version| Specifies the template version to be removed |
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
Usage:
|
|
1007
|
+
|
|
1008
|
+
```
|
|
1009
|
+
$ ./node_modules/.bin/pipeline-template-remove-version --namespace template123 –name 123 --version 1.0.0
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
***7. Get a Template Config with metadata by Tag***
|
|
1014
|
+
|
|
1015
|
+
We will add a new command `pipeline-template-get`.
|
|
1016
|
+
|
|
1017
|
+
This command will
|
|
1018
|
+
- Take template details (`name` and `namespace`) and tag name as input
|
|
1019
|
+
- Make a GET request to ‘/pipeline/templates/{templateName}/{versionOrTag}’ endpoint to get template configuration along with its metadata associated with the specified tag
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
Arguments:
|
|
1024
|
+
| Argument | Description |
|
|
1025
|
+
| ---------- | ------------- |
|
|
1026
|
+
| namespace| Specifies template namespace |
|
|
1027
|
+
| name| Specifies template name |
|
|
1028
|
+
| tag| Specifies the template tag name |
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
Usage:
|
|
1032
|
+
|
|
1033
|
+
```
|
|
1034
|
+
$ ./node_modules/.bin/pipeline-template-get --namespace template123 –name 123 --tag latest
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
## UI
|
|
1038
|
+
|
|
1039
|
+
TODO: Will be updated after the meeting with the UX designer.
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
## Template Usage
|
|
1045
|
+
|
|
1046
|
+
### Pipeline configuration
|
|
1047
|
+
|
|
1048
|
+
__Basic Configuration (without customization):__
|
|
1049
|
+
|
|
1050
|
+
```yaml
|
|
1051
|
+
template: foo/bar@latest
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
__Advanced Configuration (with customization):__
|
|
1055
|
+
|
|
1056
|
+
```yaml
|
|
1057
|
+
template: foo/bar@latest
|
|
1058
|
+
shared:
|
|
1059
|
+
environment:
|
|
1060
|
+
SD_SONAR_OPTS:
|
|
1061
|
+
settings:
|
|
1062
|
+
email: [foo@bar.com]
|
|
1063
|
+
```
|
|
1064
|
+
New fields:
|
|
1065
|
+
|
|
1066
|
+
| Field | Sub Field | Schema |Description |
|
|
1067
|
+
| ---------- | ------------- | ------------- | ------------- |
|
|
1068
|
+
| template| |Same as job `template` [schema][schema-uasage-template]| Optional. Mutually exclusive with existing fields `jobs` and `parameters` |
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
Existing fields:
|
|
1072
|
+
|
|
1073
|
+
| Field | Sub Field | Schema |Description |
|
|
1074
|
+
| ---------- | ------------- | ------------- | ------------- |
|
|
1075
|
+
| shared| settings, environment |Refer to job [schema][schema-uasage-shared]| Optional. Allowed even when pipeline is using a template |
|
|
1076
|
+
| | annotations, blockedBy, cache, description, freezeWindows, image, matrix, order, parameters, provider, requires, secrets, sourcePaths, steps, template, templateId| | Not allowed when pipeline is using a template. Note: Customization of these fields would be supported in future phases|
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
## API
|
|
1080
|
+
|
|
1081
|
+
### DB Model
|
|
1082
|
+
|
|
1083
|
+
**Pipeline**
|
|
1084
|
+
- Add a new column `templateVersionId` in ‘pipeline’ table
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
| Column | Type | Nullable |Description |
|
|
1088
|
+
| ---------- | ------------- | ------------- | ------------- |
|
|
1089
|
+
| templateVersionId | Sequelize.DOUBLE |Yes| Identifier of ‘pipelineTemplateVersions’ table |
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
### Domain Model
|
|
1093
|
+
|
|
1094
|
+
**Pipeline**
|
|
1095
|
+
- Add a new field `templateVersionId`
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
| Column | Type | Nullable |Description |
|
|
1099
|
+
| ---------- | ------------- | ------------- | ------------- |
|
|
1100
|
+
| templateVersionId | Joi.number().integer().positive() |Yes| Identifier of ‘pipelineTemplateVersions’ table |
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
### Config Parser
|
|
1104
|
+
|
|
1105
|
+

|
|
1106
|
+
|
|
1107
|
+
When pipeline configuration contains `template` we need to perform below steps before flattening the configuration to build domain objects (pipeline, jobs, etc)
|
|
1108
|
+
1. Validate the configuration
|
|
1109
|
+
|
|
1110
|
+
a. `jobs` and `parameters` should not be allowed
|
|
1111
|
+
|
|
1112
|
+
b. `shared` can contain only `settings` and `environment`
|
|
1113
|
+
|
|
1114
|
+
1. Get template configuration (`shared`, `jobs`, `parameters`) from DB
|
|
1115
|
+
1. Merge `shared` from pipeline configuration into template configuration
|
|
1116
|
+
|
|
1117
|
+
This merged configuration will then be flattened (merging `shared` into job configuration, etc) as it is done currently.
|
|
1118
|
+
|
|
1119
|
+
Also, reference to the template will be set in the `pipeline` domain object.
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
## UI
|
|
1123
|
+
|
|
1124
|
+
TODO: Will be updated after the meeting with the UX designer.
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
[schema-namespace]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#L7
|
|
1157
|
+
[schema-name]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#LL15C1-L15C41
|
|
1158
|
+
[schema-maintainer]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#LL47C1-L47C41
|
|
1159
|
+
[schema-version]: hhttps://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#L30
|
|
1160
|
+
[schema-description]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#L42
|
|
1161
|
+
[schema-shared]: https://github.com/screwdriver-cd/data-schema/blob/master/config/base.js#LL31C1-L31C1
|
|
1162
|
+
[schema-jobs]: https://github.com/screwdriver-cd/data-schema/blob/master/config/base.js#L26
|
|
1163
|
+
[schema-params]: https://github.com/screwdriver-cd/data-schema/blob/master/config/parameters.js#L13
|
|
1164
|
+
[schema-domain-id]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L9
|
|
1165
|
+
[schema-domain-name]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L12
|
|
1166
|
+
[schema-domain-namespace]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L17
|
|
1167
|
+
[schema-domain-maintainer]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L15
|
|
1168
|
+
[schema-domain-trustedSinceVersion]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#L36
|
|
1169
|
+
[schema-domain-latestVersion]: https://github.com/screwdriver-cd/data-schema/blob/master/config/template.js#L36
|
|
1170
|
+
[schema-domain-pipelineId]: https://github.com/screwdriver-cd/data-schema/blob/master/models/pipeline.js#L30C7-L30C7
|
|
1171
|
+
[schema-domain-description]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L14
|
|
1172
|
+
[schema-domain-version]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L13
|
|
1173
|
+
[schema-domain-shared]: https://github.com/screwdriver-cd/data-schema/blob/master/config/base.js#LL31C1-L31C1
|
|
1174
|
+
[schema-domain-jobs]: https://github.com/screwdriver-cd/data-schema/blob/master/config/base.js#L67
|
|
1175
|
+
[schema-domain-params]: https://github.com/screwdriver-cd/data-schema/blob/master/config/parameters.js#L6
|
|
1176
|
+
[schema-domain-createTime]: https://github.com/screwdriver-cd/data-schema/blob/master/models/template.js#L19
|
|
1177
|
+
[schema-template-validator]: https://docs.google.com/document/d/12MAT6XxHQ28vqkPw6xlcxtVR3M5tOgnYGHEfUPyAWPI/edit#heading=h.47lbrhrjbdr6
|
|
1178
|
+
[schema-uasage-template]: https://github.com/screwdriver-cd/data-schema/blob/master/config/job.js#L129
|
|
1179
|
+
[schema-uasage-shared]: https://github.com/screwdriver-cd/data-schema/blob/master/config/job.js#L161
|
|
1180
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-api",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.172",
|
|
4
4
|
"description": "API server for the Screwdriver.cd service",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"screwdriver-coverage-bookend": "^2.0.0",
|
|
107
107
|
"screwdriver-coverage-sonar": "^4.1.1",
|
|
108
108
|
"screwdriver-data-schema": "^23.2.0",
|
|
109
|
-
"screwdriver-datastore-sequelize": "^8.
|
|
109
|
+
"screwdriver-datastore-sequelize": "^8.2.0",
|
|
110
110
|
"screwdriver-executor-base": "^9.0.1",
|
|
111
111
|
"screwdriver-executor-docker": "^6.0.0",
|
|
112
112
|
"screwdriver-executor-k8s": "^15.0.1",
|
package/plugins/builds/index.js
CHANGED
|
@@ -36,6 +36,7 @@ const {
|
|
|
36
36
|
buildsToRestartFilter,
|
|
37
37
|
trimJobName,
|
|
38
38
|
getParallelBuilds,
|
|
39
|
+
isStartFromMiddleOfStage,
|
|
39
40
|
Status
|
|
40
41
|
} = require('./triggers/helpers');
|
|
41
42
|
|
|
@@ -77,7 +78,8 @@ async function triggerNextJobs(config, app) {
|
|
|
77
78
|
/** @type Array<string> */
|
|
78
79
|
const nextJobsTrigger = workflowParser.getNextJobs(currentEvent.workflowGraph, {
|
|
79
80
|
trigger: currentJob.name,
|
|
80
|
-
chainPR: currentPipeline.chainPR
|
|
81
|
+
chainPR: currentPipeline.chainPR,
|
|
82
|
+
startFrom: currentEvent.startFrom
|
|
81
83
|
});
|
|
82
84
|
const pipelineJoinData = await createJoinObject(nextJobsTrigger, current, eventFactory);
|
|
83
85
|
const originalCurrentJobName = trimJobName(currentJob.name);
|
|
@@ -114,7 +116,10 @@ async function triggerNextJobs(config, app) {
|
|
|
114
116
|
* 2. ([~D,B,C]->A) currentJob=D, nextJob=A, joinList(A)=[B,C]
|
|
115
117
|
* joinList doesn't include D, so start A
|
|
116
118
|
*/
|
|
117
|
-
if (
|
|
119
|
+
if (
|
|
120
|
+
isOrTrigger(currentEvent.workflowGraph, originalCurrentJobName, trimJobName(nextJobName)) ||
|
|
121
|
+
isStartFromMiddleOfStage(currentJob.name, currentEvent.startFrom, currentEvent.workflowGraph)
|
|
122
|
+
) {
|
|
118
123
|
nextBuild = await orTrigger.execute(
|
|
119
124
|
currentEvent,
|
|
120
125
|
currentPipeline.id,
|
|
@@ -6,6 +6,7 @@ const merge = require('lodash.mergewith');
|
|
|
6
6
|
const schema = require('screwdriver-data-schema');
|
|
7
7
|
const { EXTERNAL_TRIGGER_ALL } = schema.config.regex;
|
|
8
8
|
const { getFullStageJobName } = require('../../helper');
|
|
9
|
+
const STAGE_SETUP_PATTERN = /^stage@([\w-]+)(?::setup)$/;
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @typedef {import('screwdriver-models').JobFactory} JobFactory
|
|
@@ -1063,6 +1064,38 @@ function buildsToRestartFilter(joinPipeline, groupEventBuilds, currentEvent, cur
|
|
|
1063
1064
|
.filter(build => build !== null);
|
|
1064
1065
|
}
|
|
1065
1066
|
|
|
1067
|
+
/**
|
|
1068
|
+
* Check if the job is setup job with setup suffix
|
|
1069
|
+
* @param {String} jobName Job name
|
|
1070
|
+
* @return {Boolean}
|
|
1071
|
+
*/
|
|
1072
|
+
function isStageSetup(jobName) {
|
|
1073
|
+
return STAGE_SETUP_PATTERN.test(jobName);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Check if the job is a stage job
|
|
1078
|
+
* @param {String} jobName Job name
|
|
1079
|
+
* @param {Object} workflowGraph Workflow Graph
|
|
1080
|
+
* @return {Boolean}
|
|
1081
|
+
*/
|
|
1082
|
+
function isStageJob(workflowGraph, jobName) {
|
|
1083
|
+
const jobNode = workflowGraph.nodes.find(n => n.name === jobName);
|
|
1084
|
+
|
|
1085
|
+
return jobNode.stageName !== undefined;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Check if the current job is a stage setup and the next job is a non-setup stage job
|
|
1090
|
+
* @param {String} triggerJob Current job
|
|
1091
|
+
* @param {String} startFrom Next job
|
|
1092
|
+
* @param {Object} workflowGraph Workflow Graph
|
|
1093
|
+
* @return {Boolean}
|
|
1094
|
+
*/
|
|
1095
|
+
function isStartFromMiddleOfStage(triggerJob, startFrom, workflowGraph) {
|
|
1096
|
+
return isStageSetup(triggerJob) && !isStageSetup(startFrom) && isStageJob(workflowGraph, startFrom);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1066
1099
|
module.exports = {
|
|
1067
1100
|
Status,
|
|
1068
1101
|
parseJobInfo,
|
|
@@ -1085,5 +1118,6 @@ module.exports = {
|
|
|
1085
1118
|
extractCurrentPipelineJoinData,
|
|
1086
1119
|
extractExternalJoinData,
|
|
1087
1120
|
buildsToRestartFilter,
|
|
1088
|
-
trimJobName
|
|
1121
|
+
trimJobName,
|
|
1122
|
+
isStartFromMiddleOfStage
|
|
1089
1123
|
};
|
|
@@ -110,9 +110,13 @@ Query Params:
|
|
|
110
110
|
* `type` - *Optional* Get pipeline or pr events (default `pipeline`)
|
|
111
111
|
* `prNum` - *Optional* Return only PR events of specified PR number
|
|
112
112
|
* `sha` - *Optional* Search `sha` and `configPipelineSha` for events
|
|
113
|
+
* `id` - *Optional* Fetch specific event ID; alternatively can use greater than(`gt:`) or less than(`lt:`) prefix
|
|
113
114
|
|
|
114
115
|
`GET /pipelines/{id}/events?page={pageNumber}&count={countNumber}&sort={sort}&type={type}&prNum={prNumber}&sha={sha}`
|
|
115
116
|
|
|
117
|
+
`GET /pipelines/{id}/events?id=gt:{eventId}&count={countNumber}` (greater than eventId)
|
|
118
|
+
`GET /pipelines/{id}/events?id=lt:{eventId}&count={countNumber}` (less than eventId)
|
|
119
|
+
|
|
116
120
|
#### Get all pipeline builds
|
|
117
121
|
`page`, `count`, `sort`, `latest`, `sortBy`, `fetchSteps`, `readOnly`, and `groupEventId` are optional
|
|
118
122
|
When `latest=true` and `groupEventId` is set, only latest builds in a pipeline based on groupEventId will be returned. The `latest` parameter must be used in conjunction with the `groupEventId`.
|
|
@@ -13,6 +13,12 @@ const shaSchema = joi
|
|
|
13
13
|
.example('ccc49349d3cffbd12ea9e3d41521480b4aa5de5f');
|
|
14
14
|
const typeSchema = schema.models.event.base.extract('type');
|
|
15
15
|
const pipelineIdSchema = schema.models.pipeline.base.extract('id');
|
|
16
|
+
const INEQUALITY_SIGNS = /^(gt|lt):([\d]+)$/;
|
|
17
|
+
const queryIdSchema = joi
|
|
18
|
+
.alternatives()
|
|
19
|
+
.try(pipelineIdSchema, joi.string().regex(INEQUALITY_SIGNS))
|
|
20
|
+
.label('Query ID schema')
|
|
21
|
+
.example('gt:12345');
|
|
16
22
|
|
|
17
23
|
module.exports = () => ({
|
|
18
24
|
method: 'GET',
|
|
@@ -28,7 +34,7 @@ module.exports = () => ({
|
|
|
28
34
|
|
|
29
35
|
handler: async (request, h) => {
|
|
30
36
|
const factory = request.server.app.pipelineFactory;
|
|
31
|
-
const { page, count, sha, prNum } = request.query;
|
|
37
|
+
const { page, count, sha, prNum, id } = request.query;
|
|
32
38
|
|
|
33
39
|
return factory
|
|
34
40
|
.get(request.params.id)
|
|
@@ -61,6 +67,11 @@ module.exports = () => ({
|
|
|
61
67
|
};
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
// Event id filter
|
|
71
|
+
if (id) {
|
|
72
|
+
config.params.id = id;
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
return pipeline.getEvents(config);
|
|
65
76
|
})
|
|
66
77
|
.then(events => h.response(events.map(e => e.toJson())))
|
|
@@ -80,6 +91,7 @@ module.exports = () => ({
|
|
|
80
91
|
type: typeSchema,
|
|
81
92
|
prNum: prNumSchema,
|
|
82
93
|
sha: shaSchema,
|
|
94
|
+
id: queryIdSchema,
|
|
83
95
|
search: joi.forbidden(), // we don't support search for Pipeline list events
|
|
84
96
|
getCount: joi.forbidden() // we don't support getCount for Pipeline list events
|
|
85
97
|
})
|