88import sys
99import tempfile
1010import time
11- import typing
1211import urllib .error
1312import urllib .parse
1413import urllib .request
@@ -170,33 +169,53 @@ def report_size_deltas_from_workflow_artifacts(self) -> None:
170169 page_number += 1
171170 page_count = api_data ["page_count" ]
172171
173- def report_exists (self , pr_number : int , pr_head_sha : str ) -> bool :
172+ def report_exists (self , pr_number : int , pr_head_sha : str = "" ) -> str | None :
174173 """Return whether a report has already been commented to the pull request thread for the latest workflow run.
175174
176- Keyword arguments:
177- pr_number -- number of the pull request to check
178- pr_head_sha -- PR's head branch hash
175+ If `pr_head_sha` is a blank str, then all thread comments are traversed. Additionally,
176+ any report comment found will be deleted if it is not the first report comment found.
177+ This is designed to support the action input `update-comment` when asserted.
178+
179+ If `pr_head_sha` is not a blank str, then thread comments are traversed
180+ until a report comment that corresponds to the commit is found.
181+ No comments are deleted in this scenario.
182+
183+ Arguments:
184+ pr_number: number of the pull request to check
185+ pr_head_sha: PR's head branch hash
186+ Returns:
187+ - A URL str to use for PATCHing the first applicable report comment.
188+ - None if no applicable report comments exist.
179189 """
180- # Get the pull request's comments
190+ comment_url : str | None = None
191+ request_uri = f"repos/{ self .repository_name } /issues/{ pr_number } /comments"
181192 page_number = 1
182193 page_count = 1
183194 while page_number <= page_count :
195+ # Get the pull request's comments
184196 api_data = self .api_request (
185- request = "repos/" + self . repository_name + "/issues/" + str ( pr_number ) + "/comments" ,
197+ request = request_uri ,
186198 page_number = page_number ,
187199 )
188200
189201 comments_data = api_data ["json_data" ]
190202 for comment_data in comments_data :
191203 # Check if the comment is a report for the PR's head SHA
192204 if comment_data ["body" ].startswith (self .report_key_beginning + pr_head_sha ):
193- return True
205+ if pr_head_sha :
206+ return comment_data ["url" ]
207+ # else: pr_head_sha == ""
208+ if comment_url is None :
209+ comment_url = comment_data ["url" ]
210+ else : # found another report
211+ # delete report comment if it is not the first report found
212+ self .http_request (url = comment_data ["url" ], method = "DELETE" )
194213
195214 page_number += 1
196215 page_count = api_data ["page_count" ]
197216
198217 # No reports found for the PR's head SHA
199- return False
218+ return comment_url
200219
201220 def get_artifacts_data_for_sha (self , pr_user_login : str , pr_head_ref : str , pr_head_sha : str ):
202221 """Return the list of data objects for the report artifacts associated with the given head commit hash.
@@ -526,43 +545,6 @@ def get_summary_value(self, show_emoji: bool, minimum, maximum) -> str:
526545
527546 return value
528547
529- def get_previous_comment (self , url : str ) -> str | None :
530- """Get a previous comment to update.
531-
532- Arguments:
533- url -- The URL used to traverse existing comments of a PR thread.
534- To get the comment total, this str should be in the form:
535- "{GITHUB_API_URL}/repos/{GITHUB_REPOSITORY}/issues/{PR_NUMBER}"
536- Returns:
537- - A URL str to use for PATCHing the latest applicable comment.
538- - None if no previous/applicable comments exist.
539- """
540- comment_url : str | None = None
541-
542- pr_info = self .get_json_response (url )
543- comment_count = typing .cast (typing .Dict [str , int ], pr_info ["json_data" ])["comments" ]
544-
545- comments_api_url = url + "/comments"
546- comments_response = self .get_json_response (url = comments_api_url )
547- while comment_count :
548- comments = typing .cast (
549- typing .List [typing .Dict [str , typing .Any ]],
550- comments_response ["json_data" ],
551- )
552- for comment in comments :
553- if typing .cast (str , comment ["body" ]).startswith (self .report_key_beginning ):
554- if comment_url is not None : # we have more than 1 old comment
555- # delete old comment
556- self .http_request (url = comment_url , method = "DELETE" )
557-
558- # keep track of latest posted comment only
559- comment_url = typing .cast (str , comment ["url" ])
560- comment_count -= len (comments )
561- next_page = comments_response ["page" ] + 1
562- comments_response = self .get_json_response (url = f"{ comments_api_url } /?page={ next_page } " )
563-
564- return comment_url
565-
566548 def comment_report (self , pr_number : int , report_markdown : str ) -> None :
567549 """Submit the report as a comment on the PR thread.
568550
@@ -572,13 +554,12 @@ def comment_report(self, pr_number: int, report_markdown: str) -> None:
572554 """
573555 print ("::debug::Adding deltas report comment to pull request" )
574556 report_data = json .dumps (obj = {"body" : report_markdown }).encode (encoding = "utf-8" )
575- url = f "https://api.github.com/repos/{ self .repository_name } /issues/{ pr_number } "
557+ url = "https://api.github.com/repos/" + self .repository_name + " /issues/" + str ( pr_number ) + "/comments "
576558
577- comment_url = None if not self .update_comment else self .get_previous_comment (url )
578- url = comment_url or url + "/comments"
559+ comment_url = None if not self .update_comment else self .report_exists (pr_number = pr_number )
579560 method = "PATCH" if comment_url else None
580561
581- self .http_request (url = url , data = report_data , method = method )
562+ self .http_request (url = comment_url or url , data = report_data , method = method )
582563
583564 def api_request (self , request : str , request_parameters : str = "" , page_number : int = 1 ):
584565 """Do a GitHub API request. Return a dictionary containing:
0 commit comments