From cd40a194ed286d4b8af9780bcc2fe2a744856885 Mon Sep 17 00:00:00 2001 From: saphid <4596216+saphid@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:39:54 +1000 Subject: [PATCH] Website feedback: escape & so entities can't rebuild mentions; queue only lgtm comments Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/approve-contributor.yml | 11 ++++++----- site/lib/feedback.js | 4 +++- site/test/feedback.test.mjs | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/approve-contributor.yml b/.github/workflows/approve-contributor.yml index 38be871..665128b 100644 --- a/.github/workflows/approve-contributor.yml +++ b/.github/workflows/approve-contributor.yml @@ -7,13 +7,14 @@ on: issue_comment: types: [created] -# One approval at a time, so two lgtm replies can't race on the same commit. -concurrency: - group: approve-contributor - cancel-in-progress: false - jobs: approve: + # Only comments that might approve someone join the queue, and they run one + # at a time so two lgtm replies can't race on APPROVED_CONTRIBUTORS. + if: contains(github.event.comment.body, 'lgtm') # contains() ignores case + concurrency: + group: approve-contributor + cancel-in-progress: false runs-on: ubuntu-latest permissions: contents: write diff --git a/site/lib/feedback.js b/site/lib/feedback.js index 6c04045..91df858 100644 --- a/site/lib/feedback.js +++ b/site/lib/feedback.js @@ -19,10 +19,12 @@ const oneLine = (value, max) => String(value ?? "").replace(/\s+/g, " ").trim(). // Mentions in someone else's text would ping strangers, and issue references // (#1, owner/repo#1, GH-1, github.com links) would add backlinks to other -// people's issues, so break them all with a zero-width space. +// people's issues, so break them all with a zero-width space. Escaping & first +// stops @ and # from turning back into @ and # when GitHub renders. const ZWSP = "\u200b"; export function defang(text) { return text + .replace(/&/g, "&") .replace(/@(?=[A-Za-z0-9])/g, `@${ZWSP}`) .replace(/#(?=\d)/g, `#${ZWSP}`) .replace(/\b(GH)-(?=\d)/gi, `$1${ZWSP}-`) diff --git a/site/test/feedback.test.mjs b/site/test/feedback.test.mjs index 6ce9ed6..dcd03e2 100644 --- a/site/test/feedback.test.mjs +++ b/site/test/feedback.test.mjs @@ -56,6 +56,7 @@ test("breaks mentions, issue refs and table cells in user text", () => { assert.equal(defang("ping @valve about #12"), "ping @\u200bvalve about #\u200b12"); assert.equal(defang("email me@example.com"), "email me@\u200bexample.com"); assert.equal(defang("see valve/steam#7 and GH-8"), "see valve/steam#\u200b7 and GH\u200b-8"); + assert.equal(defang("@valve @valve #3"), "&commat;valve &#\u200b64;valve &num;3"); assert.equal(defang("https://github.com/a/b/issues/1"), "https://github\u200b.com/a/b/issues/1"); const issue = buildIssue(validate(form({ os: "a | b" })).value); assert.match(issue.body, /\| a \\\| b \|/);