Skip to content

Commit

Permalink
Fixed duplicate handling.
Browse files Browse the repository at this point in the history
Improved to call the GitHub API only once with all the comments.
Fixed issue when the filename was matching with pattern.
  • Loading branch information
jrbasso committed Feb 15, 2024
1 parent 06eddbf commit c028074
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 57 deletions.
2 changes: 1 addition & 1 deletion badges/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 46 additions & 27 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 81 additions & 29 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ enum DiffScope {
REMOVED = 'removed'
}

interface GithubComment {
body: string
path: string
line: number
side: string
}

const hiddenCommentMarkup =
'<!-- This is an auto-generated comment: regex-match-commenter-action -->'

function isDuplicateComment(
existingComments: GithubComment[],
path: string,
line: number,
side: 'LEFT' | 'RIGHT'
): boolean {
return existingComments.some(
comment =>
comment.body.includes(hiddenCommentMarkup) &&
comment.path === path &&
comment.line === line &&
comment.side === side
)
}

/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
Expand All @@ -30,7 +55,7 @@ export async function run(): Promise<void> {
const octokit = github.getOctokit(token)
const { context } = github

core.debug('Fetching pull request ...')
core.info('Fetching pull request ...')
if (context.payload.pull_request == null) {
core.setFailed('No pull request found.')
return
Expand All @@ -41,7 +66,7 @@ export async function run(): Promise<void> {
const repo = context.repo.repo

// Fetch PR diff
core.debug('Fetching pull request diff ...')
core.info('Fetching pull request diff ...')
const { data: diffData } = await octokit.rest.pulls.get({
owner,
repo,
Expand All @@ -52,24 +77,37 @@ export async function run(): Promise<void> {
})

// Fetch existing comments on the PR
core.debug('Fetching existing comments ...')
const existingComments = await octokit.rest.issues.listComments({
core.info('Fetching existing comments ...')
const existingComments = await octokit.rest.pulls.listReviewComments({
owner,
repo,
issue_number: pullRequestNumber
pull_number: pullRequestNumber
})
core.debug(JSON.stringify(existingComments, null, 2))

// Parse diff and search for regex matches
core.debug('Parsing diff and searching for matches ...')
core.info('Parsing diff and searching for matches ...')
const lines = (diffData as unknown as string).split('\n')
core.debug(JSON.stringify(lines, null, 2))

const regex = new RegExp(regexPattern)
const newComments = []
let foundMatches = false
let currentFile = ''
let oldLineNumber = 0
let newLineNumber = 0

for (const line of lines) {
if (line.startsWith('+++ b/')) {
currentFile = line.substring('+++ b/'.length)
if (line.startsWith('diff --git a/')) {
currentFile = line.substring(
'diff --git a/'.length,
line.indexOf(' b/')
)
continue
}

if (line.startsWith('--- a/') || line.startsWith('+++ b/')) {
// Ignore the file path lines
continue
}

Expand Down Expand Up @@ -98,36 +136,47 @@ export async function run(): Promise<void> {
((diffScope === DiffScope.BOTH || diffScope === DiffScope.REMOVED) &&
line.startsWith('-'))
) {
const regex = new RegExp(regexPattern)
if (regex.test(line)) {
// Before posting a new comment, check if it already exists
const isDuplicate = existingComments.data.some(
comment => comment.body === matchFoundMessage
const side = line.startsWith('+') ? 'RIGHT' : 'LEFT'
const isDuplicate = isDuplicateComment(
existingComments.data as GithubComment[],
currentFile,
side === 'RIGHT' ? newLineNumber : oldLineNumber,
side
)
foundMatches = true

core.debug(`Regex matched ...`)
core.debug(
JSON.stringify(
{
currentFile,
lineContent: line,
lineNumber: side === 'RIGHT' ? newLineNumber : oldLineNumber,
isDuplicate
},
null,
2
)
)

if (!isDuplicate) {
core.debug(`Match found`)
foundMatches = true
const side = line.startsWith('+') ? 'RIGHT' : 'LEFT'

await octokit.rest.pulls.createReviewComment({
owner,
repo,
pull_number: pullRequestNumber,
body: matchFoundMessage,
commit_id: context.payload.pull_request.head.sha,
core.info(`Match found`)
newComments.push({
path: currentFile,
side,
line: side === 'LEFT' ? oldLineNumber : newLineNumber
body: `${hiddenCommentMarkup}\n${matchFoundMessage}`,
line: side === 'RIGHT' ? newLineNumber : oldLineNumber,
side
})
} else {
core.debug(`Match found but already commented`)
core.info(`Match found but already commented`)
}
}
}
}

if (!foundMatches) {
core.info('Adding comment about no matches found ...')
await octokit.rest.issues.createComment({
owner,
repo,
Expand All @@ -136,16 +185,19 @@ export async function run(): Promise<void> {
})
}

// Optional: Mark PR as changes requested
if (markChangesRequested && foundMatches) {
if (newComments.length > 0) {
core.info('Adding comments to the pull request ...')
await octokit.rest.pulls.createReview({
owner,
repo,
pull_number: pullRequestNumber,
event: 'REQUEST_CHANGES',
body: changesRequestedMessage
event: markChangesRequested ? 'REQUEST_CHANGES' : undefined,
body: changesRequestedMessage,
comments: newComments
})
}

// If there are no matches and no new comments, then we don't need to update the PR
} catch (error) {
// Fail the workflow run if an error occurs
if (error instanceof Error) core.setFailed(error.message)
Expand Down

0 comments on commit c028074

Please sign in to comment.