Skip to content

Commit 64ecbaf

Browse files
committed
adapt report_exists() for new input
update tests accordingly replaces `get_previous_comment()` which was almost identical to `report_exists()`
1 parent 00e5d17 commit 64ecbaf

File tree

3 files changed

+63
-84
lines changed

3 files changed

+63
-84
lines changed

reportsizedeltas/reportsizedeltas.py

+31-50
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import sys
99
import tempfile
1010
import time
11-
import typing
1211
import urllib.error
1312
import urllib.parse
1413
import 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:

reportsizedeltas/tests/test_reportsizedeltas.py

+32-34
Original file line numberDiff line numberDiff line change
@@ -367,18 +367,47 @@ def test_report_exists():
367367

368368
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
369369

370-
json_data = [{"body": "foo123"}, {"body": report_size_deltas.report_key_beginning + pr_head_sha + "foo"}]
370+
json_data = [
371+
{"body": "foo123"},
372+
{"body": report_size_deltas.report_key_beginning + pr_head_sha + "foo", "url": "some/url"},
373+
]
371374
report_size_deltas.api_request = unittest.mock.MagicMock(
372375
return_value={"json_data": json_data, "additional_pages": False, "page_count": 1}
373376
)
374377

375-
assert report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha=pr_head_sha)
378+
assert json_data[1]["url"] == report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha=pr_head_sha)
376379

377380
report_size_deltas.api_request.assert_called_once_with(
378381
request="repos/" + repository_name + "/issues/" + str(pr_number) + "/comments", page_number=1
379382
)
380383

381-
assert not report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha="asdf")
384+
assert report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha="asdf") is None
385+
386+
387+
def test_delete_previous_comment():
388+
pr_number = 42
389+
repository_name = "test_user/test_repo"
390+
391+
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
392+
393+
json_comments = json.loads((test_data_path / "test_delete_previous_comment" / "comments.json").read_bytes())
394+
395+
report_size_deltas.http_request = unittest.mock.Mock()
396+
report_size_deltas.get_json_response = unittest.mock.Mock(
397+
return_value={"json_data": json_comments, "page_count": 1},
398+
)
399+
400+
comment_url = report_size_deltas.report_exists(pr_number=pr_number)
401+
assert comment_url == json_comments[0]["url"]
402+
403+
for comment in json_comments[1:4]:
404+
if comment["body"].startswith(report_size_deltas.report_key_beginning):
405+
report_size_deltas.http_request.assert_any_call(url=comment["url"], method="DELETE")
406+
407+
# It would be nicer to assert that a call has not been made.
408+
# Here, we just assert that only the last 3 out of 4 bot comments were deleted.
409+
# Implicitly, this also means the non-bot comment (`json_comment[4]`) was not deleted.
410+
assert report_size_deltas.http_request.call_count == 3
382411

383412

384413
def test_get_artifacts_data_for_sha():
@@ -789,37 +818,6 @@ def test_comment_report():
789818
)
790819

791820

792-
def test_get_previous_comment():
793-
pr_number = 42
794-
repository_name = "test_user/test_repo"
795-
url = f"https://api.github.com/repos/{repository_name}/issues/{pr_number}"
796-
797-
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
798-
799-
json_comments = json.loads((test_data_path / "test_get_previous_comment" / "comments.json").read_bytes())
800-
801-
def side_effect(url: str):
802-
ret_val = {"page": 1}
803-
if url.endswith("/comments"):
804-
return {"json_data": json_comments, **ret_val}
805-
return {"json_data": {"comments": len(json_comments)}, **ret_val}
806-
807-
report_size_deltas.http_request = unittest.mock.Mock()
808-
report_size_deltas.get_json_response = unittest.mock.Mock(side_effect=side_effect)
809-
810-
comment_url = report_size_deltas.get_previous_comment(url=url)
811-
assert comment_url == json_comments[3]["url"]
812-
813-
for comment in json_comments[:3]:
814-
if comment["body"].startswith(report_size_deltas.report_key_beginning):
815-
report_size_deltas.http_request.assert_any_call(url=comment["url"], method="DELETE")
816-
817-
# It would be nicer to assert that a call has not been made.
818-
# Here, we just assert that the first 3 out of 4 bot comments were deleted.
819-
# Implicitly, this also means the non-bot comment (`json_comment[4]`) was not deleted.
820-
assert report_size_deltas.http_request.call_count == 3
821-
822-
823821
def test_api_request():
824822
response_data = {"json_data": {"foo": "bar"}, "additional_pages": False, "page_count": 1}
825823
request = "test_request"

0 commit comments

Comments
 (0)