3737 with :
3838 script : |
3939 const STICKY = '<!-- companion-pr-check -->';
40- // Two ways to declare a companion (either works; both feed this warning):
41- // 1) a trailer anywhere: Companion: owner/repo#N (or a full PR URL)
42- // 2) refs in a task list under a "## Companion..." heading — which ALSO
43- // renders a native live badge + progress bar on the PR (the "both" path):
44- // ## Companion PRs
45- // - [ ] owner/repo#N
46- const TRAILER = /Companion:\s*(?:https?:\/\/github\.com\/)?([\w.-]+)\/([\w.-]+)(?:\/pull\/|#)(\d+)/gi;
47- const REF = /(?:https?:\/\/github\.com\/)?([\w.-]+)\/([\w.-]+)(?:\/pull\/|#)(\d+)/g;
4840 const { owner, repo } = context.repo;
4941 // Directional label: copilot/mothership PRs get "requires-sim-merge",
5042 // sim PRs get "requires-mothership-merge". Applied whenever the PR
7062 return res.json();
7163 }
7264
65+ // Two ways to declare a companion (either works; both feed this warning):
66+ // 1) a trailer anywhere: Companion: owner/repo#N (or a full PR URL)
67+ // 2) refs in a task list under a "## Companion..." heading — which ALSO
68+ // renders a native live badge + progress bar on the PR (the "both" path):
69+ // ## Companion PRs
70+ // - [ ] owner/repo#N
71+ // Regexes are local + matchAll, so there's no shared lastIndex state to leak
72+ // between calls (stateless by construction).
7373 function parseCompanions(body) {
7474 body = body || '';
75+ const TRAILER = /Companion:\s*(?:https?:\/\/github\.com\/)?([\w.-]+)\/([\w.-]+)(?:\/pull\/|#)(\d+)/gi;
76+ const REF = /(?:https?:\/\/github\.com\/)?([\w.-]+)\/([\w.-]+)(?:\/pull\/|#)(\d+)/g;
7577 const out = [];
7678 const seen = new Set();
7779 const add = (o, r, n) => {
@@ -81,17 +83,13 @@ jobs:
8183 out.push({ owner: o, repo: r, number: Number(n), ref });
8284 };
8385 // (1) "Companion:" trailers anywhere in the body.
84- let m;
85- TRAILER.lastIndex = 0;
86- while ((m = TRAILER.exec(body)) !== null) add(m[1], m[2], m[3]);
86+ for (const m of body.matchAll(TRAILER)) add(m[1], m[2], m[3]);
8787 // (2) refs in a task list under a "## Companion..." heading, until the next heading.
8888 let inSection = false;
8989 for (const line of body.split(/\r?\n/)) {
9090 if (/^#{1,6}\s/.test(line)) { inSection = /^#{1,6}\s*companion/i.test(line); continue; }
9191 if (!inSection) continue;
92- let mm;
93- REF.lastIndex = 0;
94- while ((mm = REF.exec(line)) !== null) add(mm[1], mm[2], mm[3]);
92+ for (const mm of line.matchAll(REF)) add(mm[1], mm[2], mm[3]);
9593 }
9694 return out;
9795 }
0 commit comments