mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-10 07:18:10 -05:00
Add base_domain parameter for GitHub Enterprise support (#7754)
Co-authored-by: Tom Deckers <tdeckers@cisco.com> Co-authored-by: Robert Brennan <accounts@rbren.io> Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
This commit is contained in:
@@ -12,11 +12,21 @@ from openhands.resolver.utils import extract_issue_references
|
||||
|
||||
|
||||
class GithubIssueHandler(IssueHandlerInterface):
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None):
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None, base_domain: str = "github.com"):
|
||||
"""Initialize a GitHub issue handler.
|
||||
|
||||
Args:
|
||||
owner: The owner of the repository
|
||||
repo: The name of the repository
|
||||
token: The GitHub personal access token
|
||||
username: Optional GitHub username
|
||||
base_domain: The domain for GitHub Enterprise (default: "github.com")
|
||||
"""
|
||||
self.owner = owner
|
||||
self.repo = repo
|
||||
self.token = token
|
||||
self.username = username
|
||||
self.base_domain = base_domain
|
||||
self.base_url = self.get_base_url()
|
||||
self.download_url = self.get_download_url()
|
||||
self.clone_url = self.get_clone_url()
|
||||
@@ -32,10 +42,13 @@ class GithubIssueHandler(IssueHandlerInterface):
|
||||
}
|
||||
|
||||
def get_base_url(self) -> str:
|
||||
return f'https://api.github.com/repos/{self.owner}/{self.repo}'
|
||||
if self.base_domain == "github.com":
|
||||
return f'https://api.github.com/repos/{self.owner}/{self.repo}'
|
||||
else:
|
||||
return f'https://{self.base_domain}/api/v3/repos/{self.owner}/{self.repo}'
|
||||
|
||||
def get_authorize_url(self) -> str:
|
||||
return f'https://{self.username}:{self.token}@github.com/'
|
||||
return f'https://{self.username}:{self.token}@{self.base_domain}/'
|
||||
|
||||
def get_branch_url(self, branch_name: str) -> str:
|
||||
return self.get_base_url() + f'/branches/{branch_name}'
|
||||
@@ -49,13 +62,16 @@ class GithubIssueHandler(IssueHandlerInterface):
|
||||
if self.username
|
||||
else f'x-auth-token:{self.token}'
|
||||
)
|
||||
return f'https://{username_and_token}@github.com/{self.owner}/{self.repo}.git'
|
||||
return f'https://{username_and_token}@{self.base_domain}/{self.owner}/{self.repo}.git'
|
||||
|
||||
def get_graphql_url(self) -> str:
|
||||
return 'https://api.github.com/graphql'
|
||||
if self.base_domain == "github.com":
|
||||
return 'https://api.github.com/graphql'
|
||||
else:
|
||||
return f'https://{self.base_domain}/api/v3/graphql'
|
||||
|
||||
def get_compare_url(self, branch_name: str) -> str:
|
||||
return f'https://github.com/{self.owner}/{self.repo}/compare/{branch_name}?expand=1'
|
||||
return f'https://{self.base_domain}/{self.owner}/{self.repo}/compare/{branch_name}?expand=1'
|
||||
|
||||
def get_converted_issues(
|
||||
self, issue_numbers: list[int] | None = None, comment_id: int | None = None
|
||||
@@ -220,7 +236,7 @@ class GithubIssueHandler(IssueHandlerInterface):
|
||||
response.raise_for_status()
|
||||
|
||||
def get_pull_url(self, pr_number: int) -> str:
|
||||
return f'https://github.com/{self.owner}/{self.repo}/pull/{pr_number}'
|
||||
return f'https://{self.base_domain}/{self.owner}/{self.repo}/pull/{pr_number}'
|
||||
|
||||
def get_default_branch_name(self) -> str:
|
||||
response = httpx.get(f'{self.base_url}', headers=self.headers)
|
||||
@@ -286,11 +302,21 @@ class GithubIssueHandler(IssueHandlerInterface):
|
||||
|
||||
|
||||
class GithubPRHandler(GithubIssueHandler):
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None):
|
||||
super().__init__(owner, repo, token, username)
|
||||
self.download_url = (
|
||||
f'https://api.github.com/repos/{self.owner}/{self.repo}/pulls'
|
||||
)
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None, base_domain: str = "github.com"):
|
||||
"""Initialize a GitHub PR handler.
|
||||
|
||||
Args:
|
||||
owner: The owner of the repository
|
||||
repo: The name of the repository
|
||||
token: The GitHub personal access token
|
||||
username: Optional GitHub username
|
||||
base_domain: The domain for GitHub Enterprise (default: "github.com")
|
||||
"""
|
||||
super().__init__(owner, repo, token, username, base_domain)
|
||||
if self.base_domain == "github.com":
|
||||
self.download_url = f'https://api.github.com/repos/{self.owner}/{self.repo}/pulls'
|
||||
else:
|
||||
self.download_url = f'https://{self.base_domain}/api/v3/repos/{self.owner}/{self.repo}/pulls'
|
||||
|
||||
def download_pr_metadata(
|
||||
self, pull_number: int, comment_id: int | None = None
|
||||
@@ -356,7 +382,7 @@ class GithubPRHandler(GithubIssueHandler):
|
||||
|
||||
variables = {'owner': self.owner, 'repo': self.repo, 'pr': pull_number}
|
||||
|
||||
url = 'https://api.github.com/graphql'
|
||||
url = self.get_graphql_url()
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.token}',
|
||||
'Content-Type': 'application/json',
|
||||
@@ -444,7 +470,10 @@ class GithubPRHandler(GithubIssueHandler):
|
||||
self, pr_number: int, comment_id: int | None = None
|
||||
) -> list[str] | None:
|
||||
"""Download comments for a specific pull request from Github."""
|
||||
url = f'https://api.github.com/repos/{self.owner}/{self.repo}/issues/{pr_number}/comments'
|
||||
if self.base_domain == "github.com":
|
||||
url = f'https://api.github.com/repos/{self.owner}/{self.repo}/issues/{pr_number}/comments'
|
||||
else:
|
||||
url = f'https://{self.base_domain}/api/v3/repos/{self.owner}/{self.repo}/issues/{pr_number}/comments'
|
||||
headers = {
|
||||
'Authorization': f'token {self.token}',
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
@@ -513,7 +542,10 @@ class GithubPRHandler(GithubIssueHandler):
|
||||
|
||||
for issue_number in unique_issue_references:
|
||||
try:
|
||||
url = f'https://api.github.com/repos/{self.owner}/{self.repo}/issues/{issue_number}'
|
||||
if self.base_domain == "github.com":
|
||||
url = f'https://api.github.com/repos/{self.owner}/{self.repo}/issues/{issue_number}'
|
||||
else:
|
||||
url = f'https://{self.base_domain}/api/v3/repos/{self.owner}/{self.repo}/issues/{issue_number}'
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.token}',
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
|
||||
@@ -13,11 +13,28 @@ from openhands.resolver.utils import extract_issue_references
|
||||
|
||||
|
||||
class GitlabIssueHandler(IssueHandlerInterface):
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None):
|
||||
def __init__(
|
||||
self,
|
||||
owner: str,
|
||||
repo: str,
|
||||
token: str,
|
||||
username: str | None = None,
|
||||
base_domain: str = 'gitlab.com',
|
||||
):
|
||||
"""Initialize a GitLab issue handler.
|
||||
|
||||
Args:
|
||||
owner: The owner of the repository
|
||||
repo: The name of the repository
|
||||
token: The GitLab personal access token
|
||||
username: Optional GitLab username
|
||||
base_domain: The domain for GitLab Enterprise (default: "gitlab.com")
|
||||
"""
|
||||
self.owner = owner
|
||||
self.repo = repo
|
||||
self.token = token
|
||||
self.username = username
|
||||
self.base_domain = base_domain
|
||||
self.base_url = self.get_base_url()
|
||||
self.download_url = self.get_download_url()
|
||||
self.clone_url = self.get_clone_url()
|
||||
@@ -34,10 +51,10 @@ class GitlabIssueHandler(IssueHandlerInterface):
|
||||
|
||||
def get_base_url(self) -> str:
|
||||
project_path = quote(f'{self.owner}/{self.repo}', safe='')
|
||||
return f'https://gitlab.com/api/v4/projects/{project_path}'
|
||||
return f'https://{self.base_domain}/api/v4/projects/{project_path}'
|
||||
|
||||
def get_authorize_url(self) -> str:
|
||||
return f'https://{self.username}:{self.token}@gitlab.com/'
|
||||
return f'https://{self.username}:{self.token}@{self.base_domain}/'
|
||||
|
||||
def get_branch_url(self, branch_name: str) -> str:
|
||||
return self.get_base_url() + f'/repository/branches/{branch_name}'
|
||||
@@ -49,13 +66,13 @@ class GitlabIssueHandler(IssueHandlerInterface):
|
||||
username_and_token = self.token
|
||||
if self.username:
|
||||
username_and_token = f'{self.username}:{self.token}'
|
||||
return f'https://{username_and_token}@gitlab.com/{self.owner}/{self.repo}.git'
|
||||
return f'https://{username_and_token}@{self.base_domain}/{self.owner}/{self.repo}.git'
|
||||
|
||||
def get_graphql_url(self) -> str:
|
||||
return 'https://gitlab.com/api/graphql'
|
||||
return f'https://{self.base_domain}/api/graphql'
|
||||
|
||||
def get_compare_url(self, branch_name: str) -> str:
|
||||
return f'https://gitlab.com/{self.owner}/{self.repo}/-/compare/{self.get_default_branch_name()}...{branch_name}'
|
||||
return f'https://{self.base_domain}/{self.owner}/{self.repo}/-/compare/{self.get_default_branch_name()}...{branch_name}'
|
||||
|
||||
def get_converted_issues(
|
||||
self, issue_numbers: list[int] | None = None, comment_id: int | None = None
|
||||
@@ -215,9 +232,7 @@ class GitlabIssueHandler(IssueHandlerInterface):
|
||||
response.raise_for_status()
|
||||
|
||||
def get_pull_url(self, pr_number: int) -> str:
|
||||
return (
|
||||
f'https://gitlab.com/{self.owner}/{self.repo}/-/merge_requests/{pr_number}'
|
||||
)
|
||||
return f'https://{self.base_domain}/{self.owner}/{self.repo}/-/merge_requests/{pr_number}'
|
||||
|
||||
def get_default_branch_name(self) -> str:
|
||||
response = httpx.get(f'{self.base_url}', headers=self.headers)
|
||||
@@ -248,7 +263,7 @@ class GitlabIssueHandler(IssueHandlerInterface):
|
||||
|
||||
def request_reviewers(self, reviewer: str, pr_number: int) -> None:
|
||||
response = httpx.get(
|
||||
f'https://gitlab.com/api/v4/users?username={reviewer}',
|
||||
f'https://{self.base_domain}/api/v4/users?username={reviewer}',
|
||||
headers=self.headers,
|
||||
)
|
||||
response.raise_for_status()
|
||||
@@ -298,8 +313,24 @@ class GitlabIssueHandler(IssueHandlerInterface):
|
||||
|
||||
|
||||
class GitlabPRHandler(GitlabIssueHandler):
|
||||
def __init__(self, owner: str, repo: str, token: str, username: str | None = None):
|
||||
super().__init__(owner, repo, token, username)
|
||||
def __init__(
|
||||
self,
|
||||
owner: str,
|
||||
repo: str,
|
||||
token: str,
|
||||
username: str | None = None,
|
||||
base_domain: str = 'gitlab.com',
|
||||
):
|
||||
"""Initialize a GitLab PR handler.
|
||||
|
||||
Args:
|
||||
owner: The owner of the repository
|
||||
repo: The name of the repository
|
||||
token: The GitLab personal access token
|
||||
username: Optional GitLab username
|
||||
base_domain: The domain for GitLab Enterprise (default: "gitlab.com")
|
||||
"""
|
||||
super().__init__(owner, repo, token, username, base_domain)
|
||||
self.download_url = f'{self.base_url}/merge_requests'
|
||||
|
||||
def download_pr_metadata(
|
||||
|
||||
Reference in New Issue
Block a user