fix(ci): harden PR→issue linking gate against shell injection and missed refs#35761
fix(ci): harden PR→issue linking gate against shell injection and missed refs#35761nollymar wants to merge 3 commits into
Conversation
…sed refs The "PR opened" check silently failed on PRs whose body contained shell metacharacters (backticks, `$var(`, etc.), exiting before the linkage logic ran. Move `inputs.*` into a job-level `env:` block so they are no longer template-interpolated into bash sources. Add a GraphQL `closingIssuesReferences` fallback for refs the body regex misses (e.g. markdown-linked `fixes [#123](url)`). Re-evaluate the check on `edited`, `synchronize`, and `reopened` so a once-broken PR can recover after a body edit or new push instead of being stuck on the stale `opened` run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
❌ Issue Linking RequiredThis PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes. How to fix this:Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Why is this required?Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.--- This comment was automatically generated by the issue linking workflow |
|
Claude finished @nollymar's task in 2m 24s —— View job PR Review
The three fixes are coherent and the approach is sound. A few findings worth a second look: 1. Latent substring bug now exposed by broader triggers (medium)
if ! echo "$current_body" | grep -q "#$issue_number"; thenThis was already in the file, but the Suggest a word-boundaried match: if ! grep -qE "(^|[^0-9])#${issue_number}([^0-9]|$)" <<<"$current_body"; then2.
|
The widened triggers (synchronize/edited) caused the "Add failure comment to PR" step to repost the ❌ Issue Linking Required comment on every push to an unlinked PR. Mirror the lookup used by the Remove step and skip the POST if a matching bot comment already exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Skip the linking job on fork-sourced PRs. The pull_request token is read-only for forks, so the PATCH/POST/DELETE calls would 403 on every run — now amplified by synchronize/edited triggers. - Declare explicit pull-requests/issues write permissions on the reusable workflow so the dependency is visible and survives future default permission tightening. - Surface GraphQL fallback errors via ::warning:: instead of silently swallowing stderr with 2>/dev/null; users debugging a misleading "no issue found" failure can now see the underlying call's error. - Guard the fallback against an empty pr_number (malformed PR_URL) so it skips the GraphQL call with a clear warning instead of issuing an invalid Int query. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Three fixes to
issue_open-pr.ymland the reusableissue_comp_link-issue-to-pr.yml:inputs.pr_body,pr_title,pr_author,pr_url,pr_branch,pr_mergedwere template-substituted by GitHub Actions directly into the bashrun:scripts. PRs whose body contained backticks,$var(...), or unbalanced parens (e.g. feat(tiptap): convert Story Block content to Markdown (#35727) #35728's$markdownTool.blockToMarkdown(json)) caused a bash syntax error on the very firstDebug workflow inputsstep → entire job exits with code 2 →Add failure comment to PRis skipped (its condition requiresfailure_detected=true, never set) → PR appears unchecked. Hoisted all inputs into a job-levelenv:block and reference them as$ENV_VARin shell, so user-supplied values are treated as data, not code.(close[ds]?|fix(e[ds])?|resolve[ds]?)(:)?\s+#([0-9]+)requires a literal#immediately after the keyword and misses GitHub's other valid formfixes [#123](url)(as in feat(dotAI): Dot AI LangChain4J - Amazon Bedrock #35242). Added a GraphQLclosingIssuesReferenceslookup as the 4th and final fallback inDetermine final issue number— GitHub's own parser handles markdown-linked refs.pull_request: [opened], so editing the body or pushing new commits never re-evaluated the gate. A once-broken PR stayed broken even after the author fixed the link. Broadened triggers to[opened, edited, synchronize, reopened]. Existing idempotency (grep -q "#$issue_number"before body patch,sort -uon PR-list comments,Remove failure commentstep) handles the extra runs cleanly.The check remains advisory (not in branch-protection required checks on
main). This PR does not change that.Test plan
Link issue to PRworkflow on this PR itself. Confirm no shell error inDebug workflow inputs(the PR body contains backticks and$markdownTool.blockToMarkdown(json)-style text).synchronizere-fires the check.🤖 Generated with Claude Code