screwdriver-api 8.0.9 → 8.0.11
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 +2 -2
- package/plugins/builds/helper/updateBuild.js +16 -5
- package/plugins/builds/index.js +27 -10
- package/plugins/builds/triggers/and.js +0 -1
- package/plugins/builds/triggers/helpers.js +78 -90
- package/plugins/builds/triggers/joinBase.js +7 -15
- package/plugins/builds/triggers/orBase.js +11 -5
- package/plugins/builds/triggers/remoteJoin.js +1 -9
- package/plugins/jobs/buildCluster/update.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-api",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.11",
|
|
4
4
|
"description": "API server for the Screwdriver.cd service",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"screwdriver-config-parser": "^12.0.0",
|
|
112
112
|
"screwdriver-coverage-bookend": "^3.0.0",
|
|
113
113
|
"screwdriver-coverage-sonar": "^5.0.0",
|
|
114
|
-
"screwdriver-data-schema": "^25.1.
|
|
114
|
+
"screwdriver-data-schema": "^25.1.3",
|
|
115
115
|
"screwdriver-datastore-sequelize": "^10.0.0",
|
|
116
116
|
"screwdriver-executor-base": "^11.0.0",
|
|
117
117
|
"screwdriver-executor-docker": "^8.0.1",
|
|
@@ -135,18 +135,26 @@ async function getStage({ stageFactory, workflowGraph, jobName, pipelineId }) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
138
|
+
* Get all builds in stage
|
|
139
139
|
*
|
|
140
140
|
* @param {Stage} stage Stage
|
|
141
141
|
* @param {Event} event Event
|
|
142
|
-
* @return {
|
|
142
|
+
* @return {Promise<Build[]>} Builds in stage
|
|
143
143
|
*/
|
|
144
|
-
async function
|
|
144
|
+
async function getStageJobBuilds({ stage, event }) {
|
|
145
145
|
// Get all jobIds for jobs in the stage
|
|
146
146
|
const stageJobIds = [...stage.jobIds, stage.setup];
|
|
147
147
|
|
|
148
148
|
// Get all builds in a stage for this event
|
|
149
|
-
|
|
149
|
+
return event.getBuilds({ params: { jobId: stageJobIds } });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Checks if all builds in stage are done running
|
|
154
|
+
* @param {Build[]} stageJobBuilds Builds in stage
|
|
155
|
+
* @returns {Boolean} Flag if stage is done
|
|
156
|
+
*/
|
|
157
|
+
function isStageDone(stageJobBuilds) {
|
|
150
158
|
let stageIsDone = false;
|
|
151
159
|
|
|
152
160
|
if (stageJobBuilds && stageJobBuilds.length !== 0) {
|
|
@@ -292,10 +300,13 @@ async function updateBuildAndTriggerDownstreamJobs(config, build, server, userna
|
|
|
292
300
|
|
|
293
301
|
// Start stage teardown build if stage is done
|
|
294
302
|
if (stageTeardownBuild && stageTeardownBuild.status === 'CREATED') {
|
|
295
|
-
const
|
|
303
|
+
const stageJobBuilds = await getStageJobBuilds({ stage, event: newEvent });
|
|
304
|
+
const stageIsDone = isStageDone(stageJobBuilds);
|
|
296
305
|
|
|
297
306
|
if (stageIsDone) {
|
|
298
307
|
stageTeardownBuild.status = 'QUEUED';
|
|
308
|
+
stageTeardownBuild.parentBuildId = stageJobBuilds.map(b => b.id);
|
|
309
|
+
|
|
299
310
|
await stageTeardownBuild.update();
|
|
300
311
|
await stageTeardownBuild.start();
|
|
301
312
|
}
|
package/plugins/builds/index.js
CHANGED
|
@@ -39,8 +39,7 @@ const {
|
|
|
39
39
|
getParallelBuilds,
|
|
40
40
|
isStartFromMiddleOfCurrentStage,
|
|
41
41
|
Status,
|
|
42
|
-
getSameParentEvents
|
|
43
|
-
isVirtualJob
|
|
42
|
+
getSameParentEvents
|
|
44
43
|
} = require('./triggers/helpers');
|
|
45
44
|
const { getFullStageJobName } = require('../helper');
|
|
46
45
|
|
|
@@ -96,9 +95,11 @@ async function triggerNextJobs(config, app) {
|
|
|
96
95
|
|
|
97
96
|
const downstreamOfNextJobsToBeProcessed = [];
|
|
98
97
|
|
|
99
|
-
for (const [nextJobName
|
|
98
|
+
for (const [nextJobName] of Object.entries(currentPipelineNextJobs)) {
|
|
100
99
|
const nextJob = await getJob(nextJobName, currentPipeline.id, jobFactory);
|
|
101
|
-
const
|
|
100
|
+
const node = currentEvent.workflowGraph.nodes.find(n => n.name === trimJobName(nextJobName));
|
|
101
|
+
const isNextJobVirtual = node.virtual || false;
|
|
102
|
+
const nextJobStageName = node.stageName || null;
|
|
102
103
|
const resource = `pipeline:${currentPipeline.id}:groupEvent:${currentEvent.groupEventId}`;
|
|
103
104
|
let lock;
|
|
104
105
|
let nextBuild;
|
|
@@ -124,12 +125,24 @@ async function triggerNextJobs(config, app) {
|
|
|
124
125
|
isOrTrigger(currentEvent.workflowGraph, originalCurrentJobName, trimJobName(nextJobName)) ||
|
|
125
126
|
isStartFromMiddleOfCurrentStage(currentJob.name, currentEvent.startFrom, currentEvent.workflowGraph)
|
|
126
127
|
) {
|
|
127
|
-
nextBuild = await orTrigger.execute(
|
|
128
|
+
nextBuild = await orTrigger.execute(
|
|
129
|
+
currentEvent,
|
|
130
|
+
currentPipeline.id,
|
|
131
|
+
nextJob,
|
|
132
|
+
parentBuilds,
|
|
133
|
+
isNextJobVirtual
|
|
134
|
+
);
|
|
128
135
|
} else {
|
|
129
|
-
nextBuild = await andTrigger.execute(
|
|
136
|
+
nextBuild = await andTrigger.execute(
|
|
137
|
+
nextJob,
|
|
138
|
+
parentBuilds,
|
|
139
|
+
joinListNames,
|
|
140
|
+
isNextJobVirtual,
|
|
141
|
+
nextJobStageName
|
|
142
|
+
);
|
|
130
143
|
}
|
|
131
144
|
|
|
132
|
-
if (
|
|
145
|
+
if (isNextJobVirtual && nextBuild && nextBuild.status === Status.SUCCESS) {
|
|
133
146
|
downstreamOfNextJobsToBeProcessed.push({
|
|
134
147
|
build: nextBuild,
|
|
135
148
|
event: currentEvent,
|
|
@@ -274,7 +287,9 @@ async function triggerNextJobs(config, app) {
|
|
|
274
287
|
if (externalEvent) {
|
|
275
288
|
for (const [nextJobName, nextJobInfo] of Object.entries(joinedPipeline.jobs)) {
|
|
276
289
|
const nextJob = await getJob(nextJobName, joinedPipelineId, jobFactory);
|
|
277
|
-
const
|
|
290
|
+
const node = externalEvent.workflowGraph.nodes.find(n => n.name === trimJobName(nextJobName));
|
|
291
|
+
const isNextJobVirtual = node.virtual || false;
|
|
292
|
+
const nextJobStageName = node.stageName || null;
|
|
278
293
|
|
|
279
294
|
const { parentBuilds } = parseJobInfo({
|
|
280
295
|
joinObj: joinedPipeline.jobs,
|
|
@@ -295,7 +310,8 @@ async function triggerNextJobs(config, app) {
|
|
|
295
310
|
externalEvent,
|
|
296
311
|
externalEvent.pipelineId,
|
|
297
312
|
nextJob,
|
|
298
|
-
parentBuilds
|
|
313
|
+
parentBuilds,
|
|
314
|
+
isNextJobVirtual
|
|
299
315
|
);
|
|
300
316
|
} else {
|
|
301
317
|
// Re get join list when first time remote trigger since external event was empty and cannot get workflow graph then
|
|
@@ -311,11 +327,12 @@ async function triggerNextJobs(config, app) {
|
|
|
311
327
|
parentBuilds,
|
|
312
328
|
groupEventBuilds,
|
|
313
329
|
joinListNames,
|
|
330
|
+
isNextJobVirtual,
|
|
314
331
|
nextJobStageName
|
|
315
332
|
);
|
|
316
333
|
}
|
|
317
334
|
|
|
318
|
-
if (
|
|
335
|
+
if (isNextJobVirtual && nextBuild && nextBuild.status === Status.SUCCESS) {
|
|
319
336
|
downstreamOfNextJobsToBeProcessed.push({
|
|
320
337
|
build: nextBuild,
|
|
321
338
|
event: currentEvent,
|
|
@@ -128,17 +128,6 @@ function isExternalTrigger(jobName) {
|
|
|
128
128
|
return EXTERNAL_TRIGGER_ALL.test(jobName);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
/**
|
|
132
|
-
* Checks if job is virtual
|
|
133
|
-
* @param {Job} job Job object
|
|
134
|
-
* @returns {Boolean}
|
|
135
|
-
*/
|
|
136
|
-
function isVirtualJob(job) {
|
|
137
|
-
const { annotations } = job.permutations[0];
|
|
138
|
-
|
|
139
|
-
return annotations ? annotations['screwdriver.cd/virtualJob'] === true : false;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
131
|
/**
|
|
143
132
|
* Checks if job has freezeWindows
|
|
144
133
|
* @param {Job} job Job object
|
|
@@ -545,10 +534,9 @@ async function getBuildsForGroupEvent(groupEventId, buildFactory) {
|
|
|
545
534
|
* @param {Object} arg
|
|
546
535
|
* @param {ParentBuilds} arg.joinParentBuilds Parent builds object for join job
|
|
547
536
|
* @param {Build} arg.nextBuild Next build
|
|
548
|
-
* @param {Build} arg.build Build for current completed job
|
|
549
537
|
* @returns {Promise<Build>} Updated next build
|
|
550
538
|
*/
|
|
551
|
-
async function updateParentBuilds({ joinParentBuilds, nextBuild
|
|
539
|
+
async function updateParentBuilds({ joinParentBuilds, nextBuild }) {
|
|
552
540
|
// Override old parentBuilds info
|
|
553
541
|
const newParentBuilds = merge({}, joinParentBuilds, nextBuild.parentBuilds, (objVal, srcVal) =>
|
|
554
542
|
// passthrough objects, else mergeWith mutates source
|
|
@@ -556,59 +544,69 @@ async function updateParentBuilds({ joinParentBuilds, nextBuild, build }) {
|
|
|
556
544
|
);
|
|
557
545
|
|
|
558
546
|
nextBuild.parentBuilds = newParentBuilds;
|
|
559
|
-
// nextBuild.parentBuildId may be int or Array, so it needs to be flattened
|
|
560
|
-
nextBuild.parentBuildId = Array.from(new Set([build.id, nextBuild.parentBuildId || []].flat()));
|
|
561
547
|
|
|
562
548
|
return nextBuild.update();
|
|
563
549
|
}
|
|
564
550
|
|
|
565
551
|
/**
|
|
566
|
-
*
|
|
567
|
-
* @param {
|
|
568
|
-
* @param {Build} arg.newBuild Updated build
|
|
552
|
+
* Get builds in join list from parent builds
|
|
553
|
+
* @param {newBuild} arg.newBuild Updated build
|
|
569
554
|
* @param {String[]} arg.joinListNames Join list names
|
|
570
555
|
* @param {Number} arg.pipelineId Pipeline ID
|
|
571
556
|
* @param {BuildFactory} arg.buildFactory Build factory
|
|
572
|
-
* @returns {Promise<
|
|
557
|
+
* @returns {Promise<Map<String, Build>>} Join builds
|
|
573
558
|
*/
|
|
574
|
-
async function
|
|
559
|
+
async function getJoinBuilds({ newBuild, joinListNames, pipelineId, buildFactory }) {
|
|
575
560
|
const upstream = newBuild.parentBuilds || {};
|
|
561
|
+
const joinBuilds = {};
|
|
576
562
|
|
|
577
|
-
|
|
578
|
-
const joinBuildIds = joinListNames.map(name => {
|
|
563
|
+
for (const jobName of joinListNames) {
|
|
579
564
|
let upstreamPipelineId = pipelineId;
|
|
580
|
-
let upstreamJobName =
|
|
565
|
+
let upstreamJobName = jobName;
|
|
581
566
|
|
|
582
|
-
if (isExternalTrigger(
|
|
583
|
-
const { externalPipelineId, externalJobName } = getExternalPipelineAndJob(
|
|
567
|
+
if (isExternalTrigger(upstreamJobName)) {
|
|
568
|
+
const { externalPipelineId, externalJobName } = getExternalPipelineAndJob(jobName);
|
|
584
569
|
|
|
585
570
|
upstreamPipelineId = externalPipelineId;
|
|
586
571
|
upstreamJobName = externalJobName;
|
|
587
572
|
}
|
|
588
573
|
|
|
589
574
|
if (upstream[upstreamPipelineId] && upstream[upstreamPipelineId].jobs[upstreamJobName]) {
|
|
590
|
-
|
|
575
|
+
const buildId = upstream[upstreamPipelineId].jobs[upstreamJobName];
|
|
576
|
+
|
|
577
|
+
const build = await buildFactory.get(buildId);
|
|
578
|
+
|
|
579
|
+
if (typeof build.endTime === 'string') {
|
|
580
|
+
build.endTime = new Date(build.endTime);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
joinBuilds[jobName] = build;
|
|
591
584
|
}
|
|
585
|
+
}
|
|
592
586
|
|
|
593
|
-
|
|
594
|
-
|
|
587
|
+
return joinBuilds;
|
|
588
|
+
}
|
|
595
589
|
|
|
590
|
+
/**
|
|
591
|
+
* Check if all parent builds of the new build are done
|
|
592
|
+
* @param {Object} arg
|
|
593
|
+
* @param {String[]} arg.joinListNames Join list names
|
|
594
|
+
* @param {String[]} arg.joinBuilds Join builds
|
|
595
|
+
* @returns {Promise<{hasFailure: Boolean, done: Boolean}>} Object with done and hasFailure statuses
|
|
596
|
+
*/
|
|
597
|
+
async function getParentBuildStatus({ joinListNames, joinBuilds }) {
|
|
596
598
|
// If buildId is empty, the job hasn't executed yet and the join is not done
|
|
597
|
-
const isExecuted =
|
|
599
|
+
const isExecuted = joinListNames.every(name => joinBuilds[name] !== undefined);
|
|
600
|
+
const parentBuilds = Object.values(joinBuilds);
|
|
598
601
|
|
|
599
|
-
|
|
600
|
-
const buildIds = joinBuildIds.filter(buildId => buildId !== undefined);
|
|
601
|
-
const promisesToAwait = buildIds.map(buildId => buildFactory.get(buildId));
|
|
602
|
-
const joinedBuilds = await Promise.all(promisesToAwait);
|
|
603
|
-
|
|
604
|
-
const hasFailure = joinedBuilds
|
|
602
|
+
const hasFailure = parentBuilds
|
|
605
603
|
.map(build => {
|
|
606
604
|
// Do not need to run the next build; terminal status
|
|
607
605
|
return [Status.FAILURE, Status.ABORTED, Status.COLLAPSED, Status.UNSTABLE].includes(build.status);
|
|
608
606
|
})
|
|
609
607
|
.includes(true);
|
|
610
608
|
|
|
611
|
-
const isDoneStatus =
|
|
609
|
+
const isDoneStatus = parentBuilds.every(build => {
|
|
612
610
|
// All builds are done
|
|
613
611
|
return [Status.FAILURE, Status.SUCCESS, Status.ABORTED, Status.UNSTABLE, Status.COLLAPSED].includes(
|
|
614
612
|
build.status
|
|
@@ -627,29 +625,40 @@ async function getParentBuildStatus({ newBuild, joinListNames, pipelineId, build
|
|
|
627
625
|
* if no failure, start new build
|
|
628
626
|
* Otherwise, do nothing
|
|
629
627
|
* @param {Object} arg If the build is done or not
|
|
630
|
-
* @param {
|
|
631
|
-
* @param {Boolean} arg.hasFailure If the build has a failure or not
|
|
628
|
+
* @param {String[]} arg.joinListNames Join list names
|
|
632
629
|
* @param {Build} arg.newBuild Next build
|
|
633
630
|
* @param {Job} arg.job Next job
|
|
634
631
|
* @param {String|undefined} arg.pipelineId Pipeline ID
|
|
635
632
|
* @param {String|undefined} arg.stageName Stage name
|
|
633
|
+
* @param {Boolean} arg.isVirtualJob If the job is virtual or not
|
|
636
634
|
* @param {Event} arg.event Event
|
|
637
|
-
* @param {
|
|
635
|
+
* @param {BuildFactory} arg.buildFactory Build factory
|
|
638
636
|
* @returns {Promise<Build|null>} The newly updated/created build
|
|
639
637
|
*/
|
|
640
|
-
async function handleNewBuild({
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
638
|
+
async function handleNewBuild({
|
|
639
|
+
joinListNames,
|
|
640
|
+
newBuild,
|
|
641
|
+
job,
|
|
642
|
+
pipelineId,
|
|
643
|
+
stageName,
|
|
644
|
+
isVirtualJob,
|
|
645
|
+
event,
|
|
646
|
+
buildFactory
|
|
647
|
+
}) {
|
|
648
|
+
const joinBuilds = await getJoinBuilds({
|
|
649
|
+
newBuild,
|
|
650
|
+
joinListNames,
|
|
651
|
+
pipelineId,
|
|
652
|
+
buildFactory
|
|
653
|
+
});
|
|
649
654
|
|
|
650
|
-
|
|
651
|
-
|
|
655
|
+
/* CHECK IF ALL PARENT BUILDS OF NEW BUILD ARE DONE */
|
|
656
|
+
const { hasFailure, done } = await getParentBuildStatus({
|
|
657
|
+
joinBuilds,
|
|
658
|
+
joinListNames
|
|
659
|
+
});
|
|
652
660
|
|
|
661
|
+
if (!done || Status.isStarted(newBuild.status)) {
|
|
653
662
|
return null;
|
|
654
663
|
}
|
|
655
664
|
|
|
@@ -668,14 +677,28 @@ async function handleNewBuild({ done, hasFailure, newBuild, job, pipelineId, sta
|
|
|
668
677
|
return null;
|
|
669
678
|
}
|
|
670
679
|
|
|
680
|
+
/* Prepare to execute the build */
|
|
681
|
+
const parentBuilds = Object.values(joinBuilds);
|
|
682
|
+
|
|
683
|
+
parentBuilds.sort((l, r) => {
|
|
684
|
+
if (l.endTime && r.endTime) {
|
|
685
|
+
return l.endTime.getTime() - r.endTime.getTime();
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Move to tail if endTime is not set
|
|
689
|
+
return (l.endTime ? 0 : 1) - (r.endTime ? 0 : 1);
|
|
690
|
+
});
|
|
691
|
+
newBuild.parentBuildId = parentBuilds.map(build => build.id);
|
|
692
|
+
|
|
671
693
|
// Bypass execution of the build if the job is virtual
|
|
672
|
-
if (isVirtualJob
|
|
694
|
+
if (isVirtualJob && !hasFreezeWindows(job)) {
|
|
673
695
|
newBuild.status = Status.SUCCESS;
|
|
674
696
|
newBuild.statusMessage = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessage;
|
|
675
697
|
newBuild.statusMessageType = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessageType;
|
|
698
|
+
|
|
676
699
|
// The virtual job does not inherit metadata because the Launcher is not executed.
|
|
677
700
|
// Therefore, it is necessary to take over the metadata from the previous build.
|
|
678
|
-
newBuild.meta = merge(
|
|
701
|
+
newBuild.meta = parentBuilds.reduce((acc, build) => merge(acc, build.meta), {});
|
|
679
702
|
|
|
680
703
|
return newBuild.update();
|
|
681
704
|
}
|
|
@@ -934,9 +957,7 @@ async function createJoinObject(nextJobNames, current, eventFactory) {
|
|
|
934
957
|
isExternal = true;
|
|
935
958
|
}
|
|
936
959
|
|
|
937
|
-
const
|
|
938
|
-
const jId = node.id;
|
|
939
|
-
const stageName = node.stageName || null;
|
|
960
|
+
const jId = event.workflowGraph.nodes.find(n => n.name === trimJobName(jobName)).id;
|
|
940
961
|
|
|
941
962
|
if (!joinObj[nextJobPipelineId]) joinObj[nextJobPipelineId] = {};
|
|
942
963
|
const pipelineObj = joinObj[nextJobPipelineId];
|
|
@@ -956,7 +977,7 @@ async function createJoinObject(nextJobNames, current, eventFactory) {
|
|
|
956
977
|
}
|
|
957
978
|
|
|
958
979
|
if (!pipelineObj.jobs) pipelineObj.jobs = {};
|
|
959
|
-
pipelineObj.jobs[nextJobName] = { id: jId, join: jobs, isExternal
|
|
980
|
+
pipelineObj.jobs[nextJobName] = { id: jId, join: jobs, isExternal };
|
|
960
981
|
}
|
|
961
982
|
|
|
962
983
|
return joinObj;
|
|
@@ -1017,38 +1038,6 @@ async function ensureStageTeardownBuildExists({
|
|
|
1017
1038
|
}
|
|
1018
1039
|
}
|
|
1019
1040
|
|
|
1020
|
-
/**
|
|
1021
|
-
* Get parentBuildId from parentBuilds object
|
|
1022
|
-
* @param {Object} arg
|
|
1023
|
-
* @param {ParentBuilds} arg.parentBuilds Builds that triggered this build
|
|
1024
|
-
* @param {String[]} arg.joinListNames Array of join job name
|
|
1025
|
-
* @param {Number} arg.pipelineId Pipeline ID
|
|
1026
|
-
* @returns {String[]} Array of parentBuildId
|
|
1027
|
-
*/
|
|
1028
|
-
function getParentBuildIds({ currentBuildId, parentBuilds, joinListNames, pipelineId }) {
|
|
1029
|
-
const parentBuildIds = joinListNames
|
|
1030
|
-
.map(name => {
|
|
1031
|
-
let parentBuildPipelineId = pipelineId;
|
|
1032
|
-
let parentBuildJobName = name;
|
|
1033
|
-
|
|
1034
|
-
if (isExternalTrigger(name)) {
|
|
1035
|
-
const { externalPipelineId, externalJobName } = getExternalPipelineAndJob(name);
|
|
1036
|
-
|
|
1037
|
-
parentBuildPipelineId = externalPipelineId;
|
|
1038
|
-
parentBuildJobName = externalJobName;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
if (parentBuilds[parentBuildPipelineId] && parentBuilds[parentBuildPipelineId].jobs[parentBuildJobName]) {
|
|
1042
|
-
return parentBuilds[parentBuildPipelineId].jobs[parentBuildJobName];
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
return null;
|
|
1046
|
-
})
|
|
1047
|
-
.filter(Boolean); // Remove undefined or null values
|
|
1048
|
-
|
|
1049
|
-
return Array.from(new Set([currentBuildId, ...parentBuildIds]));
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
1041
|
/**
|
|
1053
1042
|
* Extract a current pipeline's next jobs from pipeline join data
|
|
1054
1043
|
* (Next jobs triggered as external are not included)
|
|
@@ -1208,13 +1197,13 @@ module.exports = {
|
|
|
1208
1197
|
getSameParentEvents,
|
|
1209
1198
|
mergeParentBuilds,
|
|
1210
1199
|
updateParentBuilds,
|
|
1200
|
+
getJoinBuilds,
|
|
1211
1201
|
getParentBuildStatus,
|
|
1212
1202
|
handleNewBuild,
|
|
1213
1203
|
ensureStageTeardownBuildExists,
|
|
1214
1204
|
getBuildsForGroupEvent,
|
|
1215
1205
|
createJoinObject,
|
|
1216
1206
|
createExternalEvent,
|
|
1217
|
-
getParentBuildIds,
|
|
1218
1207
|
strToInt,
|
|
1219
1208
|
createEvent,
|
|
1220
1209
|
deleteBuild,
|
|
@@ -1225,7 +1214,6 @@ module.exports = {
|
|
|
1225
1214
|
buildsToRestartFilter,
|
|
1226
1215
|
trimJobName,
|
|
1227
1216
|
isStartFromMiddleOfCurrentStage,
|
|
1228
|
-
isVirtualJob,
|
|
1229
1217
|
hasFreezeWindows,
|
|
1230
1218
|
BUILD_STATUS_MESSAGES
|
|
1231
1219
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const logger = require('screwdriver-logger');
|
|
4
|
-
const { createInternalBuild, updateParentBuilds,
|
|
4
|
+
const { createInternalBuild, updateParentBuilds, handleNewBuild } = require('./helpers');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {import('screwdriver-models').EventFactory} EventFactory
|
|
@@ -41,8 +41,8 @@ class JoinBase {
|
|
|
41
41
|
* @param {Build} nextBuild
|
|
42
42
|
* @param {Job} nextJob
|
|
43
43
|
* @param {import('./helpers').ParentBuilds} parentBuilds
|
|
44
|
-
* @param {String} parentBuildId
|
|
45
44
|
* @param {String[]} joinListNames
|
|
45
|
+
* @param {Boolean} isNextJobVirtual
|
|
46
46
|
* @param {String} nextJobStageName
|
|
47
47
|
* @returns {Promise<Build[]|null>}
|
|
48
48
|
*/
|
|
@@ -52,8 +52,8 @@ class JoinBase {
|
|
|
52
52
|
nextBuild,
|
|
53
53
|
nextJob,
|
|
54
54
|
parentBuilds,
|
|
55
|
-
parentBuildId,
|
|
56
55
|
joinListNames,
|
|
56
|
+
isNextJobVirtual,
|
|
57
57
|
nextJobStageName
|
|
58
58
|
}) {
|
|
59
59
|
let newBuild;
|
|
@@ -71,7 +71,7 @@ class JoinBase {
|
|
|
71
71
|
event, // this is the parentBuild for the next build
|
|
72
72
|
baseBranch: event.baseBranch || null,
|
|
73
73
|
parentBuilds,
|
|
74
|
-
parentBuildId,
|
|
74
|
+
parentBuildId: this.currentBuild.id,
|
|
75
75
|
start: false
|
|
76
76
|
});
|
|
77
77
|
} else {
|
|
@@ -88,23 +88,15 @@ class JoinBase {
|
|
|
88
88
|
return null;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
/* CHECK IF ALL PARENT BUILDS OF NEW BUILD ARE DONE */
|
|
92
|
-
const { hasFailure, done } = await getParentBuildStatus({
|
|
93
|
-
newBuild,
|
|
94
|
-
joinListNames,
|
|
95
|
-
pipelineId,
|
|
96
|
-
buildFactory: this.buildFactory
|
|
97
|
-
});
|
|
98
|
-
|
|
99
91
|
return handleNewBuild({
|
|
100
|
-
|
|
101
|
-
hasFailure,
|
|
92
|
+
joinListNames,
|
|
102
93
|
newBuild,
|
|
103
94
|
job: nextJob,
|
|
104
95
|
pipelineId,
|
|
96
|
+
isVirtualJob: isNextJobVirtual,
|
|
105
97
|
stageName: nextJobStageName,
|
|
106
98
|
event,
|
|
107
|
-
|
|
99
|
+
buildFactory: this.buildFactory
|
|
108
100
|
});
|
|
109
101
|
}
|
|
110
102
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const merge = require('lodash.mergewith');
|
|
4
|
-
const { createInternalBuild, Status, BUILD_STATUS_MESSAGES,
|
|
4
|
+
const { createInternalBuild, Status, BUILD_STATUS_MESSAGES, hasFreezeWindows } = require('./helpers');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {import('screwdriver-models').BuildFactory} BuildFactory
|
|
@@ -39,15 +39,15 @@ class OrBase {
|
|
|
39
39
|
* @param {Number} pipelineId
|
|
40
40
|
* @param {Job} nextJob
|
|
41
41
|
* @param {import('./helpers').ParentBuilds} parentBuilds
|
|
42
|
+
* @param {Boolean} isNextJobVirtual
|
|
42
43
|
* @return {Promise<Build|null>}
|
|
43
44
|
*/
|
|
44
|
-
async trigger(event, pipelineId, nextJob, parentBuilds) {
|
|
45
|
+
async trigger(event, pipelineId, nextJob, parentBuilds, isNextJobVirtual) {
|
|
45
46
|
let nextBuild = await this.buildFactory.get({
|
|
46
47
|
eventId: event.id,
|
|
47
48
|
jobId: nextJob.id
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
const isNextJobVirtual = isVirtualJob(nextJob);
|
|
51
51
|
const hasWindows = hasFreezeWindows(nextJob);
|
|
52
52
|
const causeMessage = nextJob.name === event.startFrom ? event.causeMessage : '';
|
|
53
53
|
|
|
@@ -56,12 +56,16 @@ class OrBase {
|
|
|
56
56
|
return nextBuild;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
nextBuild.parentBuildId = [this.currentBuild.id];
|
|
60
|
+
|
|
59
61
|
// Bypass execution of the build if the job is virtual
|
|
60
62
|
if (isNextJobVirtual && !hasWindows) {
|
|
61
63
|
nextBuild.status = Status.SUCCESS;
|
|
62
64
|
nextBuild.statusMessage = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessage;
|
|
63
65
|
nextBuild.statusMessageType = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessageType;
|
|
64
|
-
|
|
66
|
+
|
|
67
|
+
// Overwrite metadata by current build's
|
|
68
|
+
nextBuild.meta = merge({}, this.currentBuild.meta);
|
|
65
69
|
|
|
66
70
|
return nextBuild.update();
|
|
67
71
|
}
|
|
@@ -93,7 +97,9 @@ class OrBase {
|
|
|
93
97
|
nextBuild.status = Status.SUCCESS;
|
|
94
98
|
nextBuild.statusMessage = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessage;
|
|
95
99
|
nextBuild.statusMessageType = BUILD_STATUS_MESSAGES.SKIP_VIRTUAL_JOB.statusMessageType;
|
|
96
|
-
|
|
100
|
+
|
|
101
|
+
// Overwrite metadata by current build's
|
|
102
|
+
nextBuild.meta = merge({}, this.currentBuild.meta);
|
|
97
103
|
|
|
98
104
|
await nextBuild.update();
|
|
99
105
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { mergeParentBuilds
|
|
3
|
+
const { mergeParentBuilds } = require('./helpers');
|
|
4
4
|
const { JoinBase } = require('./joinBase');
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -45,20 +45,12 @@ class RemoteJoin extends JoinBase {
|
|
|
45
45
|
|
|
46
46
|
const newParentBuilds = mergeParentBuilds(parentBuilds, groupEventBuilds, this.currentEvent, externalEvent);
|
|
47
47
|
|
|
48
|
-
const parentBuildId = getParentBuildIds({
|
|
49
|
-
currentBuildId: this.currentBuild.id,
|
|
50
|
-
parentBuilds: newParentBuilds,
|
|
51
|
-
joinListNames,
|
|
52
|
-
pipelineId: externalEvent.pipelineId
|
|
53
|
-
});
|
|
54
|
-
|
|
55
48
|
return this.processNextBuild({
|
|
56
49
|
pipelineId: externalEvent.pipelineId,
|
|
57
50
|
event: externalEvent,
|
|
58
51
|
nextBuild,
|
|
59
52
|
nextJob,
|
|
60
53
|
parentBuilds: newParentBuilds,
|
|
61
|
-
parentBuildId,
|
|
62
54
|
joinListNames,
|
|
63
55
|
isNextJobVirtual,
|
|
64
56
|
nextJobStageName
|