From 75167c270062ec46bf4817d4e8b3fdabbdab346c Mon Sep 17 00:00:00 2001 From: salberts Date: Sat, 8 Jul 2023 08:52:11 +0300 Subject: [PATCH] add polling --- pr_agent/agent/pr_agent.py | 8 +-- pr_agent/config_loader.py | 1 + pr_agent/servers/gitlab_polling.py | 66 ++++++++++++++++++++++++ pr_agent/settings/.secrets_template.toml | 6 +-- pr_agent/settings/configuration.toml | 12 ++++- pr_agent/tools/pr_questions.py | 3 +- pr_agent/tools/pr_reviewer.py | 2 +- 7 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 pr_agent/servers/gitlab_polling.py diff --git a/pr_agent/agent/pr_agent.py b/pr_agent/agent/pr_agent.py index 5958d15f..7e4a6c22 100644 --- a/pr_agent/agent/pr_agent.py +++ b/pr_agent/agent/pr_agent.py @@ -6,12 +6,12 @@ from pr_agent.tools.pr_reviewer import PRReviewer class PRAgent: - def __init__(self, installation_id: Optional[int] = None): - self.installation_id = installation_id + def __init__(self): + pass async def handle_request(self, pr_url, request): if 'please review' in request.lower() or 'review' == request.lower().strip() or len(request) == 0: - reviewer = PRReviewer(pr_url, self.installation_id) + reviewer = PRReviewer(pr_url) await reviewer.review() else: @@ -21,5 +21,5 @@ class PRAgent: question = re.split(r'(?i)answer', request)[1].strip() else: question = request - answerer = PRQuestions(pr_url, question, self.installation_id) + answerer = PRQuestions(pr_url, question) await answerer.answer() diff --git a/pr_agent/config_loader.py b/pr_agent/config_loader.py index 24dfdea7..550f743e 100644 --- a/pr_agent/config_loader.py +++ b/pr_agent/config_loader.py @@ -5,6 +5,7 @@ from dynaconf import Dynaconf current_dir = dirname(abspath(__file__)) settings = Dynaconf( envvar_prefix=False, + merge_enabled=True, settings_files=[join(current_dir, f) for f in [ "settings/.secrets.toml", "settings/configuration.toml", diff --git a/pr_agent/servers/gitlab_polling.py b/pr_agent/servers/gitlab_polling.py new file mode 100644 index 00000000..d86a7fe2 --- /dev/null +++ b/pr_agent/servers/gitlab_polling.py @@ -0,0 +1,66 @@ +import asyncio +import time +from urllib.parse import urlparse +import gitlab +from pr_agent.agent.pr_agent import PRAgent + +from pr_agent.config_loader import settings + + +gl = gitlab.Gitlab( + settings.get("GITLAB.URL"), + private_token=settings.get("GITLAB.PERSONAL_ACCESS_TOKEN") +) + +# Set the list of projects to monitor +projects_to_monitor = settings.get("GITLAB.PROJECTS_TO_MONITOR") +magic_word = settings.get("GITLAB.MAGIC_WORD") + +print(projects_to_monitor, magic_word, settings.get("GITLAB.PERSONAL_ACCESS_TOKEN")) +# Hold the previous seen comments +previous_comments = set() + + +def check_comments(): + print('Polling') + new_comments = {} + for project in projects_to_monitor: + project = gl.projects.get(project) + merge_requests = project.mergerequests.list(state='opened') + for mr in merge_requests: + notes = mr.notes.list(iterator=True) + for note in notes: + if note.id not in previous_comments and note.body.startswith(magic_word): + new_comments[note.id] = dict( + body=note.body[len(magic_word):], + project=project.name, + mr=mr + ) + previous_comments.add(note.id) + print(f"New comment in project {project.name}, merge request {mr.title}: {note.body}") + + return new_comments + + +def handle_new_comments(new_comments): + print('Handling new comments') + agent = PRAgent() + for _, comment in new_comments.items(): + print(f"Handling comment: {comment['body']}") + asyncio.run(agent.handle_request(comment['mr'].web_url, comment['body'])) + + +def run(): + + # Initial run to populate previous_comments + check_comments() + + # Run the check every minute + while True: + # time.sleep(60) + new_comments = check_comments() + if new_comments: + handle_new_comments(new_comments) + +if __name__ == '__main__': + run() diff --git a/pr_agent/settings/.secrets_template.toml b/pr_agent/settings/.secrets_template.toml index 82812734..9ed9ed15 100644 --- a/pr_agent/settings/.secrets_template.toml +++ b/pr_agent/settings/.secrets_template.toml @@ -27,8 +27,4 @@ app_id = 123456 # The GitHub App ID, replace with your own. webhook_secret = "" # Optional, may be commented out. [gitlab] -# The type of deployment to create. Valid values are 'app' or 'user'. -personal_access_token = "" - -# URL to the gitlab service -gitlab_url = "https://gitlab.com" \ No newline at end of file +personal_access_token = "" \ No newline at end of file diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 7368b1eb..086b96bb 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -12,4 +12,14 @@ extended_code_suggestions=false num_code_suggestions=4 -[pr_questions] \ No newline at end of file +[pr_questions] + +[gitlab] +# URL to the gitlab service +gitlab_url = "https://gitlab.com" + +# Polling +projects_to_monitor = [47494341] + +# Polling trigger +magic_word = "MagicRound" \ No newline at end of file diff --git a/pr_agent/tools/pr_questions.py b/pr_agent/tools/pr_questions.py index 38cd68b8..eb8e6bcb 100644 --- a/pr_agent/tools/pr_questions.py +++ b/pr_agent/tools/pr_questions.py @@ -13,12 +13,11 @@ from pr_agent.git_providers.git_provider import get_main_pr_language class PRQuestions: - def __init__(self, pr_url: str, question_str: str, installation_id: Optional[int] = None): + def __init__(self, pr_url: str, question_str: str): self.git_provider = get_git_provider()(pr_url) self.main_pr_language = get_main_pr_language( self.git_provider.get_languages(), self.git_provider.get_files() ) - self.installation_id = installation_id self.ai_handler = AiHandler() self.question_str = question_str self.vars = { diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index dd8d56d3..b43f274d 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -15,7 +15,7 @@ from pr_agent.git_providers.git_provider import get_main_pr_language class PRReviewer: - def __init__(self, pr_url: str, installation_id: Optional[int] = None, cli_mode=False): + def __init__(self, pr_url: str, cli_mode=False): self.git_provider = get_git_provider()(pr_url) self.main_language = get_main_pr_language(