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