feat: isolate sticky comments by job ID to prevent workflow conflicts#940
feat: isolate sticky comments by job ID to prevent workflow conflicts#940TosinAF wants to merge 4 commits intoanthropics:mainfrom
Conversation
When multiple workflows use `use_sticky_comment: true` on the same PR,
they previously co-opted each other's comments due to bot ID/name
matching. This adds a hidden `<!-- sticky-job: {jobId} -->` header
using `github.job` to isolate each workflow's sticky comment
automatically with no user configuration needed.
- Add sticky-job header to comments via createCommentBody()
- Match comments by job ID header instead of bot ID/name
- Preserve sticky-job headers through sanitizeContent() pipeline
- Preserve sticky-job headers through updateCommentBody() rebuilds
- Add pagination for comment search on busy PRs
- Fall back to bot ID/name matching when no job ID is available
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use `<!-- bot: {id} -->` header format instead of `<!-- sticky-job: -->`
- Add extractBotHeader() for cleaner header extraction
- Move header preservation to MCP server instead of modifying sanitizer
- Adopt regex-based matching with hasAnyHeader check and legacy fallback
- Use context.inputs.botId for dynamic bot ID matching
- Revert sanitizer.ts to keep security code untouched
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The bot_id default (41898282 = github-actions[bot]) doesn't match
claude[bot] (209825114) when using OIDC auth. This caused the sticky
comment matching to always fail, creating new comments each run.
Header-based matching is authoritative — if a comment has our specific
<!-- bot: {id} --> header, that's sufficient for identification. Bot ID
check is now only used for legacy comments without headers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Legacy comments without headers will naturally age out. No need for bot ID fallback logic that was broken anyway (wrong default ID). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks for this! I tested this a bit and hit an issue. With tag mode ( Sticky comment reuse doesn't work for A couple of smaller things:
|
Summary
<!-- bot: {jobId} -->HTML comment headersclaude-code-review,claude-docs-review) automatically gets its own isolated comment viaGITHUB_JOBhasAnyHeadercheck for proper multi-bot isolation and legacy fallbackKey design decisions
GITHUB_JOBfor auto-isolation: No user configuration needed — each workflow job naturally gets a unique identifiersanitizer.ts(security code), the MCP server fetches the current comment to extract and re-prepend the bot header after sanitization<!-- bot: -->format: Aligns with Allowing multiple specialized bot in the same PR (using smart invisible tags) #780's header format for future compatibilitycontext.inputs.botIdfor matching: Uses the dynamic bot ID input instead of hardcodedCLAUDE_APP_BOT_IDFiles changed
action.ymlGITHUB_JOBenv varsrc/github/context.tsjobIdto inputssrc/github/operations/comments/common.tscreateCommentBody()with bot header,extractBotHeader()src/github/operations/comments/create-initial.tshasAnyHeaderchecksrc/github/operations/comments/update-with-branch.tssrc/github/operations/comment-logic.tsupdateCommentBody()src/mcp/github-comment-server.tssrc/github/utils/sanitizer.tsTest plan
<!-- bot: {jobId} -->🤖 Generated with Claude Code