2022-09-07 13:28:25 +00:00
|
|
|
import { commentManager } from "./manager.ts";
|
2022-09-02 23:35:09 +00:00
|
|
|
import { UrlConfig } from "./types.d.ts";
|
2022-09-06 01:56:57 +00:00
|
|
|
import { requestLog } from "./util.ts";
|
2022-09-02 23:35:09 +00:00
|
|
|
|
2022-09-06 19:21:40 +00:00
|
|
|
export default async function filter(
|
|
|
|
headers: Headers,
|
|
|
|
json: any,
|
|
|
|
config: UrlConfig,
|
|
|
|
): Promise<string | null> {
|
2022-09-06 01:56:57 +00:00
|
|
|
const reqLog = requestLog(headers);
|
2022-09-03 00:39:36 +00:00
|
|
|
const event = headers.get("x-github-event") || "unknown";
|
2022-09-03 15:10:58 +00:00
|
|
|
const login: string | undefined = json.sender?.login?.toLowerCase();
|
2022-09-03 14:48:28 +00:00
|
|
|
|
|
|
|
// ignore events that Discord won't render anyway
|
2022-09-03 00:39:36 +00:00
|
|
|
if (["status", "pull_request_review_thread"].includes(event)) {
|
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
2022-09-03 14:48:28 +00:00
|
|
|
// ignore all PR actions except "opened", "closed", "reopened"
|
2022-09-03 00:39:36 +00:00
|
|
|
if (
|
|
|
|
event === "pull_request" && json.action &&
|
|
|
|
!["opened", "closed", "reopened"].includes(json.action)
|
|
|
|
) {
|
2022-09-04 22:18:12 +00:00
|
|
|
return `no-op PR action '${json.action}'`;
|
2022-09-03 00:39:36 +00:00
|
|
|
}
|
|
|
|
|
2022-09-03 14:48:28 +00:00
|
|
|
// ignore all issue actions except "opened", "deleted", "closed", "reopened", "transferred"
|
2022-09-03 00:39:36 +00:00
|
|
|
if (
|
|
|
|
event === "issues" && json.action &&
|
|
|
|
!["opened", "deleted", "closed", "reopened", "transferred"].includes(json.action)
|
|
|
|
) {
|
2022-09-04 22:18:12 +00:00
|
|
|
return `no-op issue action '${json.action}'`;
|
2022-09-03 00:39:36 +00:00
|
|
|
}
|
|
|
|
|
2022-09-03 14:48:28 +00:00
|
|
|
// ignore some PR review actions
|
2022-09-03 01:31:48 +00:00
|
|
|
if (event === "pull_request_review") {
|
2022-09-03 14:08:20 +00:00
|
|
|
// ignore edit/dismiss actions
|
2022-09-04 22:18:12 +00:00
|
|
|
if (json.action !== "submitted") return `no-op PR review action '${json.action}'`;
|
2022-09-07 13:28:25 +00:00
|
|
|
|
2022-09-03 14:08:20 +00:00
|
|
|
// if comment (not approval or changes requested), ignore empty review body
|
2022-09-07 13:28:25 +00:00
|
|
|
if (json.review?.state === "commented" && !json.review?.body) return "empty PR review";
|
2022-09-03 01:31:48 +00:00
|
|
|
}
|
|
|
|
|
2022-09-03 15:10:58 +00:00
|
|
|
// ignore some PR comment events
|
|
|
|
if (event === "pull_request_review_comment") {
|
|
|
|
// ignore edit/delete actions
|
2022-09-04 22:18:12 +00:00
|
|
|
if (json.action !== "created") return `no-op PR comment action '${json.action}'`;
|
2022-09-07 13:28:25 +00:00
|
|
|
|
2022-09-03 15:10:58 +00:00
|
|
|
// check if more than x comments on a PR review in a short timespan
|
|
|
|
const reviewId: number = json.comment?.pull_request_review_id;
|
|
|
|
if (config.commentBurstLimit && reviewId) {
|
|
|
|
const cacheKey = `${reviewId}-${login}`;
|
2022-09-07 13:28:25 +00:00
|
|
|
|
2022-09-06 01:56:57 +00:00
|
|
|
reqLog.debug(`filter: checking cache key ${cacheKey}`);
|
2022-09-07 13:28:25 +00:00
|
|
|
const curr = await commentManager.getAndIncrement(cacheKey);
|
2022-09-06 19:21:40 +00:00
|
|
|
reqLog.debug(`filter: current value: ${curr}`);
|
2022-09-07 13:28:25 +00:00
|
|
|
|
2022-09-03 15:10:58 +00:00
|
|
|
if (curr && curr >= config.commentBurstLimit) {
|
2022-09-04 13:09:33 +00:00
|
|
|
return `exceeded comment burst limit (${config.commentBurstLimit}) for review ${reviewId}`;
|
2022-09-03 15:10:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-03 14:48:28 +00:00
|
|
|
// ignore bots
|
2022-09-02 23:35:09 +00:00
|
|
|
if (
|
|
|
|
login &&
|
|
|
|
["coveralls[bot]", "netlify[bot]", "pre-commit-ci[bot]"].some((n) => login.includes(n))
|
|
|
|
) {
|
|
|
|
return "bot";
|
|
|
|
}
|
|
|
|
|
2022-10-21 17:43:36 +00:00
|
|
|
let refType: "branch" | "tag" | undefined;
|
|
|
|
let ref: string | undefined;
|
|
|
|
if (event === "push") {
|
|
|
|
// ignore branch/tag push
|
|
|
|
const refMatch = /^refs\/([^\/]+)\/(.+)$/.exec(json.ref);
|
|
|
|
if (refMatch) {
|
|
|
|
refType = refMatch[1] === "heads"
|
|
|
|
? "branch"
|
|
|
|
: (refMatch[1] == "tags" ? "tag" : undefined);
|
|
|
|
ref = refMatch[2];
|
2022-09-02 23:35:09 +00:00
|
|
|
}
|
2022-10-21 17:43:36 +00:00
|
|
|
} else if (["create", "delete"].includes(event)) {
|
|
|
|
// ignore creation/deletion of branch/tag
|
|
|
|
refType = json.ref_type;
|
|
|
|
ref = json.ref;
|
2022-09-02 23:35:09 +00:00
|
|
|
}
|
|
|
|
|
2022-10-21 17:43:36 +00:00
|
|
|
if (refType && ref) {
|
2022-09-30 12:59:30 +00:00
|
|
|
if (
|
2022-10-21 17:43:36 +00:00
|
|
|
refType == "branch" && config.allowBranches !== undefined &&
|
|
|
|
!config.allowBranches.includes(ref)
|
2022-09-30 12:59:30 +00:00
|
|
|
) {
|
2022-10-21 17:43:36 +00:00
|
|
|
return `branch '${ref}' not in ${JSON.stringify(config.allowBranches)}`;
|
2022-09-30 12:59:30 +00:00
|
|
|
}
|
2022-10-21 17:43:36 +00:00
|
|
|
if (refType == "tag" && config.hideTags === true) {
|
|
|
|
return `tag '${ref}'`;
|
2022-09-30 12:59:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-02 23:35:09 +00:00
|
|
|
return null;
|
|
|
|
}
|