|
3 | 3 | import json
|
4 | 4 | import logging
|
5 | 5 | import os
|
| 6 | +import pathlib |
6 | 7 | import re
|
7 | 8 | import sys
|
8 | 9 | import tempfile
|
@@ -84,59 +85,76 @@ def __init__(self, repository_name, sketches_reports_source_name, token):
|
84 | 85 | self.token = token
|
85 | 86 |
|
86 | 87 | def report_size_deltas(self):
|
87 |
| - """Scan the repository's pull requests and comment memory usage change reports where appropriate.""" |
88 |
| - # Get the repository's pull requests |
89 |
| - logger.debug("Getting PRs for " + self.repository_name) |
90 |
| - page_number = 1 |
91 |
| - page_count = 1 |
92 |
| - while page_number <= page_count: |
93 |
| - api_data = self.api_request(request="repos/" + self.repository_name + "/pulls", |
94 |
| - page_number=page_number) |
95 |
| - prs_data = api_data["json_data"] |
96 |
| - for pr_data in prs_data: |
97 |
| - # Note: closed PRs are not listed in the API response |
98 |
| - pr_number = pr_data["number"] |
99 |
| - pr_head_sha = pr_data["head"]["sha"] |
100 |
| - print("::debug::Processing pull request number:", pr_number) |
101 |
| - # When a PR is locked, only collaborators may comment. The automatically generated GITHUB_TOKEN will |
102 |
| - # likely be used, which is owned by the github-actions bot, who doesn't have collaborator status. So |
103 |
| - # locking the thread would cause the job to fail. |
104 |
| - if pr_data["locked"]: |
105 |
| - print("::debug::PR locked, skipping") |
106 |
| - continue |
107 |
| - |
108 |
| - if self.report_exists(pr_number=pr_number, |
109 |
| - pr_head_sha=pr_head_sha): |
110 |
| - # Go on to the next PR |
111 |
| - print("::debug::Report already exists") |
112 |
| - continue |
113 |
| - |
114 |
| - artifact_download_url = self.get_artifact_download_url_for_sha(pr_user_login=pr_data["user"]["login"], |
115 |
| - pr_head_ref=pr_data["head"]["ref"], |
116 |
| - pr_head_sha=pr_head_sha) |
117 |
| - if artifact_download_url is None: |
118 |
| - # Go on to the next PR |
119 |
| - print("::debug::No sketches report artifact found") |
120 |
| - continue |
121 |
| - |
122 |
| - artifact_folder_object = self.get_artifact(artifact_download_url=artifact_download_url) |
123 |
| - |
124 |
| - sketches_reports = self.get_sketches_reports(artifact_folder_object=artifact_folder_object) |
125 |
| - |
126 |
| - if sketches_reports: |
127 |
| - if sketches_reports[0][self.ReportKeys.commit_hash] != pr_head_sha: |
128 |
| - # The deltas report key uses the hash from the report, but the report_exists() comparison is |
129 |
| - # done using the hash provided by the API. If for some reason the two didn't match, it would |
130 |
| - # result in the deltas report being done over and over again. |
131 |
| - print("::warning::Report commit hash doesn't match PR's head commit hash, skipping") |
| 88 | + """Comment a report of memory usage change to pull request(s).""" |
| 89 | + if os.environ["GITHUB_EVENT_NAME"] == "pull_request": |
| 90 | + # 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 | + |
| 102 | + else: |
| 103 | + # The script is being run from a workflow triggered by something other than a PR |
| 104 | + # 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") |
132 | 123 | continue
|
133 | 124 |
|
134 |
| - report = self.generate_report(sketches_reports=sketches_reports) |
| 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 |
135 | 130 |
|
136 |
| - self.comment_report(pr_number=pr_number, report_markdown=report) |
| 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 |
137 | 139 |
|
138 |
| - page_number += 1 |
139 |
| - page_count = api_data["page_count"] |
| 140 | + artifact_folder_object = self.get_artifact(artifact_download_url=artifact_download_url) |
| 141 | + |
| 142 | + sketches_reports = self.get_sketches_reports(artifact_folder_object=artifact_folder_object) |
| 143 | + |
| 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 |
| 151 | + |
| 152 | + report = self.generate_report(sketches_reports=sketches_reports) |
| 153 | + |
| 154 | + self.comment_report(pr_number=pr_number, report_markdown=report) |
| 155 | + |
| 156 | + page_number += 1 |
| 157 | + page_count = api_data["page_count"] |
140 | 158 |
|
141 | 159 | def report_exists(self, pr_number, pr_head_sha):
|
142 | 160 | """Return whether a report has already been commented to the pull request thread for the latest workflow run
|
@@ -257,10 +275,12 @@ def get_sketches_reports(self, artifact_folder_object):
|
257 | 275 | artifact_folder_object -- object containing the data about the temporary folder that stores the markdown files
|
258 | 276 | """
|
259 | 277 | with artifact_folder_object as artifact_folder:
|
| 278 | + # artifact_folder will be a string when running in non-local report mode |
| 279 | + artifact_folder = pathlib.Path(artifact_folder) |
260 | 280 | sketches_reports = []
|
261 |
| - for report_filename in sorted(os.listdir(path=artifact_folder)): |
| 281 | + for report_filename in sorted(artifact_folder.iterdir()): |
262 | 282 | # Combine sketches reports into an array
|
263 |
| - with open(file=artifact_folder + "/" + report_filename) as report_file: |
| 283 | + with open(file=report_filename.joinpath(report_filename)) as report_file: |
264 | 284 | report_data = json.load(report_file)
|
265 | 285 | if (
|
266 | 286 | (self.ReportKeys.boards not in report_data)
|
|
0 commit comments