-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathapi.ts
More file actions
126 lines (115 loc) · 3.61 KB
/
api.ts
File metadata and controls
126 lines (115 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { APIError } from "@stainless-api/github-internal/core/error";
import { BaseCommits } from "@stainless-api/github-internal/resources/repos/commits";
import { BaseComments } from "@stainless-api/github-internal/resources/repos/issues/comments";
import { BasePulls } from "@stainless-api/github-internal/resources/repos/pulls";
import {
createClient,
type PartialGitHub,
} from "@stainless-api/github-internal/tree-shakable";
import { logger } from "../../logger";
import type { APIClient, Comment, PullRequest } from "../api";
import { getInput } from "../input";
import { getGitHubContext as ctx } from "./context";
class GitHubClient implements APIClient {
private client: PartialGitHub<{
repos: {
commits: BaseCommits;
issues: { comments: BaseComments };
pulls: BasePulls;
};
}>;
constructor(token: string) {
this.client = createClient({
authToken: token,
baseURL: ctx().urls.api,
owner: ctx().owner,
repo: ctx().repo,
resources: [BaseCommits, BaseComments, BasePulls],
logLevel: "warn",
logger,
});
}
async listComments(prNumber: number): Promise<Comment[]> {
const { data } = await this.client.repos.issues.comments.list(prNumber);
return data.map((c) => ({ id: c.id, body: c.body ?? "" }));
}
async createComment(
prNumber: number,
props: Omit<Comment, "id">,
): Promise<Comment> {
const data = await this.client.repos.issues.comments.create(
prNumber,
props,
);
return { id: data.id, body: data.body! };
}
async updateComment(
_prNumber: number,
{ id, body }: Comment,
): Promise<Comment> {
const data = await this.client.repos.issues.comments.update(id as number, {
body,
});
return { id: data.id, body: data.body! };
}
async getPullRequest(number: number): Promise<PullRequest | null> {
const data = await this.client.repos.pulls.retrieve(number);
return {
number,
state: data.merged_at ? "merged" : (data.state as "open" | "closed"),
title: data.title,
base_sha: data.base.sha,
base_ref: data.base.ref,
head_ref: data.head.ref,
head_sha: data.head.sha,
merge_commit_sha: data.merge_commit_sha,
};
}
async getPullRequestForCommit(sha: string): Promise<PullRequest | null> {
const pullRequests = await this.client.repos.commits
.listPullRequests(sha)
.then(({ data }) =>
data.filter((c) => c.merged_at || c.state !== "closed"),
)
.catch((err) => {
if (err instanceof APIError && err.status === 404) {
return [];
}
throw err;
});
if (pullRequests.length === 0) {
return null;
}
if (pullRequests.length > 1) {
logger.warn(
`Multiple pull requests found for commit; only using first.`,
{ commit: sha, pulls: pullRequests.map((c) => c.number) },
);
}
const pull = pullRequests[0]!;
return {
number: pull.number,
state: pull.merged_at ? "merged" : (pull.state as "open" | "closed"),
title: pull.title,
base_sha: pull.base.sha,
base_ref: pull.base.ref,
head_ref: pull.head.ref,
head_sha: pull.head.sha,
merge_commit_sha: pull.merge_commit_sha,
};
}
}
let cachedClient: GitHubClient | null | undefined;
export function getGitHubClient(): GitHubClient | null {
if (cachedClient !== undefined) {
return cachedClient;
}
const token = getInput("github_token");
if (token) {
cachedClient = new GitHubClient(token);
} else {
logger.info("No GitHub token found via input 'github_token'.");
cachedClient = null;
}
return cachedClient;
}