screwdriver-api 8.0.38 → 8.0.40
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
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const boom = require('@hapi/boom');
|
|
4
4
|
const hoek = require('@hapi/hoek');
|
|
5
5
|
const merge = require('lodash.mergewith');
|
|
6
|
+
const { PR_JOB_NAME, PR_STAGE_NAME, STAGE_TEARDOWN_PATTERN } = require('screwdriver-data-schema').config.regex;
|
|
6
7
|
const { getFullStageJobName } = require('../../helper');
|
|
7
|
-
const STAGE_TEARDOWN_PATTERN = /^stage@([\w-]+)(?::teardown)$/;
|
|
8
8
|
const TERMINAL_STATUSES = ['FAILURE', 'ABORTED', 'UNSTABLE', 'COLLAPSED'];
|
|
9
9
|
const FINISHED_STATUSES = ['FAILURE', 'SUCCESS', 'ABORTED', 'UNSTABLE', 'COLLAPSED'];
|
|
10
10
|
|
|
@@ -121,13 +121,18 @@ function updateBuildStatus(build, desiredStatus, statusMessage, statusMessageTyp
|
|
|
121
121
|
* @return {Stage} Stage for node
|
|
122
122
|
*/
|
|
123
123
|
async function getStage({ stageFactory, workflowGraph, jobName, pipelineId }) {
|
|
124
|
-
const
|
|
124
|
+
const prJobName = jobName.match(PR_JOB_NAME);
|
|
125
|
+
const nodeName = prJobName ? prJobName[2] : jobName;
|
|
126
|
+
|
|
127
|
+
const currentNode = workflowGraph.nodes.find(node => node.name === nodeName);
|
|
125
128
|
let stage = null;
|
|
126
129
|
|
|
127
130
|
if (currentNode && currentNode.stageName) {
|
|
131
|
+
const stageName = prJobName ? `${prJobName[1]}:${currentNode.stageName}` : currentNode.stageName;
|
|
132
|
+
|
|
128
133
|
stage = await stageFactory.get({
|
|
129
134
|
pipelineId,
|
|
130
|
-
name:
|
|
135
|
+
name: stageName
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
|
|
@@ -143,19 +148,24 @@ async function getStage({ stageFactory, workflowGraph, jobName, pipelineId }) {
|
|
|
143
148
|
* @return {Promise<Build[]>} Builds in stage
|
|
144
149
|
*/
|
|
145
150
|
async function getStageJobBuilds({ stage, event, jobFactory }) {
|
|
151
|
+
const prStageName = stage.name.match(PR_STAGE_NAME);
|
|
152
|
+
const stageName = prStageName ? prStageName[2] : stage.name;
|
|
153
|
+
|
|
146
154
|
// Get all jobIds for jobs in the stage
|
|
147
155
|
const stageNodes = event.workflowGraph.nodes.filter(n => {
|
|
148
156
|
const jobName = n.name.split(':')[1];
|
|
149
157
|
|
|
150
|
-
return n.stageName ===
|
|
158
|
+
return n.stageName === stageName && jobName !== 'teardown';
|
|
151
159
|
});
|
|
160
|
+
|
|
152
161
|
const stageJobIds = await Promise.all(
|
|
153
162
|
stageNodes.map(async n => {
|
|
154
163
|
if (n.id) {
|
|
155
164
|
return n.id;
|
|
156
165
|
}
|
|
157
166
|
|
|
158
|
-
const
|
|
167
|
+
const jobName = prStageName ? `${prStageName[1]}:${n.name}` : n.name;
|
|
168
|
+
const job = await jobFactory.get({ pipelineId: event.pipelineId, name: jobName });
|
|
159
169
|
|
|
160
170
|
return job.id;
|
|
161
171
|
})
|
|
@@ -333,6 +343,14 @@ async function updateBuildAndTriggerDownstreamJobs(config, build, server, userna
|
|
|
333
343
|
}
|
|
334
344
|
|
|
335
345
|
stageBuildHasFailure = TERMINAL_STATUSES.includes(stageBuild.status);
|
|
346
|
+
|
|
347
|
+
// Create a stage teardown build
|
|
348
|
+
if (!isStageTeardown) {
|
|
349
|
+
await createOrUpdateStageTeardownBuild(
|
|
350
|
+
{ pipeline, job, build, username, scmContext, event, stage },
|
|
351
|
+
server.app
|
|
352
|
+
);
|
|
353
|
+
}
|
|
336
354
|
}
|
|
337
355
|
|
|
338
356
|
// Guard against triggering non-successful or unstable builds
|
|
@@ -341,13 +359,6 @@ async function updateBuildAndTriggerDownstreamJobs(config, build, server, userna
|
|
|
341
359
|
// Check for failed jobs and remove any child jobs in created state
|
|
342
360
|
if (newBuild.status === 'FAILURE') {
|
|
343
361
|
await removeJoinBuilds({ pipeline, job, build: newBuild, event: newEvent, stage }, server.app);
|
|
344
|
-
|
|
345
|
-
if (stage && !isStageTeardown) {
|
|
346
|
-
await createOrUpdateStageTeardownBuild(
|
|
347
|
-
{ pipeline, job, build, username, scmContext, event, stage },
|
|
348
|
-
server.app
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
362
|
}
|
|
352
363
|
// Do not continue downstream is current job is stage teardown and statusBuild has failure
|
|
353
364
|
} else if (newBuild.status === 'SUCCESS' && isStageTeardown && stageBuildHasFailure) {
|
|
@@ -373,6 +384,7 @@ async function updateBuildAndTriggerDownstreamJobs(config, build, server, userna
|
|
|
373
384
|
stageTeardownBuild.status = 'QUEUED';
|
|
374
385
|
stageTeardownBuild.parentBuildId = stageJobBuilds.map(b => b.id);
|
|
375
386
|
|
|
387
|
+
// TODO: Handle if a teardown job is virtual
|
|
376
388
|
await stageTeardownBuild.update();
|
|
377
389
|
await stageTeardownBuild.start();
|
|
378
390
|
}
|
package/plugins/builds/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const logger = require('screwdriver-logger');
|
|
4
4
|
const workflowParser = require('screwdriver-workflow-parser');
|
|
5
|
+
const { STAGE_TEARDOWN_PATTERN } = require('screwdriver-data-schema').config.regex;
|
|
5
6
|
const hoek = require('@hapi/hoek');
|
|
6
7
|
const getRoute = require('./get');
|
|
7
8
|
const getBuildStatusesRoute = require('./getBuildStatuses');
|
|
@@ -39,7 +40,8 @@ const {
|
|
|
39
40
|
getParallelBuilds,
|
|
40
41
|
isStartFromMiddleOfCurrentStage,
|
|
41
42
|
Status,
|
|
42
|
-
getSameParentEvents
|
|
43
|
+
getSameParentEvents,
|
|
44
|
+
getNextJobStageName
|
|
43
45
|
} = require('./triggers/helpers');
|
|
44
46
|
const { getFullStageJobName } = require('../helper');
|
|
45
47
|
|
|
@@ -99,7 +101,7 @@ async function triggerNextJobs(config, app) {
|
|
|
99
101
|
const nextJob = await getJob(nextJobName, currentPipeline.id, jobFactory);
|
|
100
102
|
const node = currentEvent.workflowGraph.nodes.find(n => n.name === trimJobName(nextJobName));
|
|
101
103
|
const isNextJobVirtual = node.virtual || false;
|
|
102
|
-
const nextJobStageName = node.stageName
|
|
104
|
+
const nextJobStageName = getNextJobStageName({ stageName: node.stageName, nextJobName });
|
|
103
105
|
const resource = `pipeline:${currentPipeline.id}:groupEvent:${currentEvent.groupEventId}`;
|
|
104
106
|
let lock;
|
|
105
107
|
let nextBuild;
|
|
@@ -289,7 +291,7 @@ async function triggerNextJobs(config, app) {
|
|
|
289
291
|
const nextJob = await getJob(nextJobName, joinedPipelineId, jobFactory);
|
|
290
292
|
const node = externalEvent.workflowGraph.nodes.find(n => n.name === trimJobName(nextJobName));
|
|
291
293
|
const isNextJobVirtual = node.virtual || false;
|
|
292
|
-
const nextJobStageName = node.stageName
|
|
294
|
+
const nextJobStageName = getNextJobStageName({ stageName: node.stageName, nextJobName });
|
|
293
295
|
|
|
294
296
|
const { parentBuilds } = parseJobInfo({
|
|
295
297
|
joinObj: joinedPipeline.jobs,
|
|
@@ -469,29 +471,33 @@ const buildsPlugin = {
|
|
|
469
471
|
|
|
470
472
|
for (const nextJobName of Object.keys(pipelineJoinData[pid].jobs)) {
|
|
471
473
|
try {
|
|
472
|
-
const
|
|
474
|
+
const isNextJobStageTeardown = STAGE_TEARDOWN_PATTERN.test(nextJobName);
|
|
473
475
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
buildConfig.eventId = event.id;
|
|
477
|
-
} else {
|
|
478
|
-
buildConfig.eventId = hoek.reach(pipelineJoinData[pid], 'event.id');
|
|
479
|
-
}
|
|
476
|
+
if (!isNextJobStageTeardown) {
|
|
477
|
+
const nextJob = pipelineJoinData[pid].jobs[nextJobName];
|
|
480
478
|
|
|
481
|
-
|
|
482
|
-
if (
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
479
|
+
buildConfig.jobId = nextJob.id;
|
|
480
|
+
if (!isExternal) {
|
|
481
|
+
buildConfig.eventId = event.id;
|
|
482
|
+
} else {
|
|
483
|
+
buildConfig.eventId = hoek.reach(pipelineJoinData[pid], 'event.id');
|
|
484
|
+
}
|
|
487
485
|
|
|
488
|
-
|
|
489
|
-
if (
|
|
490
|
-
|
|
486
|
+
if (buildConfig.eventId) {
|
|
487
|
+
if (current.stage) {
|
|
488
|
+
const stageTeardownName = getFullStageJobName({
|
|
489
|
+
stageName: current.stage.name,
|
|
490
|
+
jobName: 'teardown'
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// Do not remove stage teardown builds as they need to be executed on stage failure as well.
|
|
494
|
+
if (nextJobName !== stageTeardownName) {
|
|
495
|
+
deletePromises.push(deleteBuild(buildConfig, buildFactory));
|
|
496
|
+
}
|
|
491
497
|
}
|
|
492
|
-
}
|
|
493
498
|
|
|
494
|
-
|
|
499
|
+
deletePromises.push(deleteBuild(buildConfig, buildFactory));
|
|
500
|
+
}
|
|
495
501
|
}
|
|
496
502
|
} catch (err) {
|
|
497
503
|
logger.error(
|
|
@@ -4,7 +4,7 @@ const logger = require('screwdriver-logger');
|
|
|
4
4
|
const workflowParser = require('screwdriver-workflow-parser');
|
|
5
5
|
const merge = require('lodash.mergewith');
|
|
6
6
|
const schema = require('screwdriver-data-schema');
|
|
7
|
-
const { EXTERNAL_TRIGGER_ALL, STAGE_SETUP_PATTERN } = schema.config.regex;
|
|
7
|
+
const { EXTERNAL_TRIGGER_ALL, STAGE_SETUP_PATTERN, PR_JOB_NAME } = schema.config.regex;
|
|
8
8
|
const { getFullStageJobName } = require('../../helper');
|
|
9
9
|
const BUILD_STATUS_MESSAGES = {
|
|
10
10
|
SKIP_VIRTUAL_JOB: {
|
|
@@ -373,27 +373,15 @@ async function createInternalBuild(config) {
|
|
|
373
373
|
return null;
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
-
/**
|
|
377
|
-
* Return PR job or not
|
|
378
|
-
* PR job name certainly has ":". e.g. "PR-1:jobName"
|
|
379
|
-
* @param {String} jobName
|
|
380
|
-
* @returns {Boolean}
|
|
381
|
-
*/
|
|
382
|
-
function isPR(jobName) {
|
|
383
|
-
return jobName.startsWith('PR-');
|
|
384
|
-
}
|
|
385
|
-
|
|
386
376
|
/**
|
|
387
377
|
* Trim Job name to follow data-schema
|
|
388
378
|
* @param {String} jobName
|
|
389
379
|
* @returns {String} trimmed jobName
|
|
390
380
|
*/
|
|
391
381
|
function trimJobName(jobName) {
|
|
392
|
-
|
|
393
|
-
return jobName.split(':')[1];
|
|
394
|
-
}
|
|
382
|
+
const matched = jobName.match(PR_JOB_NAME);
|
|
395
383
|
|
|
396
|
-
return jobName;
|
|
384
|
+
return matched ? matched[2] : jobName;
|
|
397
385
|
}
|
|
398
386
|
|
|
399
387
|
/**
|
|
@@ -1175,6 +1163,22 @@ function getStageName(workflowGraph, jobName) {
|
|
|
1175
1163
|
return jobNode ? jobNode.stageName : null;
|
|
1176
1164
|
}
|
|
1177
1165
|
|
|
1166
|
+
/**
|
|
1167
|
+
* get the stage name of a next job (foo or PR-123:foo)
|
|
1168
|
+
* @param {String} nextJobName Next jobob name
|
|
1169
|
+
* @param {String} stageName Stage name (Not have PR-xxx)
|
|
1170
|
+
* @return {String} Stage name
|
|
1171
|
+
*/
|
|
1172
|
+
function getNextJobStageName({ stageName, nextJobName }) {
|
|
1173
|
+
if (!stageName) {
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
const matched = nextJobName.match(PR_JOB_NAME);
|
|
1178
|
+
|
|
1179
|
+
return matched ? `${matched[1]}:${stageName}` : stageName;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1178
1182
|
/**
|
|
1179
1183
|
* Check if the current job is a stage setup and the next job is a non-setup job in the same stage
|
|
1180
1184
|
* @param {String} currentJobName Current job
|
|
@@ -1215,5 +1219,6 @@ module.exports = {
|
|
|
1215
1219
|
trimJobName,
|
|
1216
1220
|
isStartFromMiddleOfCurrentStage,
|
|
1217
1221
|
hasFreezeWindows,
|
|
1222
|
+
getNextJobStageName,
|
|
1218
1223
|
BUILD_STATUS_MESSAGES
|
|
1219
1224
|
};
|
package/plugins/helper.js
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const boom = require('@hapi/boom');
|
|
4
4
|
const dayjs = require('dayjs');
|
|
5
|
+
const schema = require('screwdriver-data-schema');
|
|
5
6
|
const STAGE_PREFIX = 'stage@';
|
|
6
7
|
const STAGE_TEARDOWN_PATTERN = /^stage@([\w-]+):teardown$/;
|
|
8
|
+
const { PR_STAGE_NAME } = schema.config.regex;
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Set default start time and end time
|
|
@@ -111,7 +113,11 @@ async function getScmUri({ pipeline, pipelineFactory }) {
|
|
|
111
113
|
* @return {String} Full stage name
|
|
112
114
|
*/
|
|
113
115
|
function getFullStageJobName({ stageName, jobName }) {
|
|
114
|
-
|
|
116
|
+
const prStage = stageName.match(PR_STAGE_NAME);
|
|
117
|
+
|
|
118
|
+
return prStage
|
|
119
|
+
? `${prStage[1]}:${STAGE_PREFIX}${prStage[2]}:${jobName}` // PR-123:stage@staging:deploy
|
|
120
|
+
: `${STAGE_PREFIX}${stageName}:${jobName}`; // stage@staging:deploy
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
/**
|