screwdriver-api 8.0.20 → 8.0.21
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 +4 -4
- package/plugins/webhooks/helper.js +186 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-api",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.21",
|
|
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.
|
|
114
|
+
"screwdriver-data-schema": "^25.4.0",
|
|
115
115
|
"screwdriver-datastore-sequelize": "^10.0.0",
|
|
116
116
|
"screwdriver-executor-base": "^11.0.0",
|
|
117
117
|
"screwdriver-executor-docker": "^8.0.1",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"screwdriver-executor-queue": "^6.0.0",
|
|
121
121
|
"screwdriver-executor-router": "^5.0.0",
|
|
122
122
|
"screwdriver-logger": "^3.0.0",
|
|
123
|
-
"screwdriver-models": "^32.
|
|
123
|
+
"screwdriver-models": "^32.3.0",
|
|
124
124
|
"screwdriver-notifications-email": "^5.0.0",
|
|
125
125
|
"screwdriver-notifications-slack": "^7.0.0",
|
|
126
126
|
"screwdriver-request": "^3.0.0",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"screwdriver-scm-gitlab": "^5.0.1",
|
|
131
131
|
"screwdriver-scm-router": "^9.0.0",
|
|
132
132
|
"screwdriver-template-validator": "^10.0.0",
|
|
133
|
-
"screwdriver-workflow-parser": "^6.
|
|
133
|
+
"screwdriver-workflow-parser": "^6.1.0",
|
|
134
134
|
"sqlite3": "^5.1.4",
|
|
135
135
|
"stream": "0.0.3",
|
|
136
136
|
"tinytim": "^0.1.1",
|
|
@@ -309,6 +309,52 @@ const uriTrimmer = uri => {
|
|
|
309
309
|
return uriToArray.join(':');
|
|
310
310
|
};
|
|
311
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Create metadata by the parsed event
|
|
314
|
+
* @param {Object} parsed It has information to create metadata
|
|
315
|
+
* @returns {Object} Metadata
|
|
316
|
+
*/
|
|
317
|
+
function createMeta(parsed) {
|
|
318
|
+
const { action, ref, releaseId, releaseName, releaseAuthor, prMerged, prNum, prRef } = parsed;
|
|
319
|
+
|
|
320
|
+
if (action === 'release') {
|
|
321
|
+
return {
|
|
322
|
+
sd: {
|
|
323
|
+
release: {
|
|
324
|
+
id: releaseId,
|
|
325
|
+
name: releaseName,
|
|
326
|
+
author: releaseAuthor
|
|
327
|
+
},
|
|
328
|
+
tag: {
|
|
329
|
+
name: ref
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (action === 'tag') {
|
|
335
|
+
return {
|
|
336
|
+
sd: {
|
|
337
|
+
tag: {
|
|
338
|
+
name: ref
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
if (action.toLowerCase() === 'closed') {
|
|
344
|
+
return {
|
|
345
|
+
sd: {
|
|
346
|
+
pr: {
|
|
347
|
+
name: prRef,
|
|
348
|
+
merged: prMerged,
|
|
349
|
+
number: prNum
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return {};
|
|
356
|
+
}
|
|
357
|
+
|
|
312
358
|
/**
|
|
313
359
|
* Get all pipelines which has triggered job
|
|
314
360
|
* @method triggeredPipelines
|
|
@@ -697,6 +743,101 @@ async function pullRequestOpened(options, request, h) {
|
|
|
697
743
|
});
|
|
698
744
|
}
|
|
699
745
|
|
|
746
|
+
/**
|
|
747
|
+
* Create events for each pipeline
|
|
748
|
+
* @async createPREvents
|
|
749
|
+
* @param {Object} options
|
|
750
|
+
* @param {String} options.username User who created the PR
|
|
751
|
+
* @param {String} options.scmConfig Has the token and scmUri to get branches
|
|
752
|
+
* @param {String} options.sha Specific SHA1 commit to start the build with
|
|
753
|
+
* @param {String} options.prNum Pull request number
|
|
754
|
+
* @param {Array} options.changedFiles List of changed files
|
|
755
|
+
* @param {String} options.branch The branch against which pr is opened
|
|
756
|
+
* @param {String} options.action Event action
|
|
757
|
+
* @param {String} options.prSource The origin of this PR
|
|
758
|
+
* @param {String} options.restrictPR Restrict PR setting
|
|
759
|
+
* @param {Boolean} options.chainPR Chain PR flag
|
|
760
|
+
* @param {Boolean} options.ref Chain PR flag
|
|
761
|
+
* @param {Hapi.request} request Request from user
|
|
762
|
+
* @return {Promise}
|
|
763
|
+
*/
|
|
764
|
+
async function createPrClosedEvent(options, request) {
|
|
765
|
+
const { username, scmConfig, prNum, pipelines, changedFiles, branch, action, ref, prSource, restrictPR, chainPR } =
|
|
766
|
+
options;
|
|
767
|
+
|
|
768
|
+
const { scm } = request.server.app.pipelineFactory;
|
|
769
|
+
const { pipelineFactory } = request.server.app;
|
|
770
|
+
const scmDisplayName = scm.getDisplayName({ scmContext: scmConfig.scmContext });
|
|
771
|
+
const userDisplayName = `${scmDisplayName}:${username}`;
|
|
772
|
+
const { sha } = options;
|
|
773
|
+
|
|
774
|
+
scmConfig.prNum = prNum;
|
|
775
|
+
|
|
776
|
+
const eventConfigs = await Promise.all(
|
|
777
|
+
pipelines.map(async p => {
|
|
778
|
+
try {
|
|
779
|
+
const b = await p.branch;
|
|
780
|
+
let eventConfig = {};
|
|
781
|
+
|
|
782
|
+
let configPipelineSha = '';
|
|
783
|
+
|
|
784
|
+
try {
|
|
785
|
+
configPipelineSha = await pipelineFactory.scm.getCommitSha(scmConfig);
|
|
786
|
+
} catch (err) {
|
|
787
|
+
if (err.status >= 500) {
|
|
788
|
+
throw err;
|
|
789
|
+
} else {
|
|
790
|
+
logger.info(`skip create event for branch: ${p.branch}`);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const { skipMessage, resolvedChainPR } = getSkipMessageAndChainPR({
|
|
795
|
+
pipeline: !p.annotations ? { annotations: {}, ...p } : p,
|
|
796
|
+
prSource,
|
|
797
|
+
restrictPR,
|
|
798
|
+
chainPR
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
const startFrom = `~pr-closed`;
|
|
802
|
+
const causeMessage = `PR-${prNum} ${action.toLowerCase()} by ${userDisplayName}`;
|
|
803
|
+
const isPipelineBranch = b === branch;
|
|
804
|
+
|
|
805
|
+
eventConfig = {
|
|
806
|
+
pipelineId: p.id,
|
|
807
|
+
type: 'pipeline',
|
|
808
|
+
webhooks: true,
|
|
809
|
+
username,
|
|
810
|
+
scmContext: scmConfig.scmContext,
|
|
811
|
+
sha,
|
|
812
|
+
startFrom: isPipelineBranch ? startFrom : `${startFrom}:${branch}`,
|
|
813
|
+
changedFiles,
|
|
814
|
+
causeMessage: isPipelineBranch ? causeMessage : `${causeMessage} on branch ${branch}`,
|
|
815
|
+
ref,
|
|
816
|
+
baseBranch: branch,
|
|
817
|
+
meta: createMeta(options),
|
|
818
|
+
configPipelineSha,
|
|
819
|
+
prNum,
|
|
820
|
+
chainPR: resolvedChainPR
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
if (skipMessage) {
|
|
824
|
+
eventConfig.skipMessage = skipMessage;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
return eventConfig;
|
|
828
|
+
} catch (err) {
|
|
829
|
+
logger.warn(`pipeline:${p.id} error in starting event`, err);
|
|
830
|
+
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
})
|
|
834
|
+
);
|
|
835
|
+
|
|
836
|
+
const events = await startEvents(eventConfigs, request.server);
|
|
837
|
+
|
|
838
|
+
return events;
|
|
839
|
+
}
|
|
840
|
+
|
|
700
841
|
/**
|
|
701
842
|
* Stop any running builds and disable the job for closed pull-request
|
|
702
843
|
* @async pullRequestClosed
|
|
@@ -722,23 +863,51 @@ async function pullRequestClosed(options, request, h) {
|
|
|
722
863
|
})
|
|
723
864
|
.then(() => request.log(['webhook', hookId, job.id], `${job.name} disabled and archived`));
|
|
724
865
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
866
|
+
try {
|
|
867
|
+
await Promise.all(
|
|
868
|
+
pipelines.map(p =>
|
|
869
|
+
p.getJobs({ type: 'pr' }).then(jobs => {
|
|
870
|
+
const prJobs = jobs.filter(j => j.name.includes(name));
|
|
871
|
+
|
|
872
|
+
return Promise.all(prJobs.map(j => updatePRJobs(j)));
|
|
873
|
+
})
|
|
874
|
+
)
|
|
875
|
+
);
|
|
729
876
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
)
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
877
|
+
const prClosedJobs = [];
|
|
878
|
+
|
|
879
|
+
for (const p of pipelines) {
|
|
880
|
+
const jobs = await p.getJobs({ type: 'pipeline' });
|
|
881
|
+
const filteredJobs = jobs.filter(
|
|
882
|
+
j =>
|
|
883
|
+
j.permutations &&
|
|
884
|
+
j.permutations.length > 0 &&
|
|
885
|
+
j.permutations[0] &&
|
|
886
|
+
j.permutations[0].requires &&
|
|
887
|
+
j.permutations[0].requires.includes('~pr-closed')
|
|
738
888
|
);
|
|
739
889
|
|
|
740
|
-
|
|
890
|
+
prClosedJobs.push(...filteredJobs);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
if (prClosedJobs.length === 0) {
|
|
894
|
+
return h.response().code(200);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
const events = await createPrClosedEvent(options, request);
|
|
898
|
+
|
|
899
|
+
events.forEach(e => {
|
|
900
|
+
request.log(['webhook', hookId, e.id], `Event ${e.id} started`);
|
|
741
901
|
});
|
|
902
|
+
|
|
903
|
+
return h.response().code(201);
|
|
904
|
+
} catch (err) {
|
|
905
|
+
logger.error(
|
|
906
|
+
`Failed to pullRequestClosed: [${hookId}, pipeline:${options.pipeline && options.pipeline.id}]: ${err}`
|
|
907
|
+
);
|
|
908
|
+
|
|
909
|
+
throw err;
|
|
910
|
+
}
|
|
742
911
|
}
|
|
743
912
|
|
|
744
913
|
/**
|
|
@@ -818,41 +987,6 @@ async function obtainScmToken({ pluginOptions, userFactory, username, scmContext
|
|
|
818
987
|
return user.unsealToken();
|
|
819
988
|
}
|
|
820
989
|
|
|
821
|
-
/**
|
|
822
|
-
* Create metadata by the parsed event
|
|
823
|
-
* @param {Object} parsed It has information to create metadata
|
|
824
|
-
* @returns {Object} Metadata
|
|
825
|
-
*/
|
|
826
|
-
function createMeta(parsed) {
|
|
827
|
-
const { action, ref, releaseId, releaseName, releaseAuthor } = parsed;
|
|
828
|
-
|
|
829
|
-
if (action === 'release') {
|
|
830
|
-
return {
|
|
831
|
-
sd: {
|
|
832
|
-
release: {
|
|
833
|
-
id: releaseId,
|
|
834
|
-
name: releaseName,
|
|
835
|
-
author: releaseAuthor
|
|
836
|
-
},
|
|
837
|
-
tag: {
|
|
838
|
-
name: ref
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
if (action === 'tag') {
|
|
844
|
-
return {
|
|
845
|
-
sd: {
|
|
846
|
-
tag: {
|
|
847
|
-
name: ref
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
};
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
return {};
|
|
854
|
-
}
|
|
855
|
-
|
|
856
990
|
/**
|
|
857
991
|
* Act on a Pull Request change (create, sync, close)
|
|
858
992
|
* - Opening a PR should sync the pipeline (creating the job) and start the new PR job
|
|
@@ -885,7 +1019,8 @@ function pullRequestEvent(pluginOptions, request, h, parsed, token) {
|
|
|
885
1019
|
changedFiles,
|
|
886
1020
|
type,
|
|
887
1021
|
releaseName,
|
|
888
|
-
ref
|
|
1022
|
+
ref,
|
|
1023
|
+
prMerged
|
|
889
1024
|
} = parsed;
|
|
890
1025
|
const fullCheckoutUrl = `${checkoutUrl}#${branch}`;
|
|
891
1026
|
const scmConfig = {
|
|
@@ -935,7 +1070,8 @@ function pullRequestEvent(pluginOptions, request, h, parsed, token) {
|
|
|
935
1070
|
chainPR,
|
|
936
1071
|
pipelines,
|
|
937
1072
|
ref,
|
|
938
|
-
releaseName
|
|
1073
|
+
releaseName,
|
|
1074
|
+
prMerged
|
|
939
1075
|
};
|
|
940
1076
|
|
|
941
1077
|
await batchUpdateAdmins({ userFactory, pipelines, username, scmContext, pipelineFactory });
|