feat: support simple wildcards in `allowBranches`

This commit is contained in:
shiftinv 2022-10-21 21:27:37 +02:00
parent 452482513f
commit 416928f718
5 changed files with 33 additions and 8 deletions

View File

@ -22,6 +22,9 @@ Certain no-op events (which Discord would ignore anyway) and common CI bots are
Additional options can be configured per URL:
- Only forward events from specific branches (`allowBranches`, comma-separated list)
- Only forward events from specific branches (`allowBranches`, simplified wildcard syntax)
- `abc*xyz` is equivalent to `/^(abc.*xyz)$/`
- `stuff,things` is equivalent to `/^(stuff|things)$/`
- `!oh*hi*there` is equivalent to `/^(oh.*hi.*there)$/` inverted
- Ignore tag updates (`hideTags`)
- Ignore burst PR review comments in a short timespan, only showing the first x comments (`commentBurstLimit`)

View File

@ -1,6 +1,6 @@
import { commentManager } from "./manager.ts";
import { UrlConfig } from "./types.d.ts";
import { requestLog } from "./util.ts";
import { requestLog, wildcardMatch } from "./util.ts";
export default async function filter(
headers: Headers,
@ -89,9 +89,9 @@ export default async function filter(
if (refType && ref) {
if (
refType == "branch" && config.allowBranches !== undefined &&
!config.allowBranches.includes(ref)
!wildcardMatch(config.allowBranches, ref)
) {
return `branch '${ref}' not in ${JSON.stringify(config.allowBranches)}`;
return `branch '${ref}' does not match ${JSON.stringify(config.allowBranches)}`;
}
if (refType == "tag" && config.hideTags === true) {
return `tag '${ref}'`;

View File

@ -57,7 +57,7 @@ function getUrlConfig(params: URLSearchParams): UrlConfig {
case "sig":
continue;
case "allowBranches":
config.allowBranches = value.split(",");
config.allowBranches = value;
break;
case "hideTags":
config.hideTags = parseBool(value);

2
lib/types.d.ts vendored
View File

@ -1,5 +1,5 @@
export interface UrlConfig {
allowBranches?: string[];
allowBranches?: string;
hideTags?: boolean;
commentBurstLimit?: number;
}

View File

@ -8,7 +8,29 @@ export function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function getLogString(data: unknown): string {
function _escapeRegex(pattern: string): string {
return pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
export function wildcardMatch(pattern: string, target: string): boolean {
let invert = false;
if (pattern[0] === "!") {
invert = true;
pattern = pattern.slice(1);
}
// allow `*` wildcard specifier, translate to `.*` regex;
// escape everything else
pattern = pattern.split("*").map(_escapeRegex).join(".*");
// treat `,` as `|`
pattern = pattern.replace(",", "|");
// add anchors
pattern = `^(${pattern})$`;
return invert !== new RegExp(pattern).test(target);
}
function _getLogString(data: unknown): string {
return log.getLogger().asString(data);
}
@ -23,7 +45,7 @@ export function requestLog(headers: Headers) {
// is there a better way to do this? certainly.
// does this work? also yes.
const proxyLog: (func: (s: any) => string) => (msg: any) => string = (func) => {
return (msg) => func(prefix + getLogString(msg));
return (msg) => func(prefix + _getLogString(msg));
};
return {