UNPKG

29.1 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const graphql_1 = require("@octokit/graphql");
5const plugin_enterprise_compatibility_1 = require("@octokit/plugin-enterprise-compatibility");
6const path_1 = tslib_1.__importDefault(require("path"));
7const plugin_retry_1 = require("@octokit/plugin-retry");
8const plugin_throttling_1 = require("@octokit/plugin-throttling");
9const rest_1 = require("@octokit/rest");
10const gitlog_1 = require("gitlog");
11const tinycolor2_1 = tslib_1.__importDefault(require("tinycolor2"));
12const endent_1 = tslib_1.__importDefault(require("endent"));
13const await_to_js_1 = tslib_1.__importDefault(require("await-to-js"));
14const typescript_memoize_1 = require("typescript-memoize");
15const verify_auth_1 = tslib_1.__importDefault(require("./utils/verify-auth"));
16const exec_promise_1 = tslib_1.__importDefault(require("./utils/exec-promise"));
17const logger_1 = require("./utils/logger");
18const semver_1 = require("semver");
19const match_sha_to_pr_1 = require("./match-sha-to-pr");
20/** An error originating from the GitHub */
21class GitAPIError extends Error {
22 /** Extend the base error */
23 constructor(api, args, origError) {
24 super(`Error calling github: ${api}\n\twith: ${JSON.stringify(args)}.\n\t${origError.message}`);
25 }
26}
27const taggedPackageRegex = /(\S+)@(\S+)/;
28/**
29 * Extract a version from a tag.
30 *
31 * Supports tags like:
32 *
33 * - 1.2.3
34 * - 1.2.3-beta.0
35 * - package@1.2.3-beta.0
36 * - @scope/package@1.2.3-beta.0
37 */
38function getVersionFromTag(tag) {
39 if (taggedPackageRegex.test(tag)) {
40 const [, , version] = tag.match(taggedPackageRegex);
41 return version;
42 }
43 return tag;
44}
45/** Make a comment to build automation in PRs off of. */
46const makeIdentifier = (type, context) => `<!-- GITHUB_RELEASE ${type}: ${context} -->`;
47/** Make an identifier for `auto comment` */
48const makeCommentIdentifier = (context) => makeIdentifier("COMMENT", context);
49/** Make an identifier for `auto pr-body` */
50const makePrBodyIdentifier = (context) => makeIdentifier("PR BODY", context);
51/**
52 * A class to interact with the local git instance and the git remote.
53 * currently it only interfaces with GitHub.
54 */
55class Git {
56 /** Initialize the git interface and auth with GitHub */
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 // does not retry, only logs an error
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 /** Verify the write access authorization to remote repository with push dry-run. */
94 async verifyAuth(url) {
95 return verify_auth_1.default(url, this.options.baseBranch);
96 }
97 /** Get the "Latest Release" from GitHub */
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 /** Get the "Latest Release" or the first commit SHA as a fallback */
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 /** Get the date a commit sha was created */
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 /** Get the first commit for the repo */
128 async getFirstCommit() {
129 const list = await exec_promise_1.default("git", ["rev-list", "HEAD"]);
130 return list.split("\n").pop();
131 }
132 /** Get the SHA of the latest commit */
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 /** Get the SHA of the latest commit */
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 /** Get the labels for a PR */
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 /** Get all the information about a PR or issue */
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 /** Get information about specific commit */
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 /** Get the labels for a the project */
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 /** Get the git log for a range of commits */
223 async getGitLog(start, end = "HEAD") {
224 try {
225 const first = await this.getFirstCommit();
226 // This "shaExists" is just so we don't have to refactor all the tests
227 // in auto.test.ts. If the SHA doesn't really exist then the call to
228 // gitlog will fail too.
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 // If start === firstCommit then we want to include that commit in the changelog
237 // Otherwise it was that last release and should not be included in the release.
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 // The -m option will list a commit for each merge parent. This
252 // means two items will have the same hash. We are using -m to get all the changed files
253 // in a merge commit. The following code combines these repeated hashes into
254 // one commit
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 /** Get the GitHub user for an email. Will not work if they do not have their email set to "public". */
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 /** Get collaborator permission level to the repo. */
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 /** Get the GitHub user for a username */
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 /** Get all the information about a PR or issue */
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 /** Search to GitHub project's issue and pull requests */
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 /** Run a graphql query on the GitHub project */
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 /** Create a status (or checkmark) on a commit */
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 /** Add a label to the project */
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 /** Update a label on the project */
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 /** Add a label to and issue or pull request */
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 /** Add a label to and issue or pull request */
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 /** Lock an issue */
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 /** Get information about the GitHub project */
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 /** Get all the pull requests for a project */
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 /** Get all the commits for a PR */
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 /** Find a comment that is using the context in a PR */
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 /** Delete a comment on an issue or pull request */
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 /** Create a comment on an issue or pull request */
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 /** Edit a comment on an issue or pull request */
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 /** Create a comment on a pull request body */
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 /** Create a release for the GitHub projecct */
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 /** Get the latest tag in the git tree */
593 async getLatestTagInBranch(since) {
594 return exec_promise_1.default("git", ["describe", "--tags", "--abbrev=0", since]);
595 }
596 /** Get the tag before latest in the git tree */
597 async getPreviousTagInBranch() {
598 const latest = await this.getLatestTagInBranch();
599 return this.getLatestTagInBranch(`${latest}^1`);
600 }
601 /** Get all the tags for a given branch. */
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 /** Get the a tag that isn't in the base branch */
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 /** Get the last tag that isn't in the base branch */
636 async getLastTagNotInBaseBranch(branch) {
637 return this.getTagNotInBaseBranch(branch);
638 }
639 /** Determine the pull request for a commit hash */
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}
656tslib_1.__decorate([
657 typescript_memoize_1.Memoize()
658], Git.prototype, "getLatestReleaseInfo", null);
659tslib_1.__decorate([
660 typescript_memoize_1.Memoize()
661], Git.prototype, "getLatestRelease", null);
662tslib_1.__decorate([
663 typescript_memoize_1.Memoize()
664], Git.prototype, "getLabels", null);
665tslib_1.__decorate([
666 typescript_memoize_1.Memoize()
667], Git.prototype, "getPr", null);
668tslib_1.__decorate([
669 typescript_memoize_1.Memoize()
670], Git.prototype, "getCommit", null);
671tslib_1.__decorate([
672 typescript_memoize_1.Memoize()
673], Git.prototype, "getGitLog", null);
674tslib_1.__decorate([
675 typescript_memoize_1.Memoize()
676], Git.prototype, "getUserByEmail", null);
677tslib_1.__decorate([
678 typescript_memoize_1.Memoize()
679], Git.prototype, "getTokenPermissionLevel", null);
680tslib_1.__decorate([
681 typescript_memoize_1.Memoize()
682], Git.prototype, "getUserByUsername", null);
683tslib_1.__decorate([
684 typescript_memoize_1.Memoize()
685], Git.prototype, "getPullRequest", null);
686tslib_1.__decorate([
687 typescript_memoize_1.Memoize()
688], Git.prototype, "getProject", null);
689tslib_1.__decorate([
690 typescript_memoize_1.Memoize()
691], Git.prototype, "getCommitsForPR", null);
692exports.default = Git;
693//# sourceMappingURL=git.js.map
\No newline at end of file