screwdriver-api 7.0.35 → 7.0.36

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "7.0.35",
3
+ "version": "7.0.36",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -288,4 +288,37 @@ Example payload:
288
288
  }]
289
289
  }
290
290
  }
291
- ```
291
+ ```
292
+
293
+ #### Get a pipeline template by namespace and name
294
+
295
+ `GET /pipeline/template/{namespace}/{name}`
296
+
297
+ ##### Get a specific pipeline template by id
298
+
299
+ `GET /pipeline/template/{id}`
300
+
301
+ ##### Get version of a pipeline template by name, namespace, version or tag
302
+
303
+ `GET /pipeline/template/{namespace}/{name}/{versionOrTag}`
304
+
305
+
306
+ #### Template Tag
307
+ Template tag allows fetching on template version by tag. For example, tag `mytemplate@1.1.0` as `stable`.
308
+
309
+ ##### Get all tags for a pipeline template by name, namespace
310
+
311
+ `GET /pipeline/templates/{namespace}/{name}/tags`
312
+
313
+ Can use additional options for sorting, pagination and count:
314
+ `GET /pipeline/templates/{namespace}/{name}/tags?sort=ascending&sortBy=name&page=1&count=50`
315
+
316
+ ##### Create/Update a tag
317
+
318
+ If the template tag already exists, it will update the tag with the new version. If the template tag doesn't exist yet, this endpoint will create the tag.
319
+
320
+ *Note: This endpoint is only accessible in `build` scope and the permission is tied to the pipeline that creates the template.*
321
+
322
+ `PUT /templates/{templateName}/tags/{tagName}` with the following payload
323
+
324
+ * `version` - Exact version of the template (ex: `1.1.0`)
@@ -29,10 +29,15 @@ const latestCommitEvent = require('./latestCommitEvent');
29
29
  const getAdmin = require('./admins/get');
30
30
  const deleteCache = require('./caches/delete');
31
31
  const openPrRoute = require('./openPr');
32
- const createTemplate = require('./templates/create');
33
- const validateTemplate = require('./templates/validate');
34
- const listTemplates = require('./templates/list');
35
- const listTemplateVersions = require('./templates/listVersions');
32
+ const createTemplateRoute = require('./templates/create');
33
+ const validateTemplateRoute = require('./templates/validate');
34
+ const listTemplatesRoute = require('./templates/list');
35
+ const listTemplateVersionsRoute = require('./templates/listVersions');
36
+ const listTagsRoute = require('./templates/listTags');
37
+ const getTemplateRoute = require('./templates/get');
38
+ const getTemplateByIdRoute = require('./templates/getTemplateById');
39
+ const createTagRoute = require('./templates/createTag');
40
+ const getVersionRoute = require('./templates/getVersion');
36
41
 
37
42
  /**
38
43
  * Pipeline API Plugin
@@ -200,10 +205,15 @@ const pipelinesPlugin = {
200
205
  getAdmin(),
201
206
  deleteCache(),
202
207
  openPrRoute(),
203
- createTemplate(),
204
- validateTemplate(),
205
- listTemplates(),
206
- listTemplateVersions()
208
+ createTemplateRoute(),
209
+ validateTemplateRoute(),
210
+ listTemplatesRoute(),
211
+ listTemplateVersionsRoute(),
212
+ listTagsRoute(),
213
+ getVersionRoute(),
214
+ getTemplateByIdRoute(),
215
+ getTemplateRoute(),
216
+ createTagRoute()
207
217
  ]);
208
218
  }
209
219
  };
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const baseSchema = schema.models.templateTag.base;
7
+ const metaSchema = schema.models.templateMeta.base;
8
+
9
+ module.exports = () => ({
10
+ method: 'PUT',
11
+ path: '/pipeline/template/{namespace}/{name}/tags/{tag}',
12
+ options: {
13
+ description: 'Add or update a pipeline template tag',
14
+ notes: 'Add or update a specific template',
15
+ tags: ['api', 'templates'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['build']
19
+ },
20
+ handler: async (request, h) => {
21
+ const { pipelineFactory, pipelineTemplateVersionFactory, pipelineTemplateTagFactory } = request.server.app;
22
+
23
+ const { isPR, pipelineId } = request.auth.credentials;
24
+
25
+ const { name, namespace, tag } = request.params;
26
+
27
+ const { version } = request.payload;
28
+
29
+ const [pipeline, template, templateTag] = await Promise.all([
30
+ pipelineFactory.get(pipelineId),
31
+ pipelineTemplateVersionFactory.get({ name, namespace, version }),
32
+ pipelineTemplateTagFactory.get({ name, namespace, tag })
33
+ ]);
34
+
35
+ // If template doesn't exist, throw error
36
+ if (!template) {
37
+ throw boom.notFound(`PipelineTemplate ${name}@${version} not found`);
38
+ }
39
+
40
+ // check if build has permission to publish
41
+ if (pipeline.id !== template.pipelineId || isPR) {
42
+ throw boom.forbidden('Not allowed to tag this pipeline template');
43
+ }
44
+
45
+ // If template tag exists, update the version
46
+ if (templateTag) {
47
+ templateTag.version = version;
48
+
49
+ const newTag = await templateTag.update();
50
+
51
+ return h.response(newTag.toJson()).code(200);
52
+ }
53
+
54
+ const newTag = await pipelineTemplateTagFactory.create({ namespace, name, tag, version });
55
+
56
+ const location = new URL(
57
+ `${request.path}/${newTag.id}`,
58
+ `${request.server.info.protocol}://${request.headers.host}`
59
+ ).toString();
60
+
61
+ return h.response(newTag.toJson()).header('Location', location).code(201);
62
+ },
63
+ validate: {
64
+ params: joi.object({
65
+ namespace: metaSchema.extract('namespace'),
66
+ name: metaSchema.extract('name'),
67
+ tag: baseSchema.extract('tag')
68
+ }),
69
+ payload: joi.object({
70
+ version: baseSchema.extract('version')
71
+ })
72
+ }
73
+ }
74
+ });
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const getSchema = schema.models.templateMeta.get;
7
+ const metaSchema = schema.models.templateMeta.base;
8
+
9
+ module.exports = () => ({
10
+ method: 'GET',
11
+ path: '/pipeline/template/{namespace}/{name}',
12
+ options: {
13
+ description: 'Get a specific template by namespace and name',
14
+ notes: 'Returns template meta for the specified namespace and name',
15
+ tags: ['api', 'pipeline', 'template'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['user', 'build']
19
+ },
20
+ handler: async (request, h) => {
21
+ console.log('request.params', request.params);
22
+
23
+ const { namespace, name } = request.params;
24
+ const { pipelineTemplateFactory } = request.server.app;
25
+
26
+ const pipelineTemplate = await pipelineTemplateFactory.get({
27
+ name,
28
+ namespace
29
+ });
30
+
31
+ if (!pipelineTemplate) {
32
+ throw boom.notFound('Pipeline Template does not exist');
33
+ }
34
+
35
+ return h.response(pipelineTemplate).code(200);
36
+ },
37
+ response: {
38
+ schema: getSchema
39
+ },
40
+ validate: {
41
+ params: joi.object({
42
+ namespace: metaSchema.extract('namespace'),
43
+ name: metaSchema.extract('name')
44
+ })
45
+ }
46
+ }
47
+ });
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const getSchema = schema.models.templateMeta.get;
7
+ const idSchema = schema.models.templateMeta.base.extract('id');
8
+
9
+ module.exports = () => ({
10
+ method: 'GET',
11
+ path: '/pipeline/template/{id}',
12
+ options: {
13
+ description: 'Get a single template',
14
+ notes: 'Returns a template record',
15
+ tags: ['api', 'templates'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['user', 'build']
19
+ },
20
+ handler: async (request, h) => {
21
+ const { pipelineTemplateFactory } = request.server.app;
22
+
23
+ const pipelineTemplate = await pipelineTemplateFactory.get({ id: request.params.id });
24
+
25
+ if (!pipelineTemplate) {
26
+ throw boom.notFound('Pipeline Template does not exist');
27
+ }
28
+
29
+ return h.response(pipelineTemplate).code(200);
30
+ },
31
+ response: {
32
+ schema: getSchema
33
+ },
34
+ validate: {
35
+ params: joi.object({
36
+ id: idSchema
37
+ })
38
+ }
39
+ }
40
+ });
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const metaSchema = schema.models.templateMeta.base;
7
+ const versionSchema = schema.models.pipelineTemplateVersions.base.extract('version');
8
+ const tagSchema = schema.models.templateTag.base.extract('tag');
9
+
10
+ module.exports = () => ({
11
+ method: 'GET',
12
+ path: '/pipeline/template/{namespace}/{name}/{versionOrTag}',
13
+ options: {
14
+ description: 'Get a specific template version details by version number or tag',
15
+ notes: 'Returns template meta and version for namespace, name and version/tag',
16
+ tags: ['api', 'pipeline', 'template'],
17
+ auth: {
18
+ strategies: ['token'],
19
+ scope: ['user', 'build']
20
+ },
21
+ handler: async (request, h) => {
22
+ const { namespace, name, versionOrTag } = request.params;
23
+ const { pipelineTemplateVersionFactory } = request.server.app;
24
+
25
+ const pipelineTemplate = await pipelineTemplateVersionFactory.getWithMetadata({
26
+ name,
27
+ namespace,
28
+ versionOrTag
29
+ });
30
+
31
+ if (!pipelineTemplate) {
32
+ throw boom.notFound('Pipeline Template does not exist');
33
+ }
34
+
35
+ return h.response(pipelineTemplate).code(200);
36
+ },
37
+ validate: {
38
+ params: joi.object({
39
+ namespace: metaSchema.extract('namespace'),
40
+ name: metaSchema.extract('name'),
41
+ versionOrTag: joi.alternatives().try(versionSchema, tagSchema)
42
+ })
43
+ }
44
+ }
45
+ });
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ const joi = require('joi');
4
+ const schema = require('screwdriver-data-schema');
5
+ const listSchema = joi.array().items(schema.models.templateTag.base).label('List of templates');
6
+ const metaSchema = schema.models.templateMeta.base;
7
+
8
+ module.exports = () => ({
9
+ method: 'GET',
10
+ path: '/pipeline/templates/{namespace}/{name}/tags',
11
+ options: {
12
+ description: 'Get all pipeline template tags for a given template name and namespace',
13
+ notes: 'Returns all pipeline template tags for a given template name and namespace',
14
+ tags: ['api', 'templates', 'tags'],
15
+ auth: {
16
+ strategies: ['token'],
17
+ scope: ['user', 'build']
18
+ },
19
+
20
+ handler: async (request, h) => {
21
+ const { pipelineTemplateTagFactory } = request.server.app;
22
+ const config = {
23
+ params: request.params,
24
+ sort: request.query.sort
25
+ };
26
+
27
+ if (request.query.page || request.query.count) {
28
+ config.paginate = {
29
+ page: request.query.page,
30
+ count: request.query.count
31
+ };
32
+ }
33
+
34
+ const tags = await pipelineTemplateTagFactory.list(config);
35
+
36
+ return h.response(tags);
37
+ },
38
+ response: {
39
+ schema: listSchema
40
+ },
41
+ validate: {
42
+ params: joi.object({
43
+ namespace: metaSchema.extract('namespace'),
44
+ name: metaSchema.extract('name')
45
+ }),
46
+ query: schema.api.pagination.concat(
47
+ joi.object({
48
+ search: joi.forbidden()
49
+ })
50
+ )
51
+ }
52
+ }
53
+ });