77import xml .etree .ElementTree as ET
88from pathlib import Path
99from datetime import datetime , timezone
10+ import os
1011
1112# =============================================================================
1213# Utility Functions
@@ -21,24 +22,6 @@ def parse_repository(repository):
2122 print (f"❌ Invalid repository format: { repository } . Expected: 'owner/name'" )
2223 return None , None
2324
24- def make_github_request (url , headers , method = 'GET' , data = None ):
25- """Make a GitHub API request with consistent error handling"""
26- try :
27- if method .upper () == 'GET' :
28- response = requests .get (url , headers = headers )
29- elif method .upper () == 'POST' :
30- response = requests .post (url , headers = headers , json = data )
31- elif method .upper () == 'PATCH' :
32- response = requests .patch (url , headers = headers , json = data )
33- else :
34- print (f"❌ Unsupported HTTP method: { method } " )
35- return None
36-
37- return response
38- except requests .RequestException as e :
39- print (f"❌ Request failed: { e } " )
40- return None
41-
4225# =============================================================================
4326# GitHub API Functions
4427# =============================================================================
@@ -171,9 +154,9 @@ def find_line_number_of_change(original_content, old_value):
171154# GitHub PR Comment Functions
172155# =============================================================================
173156
174- def create_pr_suggestion (repo_owner , repo_name , pr_number , calibration_file , xml_file , line_number , suggested_line , head_sha , github_token ):
175- """Create a PR review with code suggestion or update existing one """
176- print (f"Creating/updating PR review with suggestion for #{ pr_number } ..." )
157+ def create_pr_suggestion (repo_owner , repo_name , pr_number , calibration_file , xml_file , line_number , suggested_line , head_sha , github_token , artifacts_url = '' ):
158+ """Create a PR comment with proposed changes """
159+ print (f"Creating PR comment with calibration update for #{ pr_number } ..." )
177160
178161 headers = {
179162 'Accept' : 'application/vnd.github+json' ,
@@ -182,90 +165,83 @@ def create_pr_suggestion(repo_owner, repo_name, pr_number, calibration_file, xml
182165
183166 bot_comment_base = f"🤖 **Automated Calibration `{ calibration_file } ` Update**"
184167
185- # Check for existing review comments from bot
186- existing_comment_id = find_existing_bot_comment (repo_owner , repo_name , pr_number , bot_comment_base , xml_file , line_number , github_token )
168+ # Check for existing comments from bot
169+ existing_comment_id = find_existing_bot_comment_general (repo_owner , repo_name , pr_number , bot_comment_base , github_token )
187170
188171 # Generate timestamp for the comment
189172 timestamp = datetime .now (timezone .utc ).strftime ("%Y-%m-%d %H:%M:%S UTC" )
190173
191- suggestion_body = f"""{ bot_comment_base } { ' (Updated)' if existing_comment_id else '' }
174+ # Get current line content for context
175+ content = get_file_content (repo_owner , repo_name , xml_file , head_sha , github_token )
176+ lines = content .split ('\n ' ) if content else []
177+ current_line = lines [line_number - 1 ].strip () if line_number <= len (lines ) else "Line not found"
178+
179+ comment_body = f"""{ bot_comment_base } { ' (Updated)' if existing_comment_id else '' }
192180
193181A new calibration has been generated and is ready for use.
194182
183+ **File:** `{ xml_file } `
184+ **Line:** { line_number }
195185**Last updated:** { timestamp }
196186
197- ```suggestion
198- { suggested_line }
199- ```"""
187+ **Current line:**
188+ ```xml
189+ { current_line }
190+ ```
191+
192+ **Proposed change:**
193+ ```xml
194+ { suggested_line .strip ()}
195+ ```
196+
197+ Please update the calibration URL in `{ xml_file } ` at line { line_number } ."""
198+
199+ # Add artifacts link if provided
200+ if artifacts_url :
201+ comment_body += f"\n \n ---\n \n ### 📊 Review Results\n \n Please review the artifacts here: { artifacts_url } "
200202
203+ # Create or update comment via GitHub REST API (no gh CLI)
201204 if existing_comment_id :
202- # Update existing comment
203205 print (f"Updating existing comment { existing_comment_id } ..." )
204- update_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /pulls /comments/{ existing_comment_id } "
205- update_data = {'body' : suggestion_body }
206+ update_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /issues /comments/{ existing_comment_id } "
207+ update_data = {'body' : comment_body }
206208 response = requests .patch (update_url , headers = headers , json = update_data )
207-
208209 if response .status_code == 200 :
209210 print ("✅ Existing PR comment updated successfully" )
210211 return response .json ()
211212 else :
212- print (f"❌ Failed to update existing comment: { response .status_code } " )
213- print (f" Response: { response .text } " )
213+ print (f"❌ Failed to update existing comment: { response .status_code } \n { response .text } " )
214214 return None
215215 else :
216- # Create new review comment
217- print ("Creating new review comment..." )
218- review_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /pulls/{ pr_number } /reviews"
219-
220- review_data = {
221- 'body' : f'🤖 Automated review with updated calibration URLs `{ calibration_file } ` for PR #{ pr_number } ' ,
222- 'event' : 'COMMENT' ,
223- 'commit_id' : head_sha ,
224- 'comments' : [
225- {
226- 'path' : xml_file ,
227- 'line' : line_number ,
228- 'body' : suggestion_body
229- }
230- ]
231- }
232-
233- response = requests .post (review_url , headers = headers , json = review_data )
234-
235- if response .status_code == 200 :
236- print ("✅ New PR review with suggestion created successfully" )
216+ print ("Creating new PR comment..." )
217+ comment_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /issues/{ pr_number } /comments"
218+ comment_data = {'body' : comment_body }
219+ response = requests .post (comment_url , headers = headers , json = comment_data )
220+ if response .status_code == 201 :
221+ print ("✅ New PR comment created successfully" )
237222 return response .json ()
238223 else :
239- print (f"❌ Failed to create PR review: { response .status_code } " )
240- print (f" Response: { response .text } " )
224+ print (f"❌ Failed to create PR comment: { response .status_code } \n { response .text } " )
241225 return None
242226
243- def find_existing_bot_comment (repo_owner , repo_name , pr_number , bot_comment_base , xml_file , line_number , github_token ):
244- """Find existing bot comment on the specific line"""
245- print (f"Checking for existing bot comments on line { line_number } ..." )
246-
227+ def find_existing_bot_comment_general (repo_owner , repo_name , pr_number , bot_comment_base , github_token ):
228+ """Find existing bot comment (general PR comment, not line-specific)"""
247229 headers = {
248230 'Accept' : 'application/vnd.github+json' ,
249231 'Authorization' : f'token { github_token } '
250232 }
251233
252- # Get all review comments for the PR
253- comments_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /pulls /{ pr_number } /comments"
234+ # Get all general comments for the PR
235+ comments_url = f"https://api.github.com/repos/{ repo_owner } /{ repo_name } /issues /{ pr_number } /comments"
254236 response = requests .get (comments_url , headers = headers )
255237
256238 if response .status_code != 200 :
257239 print (f"❌ Failed to get PR comments: { response .status_code } " )
258240 return None
259241
260- comments = response .json ()
261-
262- # Look for existing bot comment on the same line and file
263- for comment in comments :
264- # Check if it's from the bot (contains the bot identifier)
265- # and on the same file and line
266- if (comment .get ('path' ) == xml_file and
267- comment .get ('line' ) == line_number and
268- bot_comment_base in comment .get ('body' , '' )):
242+ # Look for existing bot comment
243+ for comment in response .json ():
244+ if bot_comment_base in comment .get ('body' , '' ):
269245 print (f"✅ Found existing bot comment: { comment ['id' ]} " )
270246 return comment ['id' ]
271247
0 commit comments