Skip to content

Commit ba666ab

Browse files
committed
get everything to compile
1 parent 21e928f commit ba666ab

File tree

14 files changed

+193
-136
lines changed

14 files changed

+193
-136
lines changed

functions/.mocharc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"loader": "ts-node/esm",
3+
"extensions": ["ts"]
4+
}

functions/src/config.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,22 @@ export class BotConfig {
244244

245245
// Iterate through issue labels, see if one of the existing ones works
246246
// TODO(samstern): Deal with needs_triage separately
247-
const issueLabelNames: string[] = issue.labels.map((label) => {
248-
return label.name;
249-
});
247+
const issueLabelNames: (string | undefined)[] = issue.labels
248+
.filter((label) => {
249+
return label !== undefined;
250+
})
251+
.map((label) => {
252+
if (typeof label === "string") {
253+
return label;
254+
}
255+
return label.name;
256+
});
250257

251258
for (const key of issueLabelNames) {
259+
if (!key) {
260+
// After typescript 5.5 this check can be removed?
261+
continue;
262+
}
252263
const label_mapping = this.getRepoLabelConfig(org, name, key);
253264
if (label_mapping) {
254265
return {
@@ -274,7 +285,7 @@ export class BotConfig {
274285
const regex = new RegExp(labelInfo.regex);
275286

276287
// If the regex matches, choose the label and email then break out
277-
if (regex.test(issue.body)) {
288+
if (regex.test(issue.body ?? "")) {
278289
log.debug("Matched label: " + label, JSON.stringify(labelInfo));
279290
return {
280291
label,

functions/src/cron.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,12 @@ export class CronHandler {
173173
const actions: types.Action[] = [];
174174

175175
const number = issue.number;
176-
const labelNames = issue.labels.map((label) => label.name);
176+
const labelNames = issue.labels.map((label) => {
177+
if (typeof label === "string") {
178+
return label;
179+
}
180+
return label.name;
181+
});
177182

178183
const stateNeedsInfo = labelNames.includes(issueConfig.label_needs_info);
179184
const stateStale = labelNames.includes(issueConfig.label_stale);
@@ -214,7 +219,7 @@ export class CronHandler {
214219

215220
// When the issue was marked stale, the bot will have left a comment with certain metadata
216221
const markStaleComment = comments.find((comment) => {
217-
return comment.body.includes(EVT_MARK_STALE);
222+
return comment.body?.includes(EVT_MARK_STALE);
218223
});
219224

220225
if (stateStale && !markStaleComment) {
@@ -253,7 +258,7 @@ export class CronHandler {
253258
org,
254259
name,
255260
number,
256-
this.getCloseComment(issue.user.login),
261+
this.getCloseComment(issue.user?.login ?? "ghost"),
257262
false,
258263
`Comment after closing issue for being stale (comment at ${util.createdDate(
259264
markStaleComment!,
@@ -302,7 +307,7 @@ export class CronHandler {
302307
name,
303308
number,
304309
this.getMarkStaleComment(
305-
issue.user.login,
310+
issue.user?.login ?? "ghost",
306311
issueConfig.needs_info_days,
307312
issueConfig.stale_days,
308313
),

functions/src/github.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,13 @@ export class GitHubClient {
109109
repo: name,
110110
path: file,
111111
})
112-
.then(function (res) {
113-
// Content is encoded as base64, we need to decode it
114-
return new Buffer(res.data.content, "base64").toString();
112+
.then((res) => {
113+
if ("content" in res.data) {
114+
// Content is encoded as base64, we need to decode it
115+
return Buffer.from(res.data.content, "base64").toString();
116+
}
117+
log.warn(`Tried to get file content from non-file path ${file}`);
118+
return "";
115119
});
116120
}
117121

functions/src/index.ts

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import * as config from "./config";
2525
import * as types from "./types";
2626
import * as util from "./util";
2727
import * as log from "./log";
28+
import * as pubsub from "./pubsub";
2829

2930
import { database } from "./database";
30-
import { sendPubSub } from "./pubsub";
3131
import {
3232
createEventsTable,
3333
createIssuesTable,
@@ -89,9 +89,9 @@ const pr_handler = new pullrequests.PullRequestHandler(bot_config);
8989
// Handler for Cron jobs
9090
const cron_handler = new cron.CronHandler(gh_client, bot_config);
9191

92-
export const eventWebhook = functions
93-
.runWith(util.FUNCTION_OPTS)
94-
.https.onRequest(async (request, response) => {
92+
export const eventWebhook = functions.https.onRequest(
93+
util.FUNCTION_OPTS,
94+
async (request, response) => {
9595
const type = request.get("X-GitHub-Event");
9696
if (!type) {
9797
response.status(400).send("Must include type!");
@@ -117,14 +117,15 @@ export const eventWebhook = functions
117117
response.json({
118118
status: "ok",
119119
});
120-
});
120+
},
121+
);
121122

122123
/**
123124
* Function that responds to GitHub events (HTTP webhook).
124125
*/
125-
export const githubWebhook = functions
126-
.runWith(util.FUNCTION_OPTS)
127-
.https.onRequest(async (request, response) => {
126+
export const githubWebhook = functions.https.onRequest(
127+
util.FUNCTION_OPTS,
128+
async (request, response) => {
128129
// Get event and action;
129130
const event = request.get("X-GitHub-Event");
130131
const action = request.body.action;
@@ -272,29 +273,30 @@ export const githubWebhook = functions
272273
.catch((e) => {
273274
response.send("Error!");
274275
});
275-
});
276+
},
277+
);
276278

277279
/**
278-
* Function that responds to pubsub events sent via an AppEngine crojob.
280+
* Function that responds to pubsub events sent via an AppEngine cronjob.
279281
*/
280-
export const botCleanup = functions
281-
.runWith(util.FUNCTION_OPTS)
282-
.pubsub.schedule("every day 18:00")
283-
.onRun(async () => {
282+
export const botCleanup = functions.scheduler.onSchedule(
283+
"every day 18:00",
284+
async () => {
284285
console.log("The cleanup job is running!");
285286
const repos = bot_config.getAllRepos();
286287
for (const repo of repos) {
287-
await sendPubSub("bot-cleanup-repo", { org: repo.org, repo: repo.name });
288+
await pubsub.sendPubSub("bot-cleanup-repo", {
289+
org: repo.org,
290+
repo: repo.name,
291+
});
288292
}
293+
},
294+
);
289295

290-
return true;
291-
});
292-
293-
export const botCleanupRepo = functions
294-
.runWith(util.FUNCTION_OPTS)
295-
.pubsub.topic("bot-cleanup-repo")
296-
.onPublish(async (event, ctx) => {
297-
const data = event.json;
296+
export const botCleanupRepo = functions.pubsub.onMessagePublished(
297+
"bot-cleanup-repo",
298+
async (event) => {
299+
const data = event.data.message.json;
298300

299301
const org = data.org;
300302
const repo = data.repo;
@@ -327,7 +329,8 @@ export const botCleanupRepo = functions
327329
await safeExecuteActions(actions);
328330

329331
return true;
330-
});
332+
},
333+
);
331334

332335
async function safeExecuteActions(actions: types.Action[]): Promise<void> {
333336
for (const action of actions) {
@@ -443,10 +446,9 @@ async function executeAction(action: types.Action): Promise<any> {
443446
/**
444447
* Manually run this function to create tables.
445448
*/
446-
export const ensureBigquery = functions
447-
.runWith(util.FUNCTION_OPTS)
448-
.pubsub.topic("ensure-bigquery")
449-
.onPublish(async () => {
449+
export const ensureBigquery = functions.pubsub.onMessagePublished(
450+
"ensure-bigquery",
451+
async () => {
450452
const repos = bot_config.getAllRepos();
451453
const orgs = new Set<string>(repos.map((r) => r.org));
452454

@@ -463,4 +465,5 @@ export const ensureBigquery = functions
463465
await createEventsTable(org);
464466
}
465467
}
466-
});
468+
},
469+
);

functions/src/issues.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@ export class IssueHandler {
137137
case IssueAction.REOPENED:
138138
return this.onIssueStatusChanged(repo, issue, IssueStatus.OPEN);
139139
case IssueAction.LABELED:
140-
return this.onIssueLabeled(repo, issue, event.label.name);
140+
if (event.label.name) {
141+
return this.onIssueLabeled(repo, issue, event.label.name);
142+
}
141143
case IssueAction.UNASSIGNED:
142144
/* falls through */
143145
case IssueAction.UNLABELED:
@@ -218,18 +220,16 @@ export class IssueHandler {
218220
}
219221

220222
// If the issue is filed by a collaborator, we stop here.
221-
const isCollaborator = await snapshot.userIsCollaborator(
222-
org,
223-
name,
224-
issue.user.login,
225-
);
223+
const isCollaborator = issue.user
224+
? await snapshot.userIsCollaborator(org, name, issue.user.login)
225+
: false;
226226
if (isCollaborator) {
227227
actions.push(
228228
new types.GitHubNoOpAction(
229229
org,
230230
name,
231231
issue.number,
232-
`No further action taken on this issue because it was filed by repo collaborator: ${issue.user.login}`,
232+
`No further action taken on this issue because it was filed by repo collaborator: ${issue.user!.login}`,
233233
),
234234
);
235235

@@ -244,7 +244,6 @@ export class IssueHandler {
244244
// Filter spam from b/378634578. This can be removed in the future.
245245
const spamWords = [
246246
"pemain",
247-
"wallet wallet", // seems to be in most crypto issues
248247
"minecraft",
249248
"paybis",
250249
"blockchain",
@@ -256,7 +255,6 @@ export class IssueHandler {
256255
"moonpay",
257256
"coinmama",
258257
"daftar",
259-
["wallet", "support"],
260258
];
261259
const issueContent = ` ${issue.title} ${issue.body || ""} `.toLowerCase();
262260
// Scope spam filtering to affected repos only.
@@ -277,12 +275,12 @@ export class IssueHandler {
277275
});
278276

279277
if (isSpam) {
280-
// Discard other actions, wipe and lock the issue, and block
281-
// the offending user.
278+
// Discard other actions, wipe and lock the issue.
279+
// This function used to block the user during a major spam incident
280+
// but since then blocking has been removed.
282281
const reason = `Issue is believed to be spam: ${issue.title}`;
283282
return [
284283
new types.GitHubSpamAction(org, name, issue.number, reason),
285-
new types.GitHubBlockAction(org, issue.user.login),
286284
new types.GitHubLockAction(org, name, issue.number),
287285
];
288286
}
@@ -367,11 +365,11 @@ export class IssueHandler {
367365
label: string,
368366
): types.Action[] {
369367
// Render the issue body
370-
const body_html = marked(issue.body || "");
368+
const body_html = marked.parse(issue.body || "", { async: false });
371369

372370
// Send a new issue email
373371
const action = this.emailer.getIssueUpdateEmailAction(repo, issue, {
374-
header: `New Issue from ${issue.user.login} in label ${label}`,
372+
header: `New Issue from ${issue.user?.login ?? "ghost"} in label ${label}`,
375373
body: body_html,
376374
label: label,
377375
});
@@ -405,7 +403,7 @@ export class IssueHandler {
405403
const actions: types.Action[] = [];
406404

407405
// Send an email to subscribers
408-
const comment_html = marked(comment.body);
406+
const comment_html = marked.parse(comment.body, { async: false });
409407
const emailAction = this.emailer.getIssueUpdateEmailAction(repo, issue, {
410408
header: `New Comment by ${comment.user.login}`,
411409
body: comment_html,
@@ -426,12 +424,19 @@ export class IssueHandler {
426424

427425
if (cleanupConfig && cleanupConfig.issue && !isBotComment && !isClosed) {
428426
const issueConfig = cleanupConfig.issue;
429-
const labelNames = issue.labels.map((label) => label.name);
427+
const labelNames = issue.labels.map((label) => {
428+
if (typeof label === "string") {
429+
return label;
430+
}
431+
return label.name;
432+
});
430433

431434
const isNeedsInfo = labelNames.includes(issueConfig.label_needs_info);
432435
const isStale = labelNames.includes(issueConfig.label_stale);
433436

434-
const isAuthorComment = comment.user.login === issue.user.login;
437+
const isAuthorComment = issue.user
438+
? comment.user.login === issue.user.login
439+
: false;
435440

436441
if (isStale) {
437442
// Any comment on a stale issue removes the stale flag
@@ -452,7 +457,7 @@ export class IssueHandler {
452457
: issueConfig.label_needs_info;
453458

454459
const reason = isAuthorComment
455-
? `Comment by the author (${issue.user.login}) on a stale issue moves this to needs_attention`
460+
? `Comment by the author (${issue.user?.login ?? "ghost"}) on a stale issue moves this to needs_attention`
456461
: `Comment by a non-author (${comment.user.login}) on a stale issue moves this to needs_info`;
457462

458463
if (isAuthorComment && !issueConfig.label_needs_attention) {
@@ -476,7 +481,7 @@ export class IssueHandler {
476481

477482
if (isNeedsInfo && isAuthorComment) {
478483
// An author comment on a needs-info issue moves it to needs-attention.
479-
const reason = `Comment by the author (${issue.user.login}) moves this from needs_info to needs_attention.`;
484+
const reason = `Comment by the author (${issue.user?.login ?? "ghost"}) moves this from needs_info to needs_attention.`;
480485
actions.push(
481486
new types.GitHubRemoveLabelAction(
482487
org,
@@ -785,7 +790,7 @@ export class IssueHandler {
785790
const path_re = /template_path=(.*)/;
786791
const validate_re = /validate_template=(.*)/;
787792

788-
const body = issue.body;
793+
const body = issue.body ?? "";
789794

790795
const path_match = body.match(path_re);
791796
if (path_match) {

functions/src/pullrequests.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ export class PullRequestHandler {
7171
case PullRequestAction.OPENED:
7272
return this.onNewPullRequest(repo, pr);
7373
case PullRequestAction.LABELED:
74-
return this.onPullRequestLabeled(repo, pr, event.label.name);
74+
if (event.label.name) {
75+
return this.onPullRequestLabeled(repo, pr, event.label.name);
76+
}
7577
case PullRequestAction.ASSIGNED:
7678
/* falls through */
7779
case PullRequestAction.UNASSIGNED:
@@ -128,7 +130,7 @@ export class PullRequestHandler {
128130
label: string,
129131
): Promise<types.Action[]> {
130132
// Render the PR body
131-
const body_html = marked(pr.body || "");
133+
const body_html = marked.parse(pr.body || "", { async: false });
132134

133135
// Send a new PR email
134136
const action = this.emailer.getIssueUpdateEmailAction(repo, pr, {

0 commit comments

Comments
 (0)