Skip to content

Commit 88dd7d5

Browse files
kriscendobotclaude
andcommitted
jobs(bulletin): don't linkify issue refs inside inline code spans
Verifying the maintainer-inbox linkifier against a real live message surfaced a bug: a `#N` inside an inline `code` span (e.g. `rebase #650`) was being turned into a Markdown link, which renders as literal `[#650](…)` text inside the backticks. linkify already skipped fenced code blocks; extend that to inline `code` spans — hold them aside behind the same sentinels before the URL / slug / bare passes so their contents are emitted verbatim. Adds a SUBTEST 10 (5b) assertion that `rebase #650` in an inline span stays plain. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4858ade commit 88dd7d5

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

scripts/jobs/bulletin.sh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,18 @@ resolve_doer_repo() {
327327
# GitHub-rendered journal2 README and the gh-pages client render [label](url)):
328328
# full GitHub issue/PR URLs, "owner/repo#N", and — when the originating repo is
329329
# passed as $2 — a bare "#N" pointing at that project. Linking is skipped inside
330-
# fenced code blocks, and formed links are held aside so nothing is double-linked.
331-
# With no resolved repo ($2 empty), a bare "#N" is left as plain text.
330+
# fenced code blocks AND inline `code` spans, and formed links are held aside so
331+
# nothing is double-linked. With no resolved repo ($2 empty), a bare "#N" is left
332+
# as plain text.
332333
msg_body_quote() {
333334
awk -v repo="${2:-}" '
334335
function linkify(s, i) {
335336
# Protect already-formed links and each reference kind behind SOH/STX
336337
# sentinels so a later pass cannot re-link inside an earlier one.
337338
split("", store); nstore=0
339+
# 0) hold inline `code` spans verbatim so a `#N` / `owner/repo#N` inside a
340+
# code span is never linkified (a link inside backticks renders literally)
341+
s = protect(s, "`[^`]*`", "code")
338342
# 1) full GitHub issue/PR URLs -> [url](url)
339343
s = protect(s, "https?://github\\.com/[A-Za-z0-9._-]+/[A-Za-z0-9._-]+/(issues|pull)/[0-9]+", "url")
340344
# 2) owner/repo#N -> [owner/repo#N](https://github.com/owner/repo/issues/N)
@@ -352,7 +356,9 @@ msg_body_quote() {
352356
out = ""
353357
while (match(s, re)) {
354358
matched = substr(s, RSTART, RLENGTH)
355-
if (kind == "url") {
359+
if (kind == "code") {
360+
link = matched
361+
} else if (kind == "url") {
356362
link = "[" matched "](" matched ")"
357363
} else if (kind == "slug") {
358364
hp = index(matched, "#")

scripts/jobs/test/run-test.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ rm -rf "$BV"
718718
# owner/repo#N, a full issue/PR URL, and a bare #N (to the RESOLVED repo);
719719
# references inside a fenced code block stay plain. A second message from an
720720
# UNRESOLVABLE doer (foreman) leaves its bare #N as plain text (no mislink).
721-
lmsg="$(printf 'from_host: h\nfrom: gardener:endojs-endo-but-for-bots-linktest\nreply_to: endojs-endo-but-for-bots-linktest\nsent_at: t1\n---\nOpened endojs/endo-but-for-bots#650 (CLI follow-up for #652).\nSee https://github.com/endojs/endo-but-for-bots/pull/653.\n\n```\nleave #999 and endojs/endo-but-for-bots#111 plain in a fence\n```\n')"
721+
lmsg="$(printf 'from_host: h\nfrom: gardener:endojs-endo-but-for-bots-linktest\nreply_to: endojs-endo-but-for-bots-linktest\nsent_at: t1\n---\nOpened endojs/endo-but-for-bots#650 (CLI follow-up for #652). Run `rebase #650` first.\nSee https://github.com/endojs/endo-but-for-bots/pull/653.\n\n```\nleave #999 and endojs/endo-but-for-bots#111 plain in a fence\n```\n')"
722722
push_change "inbox/maintainer/unread/bul-maint-2.md" "$lmsg" "seed maintainer message with issue refs"
723723
umsg="$(printf 'from_host: h\nfrom: foreman\nreply_to:\nsent_at: t2\n---\nUnresolvable doer note mentioning #4242 which must stay plain text.\n')"
724724
push_change "inbox/maintainer/unread/bul-maint-3.md" "$umsg" "seed unresolvable maintainer message"
@@ -732,6 +732,10 @@ rm -rf "$BV"; git clone -q --single-branch --branch "$BRANCH" "$BARE" "$BV"
732732
{ grep -qF '> leave #999 and endojs/endo-but-for-bots#111 plain in a fence' "$BV/README.md" \
733733
&& ! grep -qF '[#999](' "$BV/README.md"; } \
734734
&& ok "references inside a fenced code block stay plain (not autolinked)" || bad "fenced references were autolinked"
735+
# references inside an inline `code` span stay plain (a link inside backticks
736+
# would render as literal text) — the `#650` in `rebase #650` must NOT be linked
737+
grep -qF '`rebase #650`' "$BV/README.md" \
738+
&& ok "reference inside an inline code span stays plain (not autolinked)" || bad "inline-code-span reference was autolinked"
735739
# unresolvable bare #N is left plain — present as text, but never turned into a link
736740
{ grep -qF '#4242 which must stay plain text' "$BV/README.md" \
737741
&& ! grep -qF '[#4242](' "$BV/README.md"; } \

0 commit comments

Comments
 (0)