@@ -7,6 +7,31 @@ enum DiffScope {
77 REMOVED = 'removed'
88}
99
10+ interface GithubComment {
11+ body : string
12+ path : string
13+ line : number
14+ side : string
15+ }
16+
17+ const hiddenCommentMarkup =
18+ '<!-- This is an auto-generated comment: regex-match-commenter-action -->'
19+
20+ function isDuplicateComment (
21+ existingComments : GithubComment [ ] ,
22+ path : string ,
23+ line : number ,
24+ side : 'LEFT' | 'RIGHT'
25+ ) : boolean {
26+ return existingComments . some (
27+ comment =>
28+ comment . body . includes ( hiddenCommentMarkup ) &&
29+ comment . path === path &&
30+ comment . line === line &&
31+ comment . side === side
32+ )
33+ }
34+
1035/**
1136 * The main function for the action.
1237 * @returns {Promise<void> } Resolves when the action is complete.
@@ -30,7 +55,7 @@ export async function run(): Promise<void> {
3055 const octokit = github . getOctokit ( token )
3156 const { context } = github
3257
33- core . debug ( 'Fetching pull request ...' )
58+ core . info ( 'Fetching pull request ...' )
3459 if ( context . payload . pull_request == null ) {
3560 core . setFailed ( 'No pull request found.' )
3661 return
@@ -41,7 +66,7 @@ export async function run(): Promise<void> {
4166 const repo = context . repo . repo
4267
4368 // Fetch PR diff
44- core . debug ( 'Fetching pull request diff ...' )
69+ core . info ( 'Fetching pull request diff ...' )
4570 const { data : diffData } = await octokit . rest . pulls . get ( {
4671 owner,
4772 repo,
@@ -52,24 +77,37 @@ export async function run(): Promise<void> {
5277 } )
5378
5479 // Fetch existing comments on the PR
55- core . debug ( 'Fetching existing comments ...' )
56- const existingComments = await octokit . rest . issues . listComments ( {
80+ core . info ( 'Fetching existing comments ...' )
81+ const existingComments = await octokit . rest . pulls . listReviewComments ( {
5782 owner,
5883 repo,
59- issue_number : pullRequestNumber
84+ pull_number : pullRequestNumber
6085 } )
86+ core . debug ( JSON . stringify ( existingComments , null , 2 ) )
6187
6288 // Parse diff and search for regex matches
63- core . debug ( 'Parsing diff and searching for matches ...' )
89+ core . info ( 'Parsing diff and searching for matches ...' )
6490 const lines = ( diffData as unknown as string ) . split ( '\n' )
91+ core . debug ( JSON . stringify ( lines , null , 2 ) )
92+
93+ const regex = new RegExp ( regexPattern )
94+ const newComments = [ ]
6595 let foundMatches = false
6696 let currentFile = ''
6797 let oldLineNumber = 0
6898 let newLineNumber = 0
6999
70100 for ( const line of lines ) {
71- if ( line . startsWith ( '+++ b/' ) ) {
72- currentFile = line . substring ( '+++ b/' . length )
101+ if ( line . startsWith ( 'diff --git a/' ) ) {
102+ currentFile = line . substring (
103+ 'diff --git a/' . length ,
104+ line . indexOf ( ' b/' )
105+ )
106+ continue
107+ }
108+
109+ if ( line . startsWith ( '--- a/' ) || line . startsWith ( '+++ b/' ) ) {
110+ // Ignore the file path lines
73111 continue
74112 }
75113
@@ -98,36 +136,47 @@ export async function run(): Promise<void> {
98136 ( ( diffScope === DiffScope . BOTH || diffScope === DiffScope . REMOVED ) &&
99137 line . startsWith ( '-' ) )
100138 ) {
101- const regex = new RegExp ( regexPattern )
102139 if ( regex . test ( line ) ) {
103- // Before posting a new comment, check if it already exists
104- const isDuplicate = existingComments . data . some (
105- comment => comment . body === matchFoundMessage
140+ const side = line . startsWith ( '+' ) ? 'RIGHT' : 'LEFT'
141+ const isDuplicate = isDuplicateComment (
142+ existingComments . data as GithubComment [ ] ,
143+ currentFile ,
144+ side === 'RIGHT' ? newLineNumber : oldLineNumber ,
145+ side
146+ )
147+ foundMatches = true
148+
149+ core . debug ( `Regex matched ...` )
150+ core . debug (
151+ JSON . stringify (
152+ {
153+ currentFile,
154+ lineContent : line ,
155+ lineNumber : side === 'RIGHT' ? newLineNumber : oldLineNumber ,
156+ isDuplicate
157+ } ,
158+ null ,
159+ 2
160+ )
106161 )
107162
108163 if ( ! isDuplicate ) {
109- core . debug ( `Match found` )
110- foundMatches = true
111- const side = line . startsWith ( '+' ) ? 'RIGHT' : 'LEFT'
112-
113- await octokit . rest . pulls . createReviewComment ( {
114- owner,
115- repo,
116- pull_number : pullRequestNumber ,
117- body : matchFoundMessage ,
118- commit_id : context . payload . pull_request . head . sha ,
164+ core . info ( `Match found` )
165+ newComments . push ( {
119166 path : currentFile ,
120- side,
121- line : side === 'LEFT' ? oldLineNumber : newLineNumber
167+ body : `${ hiddenCommentMarkup } \n${ matchFoundMessage } ` ,
168+ line : side === 'RIGHT' ? newLineNumber : oldLineNumber ,
169+ side
122170 } )
123171 } else {
124- core . debug ( `Match found but already commented` )
172+ core . info ( `Match found but already commented` )
125173 }
126174 }
127175 }
128176 }
129177
130178 if ( ! foundMatches ) {
179+ core . info ( 'Adding comment about no matches found ...' )
131180 await octokit . rest . issues . createComment ( {
132181 owner,
133182 repo,
@@ -136,16 +185,19 @@ export async function run(): Promise<void> {
136185 } )
137186 }
138187
139- // Optional: Mark PR as changes requested
140- if ( markChangesRequested && foundMatches ) {
188+ if ( newComments . length > 0 ) {
189+ core . info ( 'Adding comments to the pull request ...' )
141190 await octokit . rest . pulls . createReview ( {
142191 owner,
143192 repo,
144193 pull_number : pullRequestNumber ,
145- event : 'REQUEST_CHANGES' ,
146- body : changesRequestedMessage
194+ event : markChangesRequested ? 'REQUEST_CHANGES' : undefined ,
195+ body : changesRequestedMessage ,
196+ comments : newComments
147197 } )
148198 }
199+
200+ // If there are no matches and no new comments, then we don't need to update the PR
149201 } catch ( error ) {
150202 // Fail the workflow run if an error occurs
151203 if ( error instanceof Error ) core . setFailed ( error . message )
0 commit comments