screwdriver-api 4.1.182 → 4.1.186
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 +7 -0
- package/config/custom-environment-variables.yaml +5 -0
- package/config/default.yaml +4 -0
- package/lib/server.js +2 -1
- package/package.json +1 -1
- package/plugins/builds/index.js +6 -9
- package/plugins/events/README.md +3 -0
- package/plugins/events/listBuilds.js +26 -3
- package/plugins/jobs/README.md +2 -0
- package/plugins/jobs/listBuilds.js +25 -4
- package/plugins/webhooks/index.js +20 -2
package/bin/server
CHANGED
|
@@ -50,6 +50,9 @@ const notificationConfig = config.get('notifications');
|
|
|
50
50
|
// Multiple build cluster feature flag
|
|
51
51
|
const multiBuildClusterEnabled = convertToBool(config.get('multiBuildCluster').enabled);
|
|
52
52
|
|
|
53
|
+
// Queue Webhook feature flag
|
|
54
|
+
const queueWebhookEnabled = convertToBool(config.get('queueWebhook').enabled);
|
|
55
|
+
|
|
53
56
|
// Default cluster environment variable
|
|
54
57
|
const clusterEnvConfig = config.get('build').environment; // readonly
|
|
55
58
|
const clusterEnv = { ...clusterEnvConfig };
|
|
@@ -254,6 +257,10 @@ datastore.setup(datastoreConfig.ddlSyncEnabled).then(() =>
|
|
|
254
257
|
validator: {
|
|
255
258
|
externalJoin: true,
|
|
256
259
|
notificationsValidationErr
|
|
260
|
+
},
|
|
261
|
+
queueWebhook: {
|
|
262
|
+
executor,
|
|
263
|
+
queueWebhookEnabled
|
|
257
264
|
}
|
|
258
265
|
})
|
|
259
266
|
.then(instance => logger.info('Server running at %s', instance.info.uri))
|
package/config/default.yaml
CHANGED
package/lib/server.js
CHANGED
|
@@ -136,7 +136,8 @@ module.exports = async config => {
|
|
|
136
136
|
collectionFactory: config.collectionFactory,
|
|
137
137
|
buildClusterFactory: config.buildClusterFactory,
|
|
138
138
|
ecosystem: config.ecosystem,
|
|
139
|
-
release: config.release
|
|
139
|
+
release: config.release,
|
|
140
|
+
queueWebhook: config.queueWebhook
|
|
140
141
|
};
|
|
141
142
|
|
|
142
143
|
const bellConfigs = await config.auth.scm.getBellConfiguration();
|
package/package.json
CHANGED
package/plugins/builds/index.js
CHANGED
|
@@ -410,11 +410,6 @@ function parseJobInfo({ joinObj = {}, current, nextJobName, nextPipelineId }) {
|
|
|
410
410
|
* @return {Promise} All finished builds
|
|
411
411
|
*/
|
|
412
412
|
async function getFinishedBuilds(event, buildFactory) {
|
|
413
|
-
if (!event.parentEventId) {
|
|
414
|
-
// FIXME: remove this flow to always use buildFactory.getLatestBuilds
|
|
415
|
-
return event.getBuilds();
|
|
416
|
-
}
|
|
417
|
-
|
|
418
413
|
// FIXME: buildFactory.getLatestBuilds doesn't return build model
|
|
419
414
|
const builds = await buildFactory.getLatestBuilds({ groupEventId: event.groupEventId });
|
|
420
415
|
|
|
@@ -529,11 +524,13 @@ async function handleNewBuild({ done, hasFailure, newBuild, jobName, pipelineId
|
|
|
529
524
|
return null;
|
|
530
525
|
}
|
|
531
526
|
|
|
532
|
-
// If all join builds finished successfully, start new build
|
|
533
|
-
newBuild.status
|
|
534
|
-
|
|
527
|
+
// If all join builds finished successfully and it's clear that a new build has not been started before, start new build
|
|
528
|
+
if ([ 'CREATED', null, undefined ].includes(newBuild.status)) {
|
|
529
|
+
newBuild.status = 'QUEUED';
|
|
530
|
+
const queuedBuild = await newBuild.update();
|
|
535
531
|
|
|
536
|
-
|
|
532
|
+
return queuedBuild.start();
|
|
533
|
+
}
|
|
537
534
|
}
|
|
538
535
|
|
|
539
536
|
return null;
|
package/plugins/events/README.md
CHANGED
|
@@ -24,14 +24,23 @@ module.exports = () => ({
|
|
|
24
24
|
handler: async (request, h) => {
|
|
25
25
|
const { eventFactory } = request.server.app;
|
|
26
26
|
const event = await eventFactory.get(request.params.id);
|
|
27
|
+
const { fetchSteps, readOnly } = request.query;
|
|
27
28
|
|
|
28
29
|
if (!event) {
|
|
29
30
|
throw boom.notFound('Event does not exist');
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const
|
|
33
|
+
const config = readOnly ? { readOnly: true } : {};
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
+
const buildsModel = await event.getBuilds(config);
|
|
36
|
+
|
|
37
|
+
let data;
|
|
38
|
+
|
|
39
|
+
if (fetchSteps) {
|
|
40
|
+
data = await Promise.all(buildsModel.map(async buildModel => buildModel.toJsonWithSteps()));
|
|
41
|
+
} else {
|
|
42
|
+
data = await Promise.all(buildsModel.map(async buildModel => buildModel.toJson()));
|
|
43
|
+
}
|
|
35
44
|
|
|
36
45
|
return h.response(data);
|
|
37
46
|
},
|
|
@@ -41,7 +50,21 @@ module.exports = () => ({
|
|
|
41
50
|
validate: {
|
|
42
51
|
params: joi.object({
|
|
43
52
|
id: eventIdSchema
|
|
44
|
-
})
|
|
53
|
+
}),
|
|
54
|
+
query: schema.api.pagination.concat(
|
|
55
|
+
joi.object({
|
|
56
|
+
readOnly: joi
|
|
57
|
+
.boolean()
|
|
58
|
+
.truthy('true')
|
|
59
|
+
.falsy('false')
|
|
60
|
+
.default(false),
|
|
61
|
+
fetchSteps: joi
|
|
62
|
+
.boolean()
|
|
63
|
+
.truthy('true')
|
|
64
|
+
.falsy('false')
|
|
65
|
+
.default(true)
|
|
66
|
+
})
|
|
67
|
+
)
|
|
45
68
|
}
|
|
46
69
|
}
|
|
47
70
|
});
|
package/plugins/jobs/README.md
CHANGED
|
@@ -46,6 +46,8 @@ Example payload:
|
|
|
46
46
|
#### Get list of builds for a single job
|
|
47
47
|
`GET /jobs/{id}/builds`
|
|
48
48
|
|
|
49
|
+
`GET /jobs/{id}/builds?fetchSteps=false&readOnly=true`
|
|
50
|
+
|
|
49
51
|
`GET /jobs/{id}/builds?page=2&count=30&sort=ascending`
|
|
50
52
|
|
|
51
53
|
`GET /jobs/{id}/builds?page=2&count=30&sort=ascending&sortBy=id`
|
|
@@ -23,7 +23,7 @@ module.exports = () => ({
|
|
|
23
23
|
|
|
24
24
|
handler: async (request, h) => {
|
|
25
25
|
const factory = request.server.app.jobFactory;
|
|
26
|
-
const { sort, sortBy, page, count } = request.query;
|
|
26
|
+
const { sort, sortBy, page, count, fetchSteps, readOnly } = request.query;
|
|
27
27
|
|
|
28
28
|
return factory
|
|
29
29
|
.get(request.params.id)
|
|
@@ -32,7 +32,9 @@ module.exports = () => ({
|
|
|
32
32
|
throw boom.notFound('Job does not exist');
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const config =
|
|
35
|
+
const config = readOnly
|
|
36
|
+
? { sort, sortBy: 'createTime', readOnly: true }
|
|
37
|
+
: { sort, sortBy: 'createTime' };
|
|
36
38
|
|
|
37
39
|
if (sortBy) {
|
|
38
40
|
config.sortBy = sortBy;
|
|
@@ -45,7 +47,13 @@ module.exports = () => ({
|
|
|
45
47
|
return job.getBuilds(config);
|
|
46
48
|
})
|
|
47
49
|
.then(async builds => {
|
|
48
|
-
|
|
50
|
+
let data;
|
|
51
|
+
|
|
52
|
+
if (fetchSteps) {
|
|
53
|
+
data = await Promise.all(builds.map(b => b.toJsonWithSteps()));
|
|
54
|
+
} else {
|
|
55
|
+
data = await Promise.all(builds.map(b => b.toJson()));
|
|
56
|
+
}
|
|
49
57
|
|
|
50
58
|
return h.response(data);
|
|
51
59
|
})
|
|
@@ -60,7 +68,20 @@ module.exports = () => ({
|
|
|
60
68
|
params: joi.object({
|
|
61
69
|
id: jobIdSchema
|
|
62
70
|
}),
|
|
63
|
-
query: schema.api.pagination
|
|
71
|
+
query: schema.api.pagination.concat(
|
|
72
|
+
joi.object({
|
|
73
|
+
readOnly: joi
|
|
74
|
+
.boolean()
|
|
75
|
+
.truthy('true')
|
|
76
|
+
.falsy('false')
|
|
77
|
+
.default(false),
|
|
78
|
+
fetchSteps: joi
|
|
79
|
+
.boolean()
|
|
80
|
+
.truthy('true')
|
|
81
|
+
.falsy('false')
|
|
82
|
+
.default(true)
|
|
83
|
+
})
|
|
84
|
+
)
|
|
64
85
|
}
|
|
65
86
|
}
|
|
66
87
|
});
|
|
@@ -62,9 +62,11 @@ const webhooksPlugin = {
|
|
|
62
62
|
maxBytes: parseInt(pluginOptions.maxBytes, 10) || DEFAULT_MAX_BYTES
|
|
63
63
|
},
|
|
64
64
|
handler: async (request, h) => {
|
|
65
|
-
const { pipelineFactory } = request.server.app;
|
|
65
|
+
const { pipelineFactory, queueWebhook } = request.server.app;
|
|
66
66
|
const { scm } = pipelineFactory;
|
|
67
|
+
const { executor, queueWebhookEnabled } = queueWebhook;
|
|
67
68
|
let message = 'Unable to process this kind of event';
|
|
69
|
+
let hookId;
|
|
68
70
|
|
|
69
71
|
try {
|
|
70
72
|
const parsed = await scm.parseHook(request.headers, request.payload);
|
|
@@ -76,10 +78,26 @@ const webhooksPlugin = {
|
|
|
76
78
|
|
|
77
79
|
parsed.pluginOptions = pluginOptions;
|
|
78
80
|
|
|
79
|
-
const { type
|
|
81
|
+
const { type } = parsed;
|
|
82
|
+
hookId = parsed.hookId;
|
|
80
83
|
|
|
81
84
|
request.log(['webhook', hookId], `Received event type ${type}`);
|
|
82
85
|
|
|
86
|
+
if (queueWebhookEnabled) {
|
|
87
|
+
parsed.token = request.server.plugins.auth.generateToken({
|
|
88
|
+
scope: ['sdapi']
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
return await executor.enqueueWebhook(parsed);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
// if enqueueWebhook is not implemented, an event starts without enqueuing
|
|
95
|
+
if (err.message != 'Not implemented') {
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
83
101
|
return await startHookEvent(request, h, parsed);
|
|
84
102
|
|
|
85
103
|
} catch (err) {
|