Skip to content

Commit 30810a6

Browse files
committed
Split discrete functionalities of ReportSizeDeltas.report_size_deltas() into separate functions
The addition of support for sourcing the sketches reports from a local path resulted in the function containing code for two completely separate usages of the script. Moving each flavor of code to a separate function improves readability, maintainability, and testability.
1 parent 8a74de0 commit 30810a6

File tree

2 files changed

+95
-69
lines changed

2 files changed

+95
-69
lines changed

reportsizedeltas/reportsizedeltas.py

+63-56
Original file line numberDiff line numberDiff line change
@@ -88,73 +88,80 @@ def report_size_deltas(self):
8888
"""Comment a report of memory usage change to pull request(s)."""
8989
if os.environ["GITHUB_EVENT_NAME"] == "pull_request":
9090
# The sketches reports will be in a local folder location specified by the user
91-
sketches_reports_folder = pathlib.Path(os.environ["GITHUB_WORKSPACE"], self.sketches_reports_source_name)
92-
sketches_reports = self.get_sketches_reports(artifact_folder_object=sketches_reports_folder)
93-
94-
if sketches_reports:
95-
report = self.generate_report(sketches_reports=sketches_reports)
96-
97-
with open(file=os.environ["GITHUB_EVENT_PATH"]) as github_event_file:
98-
pr_number = json.load(github_event_file)["pull_request"]["number"]
99-
100-
self.comment_report(pr_number=pr_number, report_markdown=report)
101-
91+
self.report_size_deltas_from_local_reports()
10292
else:
10393
# The script is being run from a workflow triggered by something other than a PR
10494
# Scan the repository's pull requests and comment memory usage change reports where appropriate.
105-
# Get the repository's pull requests
106-
logger.debug("Getting PRs for " + self.repository_name)
107-
page_number = 1
108-
page_count = 1
109-
while page_number <= page_count:
110-
api_data = self.api_request(request="repos/" + self.repository_name + "/pulls",
111-
page_number=page_number)
112-
prs_data = api_data["json_data"]
113-
for pr_data in prs_data:
114-
# Note: closed PRs are not listed in the API response
115-
pr_number = pr_data["number"]
116-
pr_head_sha = pr_data["head"]["sha"]
117-
print("::debug::Processing pull request number:", pr_number)
118-
# When a PR is locked, only collaborators may comment. The automatically generated GITHUB_TOKEN will
119-
# likely be used, which is owned by the github-actions bot, who doesn't have collaborator status. So
120-
# locking the thread would cause the job to fail.
121-
if pr_data["locked"]:
122-
print("::debug::PR locked, skipping")
123-
continue
95+
self.report_size_deltas_from_workflow_artifacts()
12496

125-
if self.report_exists(pr_number=pr_number,
126-
pr_head_sha=pr_head_sha):
127-
# Go on to the next PR
128-
print("::debug::Report already exists")
129-
continue
97+
def report_size_deltas_from_local_reports(self):
98+
"""Comment a report of memory usage change to the pull request."""
99+
sketches_reports_folder = pathlib.Path(os.environ["GITHUB_WORKSPACE"], self.sketches_reports_source_name)
100+
sketches_reports = self.get_sketches_reports(artifact_folder_object=sketches_reports_folder)
130101

131-
artifact_download_url = self.get_artifact_download_url_for_sha(
132-
pr_user_login=pr_data["user"]["login"],
133-
pr_head_ref=pr_data["head"]["ref"],
134-
pr_head_sha=pr_head_sha)
135-
if artifact_download_url is None:
136-
# Go on to the next PR
137-
print("::debug::No sketches report artifact found")
138-
continue
102+
if sketches_reports:
103+
report = self.generate_report(sketches_reports=sketches_reports)
139104

140-
artifact_folder_object = self.get_artifact(artifact_download_url=artifact_download_url)
105+
with open(file=os.environ["GITHUB_EVENT_PATH"]) as github_event_file:
106+
pr_number = json.load(github_event_file)["pull_request"]["number"]
141107

142-
sketches_reports = self.get_sketches_reports(artifact_folder_object=artifact_folder_object)
108+
self.comment_report(pr_number=pr_number, report_markdown=report)
143109

144-
if sketches_reports:
145-
if sketches_reports[0][self.ReportKeys.commit_hash] != pr_head_sha:
146-
# The deltas report key uses the hash from the report, but the report_exists() comparison is
147-
# done using the hash provided by the API. If for some reason the two didn't match, it would
148-
# result in the deltas report being done over and over again.
149-
print("::warning::Report commit hash doesn't match PR's head commit hash, skipping")
150-
continue
110+
def report_size_deltas_from_workflow_artifacts(self):
111+
"""Scan the repository's pull requests and comment memory usage change reports where appropriate."""
112+
# Get the repository's pull requests
113+
logger.debug("Getting PRs for " + self.repository_name)
114+
page_number = 1
115+
page_count = 1
116+
while page_number <= page_count:
117+
api_data = self.api_request(request="repos/" + self.repository_name + "/pulls",
118+
page_number=page_number)
119+
prs_data = api_data["json_data"]
120+
for pr_data in prs_data:
121+
# Note: closed PRs are not listed in the API response
122+
pr_number = pr_data["number"]
123+
pr_head_sha = pr_data["head"]["sha"]
124+
print("::debug::Processing pull request number:", pr_number)
125+
# When a PR is locked, only collaborators may comment. The automatically generated GITHUB_TOKEN will
126+
# likely be used, which is owned by the github-actions bot, who doesn't have collaborator status. So
127+
# locking the thread would cause the job to fail.
128+
if pr_data["locked"]:
129+
print("::debug::PR locked, skipping")
130+
continue
131+
132+
if self.report_exists(pr_number=pr_number,
133+
pr_head_sha=pr_head_sha):
134+
# Go on to the next PR
135+
print("::debug::Report already exists")
136+
continue
137+
138+
artifact_download_url = self.get_artifact_download_url_for_sha(
139+
pr_user_login=pr_data["user"]["login"],
140+
pr_head_ref=pr_data["head"]["ref"],
141+
pr_head_sha=pr_head_sha)
142+
if artifact_download_url is None:
143+
# Go on to the next PR
144+
print("::debug::No sketches report artifact found")
145+
continue
146+
147+
artifact_folder_object = self.get_artifact(artifact_download_url=artifact_download_url)
148+
149+
sketches_reports = self.get_sketches_reports(artifact_folder_object=artifact_folder_object)
150+
151+
if sketches_reports:
152+
if sketches_reports[0][self.ReportKeys.commit_hash] != pr_head_sha:
153+
# The deltas report key uses the hash from the report, but the report_exists() comparison is
154+
# done using the hash provided by the API. If for some reason the two didn't match, it would
155+
# result in the deltas report being done over and over again.
156+
print("::warning::Report commit hash doesn't match PR's head commit hash, skipping")
157+
continue
151158

152-
report = self.generate_report(sketches_reports=sketches_reports)
159+
report = self.generate_report(sketches_reports=sketches_reports)
153160

154-
self.comment_report(pr_number=pr_number, report_markdown=report)
161+
self.comment_report(pr_number=pr_number, report_markdown=report)
155162

156-
page_number += 1
157-
page_count = api_data["page_count"]
163+
page_number += 1
164+
page_count = api_data["page_count"]
158165

159166
def report_exists(self, pr_number, pr_head_sha):
160167
"""Return whether a report has already been commented to the pull request thread for the latest workflow run

reportsizedeltas/tests/test_reportsizedeltas.py

+32-13
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,35 @@ def test_set_verbosity():
177177
reportsizedeltas.set_verbosity(enable_verbosity=False)
178178

179179

180-
def test_report_size_deltas_pull_request(mocker, monkeypatch):
180+
# noinspection PyUnresolvedReferences
181+
def test_report_size_deltas(mocker, monkeypatch):
182+
mocker.patch("reportsizedeltas.ReportSizeDeltas.report_size_deltas_from_local_reports", autospec=True)
183+
mocker.patch("reportsizedeltas.ReportSizeDeltas.report_size_deltas_from_workflow_artifacts", autospec=True)
184+
185+
report_size_deltas = get_reportsizedeltas_object()
186+
187+
# Test triggered by pull_request event
188+
monkeypatch.setenv("GITHUB_EVENT_NAME", "pull_request")
189+
report_size_deltas.report_size_deltas()
190+
# noinspection PyUnresolvedReferences
191+
report_size_deltas.report_size_deltas_from_local_reports.assert_called_once()
192+
report_size_deltas.report_size_deltas_from_workflow_artifacts.assert_not_called()
193+
194+
# Test triggered by other than pull_request event
195+
mocker.resetall()
196+
monkeypatch.setenv("GITHUB_EVENT_NAME", "schedule")
197+
report_size_deltas.report_size_deltas()
198+
report_size_deltas.report_size_deltas_from_local_reports.assert_not_called()
199+
report_size_deltas.report_size_deltas_from_workflow_artifacts.assert_called_once()
200+
201+
202+
def test_report_size_deltas_from_local_reports(mocker, monkeypatch):
181203
sketches_reports_source_name = "golden-sketches-reports-source-path"
182204
github_workspace = "golden-github-workspace"
183205
sketches_reports_folder = pathlib.Path(github_workspace, sketches_reports_source_name)
184206
sketches_reports = unittest.mock.sentinel.sketches_reports
185207
report = "golden report"
186208

187-
monkeypatch.setenv("GITHUB_EVENT_NAME", "pull_request")
188209
monkeypatch.setenv("GITHUB_WORKSPACE", github_workspace)
189210
monkeypatch.setenv("GITHUB_EVENT_PATH",
190211
str(test_data_path.joinpath("test_report_size_deltas_pull_request", "githubevent.json")))
@@ -197,22 +218,22 @@ def test_report_size_deltas_pull_request(mocker, monkeypatch):
197218

198219
# Test handling of no sketches reports data available
199220
reportsizedeltas.ReportSizeDeltas.get_sketches_reports.return_value = None
200-
report_size_deltas.report_size_deltas()
221+
report_size_deltas.report_size_deltas_from_local_reports()
201222

202223
report_size_deltas.comment_report.assert_not_called()
203224

204225
# Test report data available
205226
mocker.resetall()
206227
reportsizedeltas.ReportSizeDeltas.get_sketches_reports.return_value = sketches_reports
207-
report_size_deltas.report_size_deltas()
228+
report_size_deltas.report_size_deltas_from_local_reports()
208229

209230
report_size_deltas.get_sketches_reports.assert_called_once_with(report_size_deltas,
210231
artifact_folder_object=sketches_reports_folder)
211232
report_size_deltas.generate_report.assert_called_once_with(report_size_deltas, sketches_reports=sketches_reports)
212233
report_size_deltas.comment_report.assert_called_once_with(report_size_deltas, pr_number=42, report_markdown=report)
213234

214235

215-
def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
236+
def test_report_size_deltas_from_workflow_artifacts(mocker):
216237
artifact_download_url = "test_artifact_download_url"
217238
artifact_folder_object = "test_artifact_folder_object"
218239
pr_head_sha = "pr-head-sha"
@@ -221,8 +242,6 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
221242
json_data = [{"number": 1, "locked": True, "head": {"sha": pr_head_sha, "ref": "asdf"}, "user": {"login": "1234"}},
222243
{"number": 2, "locked": False, "head": {"sha": pr_head_sha, "ref": "asdf"}, "user": {"login": "1234"}}]
223244

224-
monkeypatch.setenv("GITHUB_EVENT_NAME", "schedule")
225-
226245
report_size_deltas = get_reportsizedeltas_object()
227246

228247
mocker.patch("reportsizedeltas.ReportSizeDeltas.api_request",
@@ -242,7 +261,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
242261
# Test handling of locked PR
243262
mocker.resetall()
244263

245-
report_size_deltas.report_size_deltas()
264+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
246265

247266
report_size_deltas.comment_report.assert_called_once_with(report_size_deltas, pr_number=2, report_markdown=report)
248267

@@ -252,7 +271,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
252271
reportsizedeltas.ReportSizeDeltas.report_exists.return_value = True
253272
mocker.resetall()
254273

255-
report_size_deltas.report_size_deltas()
274+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
256275

257276
report_size_deltas.comment_report.assert_not_called()
258277

@@ -261,7 +280,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
261280
reportsizedeltas.ReportSizeDeltas.get_artifact_download_url_for_sha.return_value = None
262281
mocker.resetall()
263282

264-
report_size_deltas.report_size_deltas()
283+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
265284

266285
report_size_deltas.comment_report.assert_not_called()
267286

@@ -270,7 +289,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
270289
reportsizedeltas.ReportSizeDeltas.get_sketches_reports.return_value = None
271290
mocker.resetall()
272291

273-
report_size_deltas.report_size_deltas()
292+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
274293

275294
report_size_deltas.comment_report.assert_not_called()
276295

@@ -281,7 +300,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
281300

282301
mocker.resetall()
283302

284-
report_size_deltas.report_size_deltas()
303+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
285304

286305
report_size_deltas.comment_report.assert_not_called()
287306

@@ -290,7 +309,7 @@ def test_report_size_deltas_not_pull_request(mocker, monkeypatch):
290309
reportsizedeltas.ReportSizeDeltas.get_sketches_reports.return_value = sketches_reports
291310
mocker.resetall()
292311

293-
report_size_deltas.report_size_deltas()
312+
report_size_deltas.report_size_deltas_from_workflow_artifacts()
294313

295314
report_exists_calls = []
296315
get_artifact_download_url_for_sha_calls = []

0 commit comments

Comments
 (0)