diff --git a/.github/workflows/review.yaml b/.github/workflows/review.yaml
index 31d1c982..1d20496a 100644
--- a/.github/workflows/review.yaml
+++ b/.github/workflows/review.yaml
@@ -8,7 +8,7 @@ jobs:
steps:
- name: PR Agent action step
id: pragent
- uses: Codium-ai/pr-agent@feature/github_action
+ uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
OPENAI_ORG: ${{ secrets.OPENAI_ORG }}
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index e69de29b..00000000
diff --git a/Dockerfile.github_action_dockerhub b/Dockerfile.github_action_dockerhub
new file mode 100644
index 00000000..61d64e25
--- /dev/null
+++ b/Dockerfile.github_action_dockerhub
@@ -0,0 +1 @@
+FROM codiumai/pr-agent:github_action
diff --git a/README.md b/README.md
index f556b13c..00c35c82 100644
--- a/README.md
+++ b/README.md
@@ -35,9 +35,10 @@ Example results:
- [Live demo](#live-demo)
-- [Quickstart](#Quickstart)
+- [Overview](#overview)
+- [Quickstart](#quickstart)
- [Usage and tools](#usage-and-tools)
-- [Configuration](#Configuration)
+- [Configuration](#configuration)
- [How it works](#how-it-works)
- [Roadmap](#roadmap)
- [Similar projects](#similar-projects)
@@ -52,6 +53,25 @@ Experience GPT-4 powered PR review on your public GitHub repository with our hos
To set up your own pr-agent, see the [Quickstart](#Quickstart) section
---
+## Overview
+`pr-agent` offers extensive pull request functionalities across various git providers:
+| | | Github | Gitlab | Bitbucket |
+|-------|---------------------------------------------|--------|--------|-----------|
+| TOOLS | Review | ✓ | ✓ | ✓ |
+| | ⮑ Inline review | ✓ | ✓ | |
+| | Ask | ✓ | ✓ | |
+| | Auto-Description | ✓ | | |
+| | Improve Code | ✓ | | |
+| | | | | |
+| USAGE | CLI | ✓ | ✓ | ✓ |
+| | Tagging bot | ✓ | ✓ | |
+| | Actions | ✓ | | |
+| | | | | |
+| CORE | PR compression | ✓ | ✓ | ✓ |
+| | Repo language prioritization | ✓ | ✓ | ✓ |
+| | Adaptive and token-aware
file patch fitting | ✓ | ✓ | ✓ |
+
+
## Quickstart
diff --git a/action.yaml b/action.yaml
index b592abee..a6ffe834 100644
--- a/action.yaml
+++ b/action.yaml
@@ -2,4 +2,4 @@ name: 'PR Agent'
description: 'Summarize, review and suggest improvements for pull requests'
runs:
using: 'docker'
- image: 'Dockerfile.github_action'
+ image: 'Dockerfile.github_action_dockerhub'
diff --git a/pr_agent/cli.py b/pr_agent/cli.py
index 78a795ea..da94f9a2 100644
--- a/pr_agent/cli.py
+++ b/pr_agent/cli.py
@@ -10,29 +10,48 @@ from pr_agent.tools.pr_reviewer import PRReviewer
def run():
- parser = argparse.ArgumentParser(description='AI based pull request analyzer')
+ parser = argparse.ArgumentParser(description='AI based pull request analyzer', usage="""\
+Usage: cli.py --pr-url
[].
+
+Supported commands:
+review / review_pr - Add a review that includes a summary of the PR and specific suggestions for improvement.
+ask / ask_question [question] - Ask a question about the PR.
+describe / describe_pr - Modify the PR title and description based on the PR's contents.
+improve / improve_code - Suggest improvements to the code in the PR as pull request comments ready to commit.
+""")
parser.add_argument('--pr_url', type=str, help='The URL of the PR to review', required=True)
- parser.add_argument('--question', type=str, help='Optional question to ask', required=False)
- parser.add_argument('--pr_description', action='store_true', required=False)
- parser.add_argument('--pr_code_suggestions', action='store_true', required=False)
+ parser.add_argument('command', type=str, help='The', choices=['review', 'review_pr',
+ 'ask', 'ask_question',
+ 'describe', 'describe_pr',
+ 'improve', 'improve_code'], default='review')
+ parser.add_argument('rest', nargs=argparse.REMAINDER, default=[])
args = parser.parse_args()
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
- if args.question:
- print(f"Question: {args.question} about PR {args.pr_url}")
- reviewer = PRQuestions(args.pr_url, args.question)
+ command = args.command.lower()
+ if command in ['ask', 'ask_question']:
+ question = ' '.join(args.rest).strip()
+ if len(question) == 0:
+ print("Please specify a question")
+ parser.print_help()
+ return
+ print(f"Question: {question} about PR {args.pr_url}")
+ reviewer = PRQuestions(args.pr_url, question)
asyncio.run(reviewer.answer())
- elif args.pr_description:
+ elif command in ['describe', 'describe_pr']:
print(f"PR description: {args.pr_url}")
reviewer = PRDescription(args.pr_url)
asyncio.run(reviewer.describe())
- elif args.pr_code_suggestions:
+ elif command in ['improve', 'improve_code']:
print(f"PR code suggestions: {args.pr_url}")
reviewer = PRCodeSuggestions(args.pr_url)
asyncio.run(reviewer.suggest())
- else:
+ elif command in ['review', 'review_pr']:
print(f"Reviewing PR: {args.pr_url}")
reviewer = PRReviewer(args.pr_url, cli_mode=True)
asyncio.run(reviewer.review())
+ else:
+ print(f"Unknown command: {command}")
+ parser.print_help()
if __name__ == '__main__':
diff --git a/pr_agent/servers/github_action_runner.py b/pr_agent/servers/github_action_runner.py
index 953b0b8f..ba6ffe9c 100644
--- a/pr_agent/servers/github_action_runner.py
+++ b/pr_agent/servers/github_action_runner.py
@@ -1,8 +1,11 @@
import asyncio
import json
import os
+import re
from pr_agent.config_loader import settings
+from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
+from pr_agent.tools.pr_description import PRDescription
from pr_agent.tools.pr_questions import PRQuestions
from pr_agent.tools.pr_reviewer import PRReviewer
@@ -16,10 +19,11 @@ async def run_action():
if not GITHUB_EVENT_PATH:
print("GITHUB_EVENT_PATH not set")
return
- event_payload = json.load(open(GITHUB_EVENT_PATH, 'r'))
- RUNNER_DEBUG = os.environ.get('RUNNER_DEBUG', None)
- if not RUNNER_DEBUG:
- print("RUNNER_DEBUG not set")
+ try:
+ event_payload = json.load(open(GITHUB_EVENT_PATH, 'r'))
+ except json.decoder.JSONDecodeError as e:
+ print(f"Failed to parse JSON: {e}")
+ return
OPENAI_KEY = os.environ.get('OPENAI_KEY', None)
if not OPENAI_KEY:
print("OPENAI_KEY not set")
@@ -48,10 +52,21 @@ async def run_action():
if comment_body:
pr_url = event_payload.get("issue", {}).get("pull_request", {}).get("url", None)
if pr_url:
- if comment_body.strip().lower() == "review":
+ body = comment_body.strip().lower()
+ if any(cmd in body for cmd in ["/review", "/review_pr"]):
await PRReviewer(pr_url).review()
- elif comment_body.lstrip().lower().startswith("answer"):
- await PRQuestions(pr_url, comment_body).answer()
+ elif any(cmd in body for cmd in ["/describe", "/describe_pr"]):
+ await PRDescription(pr_url).describe()
+ elif any(cmd in body for cmd in ["/improve", "/improve_code"]):
+ await PRCodeSuggestions(pr_url).suggest()
+ elif any(cmd in body for cmd in ["/ask", "/ask_question"]):
+ pattern = r'(/ask|/ask_question)\s*(.*)'
+ matches = re.findall(pattern, comment_body, re.IGNORECASE)
+ if matches:
+ question = matches[0][1]
+ await PRQuestions(pr_url, question).answer()
+ else:
+ print(f"Unknown command: {body}")
if __name__ == '__main__':
diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py
index e6d001e1..3168e459 100644
--- a/pr_agent/tools/pr_reviewer.py
+++ b/pr_agent/tools/pr_reviewer.py
@@ -96,15 +96,18 @@ class PRReviewer:
if not self.cli_mode:
markdown_text += "\n### How to use\n"
+ commands_text = "> /review - Ask for a new review after your update the PR\n" \
+ "> /describe - Modify the PR title and description based " \
+ "on the PR's contents.\n" \
+ "> /improve - Suggest improvements to the code in the PR as pull " \
+ "request comments ready to commit.\n" \
+ "> /ask - Ask a question about the PR.\n"
if user and '[bot]' not in user:
- markdown_text += f"> Tag me in a comment '@{user}' to ask for a new review after you update the PR.\n"
- markdown_text += "> You can also tag me and ask any question, " \
- f"for example '@{user} is the PR ready for merge?'"
+ markdown_text += f"> Tag me in a comment '@{user}' and add one of the following commands:\n" + \
+ commands_text
else:
- markdown_text += "> Add a comment that says 'review' to ask for a new review " \
- "after you update the PR.\n"
- markdown_text += "> You can also add a comment that says 'answer QUESTION', " \
- "for example 'answer is the PR ready for merge?'"
+ markdown_text += "> Add a comment to to invoke PR-Agent, use one of the following commands:\n" + \
+ commands_text
if settings.config.verbosity_level >= 2:
logging.info(f"Markdown response:\n{markdown_text}")