Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter SonarQube Issues by PR Diff Scope #8

Closed
adenisonafifi opened this issue Apr 13, 2022 · 2 comments
Closed

Filter SonarQube Issues by PR Diff Scope #8

adenisonafifi opened this issue Apr 13, 2022 · 2 comments

Comments

@adenisonafifi
Copy link

Thank you for this great project!

I'm testing it out currently and noticed that if the SonarQube issues are outside of the scope of the PR Diff then the Github API request fails:

PANI[0001] Failed to publish issues review               error="failed to create review: POST https://api.github.com/repos/{REPO}/pulls/3242/reviews: 422 Unprocessable Entity [{Resource: Field: Code: Message:Pull request review thread line must be part of the diff and Pull request review thread diff hunk can't be blank}]"
panic: (*logrus.Entry) 0xc0001ac1c0

This likely doesn't occur on smaller repos but my use case has functions with very large scope where pull requests making small changes get labeled with issues from the rest of the function scope.

I'm going to see if I can determine a way to filter out these issues that will not fit on the PR diff.

@adenisonafifi
Copy link
Author

adenisonafifi commented Apr 13, 2022

It looks like a combination of g.client.PullRequests.GetRaw(ctx, ghPath.Owner, ghPath.Repo, prNumber, github.RawOptions{github.Diff}) and using "github.com/sourcegraph/go-diff/diff" makes it possible to filter the issues by line number.

This is a quick pass (I'm not very familiar with Go):

github.go PublishIssuesReviewFor

        ghDiff, res, err := g.client.PullRequests.GetRaw(ctx, ghPath.Owner, ghPath.Repo, prNumber, github.RawOptions{github.Diff})
	if err != nil {
		return errors.Wrap(err, "failed to get raw PR")
	}

	fileDiffs, err := diff.ParseMultiFileDiff([]byte(ghDiff))
	if err != nil {
		return errors.Wrap(err, "failed to parse diff")	
	}

	m := make(map[string][]*diff.Hunk)

	for i := range fileDiffs {
		fileName := fileDiffs[i].OrigName[2:]
		m[fileName] = fileDiffs[i].Hunks 
	}

	comments := make([]*github.DraftReviewComment, 0)

	// Create a comment for each issue
	for _, issue := range issues {
		side := "RIGHT"
		message := issue.MarkdownMessage(g.sonar.Root)
		filePath := issue.FilePath()
		lineNumber := issue.Line

		hunks, exists := m[filePath]
		if(!exists) {
			continue
		}

		for _, hunk := range hunks {
			if(lineNumber < int(hunk.OrigStartLine) || lineNumber < int(hunk.NewStartLine)) {
				continue
			}
			if(lineNumber > int(hunk.OrigStartLine + hunk.OrigLines) || lineNumber > int(hunk.NewStartLine + hunk.NewLines)) {
				continue
			}

			comment := &github.DraftReviewComment{
				Path: &filePath,
				Body: &message,
				Side: &side,
				Line: &lineNumber,
			}

			comments = append(comments, comment)
		}
	}

	if(len(comments) <= 0) {
		return errors.Wrap(err, "failed to find relevant issues")
	}

	body := fmt.Sprintf(`:wave: Hey, I added %d comments about your changes, please take a look :slightly_smiling_face:`, len(issues))

	reviewRequest := &github.PullRequestReviewRequest{
		Body:     &body,
		Event:    &reviewEvent,
		Comments: comments,
	}

@herlon214
Copy link
Owner

hey @adenisonafifi thank you very much for reporting it, your solution sounds interesting, i will give it a try

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants