diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index bfef1240..ab9fcf48 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +## Unreleased +- review tool now posts persistent comments by default + ## [Version 0.9] - 2023-10-29 - codiumai/pr-agent:0.9 - codiumai/pr-agent:0.9-github_app diff --git a/Usage.md b/Usage.md index 9aa20482..f11b28df 100644 --- a/Usage.md +++ b/Usage.md @@ -173,7 +173,7 @@ push_commands = [ "/auto_review -i --pr_reviewer.remove_previous_review_comment=true", ] ``` -The means that when new code is pused to the PR, the PR-Agent will run the `describe` and incremental `auto_review` tools. +The means that when new code is pushed to the PR, the PR-Agent will run the `describe` and incremental `auto_review` tools. For the describe tool, the `add_original_user_description` and `keep_original_user_title` parameters will be set to true. For the `auto_review` tool, it will run in incremental mode, and the `remove_previous_review_comment` parameter will be set to true. diff --git a/docs/REVIEW.md b/docs/REVIEW.md index ac4d1b4a..342504e2 100644 --- a/docs/REVIEW.md +++ b/docs/REVIEW.md @@ -24,6 +24,8 @@ Under the section 'pr_reviewer', the [configuration file](./../pr_agent/settings - `num_code_suggestions`: number of code suggestions provided by the 'review' tool. Default is 4. - `inline_code_comments`: if set to true, the tool will publish the code suggestions as comments on the code diff. Default is false. - `automatic_review`: if set to false, no automatic reviews will be done. Default is true. +- `remove_previous_review_comment`: if set to true, the tool will remove the previous review comment before adding a new one. Default is false. +- `persistent_comment`: if set to true, the review comment will be persistent. Default is true. - `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...". - To enable `custom labels`, apply the configuration changes described [here](./GENERATE_CUSTOM_LABELS.md#configuration-changes) #### Incremental Mode diff --git a/pr_agent/git_providers/git_provider.py b/pr_agent/git_providers/git_provider.py index 59bf5956..742db30f 100644 --- a/pr_agent/git_providers/git_provider.py +++ b/pr_agent/git_providers/git_provider.py @@ -44,6 +44,9 @@ class GitProvider(ABC): def publish_comment(self, pr_comment: str, is_temporary: bool = False): pass + def publish_persistent_review(self, pr_comment: str): + self.publish_comment(pr_comment) + @abstractmethod def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): pass diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index cede29fd..67564b02 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -154,10 +154,20 @@ class GithubProvider(GitProvider): def publish_description(self, pr_title: str, pr_body: str): self.pr.edit(title=pr_title, body=pr_body) + def publish_persistent_review(self, pr_comment: str): + prev_comments = list(self.pr.get_issue_comments()) + for comment in prev_comments: + if comment.body.startswith('## PR Analysis'): + pr_comment_updated = pr_comment.replace('## PR Analysis\n', '## PR Analysis (updated)\n') + response = comment.edit(pr_comment_updated) + return + self.publish_comment(pr_comment) + def publish_comment(self, pr_comment: str, is_temporary: bool = False): if is_temporary and not get_settings().config.publish_output_progress: get_logger().debug(f"Skipping publish_comment for temporary comment: {pr_comment}") return + response = self.pr.create_issue_comment(pr_comment) if hasattr(response, "user") and hasattr(response.user, "login"): self.github_user_id = response.user.login diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index a769d079..a0e117ed 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -136,6 +136,18 @@ class GitLabProvider(GitProvider): except Exception as e: get_logger().exception(f"Could not update merge request {self.id_mr} description: {e}") + def publish_persistent_review(self, pr_comment: str): + try: + for comment in self.mr.notes.list(get_all=True)[::-1]: + if comment.body.startswith('## PR Analysis'): + pr_comment_updated = pr_comment.replace('## PR Analysis\n', '## PR Analysis (updated)\n') + response = self.mr.notes.update(comment.id, {'body': pr_comment_updated}) + return + except Exception as e: + get_logger().exception(f"Failed to update persistent review, error: {e}") + pass + self.publish_comment(pr_comment) + def publish_comment(self, mr_comment: str, is_temporary: bool = False): comment = self.mr.notes.create({'body': mr_comment}) if is_temporary: diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index b8020eeb..dd863ebb 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -26,6 +26,7 @@ inline_code_comments = false ask_and_reflect=false automatic_review=true remove_previous_review_comment=false +persistent_comment=true extra_instructions = "" # specific configurations for incremental review (/review -i) require_all_thresholds_for_incremental_review=false diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index 794b53e1..51e608a0 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -117,7 +117,13 @@ class PRReviewer: if get_settings().config.publish_output: get_logger().info('Pushing PR review...') previous_review_comment = self._get_previous_review_comment() - self.git_provider.publish_comment(pr_comment) + + # publish the review + if get_settings().pr_reviewer.persistent_comment and not self.incremental.is_incremental: + self.git_provider.publish_persistent_review(pr_comment) + else: + self.git_provider.publish_comment(pr_comment) + self.git_provider.remove_initial_comment() if previous_review_comment: self._remove_previous_review_comment(previous_review_comment) @@ -156,7 +162,6 @@ class PRReviewer: variables["diff"] = self.patches_diff # update diff environment = Environment(undefined=StrictUndefined) - # set_custom_labels(variables) system_prompt = environment.from_string(get_settings().pr_review_prompt.system).render(variables) user_prompt = environment.from_string(get_settings().pr_review_prompt.user).render(variables)