release-please 17.4.0 → 17.5.0
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/build/src/bin/release-please.js +39 -10
- package/build/src/bootstrapper.d.ts +2 -2
- package/build/src/changelog-notes/default.js +9 -1
- package/build/src/changelog-notes/github.d.ts +2 -2
- package/build/src/changelog-notes.d.ts +1 -0
- package/build/src/commit.d.ts +6 -0
- package/build/src/factories/changelog-notes-factory.d.ts +2 -2
- package/build/src/factories/plugin-factory.d.ts +2 -2
- package/build/src/factories/versioning-strategy-factory.d.ts +2 -2
- package/build/src/factory.d.ts +2 -2
- package/build/src/github-api.d.ts +260 -0
- package/build/src/github-api.js +701 -0
- package/build/src/github.d.ts +21 -171
- package/build/src/github.js +154 -687
- package/build/src/index.d.ts +2 -2
- package/build/src/index.js +1 -1
- package/build/src/local-github.d.ts +271 -0
- package/build/src/local-github.js +776 -0
- package/build/src/manifest.d.ts +7 -5
- package/build/src/manifest.js +28 -26
- package/build/src/plugin.d.ts +3 -3
- package/build/src/plugins/group-priority.d.ts +2 -2
- package/build/src/plugins/linked-versions.d.ts +2 -2
- package/build/src/plugins/maven-workspace.d.ts +2 -2
- package/build/src/plugins/merge.d.ts +2 -2
- package/build/src/plugins/node-workspace.d.ts +2 -2
- package/build/src/plugins/sentence-case.d.ts +2 -2
- package/build/src/plugins/workspace.d.ts +2 -2
- package/build/src/scm.d.ts +80 -0
- package/build/src/scm.js +16 -0
- package/build/src/strategies/base.d.ts +5 -3
- package/build/src/strategies/base.js +2 -0
- package/build/src/util/pull-request-overflow-handler.d.ts +2 -2
- package/package.json +3 -3
package/build/src/github.js
CHANGED
|
@@ -13,23 +13,17 @@
|
|
|
13
13
|
// See the License for the specific language governing permissions and
|
|
14
14
|
// limitations under the License.
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.sleepInMs = exports.GitHub =
|
|
17
|
-
const code_suggester_1 = require("code-suggester");
|
|
18
|
-
const rest_1 = require("@octokit/rest");
|
|
19
|
-
const request_1 = require("@octokit/request");
|
|
20
|
-
const graphql_1 = require("@octokit/graphql");
|
|
16
|
+
exports.sleepInMs = exports.GitHub = void 0;
|
|
21
17
|
const request_error_1 = require("@octokit/request-error");
|
|
18
|
+
const code_suggester_1 = require("code-suggester");
|
|
22
19
|
const errors_1 = require("./errors");
|
|
23
20
|
const MAX_ISSUE_BODY_SIZE = 65536;
|
|
24
21
|
const MAX_SLEEP_SECONDS = 20;
|
|
25
|
-
exports.GH_API_URL = 'https://api.github.com';
|
|
26
|
-
exports.GH_GRAPHQL_URL = 'https://api.github.com';
|
|
27
22
|
const logger_1 = require("./util/logger");
|
|
28
23
|
const manifest_1 = require("./manifest");
|
|
24
|
+
const github_api_1 = require("./github-api");
|
|
29
25
|
const signoff_commit_message_1 = require("./util/signoff-commit-message");
|
|
30
26
|
const git_file_utils_1 = require("@google-automations/git-file-utils");
|
|
31
|
-
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
32
|
-
const http_proxy_agent_1 = require("http-proxy-agent");
|
|
33
27
|
const composite_1 = require("./updaters/composite");
|
|
34
28
|
class GitHub {
|
|
35
29
|
constructor(options) {
|
|
@@ -133,118 +127,6 @@ class GitHub {
|
|
|
133
127
|
this.logger.debug(`finding files by glob: ${glob}, ref: ${ref}, prefix: ${prefix}`);
|
|
134
128
|
return await this.fileCache.findFilesByGlob(glob, ref, prefix);
|
|
135
129
|
});
|
|
136
|
-
/**
|
|
137
|
-
* Open a pull request
|
|
138
|
-
*
|
|
139
|
-
* @param {PullRequest} pullRequest Pull request data to update
|
|
140
|
-
* @param {string} targetBranch The base branch of the pull request
|
|
141
|
-
* @param {string} message The commit message for the commit
|
|
142
|
-
* @param {Update[]} updates The files to update
|
|
143
|
-
* @param {CreatePullRequestOptions} options The pull request options
|
|
144
|
-
* @throws {GitHubAPIError} on an API error
|
|
145
|
-
*/
|
|
146
|
-
this.createPullRequest = wrapAsync(async (pullRequest, targetBranch, message, updates, options) => {
|
|
147
|
-
// Update the files for the release if not already supplied
|
|
148
|
-
const changes = await this.buildChangeSet(updates, targetBranch);
|
|
149
|
-
const prNumber = await (0, code_suggester_1.createPullRequest)(this.octokit, changes, {
|
|
150
|
-
upstreamOwner: this.repository.owner,
|
|
151
|
-
upstreamRepo: this.repository.repo,
|
|
152
|
-
title: pullRequest.title,
|
|
153
|
-
branch: pullRequest.headBranchName,
|
|
154
|
-
description: pullRequest.body,
|
|
155
|
-
primary: targetBranch,
|
|
156
|
-
force: true,
|
|
157
|
-
fork: !!(options === null || options === void 0 ? void 0 : options.fork),
|
|
158
|
-
message,
|
|
159
|
-
logger: this.logger,
|
|
160
|
-
draft: !!(options === null || options === void 0 ? void 0 : options.draft),
|
|
161
|
-
labels: pullRequest.labels,
|
|
162
|
-
});
|
|
163
|
-
return await this.getPullRequest(prNumber);
|
|
164
|
-
});
|
|
165
|
-
/**
|
|
166
|
-
* Fetch a pull request given the pull number
|
|
167
|
-
* @param {number} number The pull request number
|
|
168
|
-
* @returns {PullRequest}
|
|
169
|
-
*/
|
|
170
|
-
this.getPullRequest = wrapAsync(async (number) => {
|
|
171
|
-
const response = await this.octokit.pulls.get({
|
|
172
|
-
owner: this.repository.owner,
|
|
173
|
-
repo: this.repository.repo,
|
|
174
|
-
pull_number: number,
|
|
175
|
-
});
|
|
176
|
-
return {
|
|
177
|
-
headBranchName: response.data.head.ref,
|
|
178
|
-
baseBranchName: response.data.base.ref,
|
|
179
|
-
number: response.data.number,
|
|
180
|
-
title: response.data.title,
|
|
181
|
-
body: response.data.body || '',
|
|
182
|
-
files: [],
|
|
183
|
-
labels: response.data.labels
|
|
184
|
-
.map(label => label.name)
|
|
185
|
-
.filter(name => !!name),
|
|
186
|
-
};
|
|
187
|
-
});
|
|
188
|
-
/**
|
|
189
|
-
* Update a pull request's title and body.
|
|
190
|
-
* @param {number} number The pull request number
|
|
191
|
-
* @param {ReleasePullRequest} releasePullRequest Pull request data to update
|
|
192
|
-
* @param {string} targetBranch The target branch of the pull request
|
|
193
|
-
* @param {string} options.signoffUser Optional. Commit signoff message
|
|
194
|
-
* @param {boolean} options.fork Optional. Whether to open the pull request from
|
|
195
|
-
* a fork or not. Defaults to `false`
|
|
196
|
-
* @param {PullRequestOverflowHandler} options.pullRequestOverflowHandler Optional.
|
|
197
|
-
* Handles extra large pull request body messages.
|
|
198
|
-
*/
|
|
199
|
-
this.updatePullRequest = wrapAsync(async (number, releasePullRequest, targetBranch, options) => {
|
|
200
|
-
// Update the files for the release if not already supplied
|
|
201
|
-
const changes = await this.buildChangeSet(releasePullRequest.updates, targetBranch);
|
|
202
|
-
let message = releasePullRequest.title.toString();
|
|
203
|
-
if (options === null || options === void 0 ? void 0 : options.signoffUser) {
|
|
204
|
-
message = (0, signoff_commit_message_1.signoffCommitMessage)(message, options.signoffUser);
|
|
205
|
-
}
|
|
206
|
-
const title = releasePullRequest.title.toString();
|
|
207
|
-
const body = ((options === null || options === void 0 ? void 0 : options.pullRequestOverflowHandler)
|
|
208
|
-
? await options.pullRequestOverflowHandler.handleOverflow(releasePullRequest)
|
|
209
|
-
: releasePullRequest.body)
|
|
210
|
-
.toString()
|
|
211
|
-
.slice(0, MAX_ISSUE_BODY_SIZE);
|
|
212
|
-
const prNumber = await (0, code_suggester_1.createPullRequest)(this.octokit, changes, {
|
|
213
|
-
upstreamOwner: this.repository.owner,
|
|
214
|
-
upstreamRepo: this.repository.repo,
|
|
215
|
-
title,
|
|
216
|
-
branch: releasePullRequest.headRefName,
|
|
217
|
-
description: body,
|
|
218
|
-
primary: targetBranch,
|
|
219
|
-
force: true,
|
|
220
|
-
fork: (options === null || options === void 0 ? void 0 : options.fork) === false ? false : true,
|
|
221
|
-
message,
|
|
222
|
-
logger: this.logger,
|
|
223
|
-
draft: releasePullRequest.draft,
|
|
224
|
-
});
|
|
225
|
-
if (prNumber !== number) {
|
|
226
|
-
this.logger.warn(`updated code for ${prNumber}, but update requested for ${number}`);
|
|
227
|
-
}
|
|
228
|
-
const response = await this.octokit.pulls.update({
|
|
229
|
-
owner: this.repository.owner,
|
|
230
|
-
repo: this.repository.repo,
|
|
231
|
-
pull_number: number,
|
|
232
|
-
title: releasePullRequest.title.toString(),
|
|
233
|
-
body,
|
|
234
|
-
state: 'open',
|
|
235
|
-
});
|
|
236
|
-
return {
|
|
237
|
-
headBranchName: response.data.head.ref,
|
|
238
|
-
baseBranchName: response.data.base.ref,
|
|
239
|
-
number: response.data.number,
|
|
240
|
-
title: response.data.title,
|
|
241
|
-
body: response.data.body || '',
|
|
242
|
-
files: [],
|
|
243
|
-
labels: response.data.labels
|
|
244
|
-
.map(label => label.name)
|
|
245
|
-
.filter(name => !!name),
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
130
|
/**
|
|
249
131
|
* Returns a list of paths to all files with a given file
|
|
250
132
|
* extension.
|
|
@@ -265,213 +147,27 @@ class GitHub {
|
|
|
265
147
|
}
|
|
266
148
|
return this.fileCache.findFilesByExtension(extension, ref, prefix);
|
|
267
149
|
});
|
|
268
|
-
/**
|
|
269
|
-
* Create a GitHub release
|
|
270
|
-
*
|
|
271
|
-
* @param {Release} release Release parameters
|
|
272
|
-
* @param {ReleaseOptions} options Release option parameters
|
|
273
|
-
* @throws {DuplicateReleaseError} if the release tag already exists
|
|
274
|
-
* @throws {GitHubAPIError} on other API errors
|
|
275
|
-
*/
|
|
276
|
-
this.createRelease = wrapAsync(async (release, options = {}) => {
|
|
277
|
-
if (options.forceTag) {
|
|
278
|
-
try {
|
|
279
|
-
await this.octokit.git.createRef({
|
|
280
|
-
owner: this.repository.owner,
|
|
281
|
-
repo: this.repository.repo,
|
|
282
|
-
ref: `refs/tags/${release.tag.toString()}`,
|
|
283
|
-
sha: release.sha,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
catch (err) {
|
|
287
|
-
// ignore if tag already exists
|
|
288
|
-
if (err.status === 422) {
|
|
289
|
-
this.logger.debug(`Tag ${release.tag.toString()} already exists, skipping tag creation`);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
throw err;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
const resp = await this.octokit.repos.createRelease({
|
|
297
|
-
name: release.name,
|
|
298
|
-
owner: this.repository.owner,
|
|
299
|
-
repo: this.repository.repo,
|
|
300
|
-
tag_name: release.tag.toString(),
|
|
301
|
-
body: release.notes,
|
|
302
|
-
draft: !!options.draft,
|
|
303
|
-
prerelease: !!options.prerelease,
|
|
304
|
-
target_commitish: release.sha,
|
|
305
|
-
});
|
|
306
|
-
return {
|
|
307
|
-
id: resp.data.id,
|
|
308
|
-
name: resp.data.name || undefined,
|
|
309
|
-
tagName: resp.data.tag_name,
|
|
310
|
-
sha: resp.data.target_commitish,
|
|
311
|
-
notes: resp.data.body_text ||
|
|
312
|
-
resp.data.body ||
|
|
313
|
-
resp.data.body_html ||
|
|
314
|
-
undefined,
|
|
315
|
-
url: resp.data.html_url,
|
|
316
|
-
draft: resp.data.draft,
|
|
317
|
-
uploadUrl: resp.data.upload_url,
|
|
318
|
-
};
|
|
319
|
-
}, e => {
|
|
320
|
-
if (e instanceof request_error_1.RequestError) {
|
|
321
|
-
if (e.status === 422 &&
|
|
322
|
-
errors_1.GitHubAPIError.parseErrors(e).some(error => {
|
|
323
|
-
return error.code === 'already_exists';
|
|
324
|
-
})) {
|
|
325
|
-
throw new errors_1.DuplicateReleaseError(e, 'tagName');
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
/**
|
|
330
|
-
* Makes a comment on a issue/pull request.
|
|
331
|
-
*
|
|
332
|
-
* @param {string} comment - The body of the comment to post.
|
|
333
|
-
* @param {number} number - The issue or pull request number.
|
|
334
|
-
* @throws {GitHubAPIError} on an API error
|
|
335
|
-
*/
|
|
336
|
-
this.commentOnIssue = wrapAsync(async (comment, number) => {
|
|
337
|
-
this.logger.debug(`adding comment to https://github.com/${this.repository.owner}/${this.repository.repo}/issues/${number}`);
|
|
338
|
-
const resp = await this.octokit.issues.createComment({
|
|
339
|
-
owner: this.repository.owner,
|
|
340
|
-
repo: this.repository.repo,
|
|
341
|
-
issue_number: number,
|
|
342
|
-
body: comment,
|
|
343
|
-
});
|
|
344
|
-
return resp.data.html_url;
|
|
345
|
-
});
|
|
346
|
-
/**
|
|
347
|
-
* Removes labels from an issue/pull request.
|
|
348
|
-
*
|
|
349
|
-
* @param {string[]} labels The labels to remove.
|
|
350
|
-
* @param {number} number The issue/pull request number.
|
|
351
|
-
*/
|
|
352
|
-
this.removeIssueLabels = wrapAsync(async (labels, number) => {
|
|
353
|
-
if (labels.length === 0) {
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
this.logger.debug(`removing labels: ${labels} from issue/pull ${number}`);
|
|
357
|
-
await Promise.all(labels.map(label => this.octokit.issues.removeLabel({
|
|
358
|
-
owner: this.repository.owner,
|
|
359
|
-
repo: this.repository.repo,
|
|
360
|
-
issue_number: number,
|
|
361
|
-
name: label,
|
|
362
|
-
})));
|
|
363
|
-
});
|
|
364
|
-
/**
|
|
365
|
-
* Adds label to an issue/pull request.
|
|
366
|
-
*
|
|
367
|
-
* @param {string[]} labels The labels to add.
|
|
368
|
-
* @param {number} number The issue/pull request number.
|
|
369
|
-
*/
|
|
370
|
-
this.addIssueLabels = wrapAsync(async (labels, number) => {
|
|
371
|
-
if (labels.length === 0) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
this.logger.debug(`adding labels: ${labels} from issue/pull ${number}`);
|
|
375
|
-
await this.octokit.issues.addLabels({
|
|
376
|
-
owner: this.repository.owner,
|
|
377
|
-
repo: this.repository.repo,
|
|
378
|
-
issue_number: number,
|
|
379
|
-
labels,
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
150
|
this.repository = options.repository;
|
|
383
151
|
this.octokit = options.octokitAPIs.octokit;
|
|
384
|
-
this.request = options.octokitAPIs.request;
|
|
385
152
|
this.graphql = options.octokitAPIs.graphql;
|
|
386
153
|
this.fileCache = new git_file_utils_1.RepositoryFileCache(this.octokit, this.repository);
|
|
387
154
|
this.logger = (_a = options.logger) !== null && _a !== void 0 ? _a : logger_1.logger;
|
|
155
|
+
this.gitHubApi = new github_api_1.GitHubApi({
|
|
156
|
+
repository: this.repository,
|
|
157
|
+
octokitAPIs: options.octokitAPIs,
|
|
158
|
+
logger: this.logger,
|
|
159
|
+
});
|
|
388
160
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return undefined;
|
|
392
|
-
}
|
|
393
|
-
const { host, port } = defaultProxy;
|
|
394
|
-
if (new URL(baseUrl).protocol.replace(':', '') === 'http') {
|
|
395
|
-
return new http_proxy_agent_1.HttpProxyAgent(`http://${host}:${port}`);
|
|
396
|
-
}
|
|
397
|
-
else {
|
|
398
|
-
return new https_proxy_agent_1.HttpsProxyAgent(`https://${host}:${port}`);
|
|
399
|
-
}
|
|
161
|
+
getGitHubApi() {
|
|
162
|
+
return this.gitHubApi;
|
|
400
163
|
}
|
|
401
|
-
/**
|
|
402
|
-
* Build a new GitHub client with auto-detected default branch.
|
|
403
|
-
*
|
|
404
|
-
* @param {GitHubCreateOptions} options Configuration options
|
|
405
|
-
* @param {string} options.owner The repository owner.
|
|
406
|
-
* @param {string} options.repo The repository name.
|
|
407
|
-
* @param {string} options.defaultBranch Optional. The repository's default branch.
|
|
408
|
-
* Defaults to the value fetched via the API.
|
|
409
|
-
* @param {string} options.apiUrl Optional. The base url of the GitHub API.
|
|
410
|
-
* @param {string} options.graphqlUrl Optional. The base url of the GraphQL API.
|
|
411
|
-
* @param {OctokitAPISs} options.octokitAPIs Optional. Override the internal
|
|
412
|
-
* client instances with a pre-authenticated instance.
|
|
413
|
-
* @param {string} token Optional. A GitHub API token used for authentication.
|
|
414
|
-
*/
|
|
415
164
|
static async create(options) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const apis = (_c = options.octokitAPIs) !== null && _c !== void 0 ? _c : {
|
|
421
|
-
octokit: new rest_1.Octokit({
|
|
422
|
-
baseUrl: apiUrl,
|
|
423
|
-
auth: options.token,
|
|
424
|
-
request: {
|
|
425
|
-
agent: this.createDefaultAgent(apiUrl, options.proxy),
|
|
426
|
-
fetch: options.fetch,
|
|
427
|
-
},
|
|
428
|
-
}),
|
|
429
|
-
request: request_1.request.defaults({
|
|
430
|
-
baseUrl: apiUrl,
|
|
431
|
-
headers: {
|
|
432
|
-
'user-agent': `release-please/${releasePleaseVersion}`,
|
|
433
|
-
Authorization: `token ${options.token}`,
|
|
434
|
-
},
|
|
435
|
-
fetch: options.fetch,
|
|
436
|
-
}),
|
|
437
|
-
graphql: graphql_1.graphql.defaults({
|
|
438
|
-
baseUrl: graphqlUrl,
|
|
439
|
-
request: {
|
|
440
|
-
agent: this.createDefaultAgent(graphqlUrl, options.proxy),
|
|
441
|
-
fetch: options.fetch,
|
|
442
|
-
},
|
|
443
|
-
headers: {
|
|
444
|
-
'user-agent': `release-please/${releasePleaseVersion}`,
|
|
445
|
-
Authorization: `token ${options.token}`,
|
|
446
|
-
'content-type': 'application/vnd.github.v3+json',
|
|
447
|
-
},
|
|
448
|
-
}),
|
|
449
|
-
};
|
|
450
|
-
const opts = {
|
|
451
|
-
repository: {
|
|
452
|
-
owner: options.owner,
|
|
453
|
-
repo: options.repo,
|
|
454
|
-
defaultBranch: (_d = options.defaultBranch) !== null && _d !== void 0 ? _d : (await GitHub.defaultBranch(options.owner, options.repo, apis.octokit)),
|
|
455
|
-
},
|
|
456
|
-
octokitAPIs: apis,
|
|
165
|
+
const gitHubApi = await github_api_1.GitHubApi.create(options);
|
|
166
|
+
return new GitHub({
|
|
167
|
+
repository: gitHubApi.repository,
|
|
168
|
+
octokitAPIs: gitHubApi.octokitAPIs,
|
|
457
169
|
logger: options.logger,
|
|
458
|
-
};
|
|
459
|
-
return new GitHub(opts);
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* Returns the default branch for a given repository.
|
|
463
|
-
*
|
|
464
|
-
* @param {string} owner The GitHub repository owner
|
|
465
|
-
* @param {string} repo The GitHub repository name
|
|
466
|
-
* @param {OctokitType} octokit An authenticated octokit instance
|
|
467
|
-
* @returns {string} Name of the default branch
|
|
468
|
-
*/
|
|
469
|
-
static async defaultBranch(owner, repo, octokit) {
|
|
470
|
-
const { data } = await octokit.repos.get({
|
|
471
|
-
repo,
|
|
472
|
-
owner,
|
|
473
170
|
});
|
|
474
|
-
return data.default_branch;
|
|
475
171
|
}
|
|
476
172
|
/**
|
|
477
173
|
* Returns the list of commits to the default branch after the provided filter
|
|
@@ -533,8 +229,8 @@ class GitHub {
|
|
|
533
229
|
}
|
|
534
230
|
}
|
|
535
231
|
async mergeCommitsGraphQL(targetBranch, cursor, options = {}) {
|
|
536
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
537
|
-
var
|
|
232
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
233
|
+
var _l;
|
|
538
234
|
this.logger.debug(`Fetching merge commits on branch ${targetBranch} with cursor: ${cursor}`);
|
|
539
235
|
const query = `query pullRequestsSince($owner: String!, $repo: String!, $num: Int!, $maxFilesChanged: Int, $targetBranch: String!, $cursor: String) {
|
|
540
236
|
repository(owner: $owner, name: $repo) {
|
|
@@ -571,6 +267,13 @@ class GitHub {
|
|
|
571
267
|
}
|
|
572
268
|
sha: oid
|
|
573
269
|
message
|
|
270
|
+
author {
|
|
271
|
+
name
|
|
272
|
+
email
|
|
273
|
+
user {
|
|
274
|
+
login
|
|
275
|
+
}
|
|
276
|
+
}
|
|
574
277
|
}
|
|
575
278
|
pageInfo {
|
|
576
279
|
hasNextPage
|
|
@@ -612,7 +315,7 @@ class GitHub {
|
|
|
612
315
|
for (const commit of commits) {
|
|
613
316
|
for (const pr of commit.associatedPullRequests.nodes) {
|
|
614
317
|
if ((_c = pr.mergeCommit) === null || _c === void 0 ? void 0 : _c.oid) {
|
|
615
|
-
(_d = mergeCommitCount[
|
|
318
|
+
(_d = mergeCommitCount[_l = pr.mergeCommit.oid]) !== null && _d !== void 0 ? _d : (mergeCommitCount[_l] = 0);
|
|
616
319
|
mergeCommitCount[pr.mergeCommit.oid]++;
|
|
617
320
|
}
|
|
618
321
|
}
|
|
@@ -622,6 +325,13 @@ class GitHub {
|
|
|
622
325
|
const commit = {
|
|
623
326
|
sha: graphCommit.sha,
|
|
624
327
|
message: graphCommit.message,
|
|
328
|
+
author: graphCommit.author
|
|
329
|
+
? {
|
|
330
|
+
name: graphCommit.author.name || 'Unknown',
|
|
331
|
+
email: graphCommit.author.email,
|
|
332
|
+
username: (_e = graphCommit.author.user) === null || _e === void 0 ? void 0 : _e.login,
|
|
333
|
+
}
|
|
334
|
+
: undefined,
|
|
625
335
|
};
|
|
626
336
|
const mergePullRequest = graphCommit.associatedPullRequests.nodes.find(pr => {
|
|
627
337
|
return (
|
|
@@ -642,15 +352,15 @@ class GitHub {
|
|
|
642
352
|
number: pullRequest.number,
|
|
643
353
|
baseBranchName: pullRequest.baseRefName,
|
|
644
354
|
headBranchName: pullRequest.headRefName,
|
|
645
|
-
mergeCommitOid: (
|
|
355
|
+
mergeCommitOid: (_f = pullRequest.mergeCommit) === null || _f === void 0 ? void 0 : _f.oid,
|
|
646
356
|
title: pullRequest.title,
|
|
647
357
|
body: pullRequest.body,
|
|
648
358
|
labels: pullRequest.labels.nodes.map(node => node.name),
|
|
649
|
-
files: (((
|
|
359
|
+
files: (((_g = pullRequest.files) === null || _g === void 0 ? void 0 : _g.nodes) || []).map(node => node.path),
|
|
650
360
|
};
|
|
651
361
|
}
|
|
652
362
|
if (mergePullRequest) {
|
|
653
|
-
if (((
|
|
363
|
+
if (((_j = (_h = mergePullRequest.files) === null || _h === void 0 ? void 0 : _h.pageInfo) === null || _j === void 0 ? void 0 : _j.hasNextPage) &&
|
|
654
364
|
options.backfillFiles) {
|
|
655
365
|
this.logger.info(`PR #${mergePullRequest.number} has many files, backfilling`);
|
|
656
366
|
commit.files = await this.getCommitFiles(graphCommit.sha);
|
|
@@ -658,7 +368,7 @@ class GitHub {
|
|
|
658
368
|
else {
|
|
659
369
|
// We cannot directly fetch files on commits via graphql, only provide file
|
|
660
370
|
// information for commits with associated pull requests
|
|
661
|
-
commit.files = (((
|
|
371
|
+
commit.files = (((_k = mergePullRequest.files) === null || _k === void 0 ? void 0 : _k.nodes) || []).map(node => node.path);
|
|
662
372
|
}
|
|
663
373
|
}
|
|
664
374
|
else if (options.backfillFiles) {
|
|
@@ -688,167 +398,7 @@ class GitHub {
|
|
|
688
398
|
* @throws {GitHubAPIError} on an API error
|
|
689
399
|
*/
|
|
690
400
|
async *pullRequestIterator(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER, includeFiles = true) {
|
|
691
|
-
|
|
692
|
-
? this.pullRequestIteratorWithFiles(targetBranch, status, maxResults)
|
|
693
|
-
: this.pullRequestIteratorWithoutFiles(targetBranch, status, maxResults);
|
|
694
|
-
for await (const pullRequest of generator) {
|
|
695
|
-
yield pullRequest;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* Helper implementation of pullRequestIterator that includes files via
|
|
700
|
-
* the graphQL API.
|
|
701
|
-
*
|
|
702
|
-
* @param {string} targetBranch The base branch of the pull request
|
|
703
|
-
* @param {string} status The status of the pull request
|
|
704
|
-
* @param {number} maxResults Limit the number of results searched
|
|
705
|
-
*/
|
|
706
|
-
async *pullRequestIteratorWithFiles(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER) {
|
|
707
|
-
let cursor = undefined;
|
|
708
|
-
let results = 0;
|
|
709
|
-
while (results < maxResults) {
|
|
710
|
-
const response = await this.pullRequestsGraphQL(targetBranch, status, cursor);
|
|
711
|
-
// no response usually means we ran out of results
|
|
712
|
-
if (!response) {
|
|
713
|
-
break;
|
|
714
|
-
}
|
|
715
|
-
for (let i = 0; i < response.data.length; i++) {
|
|
716
|
-
results += 1;
|
|
717
|
-
yield response.data[i];
|
|
718
|
-
}
|
|
719
|
-
if (!response.pageInfo.hasNextPage) {
|
|
720
|
-
break;
|
|
721
|
-
}
|
|
722
|
-
cursor = response.pageInfo.endCursor;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
* Helper implementation of pullRequestIterator that excludes files
|
|
727
|
-
* via the REST API.
|
|
728
|
-
*
|
|
729
|
-
* @param {string} targetBranch The base branch of the pull request
|
|
730
|
-
* @param {string} status The status of the pull request
|
|
731
|
-
* @param {number} maxResults Limit the number of results searched
|
|
732
|
-
*/
|
|
733
|
-
async *pullRequestIteratorWithoutFiles(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER) {
|
|
734
|
-
const statusMap = {
|
|
735
|
-
OPEN: 'open',
|
|
736
|
-
CLOSED: 'closed',
|
|
737
|
-
MERGED: 'closed',
|
|
738
|
-
};
|
|
739
|
-
let results = 0;
|
|
740
|
-
for await (const { data: pulls } of this.octokit.paginate.iterator('GET /repos/{owner}/{repo}/pulls', {
|
|
741
|
-
state: statusMap[status],
|
|
742
|
-
owner: this.repository.owner,
|
|
743
|
-
repo: this.repository.repo,
|
|
744
|
-
base: targetBranch,
|
|
745
|
-
sort: 'updated',
|
|
746
|
-
direction: 'desc',
|
|
747
|
-
})) {
|
|
748
|
-
for (const pull of pulls) {
|
|
749
|
-
// The REST API does not have an option for "merged"
|
|
750
|
-
// pull requests - they are closed with a `merged_at` timestamp
|
|
751
|
-
if (status !== 'MERGED' || pull.merged_at) {
|
|
752
|
-
results += 1;
|
|
753
|
-
yield {
|
|
754
|
-
headBranchName: pull.head.ref,
|
|
755
|
-
baseBranchName: pull.base.ref,
|
|
756
|
-
number: pull.number,
|
|
757
|
-
title: pull.title,
|
|
758
|
-
body: pull.body || '',
|
|
759
|
-
labels: pull.labels.map(label => label.name),
|
|
760
|
-
files: [],
|
|
761
|
-
sha: pull.merge_commit_sha || undefined,
|
|
762
|
-
};
|
|
763
|
-
if (results >= maxResults) {
|
|
764
|
-
break;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
if (results >= maxResults) {
|
|
769
|
-
break;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Return a list of merged pull requests. The list is not guaranteed to be sorted
|
|
775
|
-
* by merged_at, but is generally most recent first.
|
|
776
|
-
*
|
|
777
|
-
* @param {string} targetBranch - Base branch of the pull request. Defaults to
|
|
778
|
-
* the configured default branch.
|
|
779
|
-
* @param {number} page - Page of results. Defaults to 1.
|
|
780
|
-
* @param {number} perPage - Number of results per page. Defaults to 100.
|
|
781
|
-
* @returns {PullRequestHistory | null} - List of merged pull requests
|
|
782
|
-
* @throws {GitHubAPIError} on an API error
|
|
783
|
-
*/
|
|
784
|
-
async pullRequestsGraphQL(targetBranch, states = 'MERGED', cursor) {
|
|
785
|
-
var _a;
|
|
786
|
-
this.logger.debug(`Fetching ${states} pull requests on branch ${targetBranch} with cursor ${cursor}`);
|
|
787
|
-
const response = await this.graphqlRequest({
|
|
788
|
-
query: `query mergedPullRequests($owner: String!, $repo: String!, $num: Int!, $maxFilesChanged: Int, $targetBranch: String!, $states: [PullRequestState!], $cursor: String) {
|
|
789
|
-
repository(owner: $owner, name: $repo) {
|
|
790
|
-
pullRequests(first: $num, after: $cursor, baseRefName: $targetBranch, states: $states, orderBy: {field: CREATED_AT, direction: DESC}) {
|
|
791
|
-
nodes {
|
|
792
|
-
number
|
|
793
|
-
title
|
|
794
|
-
baseRefName
|
|
795
|
-
headRefName
|
|
796
|
-
labels(first: 10) {
|
|
797
|
-
nodes {
|
|
798
|
-
name
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
body
|
|
802
|
-
mergeCommit {
|
|
803
|
-
oid
|
|
804
|
-
}
|
|
805
|
-
files(first: $maxFilesChanged) {
|
|
806
|
-
nodes {
|
|
807
|
-
path
|
|
808
|
-
}
|
|
809
|
-
pageInfo {
|
|
810
|
-
endCursor
|
|
811
|
-
hasNextPage
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
pageInfo {
|
|
816
|
-
endCursor
|
|
817
|
-
hasNextPage
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
}`,
|
|
822
|
-
cursor,
|
|
823
|
-
owner: this.repository.owner,
|
|
824
|
-
repo: this.repository.repo,
|
|
825
|
-
num: 25,
|
|
826
|
-
targetBranch,
|
|
827
|
-
states,
|
|
828
|
-
maxFilesChanged: 64,
|
|
829
|
-
});
|
|
830
|
-
if (!((_a = response === null || response === void 0 ? void 0 : response.repository) === null || _a === void 0 ? void 0 : _a.pullRequests)) {
|
|
831
|
-
this.logger.warn(`Could not find merged pull requests for branch ${targetBranch} - it likely does not exist.`);
|
|
832
|
-
return null;
|
|
833
|
-
}
|
|
834
|
-
const pullRequests = (response.repository.pullRequests.nodes ||
|
|
835
|
-
[]);
|
|
836
|
-
return {
|
|
837
|
-
pageInfo: response.repository.pullRequests.pageInfo,
|
|
838
|
-
data: pullRequests.map(pullRequest => {
|
|
839
|
-
var _a, _b, _c;
|
|
840
|
-
return {
|
|
841
|
-
sha: (_a = pullRequest.mergeCommit) === null || _a === void 0 ? void 0 : _a.oid,
|
|
842
|
-
number: pullRequest.number,
|
|
843
|
-
baseBranchName: pullRequest.baseRefName,
|
|
844
|
-
headBranchName: pullRequest.headRefName,
|
|
845
|
-
labels: (((_b = pullRequest.labels) === null || _b === void 0 ? void 0 : _b.nodes) || []).map(l => l.name),
|
|
846
|
-
title: pullRequest.title,
|
|
847
|
-
body: pullRequest.body + '',
|
|
848
|
-
files: (((_c = pullRequest.files) === null || _c === void 0 ? void 0 : _c.nodes) || []).map(node => node.path),
|
|
849
|
-
};
|
|
850
|
-
}),
|
|
851
|
-
};
|
|
401
|
+
yield* this.gitHubApi.pullRequestIterator(targetBranch, status, maxResults, includeFiles);
|
|
852
402
|
}
|
|
853
403
|
/**
|
|
854
404
|
* Iterate through releases with a max number of results scanned.
|
|
@@ -860,80 +410,7 @@ class GitHub {
|
|
|
860
410
|
* @throws {GitHubAPIError} on an API error
|
|
861
411
|
*/
|
|
862
412
|
async *releaseIterator(options = {}) {
|
|
863
|
-
|
|
864
|
-
const maxResults = (_a = options.maxResults) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
|
|
865
|
-
let results = 0;
|
|
866
|
-
let cursor = undefined;
|
|
867
|
-
while (true) {
|
|
868
|
-
const response = await this.releaseGraphQL(cursor);
|
|
869
|
-
if (!response) {
|
|
870
|
-
break;
|
|
871
|
-
}
|
|
872
|
-
for (let i = 0; i < response.data.length; i++) {
|
|
873
|
-
if ((results += 1) > maxResults) {
|
|
874
|
-
break;
|
|
875
|
-
}
|
|
876
|
-
yield response.data[i];
|
|
877
|
-
}
|
|
878
|
-
if (results > maxResults || !response.pageInfo.hasNextPage) {
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
881
|
-
cursor = response.pageInfo.endCursor;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
async releaseGraphQL(cursor) {
|
|
885
|
-
this.logger.debug(`Fetching releases with cursor ${cursor}`);
|
|
886
|
-
const response = await this.graphqlRequest({
|
|
887
|
-
query: `query releases($owner: String!, $repo: String!, $num: Int!, $cursor: String) {
|
|
888
|
-
repository(owner: $owner, name: $repo) {
|
|
889
|
-
releases(first: $num, after: $cursor, orderBy: {field: CREATED_AT, direction: DESC}) {
|
|
890
|
-
nodes {
|
|
891
|
-
name
|
|
892
|
-
tag {
|
|
893
|
-
name
|
|
894
|
-
}
|
|
895
|
-
tagCommit {
|
|
896
|
-
oid
|
|
897
|
-
}
|
|
898
|
-
url
|
|
899
|
-
description
|
|
900
|
-
isDraft
|
|
901
|
-
}
|
|
902
|
-
pageInfo {
|
|
903
|
-
endCursor
|
|
904
|
-
hasNextPage
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
}`,
|
|
909
|
-
cursor,
|
|
910
|
-
owner: this.repository.owner,
|
|
911
|
-
repo: this.repository.repo,
|
|
912
|
-
num: 25,
|
|
913
|
-
});
|
|
914
|
-
if (!response.repository.releases.nodes.length) {
|
|
915
|
-
this.logger.warn('Could not find releases.');
|
|
916
|
-
return null;
|
|
917
|
-
}
|
|
918
|
-
const releases = response.repository.releases.nodes;
|
|
919
|
-
return {
|
|
920
|
-
pageInfo: response.repository.releases.pageInfo,
|
|
921
|
-
data: releases
|
|
922
|
-
.filter(release => !!release.tagCommit)
|
|
923
|
-
.map(release => {
|
|
924
|
-
if (!release.tag || !release.tagCommit) {
|
|
925
|
-
this.logger.debug(release);
|
|
926
|
-
}
|
|
927
|
-
return {
|
|
928
|
-
name: release.name || undefined,
|
|
929
|
-
tagName: release.tag ? release.tag.name : 'unknown',
|
|
930
|
-
sha: release.tagCommit.oid,
|
|
931
|
-
notes: release.description,
|
|
932
|
-
url: release.url,
|
|
933
|
-
draft: release.isDraft,
|
|
934
|
-
};
|
|
935
|
-
}),
|
|
936
|
-
};
|
|
413
|
+
yield* this.gitHubApi.releaseIterator(options);
|
|
937
414
|
}
|
|
938
415
|
/**
|
|
939
416
|
* Iterate through tags with a max number of results scanned.
|
|
@@ -1030,33 +507,91 @@ class GitHub {
|
|
|
1030
507
|
/**
|
|
1031
508
|
* Open a pull request
|
|
1032
509
|
*
|
|
1033
|
-
* @
|
|
1034
|
-
* can be more complicated if the release notes are too big
|
|
1035
|
-
* @param {ReleasePullRequest} releasePullRequest Pull request data to update
|
|
510
|
+
* @param {PullRequest} pullRequest Pull request data to update
|
|
1036
511
|
* @param {string} targetBranch The base branch of the pull request
|
|
1037
|
-
* @param {
|
|
512
|
+
* @param {string} message The commit message for the commit
|
|
513
|
+
* @param {Update[]} updates The files to update
|
|
514
|
+
* @param {CreatePullRequestOptions} options The pull request options
|
|
1038
515
|
* @throws {GitHubAPIError} on an API error
|
|
1039
516
|
*/
|
|
1040
|
-
async
|
|
517
|
+
async createPullRequest(pullRequest, targetBranch, message, updates, options) {
|
|
518
|
+
const changes = await this.buildChangeSet(updates, targetBranch);
|
|
519
|
+
const prNumber = await (0, code_suggester_1.createPullRequest)(this.octokit, changes, {
|
|
520
|
+
upstreamOwner: this.repository.owner,
|
|
521
|
+
upstreamRepo: this.repository.repo,
|
|
522
|
+
title: pullRequest.title,
|
|
523
|
+
branch: pullRequest.headBranchName,
|
|
524
|
+
description: pullRequest.body,
|
|
525
|
+
primary: targetBranch,
|
|
526
|
+
force: true,
|
|
527
|
+
fork: !!(options === null || options === void 0 ? void 0 : options.fork),
|
|
528
|
+
message,
|
|
529
|
+
logger: this.logger,
|
|
530
|
+
draft: !!(options === null || options === void 0 ? void 0 : options.draft),
|
|
531
|
+
labels: pullRequest.labels,
|
|
532
|
+
});
|
|
533
|
+
if (prNumber === 0) {
|
|
534
|
+
this.logger.warn('no code changes detected, skipping pull request creation');
|
|
535
|
+
return {
|
|
536
|
+
headBranchName: pullRequest.headBranchName,
|
|
537
|
+
baseBranchName: targetBranch,
|
|
538
|
+
number: 0,
|
|
539
|
+
title: pullRequest.title,
|
|
540
|
+
body: pullRequest.body,
|
|
541
|
+
labels: pullRequest.labels,
|
|
542
|
+
files: [],
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
return await this.getPullRequest(prNumber);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Fetch a pull request given the pull number
|
|
549
|
+
* @param {number} number The pull request number
|
|
550
|
+
* @returns {PullRequest}
|
|
551
|
+
*/
|
|
552
|
+
async getPullRequest(number) {
|
|
553
|
+
return await this.gitHubApi.getPullRequest(number);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Update a pull request's title and body.
|
|
557
|
+
* @param {number} number The pull request number
|
|
558
|
+
* @param {ReleasePullRequest} releasePullRequest Pull request data to update
|
|
559
|
+
* @param {string} targetBranch The target branch of the pull request
|
|
560
|
+
* @param {string} options.signoffUser Optional. Commit signoff message
|
|
561
|
+
* @param {boolean} options.fork Optional. Whether to open the pull request from
|
|
562
|
+
* a fork or not. Defaults to `false`
|
|
563
|
+
* @param {PullRequestOverflowHandler} options.pullRequestOverflowHandler Optional.
|
|
564
|
+
* Handles extra large pull request body messages.
|
|
565
|
+
*/
|
|
566
|
+
async updatePullRequest(number, releasePullRequest, targetBranch, options) {
|
|
567
|
+
const changes = await this.buildChangeSet(releasePullRequest.updates, targetBranch);
|
|
1041
568
|
let message = releasePullRequest.title.toString();
|
|
1042
569
|
if (options === null || options === void 0 ? void 0 : options.signoffUser) {
|
|
1043
570
|
message = (0, signoff_commit_message_1.signoffCommitMessage)(message, options.signoffUser);
|
|
1044
571
|
}
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
572
|
+
const title = releasePullRequest.title.toString();
|
|
573
|
+
const body = ((options === null || options === void 0 ? void 0 : options.pullRequestOverflowHandler)
|
|
574
|
+
? await options.pullRequestOverflowHandler.handleOverflow(releasePullRequest)
|
|
575
|
+
: releasePullRequest.body)
|
|
576
|
+
.toString()
|
|
577
|
+
.slice(0, MAX_ISSUE_BODY_SIZE);
|
|
578
|
+
const prNumber = await (0, code_suggester_1.createPullRequest)(this.octokit, changes, {
|
|
579
|
+
upstreamOwner: this.repository.owner,
|
|
580
|
+
upstreamRepo: this.repository.repo,
|
|
581
|
+
title,
|
|
582
|
+
branch: releasePullRequest.headRefName,
|
|
583
|
+
description: body,
|
|
584
|
+
primary: targetBranch,
|
|
585
|
+
force: true,
|
|
586
|
+
fork: (options === null || options === void 0 ? void 0 : options.fork) === false ? false : true,
|
|
587
|
+
message,
|
|
588
|
+
logger: this.logger,
|
|
1058
589
|
draft: releasePullRequest.draft,
|
|
1059
590
|
});
|
|
591
|
+
if (prNumber !== number) {
|
|
592
|
+
this.logger.warn(`updated code for ${prNumber}, but update requested for ${number}`);
|
|
593
|
+
}
|
|
594
|
+
return this.gitHubApi.updatePullRequest(number, title, body);
|
|
1060
595
|
}
|
|
1061
596
|
/**
|
|
1062
597
|
* Given a set of proposed updates, build a changeset to suggest.
|
|
@@ -1117,6 +652,45 @@ class GitHub {
|
|
|
1117
652
|
async findFilesByExtension(extension, prefix) {
|
|
1118
653
|
return this.findFilesByExtensionAndRef(extension, this.repository.defaultBranch, prefix);
|
|
1119
654
|
}
|
|
655
|
+
/**
|
|
656
|
+
* Create a GitHub release
|
|
657
|
+
*
|
|
658
|
+
* @param {Release} release Release parameters
|
|
659
|
+
* @param {ReleaseOptions} options Release option parameters
|
|
660
|
+
* @throws {DuplicateReleaseError} if the release tag already exists
|
|
661
|
+
* @throws {GitHubAPIError} on other API errors
|
|
662
|
+
*/
|
|
663
|
+
async createRelease(release, options = {}) {
|
|
664
|
+
return await this.gitHubApi.createRelease(release, options);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Makes a comment on a issue/pull request.
|
|
668
|
+
*
|
|
669
|
+
* @param {string} comment - The body of the comment to post.
|
|
670
|
+
* @param {number} number - The issue or pull request number.
|
|
671
|
+
* @throws {GitHubAPIError} on an API error
|
|
672
|
+
*/
|
|
673
|
+
async commentOnIssue(comment, number) {
|
|
674
|
+
return await this.gitHubApi.commentOnIssue(comment, number);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Removes labels from an issue/pull request.
|
|
678
|
+
*
|
|
679
|
+
* @param {string[]} labels The labels to remove.
|
|
680
|
+
* @param {number} number The issue/pull request number.
|
|
681
|
+
*/
|
|
682
|
+
async removeIssueLabels(labels, number) {
|
|
683
|
+
return await this.gitHubApi.removeIssueLabels(labels, number);
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Adds label to an issue/pull request.
|
|
687
|
+
*
|
|
688
|
+
* @param {string[]} labels The labels to add.
|
|
689
|
+
* @param {number} number The issue/pull request number.
|
|
690
|
+
*/
|
|
691
|
+
async addIssueLabels(labels, number) {
|
|
692
|
+
return await this.gitHubApi.addIssueLabels(labels, number);
|
|
693
|
+
}
|
|
1120
694
|
/**
|
|
1121
695
|
* Generate release notes from GitHub at tag
|
|
1122
696
|
* @param {string} tagName Name of new release tag
|
|
@@ -1124,14 +698,7 @@ class GitHub {
|
|
|
1124
698
|
* @param {string} previousTag Optional. Name of previous tag to analyze commits since
|
|
1125
699
|
*/
|
|
1126
700
|
async generateReleaseNotes(tagName, targetCommitish, previousTag) {
|
|
1127
|
-
|
|
1128
|
-
owner: this.repository.owner,
|
|
1129
|
-
repo: this.repository.repo,
|
|
1130
|
-
tag_name: tagName,
|
|
1131
|
-
previous_tag_name: previousTag,
|
|
1132
|
-
target_commitish: targetCommitish,
|
|
1133
|
-
});
|
|
1134
|
-
return resp.data.body;
|
|
701
|
+
return await this.gitHubApi.generateReleaseNotes(tagName, targetCommitish, previousTag);
|
|
1135
702
|
}
|
|
1136
703
|
/**
|
|
1137
704
|
* Create a single file on a new branch based on an existing
|
|
@@ -1144,107 +711,7 @@ class GitHub {
|
|
|
1144
711
|
* @returns {string} HTML URL of the new file
|
|
1145
712
|
*/
|
|
1146
713
|
async createFileOnNewBranch(filename, contents, newBranchName, baseBranchName) {
|
|
1147
|
-
|
|
1148
|
-
await this.forkBranch(newBranchName, baseBranchName);
|
|
1149
|
-
// use the single file upload API
|
|
1150
|
-
const { data: { content }, } = await this.octokit.repos.createOrUpdateFileContents({
|
|
1151
|
-
owner: this.repository.owner,
|
|
1152
|
-
repo: this.repository.repo,
|
|
1153
|
-
path: filename,
|
|
1154
|
-
// contents need to be base64 encoded
|
|
1155
|
-
content: Buffer.from(contents, 'binary').toString('base64'),
|
|
1156
|
-
message: 'Saving release notes',
|
|
1157
|
-
branch: newBranchName,
|
|
1158
|
-
});
|
|
1159
|
-
if (!(content === null || content === void 0 ? void 0 : content.html_url)) {
|
|
1160
|
-
throw new Error(`Failed to write to file: ${filename} on branch: ${newBranchName}`);
|
|
1161
|
-
}
|
|
1162
|
-
return content.html_url;
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* Helper to fetch the SHA of a branch
|
|
1166
|
-
* @param {string} branchName The name of the branch
|
|
1167
|
-
* @return {string | undefined} Returns the SHA of the branch
|
|
1168
|
-
* or undefined if it can't be found.
|
|
1169
|
-
*/
|
|
1170
|
-
async getBranchSha(branchName) {
|
|
1171
|
-
this.logger.debug(`Looking up SHA for branch: ${branchName}`);
|
|
1172
|
-
try {
|
|
1173
|
-
const { data: { object: { sha }, }, } = await this.octokit.git.getRef({
|
|
1174
|
-
owner: this.repository.owner,
|
|
1175
|
-
repo: this.repository.repo,
|
|
1176
|
-
ref: `heads/${branchName}`,
|
|
1177
|
-
});
|
|
1178
|
-
this.logger.debug(`SHA for branch: ${sha}`);
|
|
1179
|
-
return sha;
|
|
1180
|
-
}
|
|
1181
|
-
catch (e) {
|
|
1182
|
-
if (e instanceof request_error_1.RequestError && e.status === 404) {
|
|
1183
|
-
this.logger.debug(`Branch: ${branchName} does not exist`);
|
|
1184
|
-
return undefined;
|
|
1185
|
-
}
|
|
1186
|
-
throw e;
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
/**
|
|
1190
|
-
* Helper to fork a branch from an existing branch. Uses `force` so
|
|
1191
|
-
* it will overwrite the contents of `targetBranchName` to match
|
|
1192
|
-
* the current contents of `baseBranchName`.
|
|
1193
|
-
*
|
|
1194
|
-
* @param {string} targetBranchName The name of the new forked branch
|
|
1195
|
-
* @param {string} baseBranchName The base branch from which to fork.
|
|
1196
|
-
* @returns {string} The branch SHA
|
|
1197
|
-
* @throws {ConfigurationError} if the base branch cannot be found.
|
|
1198
|
-
*/
|
|
1199
|
-
async forkBranch(targetBranchName, baseBranchName) {
|
|
1200
|
-
const baseBranchSha = await this.getBranchSha(baseBranchName);
|
|
1201
|
-
if (!baseBranchSha) {
|
|
1202
|
-
// this is highly unlikely to be thrown as we will have
|
|
1203
|
-
// already attempted to read from the branch
|
|
1204
|
-
throw new errors_1.ConfigurationError(`Unable to find base branch: ${baseBranchName}`, 'core', `${this.repository.owner}/${this.repository.repo}`);
|
|
1205
|
-
}
|
|
1206
|
-
// see if newBranchName exists
|
|
1207
|
-
if (await this.getBranchSha(targetBranchName)) {
|
|
1208
|
-
// branch already exists, update it to the match the base branch
|
|
1209
|
-
const branchSha = await this.updateBranchSha(targetBranchName, baseBranchSha);
|
|
1210
|
-
this.logger.debug(`Updated ${targetBranchName} to match ${baseBranchName} at ${branchSha}`);
|
|
1211
|
-
return branchSha;
|
|
1212
|
-
}
|
|
1213
|
-
else {
|
|
1214
|
-
// branch does not exist, create a new branch from the base branch
|
|
1215
|
-
const branchSha = await this.createNewBranch(targetBranchName, baseBranchSha);
|
|
1216
|
-
this.logger.debug(`Forked ${targetBranchName} from ${baseBranchName} at ${branchSha}`);
|
|
1217
|
-
return branchSha;
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Helper to create a new branch from a given SHA.
|
|
1222
|
-
* @param {string} branchName The new branch name
|
|
1223
|
-
* @param {string} branchSha The SHA of the branch
|
|
1224
|
-
* @returns {string} The SHA of the new branch
|
|
1225
|
-
*/
|
|
1226
|
-
async createNewBranch(branchName, branchSha) {
|
|
1227
|
-
this.logger.debug(`Creating new branch: ${branchName} at ${branchSha}`);
|
|
1228
|
-
const { data: { object: { sha }, }, } = await this.octokit.git.createRef({
|
|
1229
|
-
owner: this.repository.owner,
|
|
1230
|
-
repo: this.repository.repo,
|
|
1231
|
-
ref: `refs/heads/${branchName}`,
|
|
1232
|
-
sha: branchSha,
|
|
1233
|
-
});
|
|
1234
|
-
this.logger.debug(`New branch: ${branchName} at ${sha}`);
|
|
1235
|
-
return sha;
|
|
1236
|
-
}
|
|
1237
|
-
async updateBranchSha(branchName, branchSha) {
|
|
1238
|
-
this.logger.debug(`Updating branch ${branchName} to ${branchSha}`);
|
|
1239
|
-
const { data: { object: { sha }, }, } = await this.octokit.git.updateRef({
|
|
1240
|
-
owner: this.repository.owner,
|
|
1241
|
-
repo: this.repository.repo,
|
|
1242
|
-
ref: `heads/${branchName}`,
|
|
1243
|
-
sha: branchSha,
|
|
1244
|
-
force: true,
|
|
1245
|
-
});
|
|
1246
|
-
this.logger.debug(`Updated branch: ${branchName} to ${sha}`);
|
|
1247
|
-
return sha;
|
|
714
|
+
return await this.gitHubApi.createFileOnNewBranch(filename, contents, newBranchName, baseBranchName);
|
|
1248
715
|
}
|
|
1249
716
|
}
|
|
1250
717
|
exports.GitHub = GitHub;
|