screwdriver-api 7.0.23 → 7.0.25

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/bin/server CHANGED
@@ -216,6 +216,10 @@ const stageFactory = Models.StageFactory.getInstance({
216
216
  datastore,
217
217
  datastoreRO
218
218
  });
219
+ const stageBuildFactory = Models.StageBuildFactory.getInstance({
220
+ datastore,
221
+ datastoreRO
222
+ });
219
223
  const triggerFactory = Models.TriggerFactory.getInstance({
220
224
  datastore,
221
225
  datastoreRO
@@ -253,6 +257,7 @@ datastore.setup(datastoreConfig.ddlSyncEnabled).then(() =>
253
257
  eventFactory,
254
258
  collectionFactory,
255
259
  stageFactory,
260
+ stageBuildFactory,
256
261
  triggerFactory,
257
262
  banners: authConfig,
258
263
  builds: {
@@ -315,6 +315,7 @@ bookends:
315
315
  - screwdriver-cache-bookend
316
316
  teardown:
317
317
  - screwdriver-artifact-bookend
318
+ - screwdriver-coverage-bookend
318
319
  - screwdriver-cache-bookend
319
320
 
320
321
  notifications:
package/lib/server.js CHANGED
@@ -75,6 +75,7 @@ function prettyPrintErrors(request, h) {
75
75
  * @param {Factory} config.eventFactory Event Factory instance
76
76
  * @param {Factory} config.collectionFactory Collection Factory instance
77
77
  * @param {Factory} config.stageFactory Stage Factory instance
78
+ * @param {Factory} config.stageBuildFactory Stage Build Factory instance
78
79
  * @param {Factory} config.triggerFactory Trigger Factory instance
79
80
  * @param {Object} config.builds Config to include for builds plugin
80
81
  * @param {Object} config.builds.ecosystem List of hosts in the ecosystem
@@ -126,6 +127,7 @@ module.exports = async config => {
126
127
  templateFactory: config.templateFactory,
127
128
  templateTagFactory: config.templateTagFactory,
128
129
  stageFactory: config.stageFactory,
130
+ stageBuildFactory: config.stageBuildFactory,
129
131
  triggerFactory: config.triggerFactory,
130
132
  pipelineFactory: config.pipelineFactory,
131
133
  jobFactory: config.jobFactory,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "7.0.23",
3
+ "version": "7.0.25",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -114,7 +114,7 @@
114
114
  "screwdriver-executor-queue": "^4.0.0",
115
115
  "screwdriver-executor-router": "^3.0.0",
116
116
  "screwdriver-logger": "^2.0.0",
117
- "screwdriver-models": "^29.7.0",
117
+ "screwdriver-models": "^29.11.0",
118
118
  "screwdriver-notifications-email": "^3.0.0",
119
119
  "screwdriver-notifications-slack": "^5.0.0",
120
120
  "screwdriver-request": "^2.0.1",
@@ -64,6 +64,8 @@ module.exports = config => ({
64
64
  throw boom.notFound(`Pipeline ${pipelineId} does not exist`);
65
65
  }
66
66
 
67
+ logger.info(`looking up pipeline from:${pipelineId}, and found pipeline:${pipeline}`);
68
+
67
69
  tokenConfig.pipelineName = pipeline.name;
68
70
  }
69
71
 
@@ -82,50 +84,57 @@ module.exports = config => ({
82
84
 
83
85
  const selfSonar = new CoveragePlugin(selfSonarConfig);
84
86
  const data = await selfSonar.coveragePlugin.getAccessToken(tokenConfig);
85
- const projectUrl = selfSonar.coveragePlugin.getProjectData(tokenConfig);
86
-
87
- if (pipeline && projectUrl) {
88
- try {
89
- const pipelineSonarBadge = {
90
- defaultName: pipelineId,
91
- defaultUri: projectUrl
92
- };
93
- let shouldPipelineUpdate = true;
94
-
95
- if (
96
- pipeline.badges &&
97
- pipeline.badges.sonar &&
98
- pipeline.badges.sonar.defaultName === pipelineId &&
99
- pipeline.badges.sonar.defaultUri === projectUrl
100
- ) {
101
- shouldPipelineUpdate = false;
102
- }
103
87
 
104
- if (shouldPipelineUpdate) {
105
- if (pipeline.badges) {
106
- pipeline.badges.sonar = pipelineSonarBadge;
107
- } else {
108
- pipeline.badges = {
109
- sonar: pipelineSonarBadge
110
- };
111
- }
112
-
113
- await pipeline.update();
114
- logger.info(
115
- `update pipeline:${pipeline.id}'s sonar badge with defaultName:${pipelineId}, defaultUri: ${projectUrl}`
116
- );
88
+ return h.response(data);
89
+ }
90
+
91
+ const data = await config.coveragePlugin.getAccessToken(tokenConfig);
92
+ const { projectUrl } = config.coveragePlugin.getProjectData(tokenConfig);
93
+
94
+ if (!pipeline && pipelineId) {
95
+ pipeline = await pipelineFactory.get(pipelineId);
96
+
97
+ logger.info(`looking up again, pipeline:${pipelineId}, and found pipeline: ${pipeline}`);
98
+ }
99
+
100
+ if (pipeline && projectUrl) {
101
+ try {
102
+ const pipelineSonarBadge = {
103
+ defaultName: `${pipelineId}`, // ensure pipelineId is stored as String instead of Integer
104
+ defaultUri: projectUrl
105
+ };
106
+ let shouldPipelineUpdate = true;
107
+
108
+ if (
109
+ pipeline.badges &&
110
+ pipeline.badges.sonar &&
111
+ pipeline.badges.sonar.defaultName === pipelineId &&
112
+ pipeline.badges.sonar.defaultUri === projectUrl
113
+ ) {
114
+ shouldPipelineUpdate = false;
115
+ }
116
+
117
+ if (shouldPipelineUpdate) {
118
+ if (pipeline.badges) {
119
+ pipeline.badges.sonar = pipelineSonarBadge;
120
+ } else {
121
+ pipeline.badges = {
122
+ sonar: pipelineSonarBadge
123
+ };
117
124
  }
118
- } catch (err) {
119
- logger.error(`Failed to update pipeline:${pipelineId}`, err);
120
125
 
121
- throw err;
126
+ await pipeline.update();
122
127
  }
123
- }
124
128
 
125
- return h.response(data);
126
- }
129
+ logger.info(
130
+ `update pipeline:${pipeline.id}'s sonar badge with pipeline.badges, ${pipeline.badges}`
131
+ );
132
+ } catch (err) {
133
+ logger.error(`Failed to update pipeline:${pipelineId}`, err);
127
134
 
128
- const data = await config.coveragePlugin.getAccessToken(tokenConfig);
135
+ throw err;
136
+ }
137
+ }
129
138
 
130
139
  return h.response(data);
131
140
  }
@@ -4,6 +4,7 @@ const boom = require('@hapi/boom');
4
4
  const createRoute = require('./create');
5
5
  const getRoute = require('./get');
6
6
  const listBuildsRoute = require('./listBuilds');
7
+ const listStageBuildsRoute = require('./listStageBuilds');
7
8
  const stopBuildsRoute = require('./stopBuilds');
8
9
  const metricsRoute = require('./metrics');
9
10
 
@@ -51,7 +52,14 @@ const eventsPlugin = {
51
52
  return Promise.resolve();
52
53
  });
53
54
 
54
- server.route([createRoute(), getRoute(), listBuildsRoute(), stopBuildsRoute(), metricsRoute()]);
55
+ server.route([
56
+ createRoute(),
57
+ getRoute(),
58
+ listBuildsRoute(),
59
+ listStageBuildsRoute(),
60
+ stopBuildsRoute(),
61
+ metricsRoute()
62
+ ]);
55
63
  }
56
64
  };
57
65
 
@@ -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 stageBuildListSchema = joi.array().items(schema.models.stageBuild.get).label('List of stage builds');
7
+ const eventIdSchema = schema.models.event.base.extract('id');
8
+
9
+ module.exports = () => ({
10
+ method: 'GET',
11
+ path: '/events/{id}/stageBuilds',
12
+ options: {
13
+ description: 'Get stage builds for a given event',
14
+ notes: 'Returns stage builds for a given event',
15
+ tags: ['api', 'events', 'stageBuilds'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['user', 'pipeline']
19
+ },
20
+
21
+ handler: async (request, h) => {
22
+ const { eventFactory } = request.server.app;
23
+ const event = await eventFactory.get(request.params.id);
24
+
25
+ if (!event) {
26
+ throw boom.notFound('Event does not exist');
27
+ }
28
+
29
+ return event
30
+ .getStageBuilds()
31
+ .then(stageBuilds => h.response(stageBuilds.map(c => c.toJson())))
32
+ .catch(err => {
33
+ throw err;
34
+ });
35
+ },
36
+ response: {
37
+ schema: stageBuildListSchema
38
+ },
39
+ validate: {
40
+ params: joi.object({
41
+ id: eventIdSchema
42
+ })
43
+ }
44
+ }
45
+ });
@@ -121,9 +121,6 @@ Only PR events of specified PR number will be searched when `prNum` is set
121
121
  #### Get all stages for a single pipeline
122
122
 
123
123
  `GET /pipelines/{id}/stages`
124
- Will get latest commit event's stages if no event ID or group event ID is provided
125
-
126
- `GET /pipelines/{id}/stages?groupEventId={groupEventId}`
127
124
 
128
125
  `GET /pipelines/{id}/stages?eventId={eventId}`
129
126
 
@@ -49,8 +49,6 @@ module.exports = () => ({
49
49
  throw boom.notFound(`Latest event does not exist for pipeline ${pipelineId}`);
50
50
  }
51
51
 
52
- config.params.eventId = latestCommitEvents[0].id;
53
-
54
52
  return stageFactory.list(config);
55
53
  })
56
54
  .then(stages => h.response(stages.map(s => s.toJson())))
@@ -0,0 +1,32 @@
1
+ # Stages Plugin
2
+ > API stages plugin for the Screwdriver API
3
+
4
+ ## Usage
5
+
6
+ ### Register plugin
7
+
8
+ ```javascript
9
+ const Hapi = require('@hapi/hapi');
10
+ const server = new Hapi.Server();
11
+ const stagesPlugin = require('./');
12
+
13
+ server.connection({ port: 3000 });
14
+
15
+ server.register({
16
+ register: stagesPlugin,
17
+ options: {}
18
+ }, () => {
19
+ server.start((err) => {
20
+ if (err) {
21
+ throw err;
22
+ }
23
+ console.log('Server running at:', server.info.uri);
24
+ });
25
+ });
26
+ ```
27
+
28
+ ### Routes
29
+
30
+ #### Get a listing of all stage builds for a stage
31
+
32
+ `GET /stages/{id}/stageBuilds`
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ const getStageBuildsRoute = require('./stageBuilds/list');
4
+
5
+ /**
6
+ * Stage API Plugin
7
+ * @method register
8
+ * @param {Hapi} server Hapi Server
9
+ * @param {Object} options Configuration
10
+ * @param {Function} next Function to call when done
11
+ */
12
+ const stagesPlugin = {
13
+ name: 'stages',
14
+ async register(server) {
15
+ server.route([getStageBuildsRoute()]);
16
+ }
17
+ };
18
+
19
+ module.exports = stagesPlugin;
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const listSchema = joi.array().items(schema.models.stageBuild.get).label('List of stage builds for a stage');
7
+ const idSchema = schema.models.stage.base.extract('id');
8
+ const eventIdSchema = schema.models.stageBuild.base.extract('eventId');
9
+
10
+ module.exports = () => ({
11
+ method: 'GET',
12
+ path: '/stages/{id}/stageBuilds',
13
+ options: {
14
+ description: 'Get stage builds for a stage',
15
+ notes: 'Returns all stage builds for a stage',
16
+ tags: ['api', 'stageBuilds'],
17
+ auth: {
18
+ strategies: ['token'],
19
+ scope: ['user', '!guest']
20
+ },
21
+
22
+ handler: async (request, h) => {
23
+ const { stageFactory, stageBuildFactory } = request.server.app;
24
+ const { page, count } = request.query;
25
+ const config = {
26
+ sort: request.query.sort,
27
+ params: {
28
+ stageId: request.params.id
29
+ }
30
+ };
31
+
32
+ return stageFactory.get(config.params.stageId).then(async stage => {
33
+ if (!stage) {
34
+ throw boom.notFound(`Stage ${config.params.stageId} does not exist`);
35
+ }
36
+
37
+ if (page || count) {
38
+ config.paginate = { page, count };
39
+ }
40
+
41
+ // Set eventId if provided
42
+ if (request.query.eventId) {
43
+ config.params.eventId = request.query.eventId;
44
+ }
45
+
46
+ return stageBuildFactory
47
+ .list(config)
48
+ .then(stageBuilds => h.response(stageBuilds.map(c => c.toJson())))
49
+ .catch(err => {
50
+ throw err;
51
+ });
52
+ });
53
+ },
54
+ response: {
55
+ schema: listSchema
56
+ },
57
+ validate: {
58
+ params: joi.object({
59
+ id: idSchema
60
+ }),
61
+ query: schema.api.pagination.concat(
62
+ joi.object({
63
+ eventId: eventIdSchema
64
+ })
65
+ )
66
+ }
67
+ }
68
+ });