2929logging .getLogger (__name__ )
3030logging .basicConfig (level = logging .WARNING )
3131
32- class GutHubIntegration :
32+ class GitHubIntegration :
3333 def __init__ (self ):
34- # Initialize GitHub token
34+ """
35+ Initialize the GitHubIntegration class.
36+
37+ Returns:
38+ None
39+
40+ Raises:
41+ ValueError: If the GitHub token is not found in environment variables.
42+ """
3543 self .github_token = GITHUB_TOKEN
3644 if not self .github_token :
3745 raise ValueError ("Missing GitHub GITHUB_TOKEN in environment variables" )
3846
3947 logging .info ("GitHub Integration initialized" )
4048
4149 def _get_headers (self ):
42- """Get headers for GitHub API requests."""
50+ """
51+ Return the headers required for GitHub API requests.
52+
53+ Returns:
54+ dict: A dictionary containing the required HTTP headers.
55+
56+ Raises:
57+ ValueError: If the GitHub token is missing.
58+
59+ Error Handling:
60+ Raises ValueError if the GitHub token is not set.
61+ """
62+ if not self .github_token :
63+ raise ValueError ("GitHub token is missing for API requests" )
4364 return {
4465 'Authorization' : f'token { self .github_token } ' ,
4566 'Accept' : 'application/vnd.github.v3+json'
4667 }
4768
4869 def _get_pr_url (self , repo_owner : str , repo_name : str , pr_number : int ) -> str :
49- """Construct the URL for a specific pull request."""
70+ """
71+ Generates the GitHub API URL for a specific pull request in a given repository.
72+ Args:
73+ repo_owner (str): The owner of the GitHub repository.
74+ repo_name (str): The name of the GitHub repository.
75+ pr_number (int): The pull request number.
76+ Returns:
77+ str: The formatted GitHub API URL for the specified pull request.
78+ Raises:
79+ ValueError: If any of the arguments are empty or if pr_number is not a positive integer.
80+ """
81+
5082 return f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /pulls/{ pr_number } "
5183
5284 def get_pr_diff (self , repo_owner : str , repo_name : str , pr_number : int ) -> str :
53- """Fetch the diff/patch of a pull request.
54-
85+ """
86+ Fetches the diff/patch of a pull request from a GitHub repository.
5587 Args:
56- repo_owner: The owner of the GitHub repository
57- repo_name: The name of the GitHub repository
58- pr_number: The number of the pull request to analyze
59-
88+ repo_owner (str): The owner of the GitHub repository.
89+ repo_name (str): The name of the GitHub repository.
90+ pr_number (int): The pull request number.
6091 Returns:
61- A string containing the raw patch of the pull request
92+ str: The raw patch/diff text of the pull request if successful, otherwise None.
93+ Error Handling:
94+ Logs an error message and prints the traceback if the request fails or an exception occurs.
6295 """
6396 logging .info (f"Fetching PR diff for { repo_owner } /{ repo_name } #{ pr_number } " )
6497
@@ -77,15 +110,17 @@ def get_pr_diff(self, repo_owner: str, repo_name: str, pr_number: int) -> str:
77110 return None
78111
79112 def get_pr_content (self , repo_owner : str , repo_name : str , pr_number : int ) -> Dict [str , Any ]:
80- """Fetch the content of a pull request.
81-
113+ """
114+ Fetches the content of a specific pull request from a GitHub repository.
82115 Args:
83- repo_owner: The owner of the GitHub repository
84- repo_name: The name of the GitHub repository
85- pr_number: The number of the pull request to analyze
86-
116+ repo_owner (str): The owner of the repository.
117+ repo_name (str): The name of the repository.
118+ pr_number (int): The pull request number.
87119 Returns:
88- A dictionary containing PR metadata and file changes
120+ Dict[str, Any]: A dictionary containing the pull request's title, description, author, creation and update timestamps, and state.
121+ Returns None if an error occurs during the fetch operation.
122+ Error Handling:
123+ Logs an error message and prints the traceback if the request fails or an exception is raised during processing.
89124 """
90125 logging .info (f"Fetching PR content for { repo_owner } /{ repo_name } #{ pr_number } " )
91126
@@ -117,16 +152,18 @@ def get_pr_content(self, repo_owner: str, repo_name: str, pr_number: int) -> Dic
117152 return None
118153
119154 def add_pr_comments (self , repo_owner : str , repo_name : str , pr_number : int , comment : str ) -> Dict [str , Any ]:
120- """Add a comment to a pull request.
121-
155+ """
156+ Adds a comment to a specified pull request on GitHub.
122157 Args:
123- repo_owner: The owner of the GitHub repository
124- repo_name: The name of the GitHub repository
125- pr_number: The number of the pull request to comment on
126- comment: The content of the comment
127-
158+ repo_owner (str): The owner of the repository.
159+ repo_name (str): The name of the repository.
160+ pr_number (int): The pull request number to which the comment will be added.
161+ comment (str): The content of the comment to add.
128162 Returns:
129- A dictionary containing the added comment's metadata
163+ Dict[str, Any]: The JSON response from the GitHub API containing the comment data if successful.
164+ None: If an error occurs while adding the comment.
165+ Error Handling:
166+ Logs an error message and prints the traceback if the request fails or an exception is raised.
130167 """
131168 logging .info (f"Adding comment to PR { repo_owner } /{ repo_name } #{ pr_number } " )
132169
@@ -148,17 +185,19 @@ def add_pr_comments(self, repo_owner: str, repo_name: str, pr_number: int, comme
148185 return None
149186
150187 def update_pr_description (self , repo_owner : str , repo_name : str , pr_number : int , new_title : str , new_description : str ) -> Dict [str , Any ]:
151- """Update the description of a pull request.
152-
188+ """
189+ Updates the title and description of a pull request on GitHub.
153190 Args:
154- repo_owner: The owner of the GitHub repository
155- repo
156- repo_name: The name of the GitHub repository
157- pr_number: The number of the pull request to update
158- new_title: The new title for the pull request
159- new_description: The new description for the pull request
191+ repo_owner (str): The owner of the repository.
192+ repo_name (str): The name of the repository.
193+ pr_number (int): The pull request number to update.
194+ new_title (str): The new title for the pull request.
195+ new_description (str): The new description (body) for the pull request.
160196 Returns:
161- A dictionary containing the updated pull request's metadata
197+ Dict[str, Any]: The updated pull request data as returned by the GitHub API if the update is successful.
198+ None: If an error occurs during the update process.
199+ Error Handling:
200+ Logs an error message and prints the traceback if the update fails due to an exception (e.g., network issues, invalid credentials, or API errors).
162201 """
163202 logging .info (f"Updating PR description for { repo_owner } /{ repo_name } #{ pr_number } " )
164203
@@ -181,17 +220,20 @@ def update_pr_description(self, repo_owner: str, repo_name: str, pr_number: int,
181220 return None
182221
183222 def create_issue (self , repo_owner : str , repo_name : str , title : str , body : str , labels : list [str ]) -> Dict [str , Any ]:
184- """Create a new issue in the specified GitHub repository.
185-
223+ """
224+ Creates a new issue in the specified GitHub repository.
225+ When issue is created add comment to PR with "Resolves: #<issue_number>" using add_pr_comments function.
186226 Args:
187- repo_owner: The owner of the GitHub repository
188- repo_name: The name of the GitHub repository
189- title: The title of the issue
190- body: The body content of the issue, this should include description, why, details, references
191- if there is a PR number, add resolve by PR number
192- labels: A list of labels to apply to the issue
227+ repo_owner (str): The owner of the repository.
228+ repo_name (str): The name of the repository.
229+ title (str): The title of the issue to be created.
230+ body (str): The body content of the issue.
231+ labels (list[str]): A list of labels to assign to the issue. The label 'mcp' will always be included.
193232 Returns:
194- A dictionary containing the created issue's metadata
233+ Dict[str, Any]: A dictionary containing the created issue's data if successful.
234+ None: If an error occurs during issue creation.
235+ Error Handling:
236+ Logs errors and prints the traceback if the issue creation fails, returning None.
195237 """
196238 logging .info (f"Creating issue in { repo_owner } /{ repo_name } " )
197239
@@ -218,18 +260,21 @@ def create_issue(self, repo_owner: str, repo_name: str, title: str, body: str, l
218260 return None
219261
220262 def update_issue (self , repo_owner : str , repo_name : str , issue_number : int , title : str , body : str , labels : list [str ] = [], state : str = 'open' ) -> Dict [str , Any ]:
221- """Update an existing issue in the specified GitHub repository.
222-
263+ """
264+ Updates an existing GitHub issue with the specified parameters.
223265 Args:
224- repo_owner: The owner of the GitHub repository
225- repo_name: The name of the GitHub repository
226- issue_number: The number of the issue to update
227- title: The new title of the issue
228- body: The new body content of the issue
229- labels: A list of labels to apply to the issue
230- state: The new state of the issue (open/ closed)
266+ repo_owner (str) : The owner of the repository.
267+ repo_name (str) : The name of the repository.
268+ issue_number (int) : The number of the issue to update.
269+ title (str) : The new title for the issue.
270+ body (str) : The new body content for the issue.
271+ labels (list[str], optional) : A list of labels to assign to the issue. Defaults to an empty list.
272+ state (str, optional) : The state of the issue (' open' or ' closed'). Defaults to 'open'.
231273 Returns:
232- A dictionary containing the updated issue's metadata
274+ Dict[str, Any]: The updated issue data as returned by the GitHub API if the update is successful.
275+ None: If an error occurs during the update process.
276+ Error Handling:
277+ Logs an error message and prints the traceback if the request fails or an exception is raised.
233278 """
234279 logging .info (f"Updating issue { issue_number } in { repo_owner } /{ repo_name } " )
235280
@@ -254,13 +299,16 @@ def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title
254299 return None
255300
256301 def get_latest_sha (self , repo_owner : str , repo_name : str ) -> Optional [str ]:
257- """Fetch the latest commit SHA from the specified GitHub repository.
258-
302+ """
303+ Fetches the latest commit SHA from a specified GitHub repository.
259304 Args:
260- repo_owner: The owner of the GitHub repository
261- repo_name: The name of the GitHub repository
305+ repo_owner (str) : The owner of the GitHub repository.
306+ repo_name (str) : The name of the GitHub repository.
262307 Returns:
263- The latest commit SHA as a string, or None if no commits are found
308+ Optional[str]: The SHA string of the latest commit if found, otherwise None.
309+ Error Handling:
310+ Logs errors and warnings if the request fails, the response is invalid, or no commits are found.
311+ Returns None in case of exceptions or if the repository has no commits.
264312 """
265313 logging .info (f"Fetching latest commit SHA for { repo_owner } /{ repo_name } " )
266314
@@ -287,15 +335,18 @@ def get_latest_sha(self, repo_owner: str, repo_name: str) -> Optional[str]:
287335 return None
288336
289337 def create_tag (self , repo_owner : str , repo_name : str , tag_name : str , message : str ) -> Dict [str , Any ]:
290- """Create a new tag in the specified GitHub repository.
291-
338+ """
339+ Creates a new tag in the specified GitHub repository.
292340 Args:
293- repo_owner: The owner of the GitHub repository
294- repo_name: The name of the GitHub repository
295- tag_name: The name of the new tag
296- message: The message for the tag
341+ repo_owner (str) : The owner of the repository.
342+ repo_name (str) : The name of the repository.
343+ tag_name (str) : The name of the tag to create.
344+ message (str) : The message associated with the tag.
297345 Returns:
298- A dictionary containing the created tag's metadata
346+ Dict[str, Any]: The response data from the GitHub API if the tag is created successfully.
347+ None: If an error occurs during the tag creation process.
348+ Error Handling:
349+ Logs errors and prints the traceback if fetching the latest commit SHA fails or if the GitHub API request fails.
299350 """
300351 logging .info (f"Creating tag { tag_name } in { repo_owner } /{ repo_name } " )
301352 # Construct the tags URL
@@ -324,16 +375,19 @@ def create_tag(self, repo_owner: str, repo_name: str, tag_name: str, message: st
324375 return None
325376
326377 def create_release (self , repo_owner : str , repo_name : str , tag_name : str , release_name : str , body : str ) -> Dict [str , Any ]:
327- """Create a new release in the specified GitHub repository.
328-
378+ """
379+ Creates a new release in the specified GitHub repository.
329380 Args:
330- repo_owner: The owner of the GitHub repository
331- repo_name: The name of the GitHub repository
332- tag_name: The name of the tag for the release
333- release_name: The name of the release
334- body: The body content of the release
381+ repo_owner (str) : The owner of the repository.
382+ repo_name (str) : The name of the repository.
383+ tag_name (str) : The tag name for the release.
384+ release_name (str) : The name of the release.
385+ body (str) : The description or body content of the release.
335386 Returns:
336- A dictionary containing the created release's metadata
387+ Dict[str, Any]: The JSON response from the GitHub API containing release information if successful.
388+ None: If an error occurs during the release creation process.
389+ Error Handling:
390+ Logs errors and prints the traceback if the release creation fails, returning None.
337391 """
338392 logging .info (f"Creating release { release_name } in { repo_owner } /{ repo_name } " )
339393
0 commit comments