Merge pull request #1811 from loolootech/feature/gitea-implement

[Feature] - Gitea implement
This commit is contained in:
Tal
2025-05-28 08:22:16 +03:00
committed by GitHub
14 changed files with 1216 additions and 256 deletions

View File

@ -70,47 +70,47 @@ Read more about it [here](https://qodo-merge-docs.qodo.ai/tools/scan_repo_discus
Supported commands per platform: Supported commands per platform:
| | | GitHub | GitLab | Bitbucket | Azure DevOps | | | | GitHub | GitLab | Bitbucket | Azure DevOps | Gitea |
| ----- |---------------------------------------------------------------------------------------------------------|:------:|:------:|:---------:|:------------:| | ----- |---------------------------------------------------------------------------------------------------------|:------:|:------:|:---------:|:------------:|:-----:|
| TOOLS | [Review](https://qodo-merge-docs.qodo.ai/tools/review/) | ✅ | ✅ | ✅ | ✅ | | TOOLS | [Review](https://qodo-merge-docs.qodo.ai/tools/review/) | ✅ | ✅ | ✅ | ✅ | ✅ |
| | [Describe](https://qodo-merge-docs.qodo.ai/tools/describe/) | ✅ | ✅ | ✅ | ✅ | | | [Describe](https://qodo-merge-docs.qodo.ai/tools/describe/) | ✅ | ✅ | ✅ | ✅ | ✅ |
| | [Improve](https://qodo-merge-docs.qodo.ai/tools/improve/) | ✅ | ✅ | ✅ | ✅ | | | [Improve](https://qodo-merge-docs.qodo.ai/tools/improve/) | ✅ | ✅ | ✅ | ✅ | ✅ |
| | [Ask](https://qodo-merge-docs.qodo.ai/tools/ask/) | ✅ | ✅ | ✅ | ✅ | | | [Ask](https://qodo-merge-docs.qodo.ai/tools/ask/) | ✅ | ✅ | ✅ | ✅ | |
| | ⮑ [Ask on code lines](https://qodo-merge-docs.qodo.ai/tools/ask/#ask-lines) | ✅ | ✅ | | | | | ⮑ [Ask on code lines](https://qodo-merge-docs.qodo.ai/tools/ask/#ask-lines) | ✅ | ✅ | | | |
| | [Update CHANGELOG](https://qodo-merge-docs.qodo.ai/tools/update_changelog/) | ✅ | ✅ | ✅ | ✅ | | | [Update CHANGELOG](https://qodo-merge-docs.qodo.ai/tools/update_changelog/) | ✅ | ✅ | ✅ | ✅ | |
| | [Help Docs](https://qodo-merge-docs.qodo.ai/tools/help_docs/?h=auto#auto-approval) | ✅ | ✅ | ✅ | | | | [Help Docs](https://qodo-merge-docs.qodo.ai/tools/help_docs/?h=auto#auto-approval) | ✅ | ✅ | ✅ | | |
| | [Ticket Context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) 💎 | ✅ | ✅ | ✅ | | | | [Ticket Context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) 💎 | ✅ | ✅ | ✅ | | |
| | [Utilizing Best Practices](https://qodo-merge-docs.qodo.ai/tools/improve/#best-practices) 💎 | ✅ | ✅ | ✅ | | | | [Utilizing Best Practices](https://qodo-merge-docs.qodo.ai/tools/improve/#best-practices) 💎 | ✅ | ✅ | ✅ | | |
| | [PR Chat](https://qodo-merge-docs.qodo.ai/chrome-extension/features/#pr-chat) 💎 | ✅ | | | | | | [PR Chat](https://qodo-merge-docs.qodo.ai/chrome-extension/features/#pr-chat) 💎 | ✅ | | | | |
| | [Suggestion Tracking](https://qodo-merge-docs.qodo.ai/tools/improve/#suggestion-tracking) 💎 | ✅ | ✅ | | | | | [Suggestion Tracking](https://qodo-merge-docs.qodo.ai/tools/improve/#suggestion-tracking) 💎 | ✅ | ✅ | | | |
| | [CI Feedback](https://qodo-merge-docs.qodo.ai/tools/ci_feedback/) 💎 | ✅ | | | | | | [CI Feedback](https://qodo-merge-docs.qodo.ai/tools/ci_feedback/) 💎 | ✅ | | | | |
| | [PR Documentation](https://qodo-merge-docs.qodo.ai/tools/documentation/) 💎 | ✅ | ✅ | | | | | [PR Documentation](https://qodo-merge-docs.qodo.ai/tools/documentation/) 💎 | ✅ | ✅ | | | |
| | [Custom Labels](https://qodo-merge-docs.qodo.ai/tools/custom_labels/) 💎 | ✅ | ✅ | | | | | [Custom Labels](https://qodo-merge-docs.qodo.ai/tools/custom_labels/) 💎 | ✅ | ✅ | | | |
| | [Analyze](https://qodo-merge-docs.qodo.ai/tools/analyze/) 💎 | ✅ | ✅ | | | | | [Analyze](https://qodo-merge-docs.qodo.ai/tools/analyze/) 💎 | ✅ | ✅ | | | |
| | [Similar Code](https://qodo-merge-docs.qodo.ai/tools/similar_code/) 💎 | ✅ | | | | | | [Similar Code](https://qodo-merge-docs.qodo.ai/tools/similar_code/) 💎 | ✅ | | | | |
| | [Custom Prompt](https://qodo-merge-docs.qodo.ai/tools/custom_prompt/) 💎 | ✅ | ✅ | ✅ | | | | [Custom Prompt](https://qodo-merge-docs.qodo.ai/tools/custom_prompt/) 💎 | ✅ | ✅ | ✅ | | |
| | [Test](https://qodo-merge-docs.qodo.ai/tools/test/) 💎 | ✅ | ✅ | | | | | [Test](https://qodo-merge-docs.qodo.ai/tools/test/) 💎 | ✅ | ✅ | | | |
| | [Implement](https://qodo-merge-docs.qodo.ai/tools/implement/) 💎 | ✅ | ✅ | ✅ | | | | [Implement](https://qodo-merge-docs.qodo.ai/tools/implement/) 💎 | ✅ | ✅ | ✅ | | |
| | [Scan Repo Discussions](https://qodo-merge-docs.qodo.ai/tools/scan_repo_discussions/) 💎 | ✅ | | | | | | [Scan Repo Discussions](https://qodo-merge-docs.qodo.ai/tools/scan_repo_discussions/) 💎 | ✅ | | | | |
| | [Auto-Approve](https://qodo-merge-docs.qodo.ai/tools/improve/?h=auto#auto-approval) 💎 | ✅ | ✅ | ✅ | | | | [Auto-Approve](https://qodo-merge-docs.qodo.ai/tools/improve/?h=auto#auto-approval) 💎 | ✅ | ✅ | ✅ | | |
| | | | | | | | | | | | | | |
| USAGE | [CLI](https://qodo-merge-docs.qodo.ai/usage-guide/automations_and_usage/#local-repo-cli) | ✅ | ✅ | ✅ | ✅ | | USAGE | [CLI](https://qodo-merge-docs.qodo.ai/usage-guide/automations_and_usage/#local-repo-cli) | ✅ | ✅ | ✅ | ✅ | ✅ |
| | [App / webhook](https://qodo-merge-docs.qodo.ai/usage-guide/automations_and_usage/#github-app) | ✅ | ✅ | ✅ | ✅ | | | [App / webhook](https://qodo-merge-docs.qodo.ai/usage-guide/automations_and_usage/#github-app) | ✅ | ✅ | ✅ | ✅ | ✅ |
| | [Tagging bot](https://github.com/Codium-ai/pr-agent#try-it-now) | ✅ | | | | | | [Tagging bot](https://github.com/Codium-ai/pr-agent#try-it-now) | ✅ | | | | |
| | [Actions](https://qodo-merge-docs.qodo.ai/installation/github/#run-as-a-github-action) | ✅ | ✅ | ✅ | ✅ | | | [Actions](https://qodo-merge-docs.qodo.ai/installation/github/#run-as-a-github-action) | ✅ | ✅ | ✅ | ✅ | |
| | | | | | | | | | | | | | |
| CORE | [PR compression](https://qodo-merge-docs.qodo.ai/core-abilities/compression_strategy/) | ✅ | ✅ | ✅ | ✅ | | CORE | [PR compression](https://qodo-merge-docs.qodo.ai/core-abilities/compression_strategy/) | ✅ | ✅ | ✅ | ✅ | |
| | Adaptive and token-aware file patch fitting | ✅ | ✅ | ✅ | ✅ | | | Adaptive and token-aware file patch fitting | ✅ | ✅ | ✅ | ✅ | |
| | [Multiple models support](https://qodo-merge-docs.qodo.ai/usage-guide/changing_a_model/) | ✅ | ✅ | ✅ | ✅ | | | [Multiple models support](https://qodo-merge-docs.qodo.ai/usage-guide/changing_a_model/) | ✅ | ✅ | ✅ | ✅ | |
| | [Local and global metadata](https://qodo-merge-docs.qodo.ai/core-abilities/metadata/) | ✅ | ✅ | ✅ | ✅ | | | [Local and global metadata](https://qodo-merge-docs.qodo.ai/core-abilities/metadata/) | ✅ | ✅ | ✅ | ✅ | |
| | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | ✅ | ✅ | ✅ | ✅ | | | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | ✅ | ✅ | ✅ | ✅ | |
| | [Self reflection](https://qodo-merge-docs.qodo.ai/core-abilities/self_reflection/) | ✅ | ✅ | ✅ | ✅ | | | [Self reflection](https://qodo-merge-docs.qodo.ai/core-abilities/self_reflection/) | ✅ | ✅ | ✅ | ✅ | |
| | [Static code analysis](https://qodo-merge-docs.qodo.ai/core-abilities/static_code_analysis/) 💎 | ✅ | ✅ | | | | | [Static code analysis](https://qodo-merge-docs.qodo.ai/core-abilities/static_code_analysis/) 💎 | ✅ | ✅ | | | |
| | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) 💎 | ✅ | ✅ | ✅ | | | | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) 💎 | ✅ | ✅ | ✅ | | |
| | [PR interactive actions](https://www.qodo.ai/images/pr_agent/pr-actions.mp4) 💎 | ✅ | ✅ | | | | | [PR interactive actions](https://www.qodo.ai/images/pr_agent/pr-actions.mp4) 💎 | ✅ | ✅ | | | |
| | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) 💎 | ✅ | ✅ | | | | | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) 💎 | ✅ | ✅ | | | |
| | [Code Validation 💎](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | ✅ | ✅ | ✅ | ✅ | | | [Code Validation 💎](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | ✅ | ✅ | ✅ | ✅ | |
| | [Auto Best Practices 💎](https://qodo-merge-docs.qodo.ai/core-abilities/auto_best_practices/) | ✅ | | | | | | [Auto Best Practices 💎](https://qodo-merge-docs.qodo.ai/core-abilities/auto_best_practices/) | ✅ | | | | |
- 💎 means this feature is available only in [Qodo Merge](https://www.qodo.ai/pricing/) - 💎 means this feature is available only in [Qodo Merge](https://www.qodo.ai/pricing/)
[//]: # (- Support for additional git providers is described in [here](./docs/Full_environments.md)) [//]: # (- Support for additional git providers is described in [here](./docs/Full_environments.md))

View File

@ -33,6 +33,11 @@ FROM base AS azure_devops_webhook
ADD pr_agent pr_agent ADD pr_agent pr_agent
CMD ["python", "pr_agent/servers/azuredevops_server_webhook.py"] CMD ["python", "pr_agent/servers/azuredevops_server_webhook.py"]
FROM base AS gitea_app
ADD pr_agent pr_agent
CMD ["python", "-m", "gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-c", "pr_agent/servers/gunicorn_config.py","pr_agent.servers.gitea_app:app"]
FROM base AS test FROM base AS test
ADD requirements-dev.txt . ADD requirements-dev.txt .
RUN pip install --no-cache-dir -r requirements-dev.txt && rm requirements-dev.txt RUN pip install --no-cache-dir -r requirements-dev.txt && rm requirements-dev.txt

View File

@ -0,0 +1,46 @@
## Run a Gitea webhook server
1. In Gitea create a new user and give it "Reporter" role ("Developer" if using Pro version of the agent) for the intended group or project.
2. For the user from step 1. generate a `personal_access_token` with `api` access.
3. Generate a random secret for your app, and save it for later (`webhook_secret`). For example, you can use:
```bash
WEBHOOK_SECRET=$(python -c "import secrets; print(secrets.token_hex(10))")
```
4. Clone this repository:
```bash
git clone https://github.com/qodo-ai/pr-agent.git
```
5. Prepare variables and secrets. Skip this step if you plan on setting these as environment variables when running the agent:
1. In the configuration file/variables:
- Set `config.git_provider` to "gitea"
2. In the secrets file/variables:
- Set your AI model key in the respective section
- In the [Gitea] section, set `personal_access_token` (with token from step 2) and `webhook_secret` (with secret from step 3)
6. Build a Docker image for the app and optionally push it to a Docker repository. We'll use Dockerhub as an example:
```bash
docker build -f /docker/Dockerfile -t pr-agent:gitea_app --target gitea_app .
docker push codiumai/pr-agent:gitea_webhook # Push to your Docker repository
```
7. Set the environmental variables, the method depends on your docker runtime. Skip this step if you included your secrets/configuration directly in the Docker image.
```bash
CONFIG__GIT_PROVIDER=gitea
GITEA__PERSONAL_ACCESS_TOKEN=<personal_access_token>
GITEA__WEBHOOK_SECRET=<webhook_secret>
GITEA__URL=https://gitea.com # Or self host
OPENAI__KEY=<your_openai_api_key>
```
8. Create a webhook in your Gitea project. Set the URL to `http[s]://<PR_AGENT_HOSTNAME>/api/v1/gitea_webhooks`, the secret token to the generated secret from step 3, and enable the triggers `push`, `comments` and `merge request events`.
9. Test your installation by opening a merge request or commenting on a merge request using one of PR Agent's commands.

View File

@ -9,6 +9,7 @@ There are several ways to use self-hosted PR-Agent:
- [GitLab integration](./gitlab.md) - [GitLab integration](./gitlab.md)
- [BitBucket integration](./bitbucket.md) - [BitBucket integration](./bitbucket.md)
- [Azure DevOps integration](./azure.md) - [Azure DevOps integration](./azure.md)
- [Gitea integration](./gitea.md)
## Qodo Merge 💎 ## Qodo Merge 💎

View File

@ -1,7 +1,7 @@
To run PR-Agent locally, you first need to acquire two keys: To run PR-Agent locally, you first need to acquire two keys:
1. An OpenAI key from [here](https://platform.openai.com/api-keys){:target="_blank"}, with access to GPT-4 and o4-mini (or a key for other [language models](https://qodo-merge-docs.qodo.ai/usage-guide/changing_a_model/), if you prefer). 1. An OpenAI key from [here](https://platform.openai.com/api-keys){:target="_blank"}, with access to GPT-4 and o4-mini (or a key for other [language models](https://qodo-merge-docs.qodo.ai/usage-guide/changing_a_model/), if you prefer).
2. A personal access token from your Git platform (GitHub, GitLab, BitBucket) with repo scope. GitHub token, for example, can be issued from [here](https://github.com/settings/tokens){:target="_blank"} 2. A personal access token from your Git platform (GitHub, GitLab, BitBucket,Gitea) with repo scope. GitHub token, for example, can be issued from [here](https://github.com/settings/tokens){:target="_blank"}
## Using Docker image ## Using Docker image
@ -40,6 +40,19 @@ To invoke a tool (for example `review`), you can run PR-Agent directly from the
docker run --rm -it -e CONFIG.GIT_PROVIDER=bitbucket -e OPENAI.KEY=$OPENAI_API_KEY -e BITBUCKET.BEARER_TOKEN=$BITBUCKET_BEARER_TOKEN codiumai/pr-agent:latest --pr_url=<pr_url> review docker run --rm -it -e CONFIG.GIT_PROVIDER=bitbucket -e OPENAI.KEY=$OPENAI_API_KEY -e BITBUCKET.BEARER_TOKEN=$BITBUCKET_BEARER_TOKEN codiumai/pr-agent:latest --pr_url=<pr_url> review
``` ```
- For Gitea:
```bash
docker run --rm -it -e OPENAI.KEY=<your key> -e CONFIG.GIT_PROVIDER=gitea -e GITEA.PERSONAL_ACCESS_TOKEN=<your token> codiumai/pr-agent:latest --pr_url <pr_url> review
```
If you have a dedicated Gitea instance, you need to specify the custom url as variable:
```bash
-e GITEA.URL=<your gitea instance url>
```
For other git providers, update `CONFIG.GIT_PROVIDER` accordingly and check the [`pr_agent/settings/.secrets_template.toml`](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/.secrets_template.toml) file for environment variables expected names and values. For other git providers, update `CONFIG.GIT_PROVIDER` accordingly and check the [`pr_agent/settings/.secrets_template.toml`](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/.secrets_template.toml) file for environment variables expected names and values.
### Utilizing environment variables ### Utilizing environment variables

View File

@ -30,7 +30,7 @@ verbosity_level=2
This is useful for debugging or experimenting with different tools. This is useful for debugging or experimenting with different tools.
3. **git provider**: The [git_provider](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L5) field in a configuration file determines the GIT provider that will be used by Qodo Merge. Currently, the following providers are supported: 3. **git provider**: The [git_provider](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L5) field in a configuration file determines the GIT provider that will be used by Qodo Merge. Currently, the following providers are supported:
`github` **(default)**, `gitlab`, `bitbucket`, `azure`, `codecommit`, `local`, and `gerrit`. `github` **(default)**, `gitlab`, `bitbucket`, `azure`, `codecommit`, `local`,`gitea`, and `gerrit`.
### CLI Health Check ### CLI Health Check
@ -312,3 +312,16 @@ pr_commands = [
"/improve", "/improve",
] ]
``` ```
### Gitea Webhook
After setting up a Gitea webhook, to control which commands will run automatically when a new MR is opened, you can set the `pr_commands` parameter in the configuration file, similar to the GitHub App:
```toml
[gitea]
pr_commands = [
"/describe",
"/review",
"/improve",
]
```

View File

@ -12,6 +12,7 @@ It includes information on how to adjust Qodo Merge configurations, define which
- [GitHub App](./automations_and_usage.md#github-app) - [GitHub App](./automations_and_usage.md#github-app)
- [GitHub Action](./automations_and_usage.md#github-action) - [GitHub Action](./automations_and_usage.md#github-action)
- [GitLab Webhook](./automations_and_usage.md#gitlab-webhook) - [GitLab Webhook](./automations_and_usage.md#gitlab-webhook)
- [Gitea Webhook](./automations_and_usage.md#gitea-webhook)
- [BitBucket App](./automations_and_usage.md#bitbucket-app) - [BitBucket App](./automations_and_usage.md#bitbucket-app)
- [Azure DevOps Provider](./automations_and_usage.md#azure-devops-provider) - [Azure DevOps Provider](./automations_and_usage.md#azure-devops-provider)
- [Managing Mail Notifications](./mail_notifications.md) - [Managing Mail Notifications](./mail_notifications.md)

View File

@ -58,6 +58,9 @@ def filter_ignored(files, platform = 'github'):
files = files_o files = files_o
elif platform == 'azure': elif platform == 'azure':
files = [f for f in files if not r.match(f)] files = [f for f in files if not r.match(f)]
elif platform == 'gitea':
files = [f for f in files if not r.match(f.get("filename", ""))]
except Exception as e: except Exception as e:
print(f"Could not filter file list: {e}") print(f"Could not filter file list: {e}")

View File

@ -8,6 +8,7 @@ from pr_agent.git_providers.bitbucket_server_provider import \
from pr_agent.git_providers.codecommit_provider import CodeCommitProvider from pr_agent.git_providers.codecommit_provider import CodeCommitProvider
from pr_agent.git_providers.gerrit_provider import GerritProvider from pr_agent.git_providers.gerrit_provider import GerritProvider
from pr_agent.git_providers.git_provider import GitProvider from pr_agent.git_providers.git_provider import GitProvider
from pr_agent.git_providers.gitea_provider import GiteaProvider
from pr_agent.git_providers.github_provider import GithubProvider from pr_agent.git_providers.github_provider import GithubProvider
from pr_agent.git_providers.gitlab_provider import GitLabProvider from pr_agent.git_providers.gitlab_provider import GitLabProvider
from pr_agent.git_providers.local_git_provider import LocalGitProvider from pr_agent.git_providers.local_git_provider import LocalGitProvider
@ -22,7 +23,7 @@ _GIT_PROVIDERS = {
'codecommit': CodeCommitProvider, 'codecommit': CodeCommitProvider,
'local': LocalGitProvider, 'local': LocalGitProvider,
'gerrit': GerritProvider, 'gerrit': GerritProvider,
'gitea': GiteaProvider, 'gitea': GiteaProvider
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
import asyncio
import copy
import os
from typing import Any, Dict
from fastapi import APIRouter, FastAPI, HTTPException, Request, Response
from starlette.background import BackgroundTasks
from starlette.middleware import Middleware
from starlette_context import context
from starlette_context.middleware import RawContextMiddleware
from pr_agent.agent.pr_agent import PRAgent
from pr_agent.config_loader import get_settings, global_settings
from pr_agent.log import LoggingFormat, get_logger, setup_logger
from pr_agent.servers.utils import verify_signature
# Setup logging and router
setup_logger(fmt=LoggingFormat.JSON, level=get_settings().get("CONFIG.LOG_LEVEL", "DEBUG"))
router = APIRouter()
@router.post("/api/v1/gitea_webhooks")
async def handle_gitea_webhooks(background_tasks: BackgroundTasks, request: Request, response: Response):
"""Handle incoming Gitea webhook requests"""
get_logger().debug("Received a Gitea webhook")
body = await get_body(request)
# Set context for the request
context["settings"] = copy.deepcopy(global_settings)
context["git_provider"] = {}
# Handle the webhook in background
background_tasks.add_task(handle_request, body, event=request.headers.get("X-Gitea-Event", None))
return {}
async def get_body(request: Request):
"""Parse and verify webhook request body"""
try:
body = await request.json()
except Exception as e:
get_logger().error("Error parsing request body", artifact={'error': e})
raise HTTPException(status_code=400, detail="Error parsing request body") from e
# Verify webhook signature
webhook_secret = getattr(get_settings().gitea, 'webhook_secret', None)
if webhook_secret:
body_bytes = await request.body()
signature_header = request.headers.get('x-gitea-signature', None)
if not signature_header:
get_logger().error("Missing signature header")
raise HTTPException(status_code=400, detail="Missing signature header")
try:
verify_signature(body_bytes, webhook_secret, f"sha256={signature_header}")
except Exception as ex:
get_logger().error(f"Invalid signature: {ex}")
raise HTTPException(status_code=401, detail="Invalid signature")
return body
async def handle_request(body: Dict[str, Any], event: str):
"""Process Gitea webhook events"""
action = body.get("action")
if not action:
get_logger().debug("No action found in request body")
return {}
agent = PRAgent()
# Handle different event types
if event == "pull_request":
if action in ["opened", "reopened", "synchronized"]:
await handle_pr_event(body, event, action, agent)
elif event == "issue_comment":
if action == "created":
await handle_comment_event(body, event, action, agent)
return {}
async def handle_pr_event(body: Dict[str, Any], event: str, action: str, agent: PRAgent):
"""Handle pull request events"""
pr = body.get("pull_request", {})
if not pr:
return
api_url = pr.get("url")
if not api_url:
return
# Handle PR based on action
if action in ["opened", "reopened"]:
commands = get_settings().get("gitea.pr_commands", [])
for command in commands:
await agent.handle_request(api_url, command)
elif action == "synchronized":
# Handle push to PR
await agent.handle_request(api_url, "/review --incremental")
async def handle_comment_event(body: Dict[str, Any], event: str, action: str, agent: PRAgent):
"""Handle comment events"""
comment = body.get("comment", {})
if not comment:
return
comment_body = comment.get("body", "")
if not comment_body or not comment_body.startswith("/"):
return
pr_url = body.get("pull_request", {}).get("url")
if not pr_url:
return
await agent.handle_request(pr_url, comment_body)
# FastAPI app setup
middleware = [Middleware(RawContextMiddleware)]
app = FastAPI(middleware=middleware)
app.include_router(router)
def start():
"""Start the Gitea webhook server"""
port = int(os.environ.get("PORT", "3000"))
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=port)
if __name__ == "__main__":
start()

View File

@ -68,6 +68,11 @@ webhook_secret = "<WEBHOOK SECRET>" # Optional, may be commented out.
personal_access_token = "" personal_access_token = ""
shared_secret = "" # webhook secret shared_secret = "" # webhook secret
[gitea]
# Gitea personal access token
personal_access_token=""
webhook_secret="" # webhook secret
[bitbucket] [bitbucket]
# For Bitbucket authentication # For Bitbucket authentication
auth_type = "bearer" # "bearer" or "basic" auth_type = "bearer" # "bearer" or "basic"

View File

@ -281,6 +281,15 @@ push_commands = [
"/review", "/review",
] ]
[gitea_app]
url = "https://gitea.com"
handle_push_trigger = false
pr_commands = [
"/describe",
"/review",
"/improve",
]
[bitbucket_app] [bitbucket_app]
pr_commands = [ pr_commands = [
"/describe --pr_description.final_update_message=false", "/describe --pr_description.final_update_message=false",

View File

@ -31,6 +31,7 @@ gunicorn==22.0.0
pytest-cov==5.0.0 pytest-cov==5.0.0
pydantic==2.8.2 pydantic==2.8.2
html2text==2024.2.26 html2text==2024.2.26
giteapy==1.0.8
# Uncomment the following lines to enable the 'similar issue' tool # Uncomment the following lines to enable the 'similar issue' tool
# pinecone-client # pinecone-client
# pinecone-datasets @ git+https://github.com/mrT23/pinecone-datasets.git@main # pinecone-datasets @ git+https://github.com/mrT23/pinecone-datasets.git@main