Files
OpenHands/openhands/integrations/forgejo/service/prs.py
johba f8e4b5562e Forgejo integration (#11111)
Co-authored-by: johba <admin@noreply.localhost>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: johba <johba@harb.eth>
Co-authored-by: enyst <engel.nyst@gmail.com>
Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: MrGeorgen <65063405+MrGeorgen@users.noreply.github.com>
Co-authored-by: MrGeorgen <moinl6162@gmail.com>
2025-12-27 15:57:31 -05:00

85 lines
2.9 KiB
Python

from __future__ import annotations
from typing import Any
from openhands.core.logger import openhands_logger as logger
from openhands.integrations.forgejo.service.base import ForgejoMixinBase
from openhands.integrations.service_types import RequestMethod, UnknownException
class ForgejoPRsMixin(ForgejoMixinBase):
"""Pull request helpers for Forgejo."""
async def create_pull_request(self, data: dict[str, Any] | None = None) -> dict:
payload: dict[str, Any] = dict(data or {})
repository = payload.pop('repository', None)
owner = payload.pop('owner', None)
repo_name = payload.pop('repo', None)
if repository and isinstance(repository, str):
owner, repo_name = self._split_repo(repository)
else:
owner = str(owner or self.user_id or '').strip()
repo_name = str(repo_name or '').strip()
if not owner or not repo_name:
raise ValueError(
'Repository information is required to create a pull request'
)
url = self._build_repo_api_url(owner, repo_name, 'pulls')
response, _ = await self._make_request(
url,
payload,
method=RequestMethod.POST,
)
if not isinstance(response, dict):
raise UnknownException('Unexpected response creating Forgejo pull request')
if 'number' not in response and 'index' in response:
response['number'] = response['index']
if 'html_url' not in response and 'url' in response:
response['html_url'] = response['url']
return response
async def request_reviewers(
self, repository: str, pr_number: int, reviewers: list[str]
) -> None:
if not reviewers:
return
owner, repo = self._split_repo(repository)
url = self._build_repo_api_url(
owner, repo, 'pulls', str(pr_number), 'requested_reviewers'
)
try:
await self._make_request(
url,
{'reviewers': reviewers},
method=RequestMethod.POST,
)
except Exception as exc: # pragma: no cover - log and continue
logger.warning(
'Failed to request Forgejo reviewers %s for %s/%s PR #%s: %s',
reviewers,
owner,
repo,
pr_number,
exc,
)
async def get_pr_details(self, repository: str, pr_number: int) -> dict: # type: ignore[override]
owner, repo = self._split_repo(repository)
url = self._build_repo_api_url(owner, repo, 'pulls', str(pr_number))
response, _ = await self._make_request(url)
return response
async def is_pr_open(self, repository: str, pr_number: int) -> bool: # type: ignore[override]
pr_details = await self.get_pr_details(repository, pr_number)
return (pr_details.get('state') or '').lower() == 'open'