From 3b4fdeb623194e83191a5d59dad0e2698dc24d02 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Tue, 15 Sep 2026 23:22:21 +0300 Subject: [PATCH] fix(ci): recognize bare AI co-author addresses --- tools/ci/src/commit-attribution.ts | 6 ++++-- tools/ci/tests/commit-messages.test.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/ci/src/commit-attribution.ts b/tools/ci/src/commit-attribution.ts index c137847bd..340553fa6 100644 --- a/tools/ci/src/commit-attribution.ts +++ b/tools/ci/src/commit-attribution.ts @@ -22,8 +22,10 @@ export function hasAICoauthor(message: string): boolean { encoding: 'utf8' }) return trailers.split('\n').some((line) => { - const email = /^co-authored-by:\s*.*<([^<>]+)>\s*$/i.exec(line)?.[1]?.trim().toLowerCase() - return email !== undefined && (AI_COAUTHOR_EMAILS.has(email) || AI_GITHUB_EMAIL.test(email)) + const value = /^co-authored-by:\s*(.*)$/i.exec(line)?.[1]?.trim() + if (!value) return false + const email = (/<([^<>]+)>$/.exec(value)?.[1] ?? value).trim().toLowerCase() + return AI_COAUTHOR_EMAILS.has(email) || AI_GITHUB_EMAIL.test(email) }) } diff --git a/tools/ci/tests/commit-messages.test.ts b/tools/ci/tests/commit-messages.test.ts index b33df173c..75f910c21 100644 --- a/tools/ci/tests/commit-messages.test.ts +++ b/tools/ci/tests/commit-messages.test.ts @@ -39,6 +39,7 @@ test.each([ test.each([ 'fix: document Claude Code and OpenAI integration', 'fix: preserve credits\n\nCo-authored-by: Claude Martin ', + 'fix: preserve credits\n\nCo-authored-by: person@example.org', 'fix: preserve credits\n\nCo-authored-by: Claude <123+claude@users.noreply.github.com>', 'fix: preserve credits\n\nCo-authored-by: Codex <456+codex@users.noreply.github.com>', 'fix: preserve credits\n\nCo-authored-by: Human Contributor ', @@ -49,6 +50,8 @@ test.each([ test.each([ 'Claude Sonnet 5 ', + 'noreply@anthropic.com', + 'NOREPLY@OPENAI.COM', 'Codex ', 'Cursor ', 'Gemini CLI ', @@ -84,6 +87,15 @@ test.each([ expect(result.output).toContain('Preserve human co-author credits') }) +test.each(['fix: update', 'Release v0.14.0'])( + 'rejects bare assistant email trailers: %s', + async (subject) => { + const result = await lint(`${subject}\n\nCo-authored-by: noreply@anthropic.com`) + expect(result.code).not.toBe(0) + expect(result.output).toContain('no-ai-coauthors') + } +) + test.each([ ['Fixed stuff', 'type-empty'], ['feature: add tools', 'type-enum'],