Handle wildcard branches

This commit is contained in:
Simon Engledew 2020-12-01 15:21:30 +00:00
parent ac1c081de8
commit c8ee1f4ef3
No known key found for this signature in database
GPG key ID: 84302E7B02FE8BCE
6 changed files with 130 additions and 18 deletions

61
lib/actions-util.js generated
View file

@ -101,15 +101,60 @@ exports.getCommitOid = async function () {
function isObject(o) {
return o !== null && typeof o === "object";
}
function branchesToArray(branches) {
if (typeof branches === 'string') {
if (branches === "*") {
return "*";
const WORKSPACE_BRANCES_PATTERN = new RegExp("(\\*\\*?|/)");
function tokenize(value) {
return value.split(WORKSPACE_BRANCES_PATTERN).reduce(function (arr, cur) {
if (cur) {
arr.push(cur);
}
return arr;
}, []);
}
function considerToken(a, b) {
switch (a) {
case "*":
return { advance: b === "/", consume: b !== "/" };
case "**":
return { advance: false, consume: true };
default:
return { advance: a === b, consume: a === b };
}
}
function patternsOverlap(patternA, patternB) {
const patternATokens = tokenize(patternA);
const patternBTokens = tokenize(patternB);
let indexA = 0;
let indexB = 0;
let advance;
let consume = true;
while (advance || consume) {
const currentA = patternATokens[indexA];
const currentB = patternBTokens[indexB];
if (currentB === undefined) {
return true;
}
if (currentA === undefined) {
return false;
}
const next = considerToken(currentA, currentB);
advance = next.advance;
consume = next.consume;
if (consume) {
indexB += 1;
}
if (advance) {
indexA += 1;
}
}
return false;
}
exports.patternsOverlap = patternsOverlap;
function branchesToArray(branches) {
if (typeof branches === "string") {
return [branches];
}
if (!branches || branches.length === 0) {
return "*";
return "**";
}
return branches;
}
@ -196,10 +241,10 @@ function validateWorkflow(doc) {
}
}
const push = branchesToArray((_f = doc.on.push) === null || _f === void 0 ? void 0 : _f.branches);
if (push !== "*") {
if (push !== "**") {
const pull_request = branchesToArray((_g = doc.on.pull_request) === null || _g === void 0 ? void 0 : _g.branches);
if (pull_request !== "*") {
const difference = pull_request.filter((value) => !push.includes(value));
if (pull_request !== "**") {
const difference = pull_request.filter((value) => !push.some((o) => patternsOverlap(o, value)));
if (difference.length > 0) {
// there are branches in pull_request that may not have a baseline
// because we are not building them on push

File diff suppressed because one or more lines are too long

View file

@ -195,4 +195,8 @@ ava_1.default("formatWorkflowCause()", (t) => {
t.deepEqual(message, "CheckoutWrongHead,PathsSpecified");
t.deepEqual(actionsutil.formatWorkflowCause([]), undefined);
});
ava_1.default("patternsOverlap()", (t) => {
t.false(actionsutil.patternsOverlap("main-*", "main"));
t.true(actionsutil.patternsOverlap("*", "*"));
});
//# sourceMappingURL=actions-util.test.js.map

File diff suppressed because one or more lines are too long

View file

@ -246,3 +246,8 @@ test("formatWorkflowCause()", (t) => {
t.deepEqual(message, "CheckoutWrongHead,PathsSpecified");
t.deepEqual(actionsutil.formatWorkflowCause([]), undefined);
});
test("patternsOverlap()", (t) => {
t.false(actionsutil.patternsOverlap("main-*", "main"));
t.true(actionsutil.patternsOverlap("*", "*"));
});

View file

@ -134,15 +134,73 @@ function isObject(o: unknown): o is object {
return o !== null && typeof o === "object";
}
function branchesToArray(branches?: string | null | string[]): string[] | "*" {
if (typeof branches === 'string') {
if (branches === "*") {
return "*";
const WORKSPACE_BRANCES_PATTERN = new RegExp("(\\*\\*?|/)");
function tokenize(value: string): string[] {
return value.split(WORKSPACE_BRANCES_PATTERN).reduce(function (arr, cur) {
if (cur) {
arr.push(cur);
}
return arr;
}, [] as ReturnType<typeof tokenize>);
}
function considerToken(
a: string,
b: string
): { advance: boolean; consume: boolean } {
switch (a) {
case "*":
return { advance: b === "/", consume: b !== "/" };
case "**":
return { advance: false, consume: true };
default:
return { advance: a === b, consume: a === b };
}
}
export function patternsOverlap(patternA: string, patternB: string): boolean {
const patternATokens = tokenize(patternA);
const patternBTokens = tokenize(patternB);
let indexA = 0;
let indexB = 0;
let advance;
let consume = true;
while (advance || consume) {
const currentA = patternATokens[indexA];
const currentB = patternBTokens[indexB];
if (currentB === undefined) {
return true;
}
if (currentA === undefined) {
return false;
}
const next = considerToken(currentA, currentB);
advance = next.advance;
consume = next.consume;
if (consume) {
indexB += 1;
}
if (advance) {
indexA += 1;
}
}
return false;
}
function branchesToArray(branches?: string | null | string[]): string[] | "**" {
if (typeof branches === "string") {
return [branches];
}
if (!branches || branches.length === 0) {
return "*";
return "**";
}
return branches;
}
@ -238,12 +296,12 @@ export function validateWorkflow(doc: Workflow): CodedError[] {
const push = branchesToArray(doc.on.push?.branches);
if (push !== "*") {
if (push !== "**") {
const pull_request = branchesToArray(doc.on.pull_request?.branches);
if (pull_request !== "*") {
if (pull_request !== "**") {
const difference = pull_request.filter(
(value) => !push.includes(value)
(value) => !push.some((o) => patternsOverlap(o, value))
);
if (difference.length > 0) {
// there are branches in pull_request that may not have a baseline