From ac64a343884fed688e306b9b6f9bd741a69cb813 Mon Sep 17 00:00:00 2001 From: Andrej Hoos Date: Tue, 8 Sep 2026 14:54:52 +0000 Subject: [PATCH] SH-1113 Fail CI when a PR description contains a GitHub closing keyword Issues here are synced with Linear. A closing keyword closes the GitHub issue at merge time while Linear's PR automation moves the linked issue to Self QA, and the two automations then close, reopen, and re-triage the issue in public. Reference issues with "Refs #123" and close them from Linear instead. --- .github/workflows/no-closing-keywords.yml | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/no-closing-keywords.yml diff --git a/.github/workflows/no-closing-keywords.yml b/.github/workflows/no-closing-keywords.yml new file mode 100644 index 0000000..80c2e31 --- /dev/null +++ b/.github/workflows/no-closing-keywords.yml @@ -0,0 +1,28 @@ +# Issues in this repo are synced with Linear. A GitHub closing keyword ("Closes #123", +# "Fixes owner/repo#123") closes the issue the moment the PR merges, while Linear's PR +# automation moves the linked Linear issue to Self QA at the same time. The two automations +# then fight: the GitHub issue is closed, reopened, and the Linear issue lands in Triage. +# Reference the issue with "Refs #123" instead and close it from Linear once the fix is +# released. +name: no closing keywords +on: + pull_request: + types: [opened, edited, reopened, synchronize] +permissions: + pull-requests: read +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Reject GitHub closing keywords in the PR description + env: + BODY: ${{ github.event.pull_request.body }} + run: | + pattern='\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\b:?[[:space:]]+(#[0-9]+|[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+#[0-9]+|https?://github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/issues/[0-9]+)' + if matches=$(printf '%s' "$BODY" | grep -inoE "$pattern"); then + echo "::error::The PR description contains a GitHub closing keyword, which would close the issue on merge and desync it from Linear:" + echo "$matches" + echo "Use 'Refs #123' instead and close the issue from Linear once the fix is released." + exit 1 + fi + echo "No closing keywords found."