mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-11 00:00:38 +08:00
Compare commits
51 Commits
releases/0
...
v0.8
Author | SHA1 | Date | |
---|---|---|---|
bb4c19e8d7 | |||
542be13da6 | |||
0df8071673 | |||
b17a4d9551 | |||
dc7db4cbdd | |||
4e94fcc372 | |||
4c72cfbff4 | |||
ac89867ac7 | |||
34ed598c20 | |||
e7aee84ea8 | |||
388684e2e8 | |||
8f81c18647 | |||
ba78475944 | |||
75dd5688fa | |||
aa32024078 | |||
9167c20512 | |||
a7fb5d98b1 | |||
fda47bb5cf | |||
9c4f849066 | |||
3e2e2d6c6e | |||
56cc804fcf | |||
62746294e3 | |||
d384b0644e | |||
3e07fe618f | |||
be54fb5bf8 | |||
46ec3c0754 | |||
5e608cc7e7 | |||
04162564ca | |||
992f51a019 | |||
2bc25b7435 | |||
fcd9821d10 | |||
911ad299e2 | |||
fbfa186733 | |||
7545b25823 | |||
1370a051f1 | |||
dcbd3132d1 | |||
497f84b3bd | |||
f7abdc6ae8 | |||
a2ca43afcd | |||
43af4aa182 | |||
e343ce8468 | |||
7b2c01181b | |||
978c56c128 | |||
4043dfff9e | |||
67052aa714 | |||
caee7cbf50 | |||
9bee3055c2 | |||
9bd5140ea4 | |||
12bd9e8b42 | |||
ca8997b616 | |||
ed1816a2d7 |
18
Dockerfile.bitbucket_pipeline
Normal file
18
Dockerfile.bitbucket_pipeline
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
FROM python:3.10 as base
|
||||||
|
|
||||||
|
ENV OPENAI_API_KEY=${OPENAI_API_KEY} \
|
||||||
|
BITBUCKET_BEARER_TOKEN=${BITBUCKET_BEARER_TOKEN} \
|
||||||
|
BITBUCKET_PR_ID=${BITBUCKET_PR_ID} \
|
||||||
|
BITBUCKET_REPO_SLUG=${BITBUCKET_REPO_SLUG} \
|
||||||
|
BITBUCKET_WORKSPACE=${BITBUCKET_WORKSPACE}
|
||||||
|
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ADD pyproject.toml .
|
||||||
|
ADD requirements.txt .
|
||||||
|
RUN pip install . && rm pyproject.toml requirements.txt
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
ADD pr_agent pr_agent
|
||||||
|
ADD bitbucket_pipeline/entrypoint.sh /
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
@ -1 +1 @@
|
|||||||
FROM codiumai/pr-agent:github_action
|
FROM codiumai/pr-agent:0.8-github_action
|
66
INSTALL.md
66
INSTALL.md
@ -16,6 +16,7 @@ There are several ways to use PR-Agent:
|
|||||||
- [Method 6: Deploy as a Lambda Function](INSTALL.md#method-6---deploy-as-a-lambda-function)
|
- [Method 6: Deploy as a Lambda Function](INSTALL.md#method-6---deploy-as-a-lambda-function)
|
||||||
- [Method 7: AWS CodeCommit](INSTALL.md#method-7---aws-codecommit-setup)
|
- [Method 7: AWS CodeCommit](INSTALL.md#method-7---aws-codecommit-setup)
|
||||||
- [Method 8: Run a GitLab webhook server](INSTALL.md#method-8---run-a-gitlab-webhook-server)
|
- [Method 8: Run a GitLab webhook server](INSTALL.md#method-8---run-a-gitlab-webhook-server)
|
||||||
|
- [Method 9: Run as a Bitbucket Pipeline](INSTALL.md#method-9-run-as-a-bitbucket-pipeline)
|
||||||
---
|
---
|
||||||
|
|
||||||
### Method 1: Use Docker image (no installation required)
|
### Method 1: Use Docker image (no installation required)
|
||||||
@ -122,7 +123,7 @@ jobs:
|
|||||||
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
|
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
```
|
```
|
||||||
** if you want to pin your action to a specific commit for stability reasons
|
** if you want to pin your action to a specific release (v0.7 for example) for stability reasons, use:
|
||||||
```yaml
|
```yaml
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -139,7 +140,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: PR Agent action step
|
- name: PR Agent action step
|
||||||
id: pragent
|
id: pragent
|
||||||
uses: Codium-ai/pr-agent@<commit_sha>
|
uses: Codium-ai/pr-agent@v0.7
|
||||||
env:
|
env:
|
||||||
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
|
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -155,7 +156,7 @@ The GITHUB_TOKEN secret is automatically created by GitHub.
|
|||||||
3. Merge this change to your main branch.
|
3. Merge this change to your main branch.
|
||||||
When you open your next PR, you should see a comment from `github-actions` bot with a review of your PR, and instructions on how to use the rest of the tools.
|
When you open your next PR, you should see a comment from `github-actions` bot with a review of your PR, and instructions on how to use the rest of the tools.
|
||||||
|
|
||||||
4. You may configure PR-Agent by adding environment variables under the env section corresponding to any configurable property in the [configuration](./Usage.md) file. Some examples:
|
4. You may configure PR-Agent by adding environment variables under the env section corresponding to any configurable property in the [configuration](pr_agent/settings/configuration.toml) file. Some examples:
|
||||||
```yaml
|
```yaml
|
||||||
env:
|
env:
|
||||||
# ... previous environment values
|
# ... previous environment values
|
||||||
@ -370,4 +371,63 @@ In the "Trigger" section, check the ‘comments’ and ‘merge request events
|
|||||||
6. Test your installation by opening a merge request or commenting or a merge request using one of CodiumAI's commands.
|
6. Test your installation by opening a merge request or commenting or a merge request using one of CodiumAI's commands.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Method 9: Run as a Bitbucket Pipeline
|
||||||
|
|
||||||
|
|
||||||
|
You can use our pre-build Bitbucket-Pipeline docker image to run as Bitbucket-Pipeline.
|
||||||
|
|
||||||
|
1. Add the following file in your repository bitbucket_pipelines.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
pipelines:
|
||||||
|
pull-requests:
|
||||||
|
'**':
|
||||||
|
- step:
|
||||||
|
name: PR Agent Pipeline
|
||||||
|
caches:
|
||||||
|
- pip
|
||||||
|
image: python:3.8
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
script:
|
||||||
|
- git clone https://github.com/Codium-ai/pr-agent.git
|
||||||
|
- cd pr-agent
|
||||||
|
- docker build -t bitbucket_runner:latest -f Dockerfile.bitbucket_pipeline .
|
||||||
|
- docker run -e OPENAI_API_KEY=$OPENAI_API_KEY -e BITBUCKET_BEARER_TOKEN=$BITBUCKET_BEARER_TOKEN -e BITBUCKET_PR_ID=$BITBUCKET_PR_ID -e BITBUCKET_REPO_SLUG=$BITBUCKET_REPO_SLUG -e BITBUCKET_WORKSPACE=$BITBUCKET_WORKSPACE bitbucket_runner:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add the following secret to your repository under Repository settings > Pipelines > Repository variables.
|
||||||
|
OPENAI_API_KEY: <your key>
|
||||||
|
BITBUCKET_BEARER_TOKEN: <your token>
|
||||||
|
|
||||||
|
3. To get BITBUCKET_BEARER_TOKEN follow these steps
|
||||||
|
So here is my step by step tutorial
|
||||||
|
i) Insert your workspace name instead of {workspace_name} and go to the following link in order to create an OAuth consumer.
|
||||||
|
|
||||||
|
https://bitbucket.org/{workspace_name}/workspace/settings/api
|
||||||
|
|
||||||
|
set callback URL to http://localhost:8976 (doesn't need to be a real server there)
|
||||||
|
select permissions: repository -> read
|
||||||
|
|
||||||
|
ii) use consumer's Key as a {client_id} and open the following URL in the browser
|
||||||
|
|
||||||
|
https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=code
|
||||||
|
|
||||||
|
iii)
|
||||||
|
after you press "Grant access" in the browser it will redirect you to
|
||||||
|
|
||||||
|
http://localhost:8976?code=<CODE>
|
||||||
|
|
||||||
|
iv) use the code from the previous step and consumer's Key as a {client_id}, and consumer's Secret as {client_secret}
|
||||||
|
|
||||||
|
curl -X POST -u "{client_id}:{client_secret}" \
|
||||||
|
https://bitbucket.org/site/oauth2/access_token \
|
||||||
|
-d grant_type=authorization_code \
|
||||||
|
-d code={code} \
|
||||||
|
|
||||||
|
|
||||||
|
After completing this steps, you just to place this access token in the repository varibles.
|
||||||
|
|
||||||
|
|
||||||
=======
|
=======
|
||||||
|
@ -32,6 +32,8 @@ CodiumAI `PR-Agent` is an open-source tool aiming to help developers review pull
|
|||||||
|
|
||||||
See the [usage guide](./Usage.md) for instructions how to run the different tools from [CLI](./Usage.md#working-from-a-local-repo-cli), or by [online usage](./Usage.md#online-usage), as well as additional details on optional commands and configurations.
|
See the [usage guide](./Usage.md) for instructions how to run the different tools from [CLI](./Usage.md#working-from-a-local-repo-cli), or by [online usage](./Usage.md#online-usage), as well as additional details on optional commands and configurations.
|
||||||
|
|
||||||
|
[Release notes](./RELEASE_NOTES.md)
|
||||||
|
|
||||||
<h3>Example results:</h3>
|
<h3>Example results:</h3>
|
||||||
</div>
|
</div>
|
||||||
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1687561986">/describe:</a></h4>
|
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1687561986">/describe:</a></h4>
|
||||||
@ -157,6 +159,7 @@ There are several ways to use PR-Agent:
|
|||||||
- [Method 6: Deploy as a Lambda Function](INSTALL.md#method-6---deploy-as-a-lambda-function)
|
- [Method 6: Deploy as a Lambda Function](INSTALL.md#method-6---deploy-as-a-lambda-function)
|
||||||
- [Method 7: AWS CodeCommit](INSTALL.md#method-7---aws-codecommit-setup)
|
- [Method 7: AWS CodeCommit](INSTALL.md#method-7---aws-codecommit-setup)
|
||||||
- [Method 8: Run a GitLab webhook server](INSTALL.md#method-8---run-a-gitlab-webhook-server)
|
- [Method 8: Run a GitLab webhook server](INSTALL.md#method-8---run-a-gitlab-webhook-server)
|
||||||
|
- [Method 9: Run as a Bitbucket Pipeline](INSTALL.md#method-9-run-as-a-bitbucket-pipeline)
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
## [Version 0.8] - 2023-09-27
|
||||||
|
- codiumai/pr-agent:0.8
|
||||||
|
- codiumai/pr-agent:0.8-github_app
|
||||||
|
- codiumai/pr-agent:0.8-bitbucket-app
|
||||||
|
- codiumai/pr-agent:0.8-gitlab_webhook
|
||||||
|
- codiumai/pr-agent:0.8-github_polling
|
||||||
|
- codiumai/pr-agent:0.8-github_action
|
||||||
|
|
||||||
|
### Added::Algo
|
||||||
|
- GitHub Action: Can control which tools will run automatically when a new PR is created. (see usage guide: https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#working-with-github-action)
|
||||||
|
- Code suggestion tool: Will try to avoid an 'add comments' suggestion (see https://github.com/Codium-ai/pr-agent/pull/327)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Gitlab: Fixed a bug of improper usage of pr_id
|
||||||
|
|
||||||
|
|
||||||
## [Version 0.7] - 2023-09-20
|
## [Version 0.7] - 2023-09-20
|
||||||
|
|
||||||
### Docker Tags
|
### Docker Tags
|
||||||
@ -8,17 +24,18 @@
|
|||||||
- codiumai/pr-agent:0.7-github_polling
|
- codiumai/pr-agent:0.7-github_polling
|
||||||
- codiumai/pr-agent:0.7-github_action
|
- codiumai/pr-agent:0.7-github_action
|
||||||
|
|
||||||
### Added
|
### Added::Algo
|
||||||
-
|
- New tool /similar_issue - Currently on GitHub app and CLI: indexes the issues in the repo, find the most similar issues to the target issue.
|
||||||
|
- Describe markers: Empower the /describe tool with a templating capability (see more details in https://github.com/Codium-ai/pr-agent/pull/273).
|
||||||
|
- New feature in the /review tool - added an estimated effort estimation to the review (https://github.com/Codium-ai/pr-agent/pull/306).
|
||||||
|
|
||||||
### Changed
|
### Added::Infrastructure
|
||||||
-
|
- Implementation of a GitLab webhook.
|
||||||
|
- Implementation of a BitBucket app.
|
||||||
### Deprecated
|
|
||||||
-
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
-
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
-
|
- Protection against no code suggestions generated.
|
||||||
|
- Resilience to repositories where the languages cannot be automatically detected.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
16
Usage.md
16
Usage.md
@ -142,7 +142,21 @@ user="""
|
|||||||
Note that the new prompt will need to generate an output compatible with the relevant [post-process function](./pr_agent/tools/pr_description.py#L137).
|
Note that the new prompt will need to generate an output compatible with the relevant [post-process function](./pr_agent/tools/pr_description.py#L137).
|
||||||
|
|
||||||
### Working with GitHub Action
|
### Working with GitHub Action
|
||||||
TBD
|
You can configure settings in GitHub action by adding environment variables under the env section in `.github/workflows/pr_agent.yml` file. Some examples:
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
# ... previous environment values
|
||||||
|
OPENAI.ORG: "<Your organization name under your OpenAI account>"
|
||||||
|
PR_REVIEWER.REQUIRE_TESTS_REVIEW: "false" # Disable tests review
|
||||||
|
PR_CODE_SUGGESTIONS.NUM_CODE_SUGGESTIONS: 6 # Increase number of code suggestions
|
||||||
|
github_action.auto_review: "true" # Enable auto review
|
||||||
|
github_action.auto_describe: "true" # Enable auto describe
|
||||||
|
github_action.auto_improve: "false" # Disable auto improve
|
||||||
|
```
|
||||||
|
specifically, `github_action.auto_review`, `github_action.auto_describe` and `github_action.auto_improve` are used to enable/disable automatic tools that run when a new PR is opened.
|
||||||
|
|
||||||
|
if not set, the default option is that only the `review` tool will run automatically when a new PR is opened.
|
||||||
|
|
||||||
|
|
||||||
### Appendix - additional configurations walkthrough
|
### Appendix - additional configurations walkthrough
|
||||||
|
|
||||||
|
2
bitbucket_pipeline/entrypoint.sh
Normal file
2
bitbucket_pipeline/entrypoint.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
python /app/pr_agent/servers/bitbucket_pipeline_runner.py
|
@ -40,12 +40,16 @@ def extend_patch(original_file_str, patch_str, num_lines) -> str:
|
|||||||
extended_patch_lines.extend(
|
extended_patch_lines.extend(
|
||||||
original_lines[start1 + size1 - 1:start1 + size1 - 1 + num_lines])
|
original_lines[start1 + size1 - 1:start1 + size1 - 1 + num_lines])
|
||||||
|
|
||||||
|
res = list(match.groups())
|
||||||
|
for i in range(len(res)):
|
||||||
|
if res[i] is None:
|
||||||
|
res[i] = 0
|
||||||
try:
|
try:
|
||||||
start1, size1, start2, size2 = map(int, match.groups()[:4])
|
start1, size1, start2, size2 = map(int, res[:4])
|
||||||
except: # '@@ -0,0 +1 @@' case
|
except: # '@@ -0,0 +1 @@' case
|
||||||
start1, size1, size2 = map(int, match.groups()[:3])
|
start1, size1, size2 = map(int, res[:3])
|
||||||
start2 = 0
|
start2 = 0
|
||||||
section_header = match.groups()[4]
|
section_header = res[4]
|
||||||
extended_start1 = max(1, start1 - num_lines)
|
extended_start1 = max(1, start1 - num_lines)
|
||||||
extended_size1 = size1 + (start1 - extended_start1) + num_lines
|
extended_size1 = size1 + (start1 - extended_start1) + num_lines
|
||||||
extended_start2 = max(1, start2 - num_lines)
|
extended_start2 = max(1, start2 - num_lines)
|
||||||
@ -207,10 +211,15 @@ __old hunk__
|
|||||||
old_content_lines = []
|
old_content_lines = []
|
||||||
if match:
|
if match:
|
||||||
prev_header_line = header_line
|
prev_header_line = header_line
|
||||||
|
|
||||||
|
res = list(match.groups())
|
||||||
|
for i in range(len(res)):
|
||||||
|
if res[i] is None:
|
||||||
|
res[i] = 0
|
||||||
try:
|
try:
|
||||||
start1, size1, start2, size2 = map(int, match.groups()[:4])
|
start1, size1, start2, size2 = map(int, res[:4])
|
||||||
except: # '@@ -0,0 +1 @@' case
|
except: # '@@ -0,0 +1 @@' case
|
||||||
start1, size1, size2 = map(int, match.groups()[:3])
|
start1, size1, size2 = map(int, res[:3])
|
||||||
start2 = 0
|
start2 = 0
|
||||||
|
|
||||||
elif line.startswith('+'):
|
elif line.startswith('+'):
|
||||||
|
@ -233,8 +233,20 @@ class CodeCommitProvider(GitProvider):
|
|||||||
raise NotImplementedError("CodeCommit provider does not support publishing inline comments yet")
|
raise NotImplementedError("CodeCommit provider does not support publishing inline comments yet")
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return self.pr.get("title", "")
|
return self.pr.title
|
||||||
|
|
||||||
|
def get_pr_id(self):
|
||||||
|
"""
|
||||||
|
Returns the PR ID in the format: "repo_name/pr_number".
|
||||||
|
Note: This is an internal identifier for PR-Agent,
|
||||||
|
and is not the same as the CodeCommit PR identifier.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
pr_id = f"{self.repo_name}/{self.pr_num}"
|
||||||
|
return pr_id
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
|
||||||
def get_languages(self):
|
def get_languages(self):
|
||||||
"""
|
"""
|
||||||
Returns a dictionary of languages, containing the percentage of each language used in the PR.
|
Returns a dictionary of languages, containing the percentage of each language used in the PR.
|
||||||
|
@ -127,6 +127,9 @@ class GitProvider(ABC):
|
|||||||
def get_commit_messages(self):
|
def get_commit_messages(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_pr_id(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
def get_main_pr_language(languages, files) -> str:
|
def get_main_pr_language(languages, files) -> str:
|
||||||
"""
|
"""
|
||||||
Get the main language of the commit. Return an empty string if cannot determine.
|
Get the main language of the commit. Return an empty string if cannot determine.
|
||||||
|
@ -239,9 +239,10 @@ class GithubProvider(GitProvider):
|
|||||||
def get_user_id(self):
|
def get_user_id(self):
|
||||||
if not self.github_user_id:
|
if not self.github_user_id:
|
||||||
try:
|
try:
|
||||||
self.github_user_id = self.github_client.get_user().login
|
self.github_user_id = self.github_client.get_user().raw_data['login']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"Failed to get user id, error: {e}")
|
self.github_user_id = ""
|
||||||
|
# logging.exception(f"Failed to get user id, error: {e}")
|
||||||
return self.github_user_id
|
return self.github_user_id
|
||||||
|
|
||||||
def get_notifications(self, since: datetime):
|
def get_notifications(self, since: datetime):
|
||||||
@ -446,3 +447,10 @@ class GithubProvider(GitProvider):
|
|||||||
logging.info(f"Failed adding line link, error: {e}")
|
logging.info(f"Failed adding line link, error: {e}")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def get_pr_id(self):
|
||||||
|
try:
|
||||||
|
pr_id = f"{self.repo}/{self.pr_num}"
|
||||||
|
return pr_id
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
@ -378,4 +378,11 @@ class GitLabProvider(GitProvider):
|
|||||||
commit_messages_str = ""
|
commit_messages_str = ""
|
||||||
if max_tokens:
|
if max_tokens:
|
||||||
commit_messages_str = clip_tokens(commit_messages_str, max_tokens)
|
commit_messages_str = clip_tokens(commit_messages_str, max_tokens)
|
||||||
return commit_messages_str
|
return commit_messages_str
|
||||||
|
|
||||||
|
def get_pr_id(self):
|
||||||
|
try:
|
||||||
|
pr_id = self.mr.web_url
|
||||||
|
return pr_id
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
34
pr_agent/servers/bitbucket_pipeline_runner.py
Normal file
34
pr_agent/servers/bitbucket_pipeline_runner.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import os
|
||||||
|
from pr_agent.agent.pr_agent import PRAgent
|
||||||
|
from pr_agent.config_loader import get_settings
|
||||||
|
from pr_agent.tools.pr_reviewer import PRReviewer
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async def run_action():
|
||||||
|
try:
|
||||||
|
pull_request_id = os.environ.get("BITBUCKET_PR_ID", '')
|
||||||
|
slug = os.environ.get("BITBUCKET_REPO_SLUG", '')
|
||||||
|
workspace = os.environ.get("BITBUCKET_WORKSPACE", '')
|
||||||
|
bearer_token = os.environ.get('BITBUCKET_BEARER_TOKEN', None)
|
||||||
|
OPENAI_KEY = os.environ.get('OPENAI_API_KEY') or os.environ.get('OPENAI.KEY')
|
||||||
|
OPENAI_ORG = os.environ.get('OPENAI_ORG') or os.environ.get('OPENAI.ORG')
|
||||||
|
# Check if required environment variables are set
|
||||||
|
if not bearer_token:
|
||||||
|
print("BITBUCKET_BEARER_TOKEN not set")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not OPENAI_KEY:
|
||||||
|
print("OPENAI_KEY not set")
|
||||||
|
return
|
||||||
|
# Set the environment variables in the settings
|
||||||
|
get_settings().set("BITBUCKET.BEARER_TOKEN", bearer_token)
|
||||||
|
get_settings().set("OPENAI.KEY", OPENAI_KEY)
|
||||||
|
if OPENAI_ORG:
|
||||||
|
get_settings().set("OPENAI.ORG", OPENAI_ORG)
|
||||||
|
if pull_request_id and slug and workspace:
|
||||||
|
pr_url = f"https://bitbucket.org/{workspace}/{slug}/pull-requests/{pull_request_id}"
|
||||||
|
await PRReviewer(pr_url).run()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred: {e}")
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(run_action())
|
@ -5,6 +5,8 @@ import os
|
|||||||
from pr_agent.agent.pr_agent import PRAgent
|
from pr_agent.agent.pr_agent import PRAgent
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
from pr_agent.git_providers import get_git_provider
|
from pr_agent.git_providers import get_git_provider
|
||||||
|
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
||||||
|
from pr_agent.tools.pr_description import PRDescription
|
||||||
from pr_agent.tools.pr_reviewer import PRReviewer
|
from pr_agent.tools.pr_reviewer import PRReviewer
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +55,15 @@ async def run_action():
|
|||||||
if action in ["opened", "reopened"]:
|
if action in ["opened", "reopened"]:
|
||||||
pr_url = event_payload.get("pull_request", {}).get("url")
|
pr_url = event_payload.get("pull_request", {}).get("url")
|
||||||
if pr_url:
|
if pr_url:
|
||||||
await PRReviewer(pr_url).run()
|
auto_review = os.environ.get('github_action.auto_review', None)
|
||||||
|
if auto_review is None or (isinstance(auto_review, str) and auto_review.lower() == 'true'):
|
||||||
|
await PRReviewer(pr_url).run()
|
||||||
|
auto_describe = os.environ.get('github_action.auto_describe', None)
|
||||||
|
if isinstance(auto_describe, str) and auto_describe.lower() == 'true':
|
||||||
|
await PRDescription(pr_url).run()
|
||||||
|
auto_improve = os.environ.get('github_action.auto_improve', None)
|
||||||
|
if isinstance(auto_improve, str) and auto_improve.lower() == 'true':
|
||||||
|
await PRCodeSuggestions(pr_url).run()
|
||||||
|
|
||||||
# Handle issue comment event
|
# Handle issue comment event
|
||||||
elif GITHUB_EVENT_NAME == "issue_comment":
|
elif GITHUB_EVENT_NAME == "issue_comment":
|
||||||
|
@ -58,6 +58,11 @@ extra_instructions = ""
|
|||||||
deployment_type = "user"
|
deployment_type = "user"
|
||||||
ratelimit_retries = 5
|
ratelimit_retries = 5
|
||||||
|
|
||||||
|
[github_action]
|
||||||
|
# auto_review = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
|
# auto_describe = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
|
# auto_improve = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
|
|
||||||
[github_app]
|
[github_app]
|
||||||
# these toggles allows running the github app from custom deployments
|
# these toggles allows running the github app from custom deployments
|
||||||
bot_user = "github-actions[bot]"
|
bot_user = "github-actions[bot]"
|
||||||
|
@ -34,7 +34,7 @@ Specific instructions:
|
|||||||
- Provide up to {{ num_code_suggestions }} code suggestions.
|
- Provide up to {{ num_code_suggestions }} code suggestions.
|
||||||
- Prioritize suggestions that address major problems, issues and bugs in the code.
|
- Prioritize suggestions that address major problems, issues and bugs in the code.
|
||||||
As a second priority, suggestions should focus on best practices, code readability, maintainability, enhancments, performance, and other aspects.
|
As a second priority, suggestions should focus on best practices, code readability, maintainability, enhancments, performance, and other aspects.
|
||||||
Don't suggest to add docstring or type hints.
|
Don't suggest to add docstring, type hints, or comments.
|
||||||
Try to provide diverse and insightful suggestions.
|
Try to provide diverse and insightful suggestions.
|
||||||
- Suggestions should refer only to code from the '__new hunk__' sections, and focus on new lines of code (lines starting with '+').
|
- Suggestions should refer only to code from the '__new hunk__' sections, and focus on new lines of code (lines starting with '+').
|
||||||
Avoid making suggestions that have already been implemented in the PR code. For example, if you want to add logs, or change a variable to const, or anything else, make sure it isn't already in the '__new hunk__' code.
|
Avoid making suggestions that have already been implemented in the PR code. For example, if you want to add logs, or change a variable to const, or anything else, make sure it isn't already in the '__new hunk__' code.
|
||||||
|
@ -22,13 +22,13 @@ code line that already existed in the file....
|
|||||||
...
|
...
|
||||||
'
|
'
|
||||||
|
|
||||||
Thre review should focus on new code added in the PR (lines starting with '+'), and not on code that already existed in the file (lines starting with '-', or without prefix).
|
The review should focus on new code added in the PR (lines starting with '+'), and not on code that already existed in the file (lines starting with '-', or without prefix).
|
||||||
|
|
||||||
{%- if num_code_suggestions > 0 %}
|
{%- if num_code_suggestions > 0 %}
|
||||||
- Provide up to {{ num_code_suggestions }} code suggestions.
|
- Provide up to {{ num_code_suggestions }} code suggestions.
|
||||||
- Focus on important suggestions like fixing code problems, issues and bugs. As a second priority, provide suggestions for meaningful code improvements, like performance, vulnerability, modularity, and best practices.
|
- Focus on important suggestions like fixing code problems, issues and bugs. As a second priority, provide suggestions for meaningful code improvements, like performance, vulnerability, modularity, and best practices.
|
||||||
- Avoid making suggestions that have already been implemented in the PR code. For example, if you want to add logs, or change a variable to const, or anything else, make sure it isn't already in the PR code.
|
- Avoid making suggestions that have already been implemented in the PR code. For example, if you want to add logs, or change a variable to const, or anything else, make sure it isn't already in the PR code.
|
||||||
- Don't suggest to add docstring or type hints.
|
- Don't suggest to add docstring, type hints, or comments.
|
||||||
- Suggestions should focus on improving the new code added in the PR (lines starting with '+')
|
- Suggestions should focus on improving the new code added in the PR (lines starting with '+')
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
|
@ -22,7 +22,10 @@ class PRCodeSuggestions:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# extended mode
|
# extended mode
|
||||||
self.is_extended = any(["extended" in arg for arg in args])
|
try:
|
||||||
|
self.is_extended = any(["extended" in arg for arg in args])
|
||||||
|
except:
|
||||||
|
self.is_extended = False
|
||||||
if self.is_extended:
|
if self.is_extended:
|
||||||
num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions_per_chunk
|
num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions_per_chunk
|
||||||
else:
|
else:
|
||||||
|
@ -29,7 +29,7 @@ class PRDescription:
|
|||||||
self.main_pr_language = get_main_pr_language(
|
self.main_pr_language = get_main_pr_language(
|
||||||
self.git_provider.get_languages(), self.git_provider.get_files()
|
self.git_provider.get_languages(), self.git_provider.get_files()
|
||||||
)
|
)
|
||||||
self.pr_id = f"{self.git_provider.repo}/{self.git_provider.pr_num}"
|
self.pr_id = self.git_provider.get_pr_id()
|
||||||
|
|
||||||
# Initialize the AI handler
|
# Initialize the AI handler
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = AiHandler()
|
||||||
@ -67,7 +67,7 @@ class PRDescription:
|
|||||||
try:
|
try:
|
||||||
logging.info(f"Generating a PR description {self.pr_id}")
|
logging.info(f"Generating a PR description {self.pr_id}")
|
||||||
if get_settings().config.publish_output:
|
if get_settings().config.publish_output:
|
||||||
self.git_provider.publish_comment("Preparing pr description...", is_temporary=True)
|
self.git_provider.publish_comment("Preparing PR description...", is_temporary=True)
|
||||||
|
|
||||||
await retry_with_fallback_models(self._prepare_prediction)
|
await retry_with_fallback_models(self._prepare_prediction)
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class TestCodeCommitProvider:
|
|||||||
# Mock the response from the AWS client for get_pull_request method
|
# Mock the response from the AWS client for get_pull_request method
|
||||||
api.boto_client.get_pull_request.return_value = {
|
api.boto_client.get_pull_request.return_value = {
|
||||||
"pullRequest": {
|
"pullRequest": {
|
||||||
"pullRequestId": "3",
|
"pullRequestId": "321",
|
||||||
"title": "My PR",
|
"title": "My PR",
|
||||||
"description": "My PR description",
|
"description": "My PR description",
|
||||||
"pullRequestTargets": [
|
"pullRequestTargets": [
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
from unittest.mock import patch
|
||||||
from pr_agent.git_providers.codecommit_provider import CodeCommitFile
|
from pr_agent.git_providers.codecommit_provider import CodeCommitFile
|
||||||
from pr_agent.git_providers.codecommit_provider import CodeCommitProvider
|
from pr_agent.git_providers.codecommit_provider import CodeCommitProvider
|
||||||
|
from pr_agent.git_providers.codecommit_provider import PullRequestCCMimic
|
||||||
from pr_agent.git_providers.git_provider import EDIT_TYPE
|
from pr_agent.git_providers.git_provider import EDIT_TYPE
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +27,21 @@ class TestCodeCommitFile:
|
|||||||
|
|
||||||
|
|
||||||
class TestCodeCommitProvider:
|
class TestCodeCommitProvider:
|
||||||
|
def test_get_title(self):
|
||||||
|
# Test that the get_title() function returns the PR title
|
||||||
|
with patch.object(CodeCommitProvider, "__init__", lambda x, y: None):
|
||||||
|
provider = CodeCommitProvider(None)
|
||||||
|
provider.pr = PullRequestCCMimic("My Test PR Title", [])
|
||||||
|
assert provider.get_title() == "My Test PR Title"
|
||||||
|
|
||||||
|
def test_get_pr_id(self):
|
||||||
|
# Test that the get_pr_id() function returns the correct ID
|
||||||
|
with patch.object(CodeCommitProvider, "__init__", lambda x, y: None):
|
||||||
|
provider = CodeCommitProvider(None)
|
||||||
|
provider.repo_name = "my_test_repo"
|
||||||
|
provider.pr_num = 321
|
||||||
|
assert provider.get_pr_id() == "my_test_repo/321"
|
||||||
|
|
||||||
def test_parse_pr_url(self):
|
def test_parse_pr_url(self):
|
||||||
# Test that the _parse_pr_url() function can extract the repo name and PR number from a CodeCommit URL
|
# Test that the _parse_pr_url() function can extract the repo name and PR number from a CodeCommit URL
|
||||||
url = "https://us-east-1.console.aws.amazon.com/codesuite/codecommit/repositories/my_test_repo/pull-requests/321"
|
url = "https://us-east-1.console.aws.amazon.com/codesuite/codecommit/repositories/my_test_repo/pull-requests/321"
|
||||||
@ -169,4 +186,4 @@ class TestCodeCommitProvider:
|
|||||||
def test_remove_markdown_html(self):
|
def test_remove_markdown_html(self):
|
||||||
input = "## PR Feedback\n<details><summary>Code feedback:</summary>\nfile foo\n</summary>\n"
|
input = "## PR Feedback\n<details><summary>Code feedback:</summary>\nfile foo\n</summary>\n"
|
||||||
expect = "## PR Feedback\nCode feedback:\nfile foo\n\n"
|
expect = "## PR Feedback\nCode feedback:\nfile foo\n\n"
|
||||||
assert CodeCommitProvider._remove_markdown_html(input) == expect
|
assert CodeCommitProvider._remove_markdown_html(input) == expect
|
||||||
|
Reference in New Issue
Block a user