From d7730788faeb9993d408bd8df5307a6b043ca141 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:28:36 -0400 Subject: [PATCH] Recognize all GitHub issue-link forms in require-issue-link workflow (#4359) --- .github/workflows/require-issue-link.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/require-issue-link.yml b/.github/workflows/require-issue-link.yml index 044d4f9cd..4596dd448 100644 --- a/.github/workflows/require-issue-link.yml +++ b/.github/workflows/require-issue-link.yml @@ -277,7 +277,17 @@ jobs: // ── The actual check: an auto-close keyword + issue number ───── const body = pr.body || ''; - const pattern = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*:?\s*#(\d+)/gi; + // Match GitHub's auto-close keywords against any reference form + // that GitHub itself honors: bare `#123`, the `owner/repo#123` + // shorthand, and the full issue URL. Scope the qualified forms to + // THIS repo — GitHub only auto-closes same-repo issues, so a + // cross-repo reference must not be resolved against our numbering. + const repoRef = `${owner}/${repo}`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const pattern = new RegExp( + '(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s*:?\\s*' + + `(?:${repoRef}#|#|https?://github\\.com/${repoRef}/issues/)(\\d+)`, + 'gi', + ); const matches = [...body.matchAll(pattern)]; if (matches.length === 0) { @@ -425,7 +435,17 @@ jobs: const enforce = process.env.ENFORCE_ISSUE_LINK === 'true'; const LABEL = 'missing-issue-link'; const MARKER = ''; - const pattern = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*:?\s*#(\d+)/gi; + // Match GitHub's auto-close keywords against any reference form + // that GitHub itself honors: bare `#123`, the `owner/repo#123` + // shorthand, and the full issue URL. Scope the qualified forms to + // THIS repo — GitHub only auto-closes same-repo issues, so a + // cross-repo reference must not be resolved against our numbering. + const repoRef = `${owner}/${repo}`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const pattern = new RegExp( + '(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s*:?\\s*' + + `(?:${repoRef}#|#|https?://github\\.com/${repoRef}/issues/)(\\d+)`, + 'gi', + ); async function mutate(description, fn) { if (!enforce) {