mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-08-09 00:16:57 -07:00
98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
"""GitHub REST API Client module.
|
|
|
|
Handles GitHub pull request creation and branch push operations cleanly using
|
|
standard urllib to minimize container dependency footprint.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
|
|
class GitHubClientError(Exception):
|
|
"""Raised when a GitHub API request fails or is rejected."""
|
|
|
|
|
|
class GitHubClient:
|
|
"""Lightweight client for communicating with the GitHub v3 REST API."""
|
|
|
|
def __init__(self, owner: str, repo: str, token: str | None = None) -> None:
|
|
"""Initializes the GitHub REST Client.
|
|
|
|
Args:
|
|
owner: Owner/organization of the repository.
|
|
repo: Name of the repository.
|
|
token: Authentication token. If missing, API calls will fail.
|
|
"""
|
|
self.owner = owner
|
|
self.repo = repo
|
|
self._token = token
|
|
self._base_url = f"https://api.github.com/repos/{owner}/{repo}/pulls"
|
|
|
|
def create_pull_request(
|
|
self, branch_name: str, title: str, body: str
|
|
) -> str:
|
|
"""Submits a POST request to GitHub to create a new Pull Request.
|
|
|
|
Args:
|
|
branch_name: The feature branch to be merged.
|
|
title: Title of the Pull Request.
|
|
body: Body description markdown of the Pull Request.
|
|
|
|
Returns:
|
|
The PR number of the successfully created Pull Request as a string.
|
|
|
|
Raises:
|
|
GitHubClientError: If the HTTP request fails or token is missing.
|
|
"""
|
|
if not self._token:
|
|
raise GitHubClientError(
|
|
"GitHub token is missing. Cannot authorize Pull Request creation."
|
|
)
|
|
|
|
data = {
|
|
"title": title,
|
|
"body": body,
|
|
"head": branch_name,
|
|
"base": "main",
|
|
}
|
|
|
|
req = urllib.request.Request(
|
|
self._base_url,
|
|
data=json.dumps(data).encode("utf-8"),
|
|
headers={
|
|
"Accept": "application/vnd.github+json",
|
|
"Authorization": f"Bearer {self._token}",
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
"Content-Type": "application/json",
|
|
},
|
|
method="POST",
|
|
)
|
|
|
|
logging.info(
|
|
"Sending Pull Request creation request for branch: %s", branch_name
|
|
)
|
|
try:
|
|
with urllib.request.urlopen(req,timeout=60) as response:
|
|
response_payload = json.loads(response.read().decode("utf-8"))
|
|
pr_number: str = str(response_payload.get("number", response_payload.get("html_url", "")))
|
|
logging.info(
|
|
"Pull Request created successfully! PR Number: %s", pr_number
|
|
)
|
|
return pr_number
|
|
except urllib.error.URLError as e:
|
|
if isinstance(e, urllib.error.HTTPError):
|
|
err_body = e.read().decode("utf-8") if e.fp else "No body content"
|
|
err_msg = f"HTTP {e.code}: {err_body}"
|
|
else:
|
|
err_msg = f"Network Error: {getattr(e, 'reason', e)}"
|
|
|
|
logging.error("Failed to create Pull Request: %s", err_msg)
|
|
raise GitHubClientError(f"GitHub API Error: {err_msg}") from e
|
|
except Exception as e:
|
|
logging.exception("Encountered unexpected error during PR creation.")
|
|
raise GitHubClientError(
|
|
f"Unexpected API client error: {e}"
|
|
) from e
|