1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const graphql_1 = require("@octokit/graphql");
|
5 | const plugin_enterprise_compatibility_1 = require("@octokit/plugin-enterprise-compatibility");
|
6 | const path_1 = tslib_1.__importDefault(require("path"));
|
7 | const plugin_retry_1 = require("@octokit/plugin-retry");
|
8 | const plugin_throttling_1 = require("@octokit/plugin-throttling");
|
9 | const rest_1 = require("@octokit/rest");
|
10 | const gitlog_1 = require("gitlog");
|
11 | const tinycolor2_1 = tslib_1.__importDefault(require("tinycolor2"));
|
12 | const endent_1 = tslib_1.__importDefault(require("endent"));
|
13 | const await_to_js_1 = tslib_1.__importDefault(require("await-to-js"));
|
14 | const typescript_memoize_1 = require("typescript-memoize");
|
15 | const verify_auth_1 = tslib_1.__importDefault(require("./utils/verify-auth"));
|
16 | const exec_promise_1 = tslib_1.__importDefault(require("./utils/exec-promise"));
|
17 | const logger_1 = require("./utils/logger");
|
18 | const semver_1 = require("semver");
|
19 | const match_sha_to_pr_1 = require("./match-sha-to-pr");
|
20 |
|
21 | class GitAPIError extends Error {
|
22 |
|
23 | constructor(api, args, origError) {
|
24 | super(`Error calling github: ${api}\n\twith: ${JSON.stringify(args)}.\n\t${origError.message}`);
|
25 | }
|
26 | }
|
27 | const taggedPackageRegex = /(\S+)@(\S+)/;
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | function getVersionFromTag(tag) {
|
39 | if (taggedPackageRegex.test(tag)) {
|
40 | const [, , version] = tag.match(taggedPackageRegex);
|
41 | return version;
|
42 | }
|
43 | return tag;
|
44 | }
|
45 |
|
46 | const makeIdentifier = (type, context) => `<!-- GITHUB_RELEASE ${type}: ${context} -->`;
|
47 |
|
48 | const makeCommentIdentifier = (context) => makeIdentifier("COMMENT", context);
|
49 |
|
50 | const makePrBodyIdentifier = (context) => makeIdentifier("PR BODY", context);
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | class Git {
|
56 |
|
57 | constructor(options, logger = logger_1.dummyLog()) {
|
58 | this.logger = logger;
|
59 | this.options = options;
|
60 | this.baseUrl = this.options.baseUrl || "https://api.github.com";
|
61 | this.graphqlBaseUrl = this.options.graphqlBaseUrl || this.baseUrl;
|
62 | this.logger.veryVerbose.info(`Initializing GitHub with: ${this.baseUrl}`);
|
63 | const GitHub = rest_1.Octokit.plugin(plugin_enterprise_compatibility_1.enterpriseCompatibility)
|
64 | .plugin(plugin_retry_1.retry)
|
65 | .plugin(plugin_throttling_1.throttling);
|
66 | this.github = new GitHub({
|
67 | baseUrl: this.baseUrl,
|
68 | auth: this.options.token,
|
69 | previews: ["symmetra-preview"],
|
70 | request: { agent: this.options.agent },
|
71 | throttle: {
|
72 | onRateLimit: (retryAfter, opts) => {
|
73 | this.logger.log.warn(`Request quota exhausted for request ${opts.method} ${opts.url}`);
|
74 | if (opts.request.retryCount < 5) {
|
75 | this.logger.verbose.log(`Retrying after ${retryAfter} seconds!`);
|
76 | return true;
|
77 | }
|
78 | },
|
79 | onAbuseLimit: (_, opts) => {
|
80 |
|
81 | this.logger.log.error(`Went over abuse rate limit ${opts.method} ${opts.url}`);
|
82 | },
|
83 | },
|
84 | });
|
85 | this.github.hook.error("request", (error) => {
|
86 | var _a;
|
87 | if ((_a = error === null || error === void 0 ? void 0 : error.headers) === null || _a === void 0 ? void 0 : _a.authorization) {
|
88 | delete error.headers.authorization;
|
89 | }
|
90 | throw error;
|
91 | });
|
92 | }
|
93 |
|
94 | async verifyAuth(url) {
|
95 | return verify_auth_1.default(url, this.options.baseBranch);
|
96 | }
|
97 |
|
98 | async getLatestReleaseInfo() {
|
99 | const latestRelease = await this.github.repos.getLatestRelease({
|
100 | owner: this.options.owner,
|
101 | repo: this.options.repo,
|
102 | });
|
103 | return latestRelease.data;
|
104 | }
|
105 |
|
106 | async getLatestRelease() {
|
107 | try {
|
108 | const latestRelease = await this.getLatestReleaseInfo();
|
109 | this.logger.veryVerbose.info('Got response for "getLatestRelease":\n', latestRelease);
|
110 | this.logger.verbose.info("Got latest release:\n", latestRelease);
|
111 | return latestRelease.tag_name;
|
112 | }
|
113 | catch (e) {
|
114 | if (e.status === 404) {
|
115 | this.logger.verbose.info("Couldn't find latest release on GitHub, using first commit.");
|
116 | return this.getFirstCommit();
|
117 | }
|
118 | throw e;
|
119 | }
|
120 | }
|
121 |
|
122 | async getCommitDate(sha) {
|
123 | const date = await exec_promise_1.default("git", ["show", "-s", "--format=%ci", sha]);
|
124 | const [day, time, timezone] = date.split(" ");
|
125 | return `${day}T${time}${timezone}`;
|
126 | }
|
127 |
|
128 | async getFirstCommit() {
|
129 | const list = await exec_promise_1.default("git", ["rev-list", "HEAD"]);
|
130 | return list.split("\n").pop();
|
131 | }
|
132 |
|
133 | async getSha(short) {
|
134 | const result = await exec_promise_1.default("git", [
|
135 | "rev-parse",
|
136 | short && "--short",
|
137 | "HEAD",
|
138 | ]);
|
139 | this.logger.verbose.info(`Got commit SHA from HEAD: ${result}`);
|
140 | return result;
|
141 | }
|
142 |
|
143 | async shaExists(sha) {
|
144 | try {
|
145 | await exec_promise_1.default("git", ["rev-parse", "--verify", sha]);
|
146 | return true;
|
147 | }
|
148 | catch (error) {
|
149 | return false;
|
150 | }
|
151 | }
|
152 |
|
153 | async getLabels(prNumber) {
|
154 | this.logger.verbose.info(`Getting labels for PR: ${prNumber}`);
|
155 | const args = {
|
156 | owner: this.options.owner,
|
157 | repo: this.options.repo,
|
158 | issue_number: prNumber,
|
159 | };
|
160 | this.logger.verbose.info("Getting issue labels using:", args);
|
161 | try {
|
162 | const labels = await this.github.issues.listLabelsOnIssue(args);
|
163 | this.logger.veryVerbose.info('Got response for "listLabelsOnIssue":\n', labels);
|
164 | this.logger.verbose.info("Found labels on PR:\n", labels.data);
|
165 | return labels.data.map((l) => l.name);
|
166 | }
|
167 | catch (e) {
|
168 | throw new GitAPIError("listLabelsOnIssue", args, e);
|
169 | }
|
170 | }
|
171 |
|
172 | async getPr(prNumber) {
|
173 | this.logger.verbose.info(`Getting info for PR: ${prNumber}`);
|
174 | const args = {
|
175 | owner: this.options.owner,
|
176 | repo: this.options.repo,
|
177 | issue_number: prNumber,
|
178 | };
|
179 | this.logger.verbose.info("Getting issue info using:", args);
|
180 | try {
|
181 | const info = await this.github.issues.get(args);
|
182 | this.logger.veryVerbose.info('Got response for "issues.get":\n', info);
|
183 | return info;
|
184 | }
|
185 | catch (e) {
|
186 | throw new GitAPIError("getPr", args, e);
|
187 | }
|
188 | }
|
189 |
|
190 | async getCommit(sha) {
|
191 | this.logger.verbose.info(`Getting info for commit: ${sha}`);
|
192 | try {
|
193 | const info = await this.github.repos.getCommit({
|
194 | owner: this.options.owner,
|
195 | repo: this.options.repo,
|
196 | ref: sha,
|
197 | });
|
198 | this.logger.veryVerbose.info('Got response for "repos.getCommit":\n', info);
|
199 | return info;
|
200 | }
|
201 | catch (e) {
|
202 | throw new GitAPIError("getCommit", [], e);
|
203 | }
|
204 | }
|
205 |
|
206 | async getProjectLabels() {
|
207 | this.logger.verbose.info(`Getting labels for project: ${this.options.repo}`);
|
208 | const args = {
|
209 | owner: this.options.owner,
|
210 | repo: this.options.repo,
|
211 | };
|
212 | try {
|
213 | const labels = await this.github.paginate(this.github.issues.listLabelsForRepo, args);
|
214 | this.logger.veryVerbose.info('Got response for "getProjectLabels":\n', labels);
|
215 | this.logger.verbose.info("Found labels on project:\n", labels);
|
216 | return labels.map((l) => l.name);
|
217 | }
|
218 | catch (e) {
|
219 | throw new GitAPIError("getProjectLabels", args, e);
|
220 | }
|
221 | }
|
222 |
|
223 | async getGitLog(start, end = "HEAD") {
|
224 | try {
|
225 | const first = await this.getFirstCommit();
|
226 |
|
227 |
|
228 |
|
229 | const startSha = (await this.shaExists(start))
|
230 | ? await exec_promise_1.default("git", ["rev-parse", start])
|
231 | : "";
|
232 | const log = await gitlog_1.gitlogPromise({
|
233 | repo: process.cwd(),
|
234 | number: Number.MAX_SAFE_INTEGER,
|
235 | fields: ["hash", "authorName", "authorEmail", "rawBody"],
|
236 |
|
237 |
|
238 | branch: first === startSha ? end : `${start.trim()}..${end.trim()}`,
|
239 | execOptions: { maxBuffer: Infinity },
|
240 | includeMergeCommitFiles: true,
|
241 | });
|
242 | return log
|
243 | .map((commit) => ({
|
244 | hash: commit.hash,
|
245 | authorName: commit.authorName,
|
246 | authorEmail: commit.authorEmail,
|
247 | subject: commit.rawBody,
|
248 | files: (commit.files || []).map((file) => path_1.default.resolve(file)),
|
249 | }))
|
250 | .reduce((all, commit) => {
|
251 |
|
252 |
|
253 |
|
254 |
|
255 | const current = all.find((c) => c.hash === commit.hash);
|
256 | if (current) {
|
257 | current.files = [...current.files, ...commit.files];
|
258 | }
|
259 | else {
|
260 | all.push(commit);
|
261 | }
|
262 | return all;
|
263 | }, []);
|
264 | }
|
265 | catch (error) {
|
266 | console.log(error);
|
267 | const tag = error.match(/ambiguous argument '(\S+)\.\.\S+'/);
|
268 | if (tag) {
|
269 | this.logger.log.error(endent_1.default `
|
270 | Missing tag "${tag[1]}" so the command could not run.
|
271 |
|
272 | To fix this run the following command:
|
273 |
|
274 | git fetch --tags\n
|
275 | `);
|
276 | process.exit(1);
|
277 | }
|
278 | throw new Error(error);
|
279 | }
|
280 | }
|
281 |
|
282 | async getUserByEmail(email) {
|
283 | try {
|
284 | const search = (await this.github.search.users({
|
285 | q: `in:email ${email}`,
|
286 | })).data;
|
287 | return (search === null || search === void 0 ? void 0 : search.items.length) > 0 ? search.items[0] : {};
|
288 | }
|
289 | catch (error) {
|
290 | this.logger.verbose.warn(`Could not find user by email: ${email}`);
|
291 | }
|
292 | }
|
293 |
|
294 | async getTokenPermissionLevel() {
|
295 | const [, user] = await await_to_js_1.default(this.github.users.getAuthenticated());
|
296 | if (!user) {
|
297 | return {
|
298 | permission: "none",
|
299 | };
|
300 | }
|
301 | try {
|
302 | const { permission } = (await this.github.repos.getCollaboratorPermissionLevel({
|
303 | owner: this.options.owner,
|
304 | repo: this.options.repo,
|
305 | username: user.data.login,
|
306 | })).data;
|
307 | return { permission, user: user.data };
|
308 | }
|
309 | catch (error) {
|
310 | this.logger.verbose.error(`Could not get permissions for token`);
|
311 | return { permission: "read", user: user.data };
|
312 | }
|
313 | }
|
314 |
|
315 | async getUserByUsername(username) {
|
316 | try {
|
317 | const user = await this.github.users.getByUsername({
|
318 | username,
|
319 | });
|
320 | return user.data;
|
321 | }
|
322 | catch (error) {
|
323 | this.logger.verbose.warn(`Could not find user by username: ${username}`);
|
324 | }
|
325 | }
|
326 |
|
327 | async getPullRequest(pr) {
|
328 | this.logger.verbose.info(`Getting Pull Request: ${pr}`);
|
329 | const args = {
|
330 | owner: this.options.owner,
|
331 | repo: this.options.repo,
|
332 | pull_number: pr,
|
333 | };
|
334 | this.logger.verbose.info("Getting pull request info using:", args);
|
335 | const result = await this.github.pulls.get(args);
|
336 | this.logger.veryVerbose.info("Got pull request data\n", result);
|
337 | this.logger.verbose.info("Got pull request info");
|
338 | return result;
|
339 | }
|
340 |
|
341 | async searchRepo(options) {
|
342 | const repo = `repo:${this.options.owner}/${this.options.repo}`;
|
343 | options.q = `${repo} ${options.q}`;
|
344 | this.logger.verbose.info("Searching repo using:\n", options);
|
345 | const result = await this.github.search.issuesAndPullRequests(options);
|
346 | this.logger.veryVerbose.info("Got response from search\n", result);
|
347 | this.logger.verbose.info("Searched repo on GitHub.");
|
348 | return result.data;
|
349 | }
|
350 |
|
351 | async graphql(query) {
|
352 | this.logger.verbose.info("Querying Github using GraphQL:\n", query);
|
353 | const data = await graphql_1.graphql(query, {
|
354 | baseUrl: this.graphqlBaseUrl,
|
355 | request: { agent: this.options.agent },
|
356 | headers: {
|
357 | authorization: `token ${this.options.token}`,
|
358 | },
|
359 | });
|
360 | this.logger.veryVerbose.info("Got response from query\n", data);
|
361 | return data;
|
362 | }
|
363 |
|
364 | async createStatus(prInfo) {
|
365 | const args = Object.assign(Object.assign({}, prInfo), { owner: this.options.owner, repo: this.options.repo });
|
366 | this.logger.verbose.info("Creating status using:\n", args);
|
367 | const result = await this.github.repos.createStatus(args);
|
368 | this.logger.veryVerbose.info("Got response from createStatues\n", result);
|
369 | this.logger.verbose.info("Created status on GitHub.");
|
370 | return result;
|
371 | }
|
372 |
|
373 | async createLabel(label) {
|
374 | this.logger.verbose.info(`Creating "${label.releaseType || "general"}" label :\n${label.name}`);
|
375 | const color = label.color
|
376 | ? tinycolor2_1.default(label.color).toString("hex6")
|
377 | : tinycolor2_1.default.random().toString("hex6");
|
378 | const result = await this.github.issues.createLabel({
|
379 | name: label.name,
|
380 | owner: this.options.owner,
|
381 | repo: this.options.repo,
|
382 | color: color.replace("#", ""),
|
383 | description: label.description,
|
384 | });
|
385 | this.logger.veryVerbose.info("Got response from createLabel\n", result);
|
386 | this.logger.verbose.info("Created label on GitHub.");
|
387 | return result;
|
388 | }
|
389 |
|
390 | async updateLabel(label) {
|
391 | this.logger.verbose.info(`Updating "${label.releaseType || "generic"}" label :\n${label.name}`);
|
392 | const color = label.color
|
393 | ? tinycolor2_1.default(label.color).toString("hex6")
|
394 | : tinycolor2_1.default.random().toString("hex6");
|
395 | const result = await this.github.issues.updateLabel({
|
396 | current_name: label.name,
|
397 | name: label.name,
|
398 | owner: this.options.owner,
|
399 | repo: this.options.repo,
|
400 | color: color.replace("#", ""),
|
401 | description: label.description,
|
402 | });
|
403 | this.logger.veryVerbose.info("Got response from updateLabel\n", result);
|
404 | this.logger.verbose.info("Updated label on GitHub.");
|
405 | return result;
|
406 | }
|
407 |
|
408 | async addLabelToPr(pr, label) {
|
409 | this.logger.verbose.info(`Creating "${label}" label to PR ${pr}`);
|
410 | const result = await this.github.issues.addLabels({
|
411 | issue_number: pr,
|
412 | owner: this.options.owner,
|
413 | repo: this.options.repo,
|
414 | labels: [label],
|
415 | });
|
416 | this.logger.veryVerbose.info("Got response from addLabels\n", result);
|
417 | this.logger.verbose.info("Added labels on Pull Request.");
|
418 | return result;
|
419 | }
|
420 |
|
421 | async removeLabel(pr, label) {
|
422 | this.logger.verbose.info(`Removing "${label}" from #${pr}`);
|
423 | const result = await this.github.issues.removeLabel({
|
424 | issue_number: pr,
|
425 | owner: this.options.owner,
|
426 | repo: this.options.repo,
|
427 | name: label,
|
428 | });
|
429 | this.logger.veryVerbose.info("Got response from removeLabel\n", result);
|
430 | this.logger.verbose.info("Removed label on Pull Request.");
|
431 | return result;
|
432 | }
|
433 |
|
434 | async lockIssue(issue) {
|
435 | this.logger.verbose.info(`Locking #${issue} issue...`);
|
436 | const result = await this.github.issues.lock({
|
437 | issue_number: issue,
|
438 | owner: this.options.owner,
|
439 | repo: this.options.repo,
|
440 | });
|
441 | this.logger.veryVerbose.info("Got response from lock\n", result);
|
442 | this.logger.verbose.info("Locked issue.");
|
443 | return result;
|
444 | }
|
445 |
|
446 | async getProject() {
|
447 | this.logger.verbose.info("Getting project from GitHub");
|
448 | const result = (await this.github.repos.get({
|
449 | owner: this.options.owner,
|
450 | repo: this.options.repo,
|
451 | })).data;
|
452 | this.logger.veryVerbose.info("Got response from repos\n", result);
|
453 | this.logger.verbose.info("Got project information.");
|
454 | return result;
|
455 | }
|
456 |
|
457 | async getPullRequests(options) {
|
458 | this.logger.verbose.info("Getting pull requests...");
|
459 | const result = (await this.github.pulls.list(Object.assign({ owner: this.options.owner.toLowerCase(), repo: this.options.repo.toLowerCase() }, options))).data;
|
460 | this.logger.veryVerbose.info("Got response from pull requests", result);
|
461 | this.logger.verbose.info("Got pull request");
|
462 | return result;
|
463 | }
|
464 |
|
465 | async getCommitsForPR(pr) {
|
466 | this.logger.verbose.info(`Getting commits for PR #${pr}`);
|
467 | const result = await this.github.paginate(this.github.pulls.listCommits, {
|
468 | owner: this.options.owner.toLowerCase(),
|
469 | repo: this.options.repo.toLowerCase(),
|
470 | pull_number: pr,
|
471 | });
|
472 | this.logger.veryVerbose.info(`Got response from PR #${pr}\n`, result);
|
473 | this.logger.verbose.info(`Got commits for PR #${pr}.`);
|
474 | return result;
|
475 | }
|
476 |
|
477 | async getCommentId(pr, context = "default") {
|
478 | const commentIdentifier = makeCommentIdentifier(context);
|
479 | this.logger.verbose.info("Getting previous comments on:", pr);
|
480 | const comments = await this.github.issues.listComments({
|
481 | owner: this.options.owner,
|
482 | repo: this.options.repo,
|
483 | issue_number: pr,
|
484 | });
|
485 | this.logger.veryVerbose.info("Got PR comments\n", comments);
|
486 | const oldMessage = comments.data.find((comment) => comment.body.includes(commentIdentifier));
|
487 | if (!oldMessage) {
|
488 | return -1;
|
489 | }
|
490 | this.logger.verbose.info("Found previous message from same scope.");
|
491 | return oldMessage.id;
|
492 | }
|
493 |
|
494 | async deleteComment(pr, context = "default") {
|
495 | const commentId = await this.getCommentId(pr, context);
|
496 | if (commentId === -1) {
|
497 | return;
|
498 | }
|
499 | this.logger.verbose.info(`Deleting comment: ${commentId}`);
|
500 | await this.github.issues.deleteComment({
|
501 | owner: this.options.owner,
|
502 | repo: this.options.repo,
|
503 | comment_id: commentId,
|
504 | });
|
505 | this.logger.verbose.info(`Successfully deleted comment: ${commentId}`);
|
506 | }
|
507 |
|
508 | async createComment(message, pr, context = "default") {
|
509 | const commentIdentifier = makeCommentIdentifier(context);
|
510 | this.logger.verbose.info("Using comment identifier:", commentIdentifier);
|
511 | await this.deleteComment(pr, context);
|
512 | this.logger.verbose.info("Creating new comment");
|
513 | const result = await this.github.issues.createComment({
|
514 | owner: this.options.owner,
|
515 | repo: this.options.repo,
|
516 | issue_number: pr,
|
517 | body: `${commentIdentifier}\n${message}`,
|
518 | });
|
519 | this.logger.veryVerbose.info("Got response from creating comment\n", result);
|
520 | this.logger.verbose.info("Successfully posted comment to PR");
|
521 | return result;
|
522 | }
|
523 |
|
524 | async editComment(message, pr, context = "default") {
|
525 | const commentIdentifier = makeCommentIdentifier(context);
|
526 | this.logger.verbose.info("Using comment identifier:", commentIdentifier);
|
527 | const commentId = await this.getCommentId(pr, context);
|
528 | if (commentId === -1) {
|
529 | return this.createComment(message, pr, context);
|
530 | }
|
531 | this.logger.verbose.info("Editing comment");
|
532 | const result = await this.github.issues.updateComment({
|
533 | owner: this.options.owner,
|
534 | repo: this.options.repo,
|
535 | comment_id: commentId,
|
536 | body: `${commentIdentifier}\n${message}`,
|
537 | });
|
538 | this.logger.veryVerbose.info("Got response from editing comment\n", result);
|
539 | this.logger.verbose.info("Successfully edited comment on PR");
|
540 | return result;
|
541 | }
|
542 |
|
543 | async addToPrBody(message, pr, context = "default") {
|
544 | const id = makePrBodyIdentifier(context);
|
545 | this.logger.verbose.info("Using PR body identifier:", id);
|
546 | this.logger.verbose.info("Getting previous pr body on:", pr);
|
547 | const issue = await this.github.issues.get({
|
548 | owner: this.options.owner,
|
549 | repo: this.options.repo,
|
550 | issue_number: pr,
|
551 | });
|
552 | this.logger.veryVerbose.info("Got PR description\n", issue.data.body);
|
553 | const regex = new RegExp(`(${id})\\s*([\\S\\s]*)\\s*(${id})`);
|
554 | let body = issue.data.body;
|
555 | if (!body) {
|
556 | body = message ? `\n${id}\n${message}\n${id}\n` : "";
|
557 | }
|
558 | else if (body.match(regex)) {
|
559 | this.logger.verbose.info("Found previous message from same scope.");
|
560 | this.logger.verbose.info("Replacing pr body comment");
|
561 | body = body.replace(regex, message ? `$1\n${message}\n$3` : "");
|
562 | }
|
563 | else {
|
564 | body += message ? `\n${id}\n${message}\n${id}\n` : "";
|
565 | }
|
566 | this.logger.verbose.info("Creating new pr body");
|
567 | const result = await this.github.issues.update({
|
568 | owner: this.options.owner,
|
569 | repo: this.options.repo,
|
570 | issue_number: pr,
|
571 | body,
|
572 | });
|
573 | this.logger.veryVerbose.info("Got response from updating body\n", result);
|
574 | this.logger.verbose.info(`Successfully updated body of PR #${pr}`);
|
575 | return result;
|
576 | }
|
577 |
|
578 | async publish(releaseNotes, tag, prerelease = false) {
|
579 | this.logger.verbose.info("Creating release on GitHub for tag:", tag);
|
580 | const result = await this.github.repos.createRelease({
|
581 | owner: this.options.owner,
|
582 | repo: this.options.repo,
|
583 | tag_name: tag,
|
584 | name: tag,
|
585 | body: releaseNotes,
|
586 | prerelease,
|
587 | });
|
588 | this.logger.veryVerbose.info("Got response from createRelease\n", result);
|
589 | this.logger.verbose.info("Created GitHub release.");
|
590 | return result;
|
591 | }
|
592 |
|
593 | async getLatestTagInBranch(since) {
|
594 | return exec_promise_1.default("git", ["describe", "--tags", "--abbrev=0", since]);
|
595 | }
|
596 |
|
597 | async getPreviousTagInBranch() {
|
598 | const latest = await this.getLatestTagInBranch();
|
599 | return this.getLatestTagInBranch(`${latest}^1`);
|
600 | }
|
601 |
|
602 | async getTags(branch) {
|
603 | const tags = await exec_promise_1.default("git", [
|
604 | "tag",
|
605 | "--sort='creatordate'",
|
606 | "--merged",
|
607 | branch,
|
608 | ]);
|
609 | return tags
|
610 | .split("\n")
|
611 | .map((tag) => tag.trim())
|
612 | .filter(Boolean);
|
613 | }
|
614 |
|
615 | async getTagNotInBaseBranch(branch, options = {}) {
|
616 | const baseTags = (await this.getTags(`origin/${this.options.baseBranch}`)).reverse();
|
617 | const branchTags = (await this.getTags(`heads/${branch}`)).reverse();
|
618 | const comparator = options.first ? semver_1.lt : semver_1.gt;
|
619 | let firstGreatestUnique;
|
620 | branchTags.forEach((tag) => {
|
621 | const tagVersion = getVersionFromTag(tag);
|
622 | const greatestVersion = firstGreatestUnique
|
623 | ? getVersionFromTag(firstGreatestUnique)
|
624 | : undefined;
|
625 | if (!baseTags.includes(tag) &&
|
626 | (!greatestVersion || comparator(tagVersion, greatestVersion))) {
|
627 | firstGreatestUnique = tag;
|
628 | }
|
629 | });
|
630 | this.logger.verbose.info("Tags found in base branch:", baseTags);
|
631 | this.logger.verbose.info("Tags found in branch:", branchTags);
|
632 | this.logger.verbose.info(`${options.first ? "First" : "Latest"} tag in branch:`, firstGreatestUnique || "Not Found");
|
633 | return firstGreatestUnique;
|
634 | }
|
635 |
|
636 | async getLastTagNotInBaseBranch(branch) {
|
637 | return this.getTagNotInBaseBranch(branch);
|
638 | }
|
639 |
|
640 | async matchCommitToPr(sha) {
|
641 | const query = match_sha_to_pr_1.buildSearchQuery(this.options.owner, this.options.repo, [
|
642 | sha,
|
643 | ]);
|
644 | if (!query) {
|
645 | return;
|
646 | }
|
647 | const key = `hash_${sha}`;
|
648 | const result = (await this.graphql(query));
|
649 | if (!result || !result[key] || !result[key].edges[0]) {
|
650 | return;
|
651 | }
|
652 | const pr = result[key].edges[0].node;
|
653 | return Object.assign(Object.assign({}, pr), { labels: pr.labels ? pr.labels.edges.map((edge) => edge.node.name) : [] });
|
654 | }
|
655 | }
|
656 | tslib_1.__decorate([
|
657 | typescript_memoize_1.Memoize()
|
658 | ], Git.prototype, "getLatestReleaseInfo", null);
|
659 | tslib_1.__decorate([
|
660 | typescript_memoize_1.Memoize()
|
661 | ], Git.prototype, "getLatestRelease", null);
|
662 | tslib_1.__decorate([
|
663 | typescript_memoize_1.Memoize()
|
664 | ], Git.prototype, "getLabels", null);
|
665 | tslib_1.__decorate([
|
666 | typescript_memoize_1.Memoize()
|
667 | ], Git.prototype, "getPr", null);
|
668 | tslib_1.__decorate([
|
669 | typescript_memoize_1.Memoize()
|
670 | ], Git.prototype, "getCommit", null);
|
671 | tslib_1.__decorate([
|
672 | typescript_memoize_1.Memoize()
|
673 | ], Git.prototype, "getGitLog", null);
|
674 | tslib_1.__decorate([
|
675 | typescript_memoize_1.Memoize()
|
676 | ], Git.prototype, "getUserByEmail", null);
|
677 | tslib_1.__decorate([
|
678 | typescript_memoize_1.Memoize()
|
679 | ], Git.prototype, "getTokenPermissionLevel", null);
|
680 | tslib_1.__decorate([
|
681 | typescript_memoize_1.Memoize()
|
682 | ], Git.prototype, "getUserByUsername", null);
|
683 | tslib_1.__decorate([
|
684 | typescript_memoize_1.Memoize()
|
685 | ], Git.prototype, "getPullRequest", null);
|
686 | tslib_1.__decorate([
|
687 | typescript_memoize_1.Memoize()
|
688 | ], Git.prototype, "getProject", null);
|
689 | tslib_1.__decorate([
|
690 | typescript_memoize_1.Memoize()
|
691 | ], Git.prototype, "getCommitsForPR", null);
|
692 | exports.default = Git;
|
693 |
|
\ | No newline at end of file |