@@ -52,23 +52,18 @@ async function githubRequest<T>(path: string, options: RequestInit = {}): Promis
5252 return response . json ( ) as Promise < T > ;
5353}
5454
55- const repository = requiredEnv ( 'GITHUB_REPOSITORY' ) ;
56- const prNumber = requiredEnv ( 'PR_NUMBER' ) ;
57- const marker = requiredEnv ( 'COMMENT_MARKER' ) ;
58- const body = await Bun . file ( requiredEnv ( 'COMMENT_FILE' ) ) . text ( ) ;
59-
60- async function createComment ( ) : Promise < void > {
55+ async function createComment ( repository : string , prNumber : string , body : string ) : Promise < void > {
6156 await githubRequest ( `/repos/${ repository } /issues/${ prNumber } /comments` , {
6257 method : 'POST' ,
6358 body : JSON . stringify ( { body } ) ,
6459 } ) ;
6560}
6661
67- async function tryCreateComment ( ) : Promise < void > {
62+ async function tryCreateComment ( repository : string , prNumber : string , body : string ) : Promise < void > {
6863 try {
69- await createComment ( ) ;
64+ await createComment ( repository , prNumber , body ) ;
7065 } catch ( error ) {
71- if ( error instanceof GitHubRequestError && error . status === 403 ) {
66+ if ( isCommentWriteAuthFailure ( error ) ) {
7267 console . warn (
7368 `Skipping PR comment because GitHub token cannot write comments: ${ error . message } ` ,
7469 ) ;
@@ -78,24 +73,52 @@ async function tryCreateComment(): Promise<void> {
7873 }
7974}
8075
81- const comments = await githubRequest < GitHubComment [ ] > (
82- `/repos/${ repository } /issues/${ prNumber } /comments?per_page=100` ,
83- ) ;
84- const existing = comments . find (
85- ( comment ) => comment . user ?. login === 'github-actions[bot]' && comment . body ?. includes ( marker ) ,
86- ) ;
76+ function isCommentWriteAuthFailure ( error : unknown ) : error is GitHubRequestError {
77+ return error instanceof GitHubRequestError && ( error . status === 401 || error . status === 403 ) ;
78+ }
8779
88- if ( existing == null ) {
89- await tryCreateComment ( ) ;
90- } else {
91- try {
92- await githubRequest ( `/repos/${ repository } /issues/comments/${ existing . id } ` , {
93- method : 'PATCH' ,
94- body : JSON . stringify ( { body } ) ,
95- } ) ;
96- } catch ( error ) {
97- console . warn ( `Failed to update existing PR comment; creating a new comment instead.` ) ;
98- console . warn ( error ) ;
99- await tryCreateComment ( ) ;
80+ async function main ( ) : Promise < void > {
81+ const repository = requiredEnv ( 'GITHUB_REPOSITORY' ) ;
82+ const prNumber = requiredEnv ( 'PR_NUMBER' ) ;
83+ const marker = requiredEnv ( 'COMMENT_MARKER' ) ;
84+ const body = await Bun . file ( requiredEnv ( 'COMMENT_FILE' ) ) . text ( ) ;
85+ const comments = await githubRequest < GitHubComment [ ] > (
86+ `/repos/${ repository } /issues/${ prNumber } /comments?per_page=100` ,
87+ ) ;
88+ const existing = comments . find (
89+ ( comment ) => comment . user ?. login === 'github-actions[bot]' && comment . body ?. includes ( marker ) ,
90+ ) ;
91+
92+ if ( existing == null ) {
93+ await tryCreateComment ( repository , prNumber , body ) ;
94+ } else {
95+ try {
96+ await githubRequest ( `/repos/${ repository } /issues/comments/${ existing . id } ` , {
97+ method : 'PATCH' ,
98+ body : JSON . stringify ( { body } ) ,
99+ } ) ;
100+ } catch ( error ) {
101+ console . warn ( `Failed to update existing PR comment; creating a new comment instead.` ) ;
102+ console . warn ( error ) ;
103+ await tryCreateComment ( repository , prNumber , body ) ;
104+ }
100105 }
101106}
107+
108+ if ( import . meta. vitest != null ) {
109+ describe ( isCommentWriteAuthFailure , ( ) => {
110+ it ( 'treats unauthenticated comment writes as skippable' , ( ) => {
111+ expect ( isCommentWriteAuthFailure ( new GitHubRequestError ( 'unauthenticated' , 401 ) ) ) . toBe ( true ) ;
112+ } ) ;
113+
114+ it ( 'treats forbidden comment writes as skippable' , ( ) => {
115+ expect ( isCommentWriteAuthFailure ( new GitHubRequestError ( 'forbidden' , 403 ) ) ) . toBe ( true ) ;
116+ } ) ;
117+
118+ it ( 'keeps other GitHub errors fatal' , ( ) => {
119+ expect ( isCommentWriteAuthFailure ( new GitHubRequestError ( 'server error' , 500 ) ) ) . toBe ( false ) ;
120+ } ) ;
121+ } ) ;
122+ } else {
123+ await main ( ) ;
124+ }
0 commit comments