From 0f07aee43515c58828104d3f2391785c2c565dd5 Mon Sep 17 00:00:00 2001 From: tarunag10 Date: Sat, 4 Jul 2026 11:08:02 +0530 Subject: [PATCH] Use modern noreply email for co-author trailers (#1369) --- src/create-prompt/index.ts | 17 +++++++++++++++-- src/create-prompt/types.ts | 1 + test/create-prompt.test.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/create-prompt/index.ts b/src/create-prompt/index.ts index b7a48d31..9d9fa08b 100644 --- a/src/create-prompt/index.ts +++ b/src/create-prompt/index.ts @@ -122,6 +122,7 @@ export function prepareContext( // Extract trigger username and comment data based on event type let triggerUsername: string | undefined; + let triggerUserId: number | undefined; let commentId: string | undefined; let commentBody: string | undefined; @@ -129,15 +130,19 @@ export function prepareContext( commentId = context.payload.comment.id.toString(); commentBody = context.payload.comment.body; triggerUsername = context.payload.comment.user.login; + triggerUserId = context.payload.comment.user.id; } else if (isPullRequestReviewEvent(context)) { commentBody = context.payload.review.body ?? ""; triggerUsername = context.payload.review.user.login; + triggerUserId = context.payload.review.user.id; } else if (isPullRequestReviewCommentEvent(context)) { commentId = context.payload.comment.id.toString(); commentBody = context.payload.comment.body; triggerUsername = context.payload.comment.user.login; + triggerUserId = context.payload.comment.user.id; } else if (isIssuesEvent(context)) { triggerUsername = context.payload.issue.user.login; + triggerUserId = context.payload.issue.user.id; } // Create infrastructure fields object @@ -146,6 +151,7 @@ export function prepareContext( claudeCommentId, triggerPhrase, ...(triggerUsername && { triggerUsername }), + ...(triggerUserId && { triggerUserId }), ...(prompt && { prompt }), ...(claudeBranch && { claudeBranch }), }; @@ -394,9 +400,16 @@ function getCommitInstructions( context: PreparedContext, useCommitSigning: boolean, ): string { + const triggerName = githubData.triggerDisplayName ?? context.triggerUsername; + const triggerEmail = + context.triggerUserId && context.triggerUsername + ? `${context.triggerUserId}+${context.triggerUsername}@users.noreply.github.com` + : context.triggerUsername + ? `${context.triggerUsername}@users.noreply.github.com` + : undefined; const coAuthorLine = - (githubData.triggerDisplayName ?? context.triggerUsername) !== "Unknown" - ? `Co-authored-by: ${githubData.triggerDisplayName ?? context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>` + triggerName && triggerName !== "Unknown" && triggerEmail + ? `Co-authored-by: ${triggerName} <${triggerEmail}>` : ""; if (useCommitSigning) { diff --git a/src/create-prompt/types.ts b/src/create-prompt/types.ts index 27a15df0..5b3dd0e8 100644 --- a/src/create-prompt/types.ts +++ b/src/create-prompt/types.ts @@ -5,6 +5,7 @@ export type CommonFields = { claudeCommentId: string; triggerPhrase: string; triggerUsername?: string; + triggerUserId?: number; prompt?: string; claudeBranch?: string; }; diff --git a/test/create-prompt.test.ts b/test/create-prompt.test.ts index f0a02ffc..cf5a44ae 100644 --- a/test/create-prompt.test.ts +++ b/test/create-prompt.test.ts @@ -495,6 +495,32 @@ describe("generatePrompt", () => { ); }); + test("should use numeric GitHub noreply address when trigger user id is provided", async () => { + const envVars: PreparedContext = { + repository: "owner/repo", + claudeCommentId: "12345", + triggerPhrase: "@claude", + triggerUsername: "johndoe", + triggerUserId: 123456, + eventData: { + eventName: "issue_comment", + commentId: "67890", + isPR: false, + issueNumber: "123", + baseBranch: "main", + claudeBranch: "claude/issue-67890-20240101-1200", + commentBody: "@claude please fix this", + }, + }; + + const prompt = await generatePrompt(envVars, mockGitHubData, false, "tag"); + + expect(prompt).toContain( + "Co-authored-by: johndoe <123456+johndoe@users.noreply.github.com>", + ); + expect(prompt).not.toContain(""); + }); + test("should include PR-specific instructions only for PR events", async () => { const envVars: PreparedContext = { repository: "owner/repo",