Publish GitHub review comments with single API call

This commit is contained in:
zmeir
2023-07-17 10:41:02 +03:00
parent 865888e4e8
commit 24583b05f7
3 changed files with 39 additions and 10 deletions

View File

@ -3,7 +3,7 @@ from datetime import datetime
from typing import Optional, Tuple from typing import Optional, Tuple
from urllib.parse import urlparse from urllib.parse import urlparse
from github import AppAuthentication, Github from github import AppAuthentication, Github, Auth
from pr_agent.config_loader import settings from pr_agent.config_loader import settings
@ -54,6 +54,10 @@ class GithubProvider(GitProvider):
self.pr.comments_list.append(response) self.pr.comments_list.append(response)
def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str):
logging.warning("Using deprecated `publish_inline_comment` - use `publish_inline_comments` instead")
self.publish_inline_comments([self.create_inline_comment(body, relevant_file, relevant_line_in_file)])
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str):
self.diff_files = self.diff_files if self.diff_files else self.get_diff_files() self.diff_files = self.diff_files if self.diff_files else self.get_diff_files()
position = -1 position = -1
for file in self.diff_files: for file in self.diff_files:
@ -72,9 +76,16 @@ class GithubProvider(GitProvider):
if position == -1: if position == -1:
if settings.config.verbosity_level >= 2: if settings.config.verbosity_level >= 2:
logging.info(f"Could not find position for {relevant_file} {relevant_line_in_file}") logging.info(f"Could not find position for {relevant_file} {relevant_line_in_file}")
subject_type = "FILE"
else: else:
subject_type = "LINE"
path = relevant_file.strip() path = relevant_file.strip()
self.pr.create_review_comment(body=body, commit_id=self.last_commit_id, path=path, position=position) # placeholder for future API support (already supported in single inline comment)
# return dict(body=body, path=path, position=position, subject_type=subject_type)
return dict(body=body, path=path, position=position) if subject_type == "LINE" else {}
def publish_inline_comments(self, comments: list[dict]):
self.pr.create_review(commit=self.last_commit_id, comments=comments)
def publish_code_suggestion(self, body: str, def publish_code_suggestion(self, body: str,
relevant_file: str, relevant_file: str,
@ -212,7 +223,7 @@ class GithubProvider(GitProvider):
raise ValueError( raise ValueError(
"GitHub token is required when using user deployment. See: " "GitHub token is required when using user deployment. See: "
"https://github.com/Codium-ai/pr-agent#method-2-run-from-source") from e "https://github.com/Codium-ai/pr-agent#method-2-run-from-source") from e
return Github(token) return Github(auth=Auth.Token(token))
def _get_repo(self): def _get_repo(self):
return self.github_client.get_repo(self.repo) return self.github_client.get_repo(self.repo)

View File

@ -92,6 +92,12 @@ class PRReviewer:
if settings.config.git_provider == 'github' and \ if settings.config.git_provider == 'github' and \
settings.pr_reviewer.inline_code_comments and \ settings.pr_reviewer.inline_code_comments and \
'Code suggestions' in data['PR Feedback']: 'Code suggestions' in data['PR Feedback']:
# keeping only code suggestions that can't be submitted as inline comments
data['PR Feedback']['Code suggestions'] = [
d for d in data['PR Feedback']['Code suggestions']
if any(key not in d for key in ('relevant file', 'relevant line in file', 'suggestion content'))
]
if not data['PR Feedback']['Code suggestions']:
del data['PR Feedback']['Code suggestions'] del data['PR Feedback']['Code suggestions']
markdown_text = convert_to_markdown(data) markdown_text = convert_to_markdown(data)
@ -118,9 +124,21 @@ class PRReviewer:
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
data = try_fix_json(review) data = try_fix_json(review)
comments = []
for d in data['PR Feedback']['Code suggestions']: for d in data['PR Feedback']['Code suggestions']:
relevant_file = d['relevant file'].strip() relevant_file = d.get('relevant file', '').strip()
relevant_line_in_file = d['relevant line in file'].strip() relevant_line_in_file = d.get('relevant line in file', '').strip()
content = d['suggestion content'] content = d.get('suggestion content', '')
if not relevant_file or not relevant_line_in_file or not content:
logging.info("Skipping inline comment with missing file/line/content")
continue
if settings.config.git_provider == 'github':
comment = self.git_provider.create_inline_comment(content, relevant_file, relevant_line_in_file)
if comment:
comments.append(comment)
else:
self.git_provider.publish_inline_comment(content, relevant_file, relevant_line_in_file) self.git_provider.publish_inline_comment(content, relevant_file, relevant_line_in_file)
if comments:
self.git_provider.publish_inline_comments(comments)

View File

@ -1,6 +1,6 @@
dynaconf==3.1.12 dynaconf==3.1.12
fastapi==0.99.0 fastapi==0.99.0
PyGithub==1.58.2 PyGithub==1.59.*
retry==0.9.2 retry==0.9.2
openai==0.27.8 openai==0.27.8
Jinja2==3.1.2 Jinja2==3.1.2