fix: route Forgejo review comment updates to issue comment API
On Forgejo, the tracking comment for pull_request_review_comment events is always created as a regular issue comment (because Forgejo's webhook payload lacks the top-level comment object). The MCP server was incorrectly setting isPullRequestReviewComment=true based on the event name, causing every update to try pulls.updateReviewComment first — which 404'd and silently swallowed Claude's responses. Three fixes: - MCP server: detect Forgejo and always use issue comment path - update-comment-link: skip pulls.getReviewComment on Forgejo (saves one wasted 404 API call) - update-claude-comment: expand fallback to also catch 422 (defense in depth for Forgejo edge cases) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
821cc86c6e
commit
84cf34ff1f
3 files changed
+26
-8
No files matched your search
@@ -65,11 +65,13 @@ export async function updateCommentLink(
|
||||
try {
|
||||
// GitHub has separate ID namespaces for review comments and issue comments
|
||||
// We need to use the correct API based on the event type
|
||||
if (isPullRequestReviewCommentEvent(context)) {
|
||||
// For PR review comments, try the pulls API first.
|
||||
// On Forgejo, the initial comment may have been created as a regular
|
||||
// issue comment (because the payload lacks comment.id), so the pulls
|
||||
// endpoint may 404. Fall through to issue comment fetch in that case.
|
||||
//
|
||||
// On Forgejo, the tracking comment is always an issue comment because
|
||||
// Forgejo's pull_request_review_comment payload lacks the top-level
|
||||
// `comment` object (so createInitialComment falls back to
|
||||
// issues.createComment). Skip the pulls API attempt on Forgejo to avoid
|
||||
// a wasted 404 round-trip.
|
||||
if (isPullRequestReviewCommentEvent(context) && platform !== "forgejo") {
|
||||
try {
|
||||
console.log(`Fetching PR review comment ${commentId}`);
|
||||
const { data: prComment } = await octokit.rest.pulls.getReviewComment({
|
||||
|
||||
@@ -49,8 +49,14 @@ export async function updateClaudeComment(
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
// If PR review comment update fails with 404, fall back to issue comment API
|
||||
if (isPullRequestReviewComment && error.status === 404) {
|
||||
// If PR review comment update fails, fall back to issue comment API.
|
||||
// 404 = comment ID not in PR review namespace (expected on Forgejo where
|
||||
// tracking comments are always issue comments).
|
||||
// 422 = some Forgejo versions return Unprocessable Entity instead of 404.
|
||||
if (
|
||||
isPullRequestReviewComment &&
|
||||
(error.status === 404 || error.status === 422)
|
||||
) {
|
||||
response = await octokit.rest.issues.updateComment({
|
||||
owner,
|
||||
repo,
|
||||
|
||||
@@ -52,8 +52,18 @@ server.tool(
|
||||
baseUrl: GITHUB_API_URL,
|
||||
});
|
||||
|
||||
// The tracking comment is always created as a regular issue comment on
|
||||
// Forgejo because Forgejo's pull_request_review_comment payload lacks the
|
||||
// top-level `comment` object (so createInitialComment falls back to
|
||||
// issues.createComment). On GitHub, the tracking comment IS a review
|
||||
// comment reply (created via pulls.createReplyForReviewComment).
|
||||
//
|
||||
// Setting this wrong causes every MCP update to first try
|
||||
// pulls.updateReviewComment (404), and if the fallback doesn't trigger,
|
||||
// Claude's responses never reach the comment.
|
||||
const isForgejo = (process.env.GITHUB_API_URL || "").includes("/api/v1");
|
||||
const isPullRequestReviewComment =
|
||||
eventName === "pull_request_review_comment";
|
||||
eventName === "pull_request_review_comment" && !isForgejo;
|
||||
|
||||
const sanitizedBody = sanitizeContent(body);
|
||||
|
||||
|
||||
Reference in new issue
Block a user