@@ -124,6 +124,7 @@ export async function tagPatterns(
124124 repoOwner ,
125125 repoName ,
126126 prNumber ,
127+ headSha ,
127128 checkRun . html_url ,
128129 appToken
129130 ) ;
@@ -280,47 +281,98 @@ async function downloadFileEntries(solutionFiles) {
280281/**
281282 * issue comment ๋ชฉ๋ก์ ํ ๋ฒ ์ฝ์ด ๋ ๊ฐ์ง๋ฅผ ์ฒ๋ฆฌํ๋ค.
282283 * - ๋งํฌ ๋๊ธ: ๋ด์ด ๋จ ๊ฒ์ด ์์ผ๋ฉด ์ต์ check run ๋งํฌ๋ก ๊ณ ์น๊ณ , ์์ผ๋ฉด ์๋ก ๋จ๋ค.
284+ * ๋ถ์ ์ค์ ์ ์ปค๋ฐ์ด ํธ์๋๋ค๋ฉด ๋ ๋ฆ๊ฒ ๋๋ ์ด์ ๋ถ์์ด ์ต์ ๋งํฌ๋ฅผ ๋ฎ์ง ์๋๋ก ๊ฑด๋๋ด๋ค.
283285 * - ๋ ๊ฑฐ์ ๋จ๋
๋ณต์ก๋ issue comment: ์์ผ๋ฉด ์ญ์ ํ๋ค (๋ง์ด๊ทธ๋ ์ด์
).
284286 * ์คํจํด๋ check run ์ ์ด๋ฏธ ๊ฒ์๋์ผ๋ฏ๋ก ๋ก๊ทธ๋ง ๋จ๊ธด๋ค.
285287 */
286288async function syncIssueComments (
287289 repoOwner ,
288290 repoName ,
289291 prNumber ,
292+ headSha ,
290293 checkRunUrl ,
291294 appToken
292295) {
293- const listResponse = await fetch (
294- `https://api.github.com/repos/${ repoOwner } /${ repoName } /issues/${ prNumber } /comments?per_page=100` ,
295- { headers : getGitHubHeaders ( appToken ) }
296+ const comments = await listIssueComments (
297+ repoOwner ,
298+ repoName ,
299+ prNumber ,
300+ appToken
296301 ) ;
302+ if ( comments === null ) return ;
297303
298- if ( ! listResponse . ok ) {
299- console . error (
300- `[tagPatterns] Failed to list issue comments: ${ listResponse . status } `
301- ) ;
302- return ;
303- }
304-
305- const comments = await listResponse . json ( ) ;
306304 const findBotComment = ( marker ) =>
307305 comments . find ( ( c ) => c . user ?. type === "Bot" && c . body ?. includes ( marker ) ) ;
308306
309- await upsertLinkComment (
307+ const latestHeadSha = await getHeadSha (
310308 repoOwner ,
311309 repoName ,
312310 prNumber ,
313- findBotComment ( LINK_COMMENT_MARKER ) ,
314- checkRunUrl ,
315311 appToken
316312 ) ;
313+ if ( latestHeadSha === headSha ) {
314+ await upsertLinkComment (
315+ repoOwner ,
316+ repoName ,
317+ prNumber ,
318+ findBotComment ( LINK_COMMENT_MARKER ) ,
319+ checkRunUrl ,
320+ appToken
321+ ) ;
322+ } else {
323+ console . log (
324+ `[tagPatterns] Skipping link comment on PR #${ prNumber } : head moved from ${ headSha } to ${ latestHeadSha } `
325+ ) ;
326+ }
317327
318328 const legacy = findBotComment ( LEGACY_COMPLEXITY_MARKER ) ;
319329 if ( legacy ) {
320330 await deleteIssueComment ( repoOwner , repoName , legacy . id , appToken ) ;
321331 }
322332}
323333
334+ /**
335+ * PR ์ issue comment ๋ฅผ ๋ชจ๋ ํ์ด์ง์ ๊ฑธ์ณ ๋ชจ์๋ค. ์คํจํ๋ฉด null.
336+ */
337+ async function listIssueComments ( repoOwner , repoName , prNumber , appToken ) {
338+ const comments = [ ] ;
339+ for ( let page = 1 ; ; page ++ ) {
340+ const response = await fetch (
341+ `https://api.github.com/repos/${ repoOwner } /${ repoName } /issues/${ prNumber } /comments?per_page=100&page=${ page } ` ,
342+ { headers : getGitHubHeaders ( appToken ) }
343+ ) ;
344+
345+ if ( ! response . ok ) {
346+ console . error (
347+ `[tagPatterns] Failed to list issue comments: ${ response . status } `
348+ ) ;
349+ return null ;
350+ }
351+
352+ const batch = await response . json ( ) ;
353+ comments . push ( ...batch ) ;
354+ if ( batch . length < 100 ) return comments ;
355+ }
356+ }
357+
358+ /**
359+ * PR ์ ํ์ฌ head ์ปค๋ฐ SHA. ์คํจํ๋ฉด null ์ด๋ผ ๋งํฌ ๋๊ธ ๊ฐฑ์ ์ ๊ฑด๋๋ด๋ค.
360+ */
361+ async function getHeadSha ( repoOwner , repoName , prNumber , appToken ) {
362+ const response = await fetch (
363+ `https://api.github.com/repos/${ repoOwner } /${ repoName } /pulls/${ prNumber } ` ,
364+ { headers : getGitHubHeaders ( appToken ) }
365+ ) ;
366+
367+ if ( ! response . ok ) {
368+ console . error ( `[tagPatterns] Failed to get PR #${ prNumber } : ${ response . status } ` ) ;
369+ return null ;
370+ }
371+
372+ const pr = await response . json ( ) ;
373+ return pr . head ?. sha ?? null ;
374+ }
375+
324376async function upsertLinkComment (
325377 repoOwner ,
326378 repoName ,
0 commit comments