mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-04 04:40:38 +08:00
feat: Added server and documentation
This commit is contained in:
37
INSTALL.md
37
INSTALL.md
@ -415,4 +415,41 @@ You can get a Bitbucket token for your repository by following Repository Settin
|
|||||||
Please contact <support@codium.ai> if you're interested in a hosted BitBucket app solution that provides full functionality including PR reviews and comment handling. It's based on the [bitbucket_app.py](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/git_providers/bitbucket_provider.py) implmentation.
|
Please contact <support@codium.ai> if you're interested in a hosted BitBucket app solution that provides full functionality including PR reviews and comment handling. It's based on the [bitbucket_app.py](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/git_providers/bitbucket_provider.py) implmentation.
|
||||||
|
|
||||||
|
|
||||||
|
### Bitbucket Server and Data Center
|
||||||
|
|
||||||
|
Login into your on-prem instance of Bitbucket with your service account username and password.
|
||||||
|
Navigate to `Manage account`, `HTTP Access tokens`, `Create Token`.
|
||||||
|
Generate the token and add it to .secret.toml under `bitbucket_server` section
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[bitbucket_server]
|
||||||
|
bearer_token = "<your key>"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run it as CLI
|
||||||
|
|
||||||
|
Modify `configuration.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
git_provider="bitbucket_server"
|
||||||
|
```
|
||||||
|
|
||||||
|
and pass the Pull request URL:
|
||||||
|
```shell
|
||||||
|
python cli.py --pr_url https://git.onpreminstanceofbitbucket.com/projects/PROJECT/repos/REPO/pull-requests/1 review
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run it as service
|
||||||
|
|
||||||
|
To run pr-agent as webhook, build the docker image:
|
||||||
|
```
|
||||||
|
docker build . -t codiumai/pr-agent:bitbucket_server_webhook --target bitbucket_server_webhook -f docker/Dockerfile
|
||||||
|
docker push codiumai/pr-agent:bitbucket_server_webhook # Push to your Docker repository
|
||||||
|
```
|
||||||
|
|
||||||
|
Navigate to `Projects` or `Repositories`, `Settings`, `Webhooks`, `Create Webhook`.
|
||||||
|
Fill the name and URL, Authentication None select the Pull Request Opened checkbox to receive that event as webhook.
|
||||||
|
|
||||||
|
The url should be ends with `/webhook`, example: https://domain.com/webhook
|
||||||
|
|
||||||
=======
|
=======
|
||||||
|
@ -14,6 +14,10 @@ FROM base as bitbucket_app
|
|||||||
ADD pr_agent pr_agent
|
ADD pr_agent pr_agent
|
||||||
CMD ["python", "pr_agent/servers/bitbucket_app.py"]
|
CMD ["python", "pr_agent/servers/bitbucket_app.py"]
|
||||||
|
|
||||||
|
FROM base as bitbucket_server_webhook
|
||||||
|
ADD pr_agent pr_agent
|
||||||
|
CMD ["python", "pr_agent/servers/bitbucket_server_webhook.py"]
|
||||||
|
|
||||||
FROM base as github_polling
|
FROM base as github_polling
|
||||||
ADD pr_agent pr_agent
|
ADD pr_agent pr_agent
|
||||||
CMD ["python", "pr_agent/servers/github_polling.py"]
|
CMD ["python", "pr_agent/servers/github_polling.py"]
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import difflib
|
|
||||||
import json
|
import json
|
||||||
import re
|
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
@ -26,7 +24,7 @@ class BitbucketServerProvider(GitProvider):
|
|||||||
except Exception:
|
except Exception:
|
||||||
s.headers[
|
s.headers[
|
||||||
"Authorization"
|
"Authorization"
|
||||||
] = f'Bearer {get_settings().get("BITBUCKET.BEARER_TOKEN", None)}'
|
] = f'Bearer {get_settings().get("BITBUCKET_SERVER.BEARER_TOKEN", None)}'
|
||||||
|
|
||||||
s.headers["Content-Type"] = "application/json"
|
s.headers["Content-Type"] = "application/json"
|
||||||
self.headers = s.headers
|
self.headers = s.headers
|
||||||
@ -44,7 +42,7 @@ class BitbucketServerProvider(GitProvider):
|
|||||||
|
|
||||||
self.bitbucket_server_url = self._parse_bitbucket_server(url=pr_url)
|
self.bitbucket_server_url = self._parse_bitbucket_server(url=pr_url)
|
||||||
self.bitbucket_client = Bitbucket(url=self.bitbucket_server_url,
|
self.bitbucket_client = Bitbucket(url=self.bitbucket_server_url,
|
||||||
token=get_settings().get("BITBUCKET.BEARER_TOKEN", None))
|
token=get_settings().get("BITBUCKET_SERVER.BEARER_TOKEN", None))
|
||||||
|
|
||||||
if pr_url:
|
if pr_url:
|
||||||
self.set_pr(pr_url)
|
self.set_pr(pr_url)
|
||||||
@ -114,7 +112,7 @@ class BitbucketServerProvider(GitProvider):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def is_supported(self, capability: str) -> bool:
|
def is_supported(self, capability: str) -> bool:
|
||||||
if capability in ['get_issue_comments', 'publish_inline_comments', 'get_labels', 'gfm_markdown']:
|
if capability in ['get_issue_comments', 'get_labels', 'gfm_markdown']:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
64
pr_agent/servers/bitbucket_server_webhook.py
Normal file
64
pr_agent/servers/bitbucket_server_webhook.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import uvicorn
|
||||||
|
from fastapi import APIRouter, FastAPI
|
||||||
|
from fastapi.encoders import jsonable_encoder
|
||||||
|
from starlette import status
|
||||||
|
from starlette.background import BackgroundTasks
|
||||||
|
from starlette.middleware import Middleware
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import JSONResponse
|
||||||
|
from starlette_context.middleware import RawContextMiddleware
|
||||||
|
|
||||||
|
from pr_agent.agent.pr_agent import PRAgent
|
||||||
|
from pr_agent.config_loader import get_settings
|
||||||
|
from pr_agent.log import get_logger
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
def handle_request(background_tasks: BackgroundTasks, url: str, body: str, log_context: dict):
|
||||||
|
log_context["action"] = body
|
||||||
|
log_context["event"] = "pull_request" if body == "review" else "comment"
|
||||||
|
log_context["api_url"] = url
|
||||||
|
with get_logger().contextualize(**log_context):
|
||||||
|
background_tasks.add_task(PRAgent().handle_request, url, body)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/webhook")
|
||||||
|
async def handle_webhook(background_tasks: BackgroundTasks, request: Request):
|
||||||
|
log_context = {"server_type": "bitbucket_server"}
|
||||||
|
data = await request.json()
|
||||||
|
get_logger().info(json.dumps(data))
|
||||||
|
|
||||||
|
pr_id = data['pullRequest']['id']
|
||||||
|
repository_name = data['pullRequest']['toRef']['repository']['slug']
|
||||||
|
project_name = data['pullRequest']['toRef']['repository']['project']['key']
|
||||||
|
bitbucket_server = get_settings().get("BITBUCKET_SERVER.URL")
|
||||||
|
pr_url = f"{bitbucket_server}/projects/{project_name}/repos/{repository_name}/pull-requests/{pr_id}"
|
||||||
|
|
||||||
|
log_context["api_url"] = pr_url
|
||||||
|
log_context["event"] = "pull_request"
|
||||||
|
|
||||||
|
handle_request(background_tasks, pr_url, "review", log_context)
|
||||||
|
return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"}))
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
async def root():
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
def start():
|
||||||
|
bitbucket_server_url = get_settings().get("BITBUCKET_SERVER.URL", None)
|
||||||
|
if not bitbucket_server_url:
|
||||||
|
raise ValueError("BITBUCKET_SERVER.URL is not set")
|
||||||
|
get_settings().config.git_provider = "bitbucket_server"
|
||||||
|
middleware = [Middleware(RawContextMiddleware)]
|
||||||
|
app = FastAPI(middleware=middleware)
|
||||||
|
app.include_router(router)
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=3000)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
start()
|
Reference in New Issue
Block a user