Hey @mrT23, I thinks there's a problem with moving this line to after `self.git_provider.publish_comment(pr_comment)`.
The reason I originally placed it here is because otherwise, if you run `/review --pr_reviewer.remove_previous_review_comment=true` it will publish your review and then immediately after delete it, because it will look for the previous review comment only after you published your new review - so it will take your new review as the previous one. In order to get the real "previous" review you must collect the comments list before publishing a review, so placing this method call first ensures that.
The method `self._get_previous_review_comment()` is a no-op if `pr_reviewer.remove_previous_review_comment=false` so I see no downside in keeping it before `self.git_provider.publish_comment(pr_comment)`
Additionally, the check for `if previous_review_comment:` is redundant because it's done internally in `self._remove_previous_review_comment`. I thought it looked cleaner without this extra nesting here, but if you think more verbosity is better I'll keep it.
The new feature can be enabled via the new configuration `github_app.handle_push_event`. To avoid any unwanted side-effects, the current default of this configuration is set to `false`.
The high level flow (assuming the configuration is enabled):
1. receive push event from GitHub
2. extract branch and commits from event
3. find PR url for branch (currently does not support PRs from forks)
4. perform configured commands (e.g. `/describe`, `/review -i`)
The push event flow is guarded by a backlog queue so that multiple push events on the same branch won't trigger multiple duplicate runs of the PR-Agent commands.
Example timeline:
1. push 1 - start handling event
2. push 2 - waiting to be handled while push 1 event is still running
3. push 3 - event is dropped since handling it and handling push 2 is the same, so it is redundant
4. push 1 finished being handled
5. push 2 awakens from wait and continues handling (potentially reviewing the commits of both push 2 and push 3)
All of these options are configurable and can be enabled/disabled as per the user's desire.
Additional minor changes in this PR:
1. Created `DefaultDictWithTimeout` utility class to avoid too much boilerplate code in managing caches for outdated triggers.
2. Guard against running increment review when there are no new commits.
3. Minor styling changes for incremented review text.
This changes the help message to display properly when running a custom deployment of the PR-Agent app (i.e. not via GitHub Actions, and with the setting `github_app.override_deployment_type=false`)
When `pr-agent` is reviewing a long list of messages, a TypeError is thrown on the line
```python
for message in reversed(discussion_messages):
```
When reviewing the PyGithub library, the recommend an alternate syntax for iterating a paginated list in reverse.
https://github.com/PyGithub/PyGithub/blob/v1.59.0/github/PaginatedList.py#L122-L125
```
If you want to iterate in reversed order, just do::
for repo in user.get_repos().reversed:
print(repo.name)
```
And here's a copy of the actual traceback
```
Traceback (most recent call last):
File "/app/pr_agent/servers/github_action_runner.py", line 68, in <module>
asyncio.run(run_action())
File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/app/pr_agent/servers/github_action_runner.py", line 64, in run_action
await PRAgent().handle_request(pr_url, body)
File "/app/pr_agent/agent/pr_agent.py", line 19, in handle_request
await PRReviewer(pr_url, is_answer=True).review()
File "/app/pr_agent/tools/pr_reviewer.py", line 49, in __init__
answer_str, question_str = self._get_user_answers()
File "/app/pr_agent/tools/pr_reviewer.py", line 253, in _get_user_answers
for message in reversed(discussion_messages):
TypeError: object of type 'PaginatedList' has no len()
```
This can help teams compare the review of the PR agent with that of a human reviewer, and fine-tune a score threshold for automatic approval where they decide the agent's review is satisfactory.