1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.handleBuildEvent = undefined;
|
7 |
|
8 | let makeRequest = (() => {
|
9 | var _ref = _asyncToGenerator(function* (uri, body) {
|
10 | const repo = GITHUB_URL_REPO_REGEX.exec(uri)[1];
|
11 | const githubToken = yield _keymanager.keyManager.getGithubToken(repo);
|
12 | return (0, _requestPromiseNative2.default)({
|
13 | method: 'POST',
|
14 | uri,
|
15 | body,
|
16 | json: true,
|
17 | headers: {
|
18 | 'User-Agent': 'cloudbuild-github'
|
19 | },
|
20 | auth: {
|
21 | user: 'token',
|
22 | pass: githubToken
|
23 | }
|
24 | });
|
25 | });
|
26 |
|
27 | return function makeRequest(_x, _x2) {
|
28 | return _ref.apply(this, arguments);
|
29 | };
|
30 | })();
|
31 |
|
32 | let handleBuildEvent = exports.handleBuildEvent = (() => {
|
33 | var _ref2 = _asyncToGenerator(function* (event) {
|
34 | const build = JSON.parse(Buffer.from(event.data.data, 'base64').toString('utf8'));
|
35 |
|
36 | let repoName = null;
|
37 | let revisionId = null;
|
38 | if (!build.substitutions) {
|
39 | // No substitutions for triggered builds, we'll post to the commit instead.
|
40 | const repoSource = build.sourceProvenance.resolvedRepoSource;
|
41 | // eslint-disable-next-line prefer-destructuring
|
42 | const cloudbuildRepoName = repoSource.repoName;
|
43 | if (!cloudbuildRepoName.startsWith('github-')) {
|
44 | // Not a github repo.
|
45 | return;
|
46 | }
|
47 | repoName = cloudbuildRepoName.substring('github-'.length).replace('-', '/');
|
48 | revisionId = repoSource.commitSha;
|
49 | }
|
50 |
|
51 | const statusesUrl = repoName && revisionId ? `${GITHUB_API_BASE}/repos/${repoName}/statuses/${revisionId}` : build.substitutions[_constants.STATUSES_URL_KEY];
|
52 | if (!statusesUrl) {
|
53 | // A non-triggered build not from the webhook, nothing to do.
|
54 | return;
|
55 | }
|
56 |
|
57 | const status = {
|
58 | state: statusToState(build.status),
|
59 | target_url: build.logUrl,
|
60 | description: statusToDescription(build.status),
|
61 | context: 'ci/cloudbuild'
|
62 | };
|
63 |
|
64 | const statusResponse = yield makeRequest(statusesUrl, status);
|
65 | if (!statusResponse.state) {
|
66 | throw new Error(`Failed to set status: ${JSON.stringify(statusResponse)}`);
|
67 | }
|
68 |
|
69 | const commentsUrl = repoName && revisionId ? `${GITHUB_API_BASE}/repos/${repoName}/commits/${revisionId}/comments` : build.substitutions[_constants.COMMENTS_URL_KEY];
|
70 | if (!commentsUrl) {
|
71 | // A non-triggered build not from the webhook, nothing to do (we shouldn't
|
72 | // actually get here since we have a similar check for statuses).
|
73 | return;
|
74 | }
|
75 |
|
76 | let comment;
|
77 | switch (build.status) {
|
78 | case 'QUEUED':
|
79 | case 'WORKING':
|
80 | case 'CANCELLED':
|
81 | case 'STATUS_UNKNOWN':
|
82 | return;
|
83 | case 'SUCCESS':
|
84 | {
|
85 | if (repoName) {
|
86 | // Don't comment on success for triggered builds.
|
87 | return;
|
88 | }
|
89 | comment = `Build succeded. If you have approval, you're ready to merge!\n\nLogs:\n${build.logUrl}`;
|
90 | break;
|
91 | }
|
92 | case 'FAILURE':
|
93 | comment = `Build failed. Check the logs and try again.\n\nLogs:\n${build.logUrl}`;
|
94 | break;
|
95 | default:
|
96 | comment = `Build terminated with unknown error. You may want to retry.\n\nLogs:\n${build.logUrl}`;
|
97 | break;
|
98 | }
|
99 | const commentResponse = yield makeRequest(commentsUrl, { body: comment });
|
100 | if (!commentResponse.id) {
|
101 | throw new Error(`Failed to set comment: ${JSON.stringify(commentResponse)}`);
|
102 | }
|
103 | });
|
104 |
|
105 | return function handleBuildEvent(_x3) {
|
106 | return _ref2.apply(this, arguments);
|
107 | };
|
108 | })();
|
109 |
|
110 | var _requestPromiseNative = require('request-promise-native');
|
111 |
|
112 | var _requestPromiseNative2 = _interopRequireDefault(_requestPromiseNative);
|
113 |
|
114 | var _keymanager = require('./keymanager');
|
115 |
|
116 | var _constants = require('./constants');
|
117 |
|
118 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
119 |
|
120 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /*
|
121 | * MIT License
|
122 | *
|
123 | * Copyright (c) 2017 Choko (choko@curioswitch.org)
|
124 | *
|
125 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
126 | * of this software and associated documentation files (the "Software"), to deal
|
127 | * in the Software without restriction, including without limitation the rights
|
128 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
129 | * copies of the Software, and to permit persons to whom the Software is
|
130 | * furnished to do so, subject to the following conditions:
|
131 | *
|
132 | * The above copyright notice and this permission notice shall be included in all
|
133 | * copies or substantial portions of the Software.
|
134 | *
|
135 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
136 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
137 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
138 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
139 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
140 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
141 | * SOFTWARE.
|
142 | */
|
143 |
|
144 | const GITHUB_API_BASE = 'https://api.github.com';
|
145 |
|
146 | const GITHUB_URL_REPO_REGEX = /repos\/([^/]+\/[^/]+)\//;
|
147 |
|
148 | function statusToState(status) {
|
149 | switch (status) {
|
150 | case 'QUEUED':
|
151 | case 'WORKING':
|
152 | return 'pending';
|
153 | case 'SUCCESS':
|
154 | return 'success';
|
155 | case 'FAILURE':
|
156 | return 'failure';
|
157 | default:
|
158 | return 'error';
|
159 | }
|
160 | }
|
161 |
|
162 | function statusToDescription(status) {
|
163 | switch (status) {
|
164 | case 'QUEUED':
|
165 | return 'Build queued.';
|
166 | case 'WORKING':
|
167 | return 'Build started.';
|
168 | case 'SUCCESS':
|
169 | return 'Build succeeded.';
|
170 | case 'FAILURE':
|
171 | return 'Build failed.';
|
172 | case 'INTERNAL_ERROR':
|
173 | return 'Build internal error.';
|
174 | case 'TIMEOUT':
|
175 | return 'Build timed out.';
|
176 | case 'CANCELLED':
|
177 | return 'Build cancelled.';
|
178 | default:
|
179 | return 'Build status unknown.';
|
180 | }
|
181 | } |
\ | No newline at end of file |