From 13464687efb0c5e63e2faf4eccc1a0e854ceba1b Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Wed, 21 Feb 2024 20:13:58 -0800
Subject: [PATCH 1/5] update comment if exists
If no comment exists, then simply post a new comment. If more than 1 comment found, then delete all but last one and update the last one.
---
.flake8 | 1 +
.gitignore | 5 +++
.prettierignore | 5 +++
reportsizedeltas/reportsizedeltas.py | 60 ++++++++++++++++++++++++----
4 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/.flake8 b/.flake8
index efde3a0..2bd90f7 100644
--- a/.flake8
+++ b/.flake8
@@ -10,3 +10,4 @@ ignore = W503
max-complexity = 10
max-line-length = 120
select = E,W,F,C,N
+exclude = .env,env,venv,.venv
diff --git a/.gitignore b/.gitignore
index b9597c0..4891504 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,8 @@
__pycache__/
.coverage
/coverage.xml
+.env/
+.venv/
+venv/
+env/
+.vscode/
diff --git a/.prettierignore b/.prettierignore
index 79bae62..d53f2d6 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -4,3 +4,8 @@
.licenses/
__pycache__/
node_modules/
+.env/
+.venv/
+env/
+venv/
+.mypy_cache/
diff --git a/reportsizedeltas/reportsizedeltas.py b/reportsizedeltas/reportsizedeltas.py
index b9be40c..2892b6e 100644
--- a/reportsizedeltas/reportsizedeltas.py
+++ b/reportsizedeltas/reportsizedeltas.py
@@ -8,6 +8,7 @@
import sys
import tempfile
import time
+import typing
import urllib.error
import urllib.parse
import urllib.request
@@ -47,7 +48,7 @@ def set_verbosity(enable_verbosity: bool) -> None:
# INFO: manually specified output and all higher log level output
verbose_logging_level = logging.DEBUG
- if type(enable_verbosity) is not bool:
+ if not isinstance(enable_verbosity, bool):
raise TypeError
if enable_verbosity:
logger.setLevel(level=verbose_logging_level)
@@ -523,6 +524,43 @@ def get_summary_value(self, show_emoji: bool, minimum, maximum) -> str:
return value
+ def get_previous_comment(self, url: str) -> str | None:
+ """Get a previous comment to update.
+
+ Arguments:
+ url -- The URL used to traverse existing comments of a PR thread.
+ To get the comment total, this str should be in the form:
+ "{GITHUB_API_URL}/repos/{GITHUB_REPOSITORY}/issues/{PR_NUMBER}"
+ Returns:
+ - A URL str to use for PATCHing the latest applicable comment.
+ - None if no previous/applicable comments exist.
+ """
+ comment_url: str | None = None
+
+ pr_info = self.get_json_response(url)
+ comment_count = typing.cast(typing.Dict[str, int], pr_info["json_data"])["comments"]
+
+ comments_api_url = url + "/comments"
+ comments_response = self.get_json_response(url=comments_api_url)
+ while comment_count:
+ comments = typing.cast(
+ typing.List[typing.Dict[str, typing.Any]],
+ comments_response["json_data"],
+ )
+ for comment in comments:
+ if typing.cast(str, comment["body"]).startswith(self.report_key_beginning):
+ if comment_url is not None: # we have more than 1 old comment
+ # delete old comment
+ self.http_request(url=comment_url, method="DELETE")
+
+ # keep track of latest posted comment only
+ comment_url = typing.cast(str, comment["url"])
+ comment_count -= len(comments)
+ next_page = comments_response["page"] + 1
+ comments_response = self.get_json_response(url=f"{comments_api_url}/?page={next_page}")
+
+ return comment_url
+
def comment_report(self, pr_number: int, report_markdown: str) -> None:
"""Submit the report as a comment on the PR thread.
@@ -532,9 +570,13 @@ def comment_report(self, pr_number: int, report_markdown: str) -> None:
"""
print("::debug::Adding deltas report comment to pull request")
report_data = json.dumps(obj={"body": report_markdown}).encode(encoding="utf-8")
- url = "https://api.github.com/repos/" + self.repository_name + "/issues/" + str(pr_number) + "/comments"
+ url = f"https://api.github.com/repos/{self.repository_name}/issues/{pr_number}"
+
+ comment_url = self.get_previous_comment(url)
+ url = comment_url or url + "/comments"
+ method = "PATCH" if comment_url else None
- self.http_request(url=url, data=report_data)
+ self.http_request(url=url, data=report_data, method=method)
def api_request(self, request: str, request_parameters: str = "", page_number: int = 1):
"""Do a GitHub API request. Return a dictionary containing:
@@ -594,7 +636,7 @@ def get_json_response(self, url: str):
except Exception as exception:
raise exception
- def http_request(self, url: str, data: bytes | None = None):
+ def http_request(self, url: str, data: bytes | None = None, method: str | None = None):
"""Make a request and return a dictionary:
read -- the response
info -- headers
@@ -604,28 +646,32 @@ def http_request(self, url: str, data: bytes | None = None):
url -- the URL to load
data -- data to pass with the request
(default value: None)
+ method -- the HTTP request method to use
+ (default is None which means ``'GET' if data is None else 'POST'``).
"""
- with self.raw_http_request(url=url, data=data) as response_object:
+ with self.raw_http_request(url=url, data=data, method=method) as response_object:
return {
"body": response_object.read().decode(encoding="utf-8", errors="ignore"),
"headers": response_object.info(),
"url": response_object.geturl(),
}
- def raw_http_request(self, url: str, data: bytes | None = None):
+ def raw_http_request(self, url: str, data: bytes | None = None, method: str | None = None):
"""Make a request and return an object containing the response.
Keyword arguments:
url -- the URL to load
data -- data to pass with the request
(default value: None)
+ method -- the HTTP request method to use
+ (default is None which means ``'GET' if data is None else 'POST'``).
"""
# Maximum times to retry opening the URL before giving up
maximum_urlopen_retries = 3
logger.info("Opening URL: " + url)
- request = urllib.request.Request(url=url, data=data)
+ request = urllib.request.Request(url=url, data=data, method=method)
request.add_unredirected_header(key="Accept", val="application/vnd.github+json")
request.add_unredirected_header(key="Authorization", val="Bearer " + self.token)
request.add_unredirected_header(key="User-Agent", val=self.repository_name.split("/")[0])
From fe993261ffea1be421bb7e56eb390fc492d54d55 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Wed, 21 Feb 2024 19:59:29 -0800
Subject: [PATCH 2/5] update tests
distutils has been deprecated for years; use shutil instead
add unit test for `get_previous_comment()`
---
.../test_get_previous_comment/comments.json | 22 ++++++++++
.../tests/test_reportsizedeltas.py | 44 ++++++++++++++++---
2 files changed, 61 insertions(+), 5 deletions(-)
create mode 100644 reportsizedeltas/tests/data/test_get_previous_comment/comments.json
diff --git a/reportsizedeltas/tests/data/test_get_previous_comment/comments.json b/reportsizedeltas/tests/data/test_get_previous_comment/comments.json
new file mode 100644
index 0000000..627b000
--- /dev/null
+++ b/reportsizedeltas/tests/data/test_get_previous_comment/comments.json
@@ -0,0 +1,22 @@
+[
+ {
+ "url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1953679626",
+ "body": "**Memory usage change @ 525def8e855e5f227a4b4a0b6f84c34cd288a5ea**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ },
+ {
+ "url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1953996601",
+ "body": "**Memory usage change @ 862a917fe24c6f737abc336b681b7326c0fcceec**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ },
+ {
+ "url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1954284300",
+ "body": "**Memory usage change @ 0098017901c516c6cd49e248f1aabd6b30c91aa9**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ },
+ {
+ "url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1955441026",
+ "body": "**Memory usage change @ f9881f578cf28800a2076ae709434249e9cb9d67**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ },
+ {
+ "url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1955465432",
+ "body": "NOT A BOT COMMENT"
+ }
+]
diff --git a/reportsizedeltas/tests/test_reportsizedeltas.py b/reportsizedeltas/tests/test_reportsizedeltas.py
index 4fe96cd..78976d3 100644
--- a/reportsizedeltas/tests/test_reportsizedeltas.py
+++ b/reportsizedeltas/tests/test_reportsizedeltas.py
@@ -1,4 +1,4 @@
-import distutils.dir_util
+import shutil
import filecmp
import json
import os
@@ -526,8 +526,8 @@ def test_get_sketches_reports(test_data_folder_name):
artifacts_folder_object = tempfile.TemporaryDirectory(prefix="test_reportsizedeltas-")
try:
- distutils.dir_util.copy_tree(
- src=str(current_test_data_path.joinpath("artifacts")), dst=artifacts_folder_object.name
+ shutil.copytree(
+ src=str(current_test_data_path.joinpath("artifacts")), dst=artifacts_folder_object.name, dirs_exist_ok=True
)
except Exception: # pragma: no cover
artifacts_folder_object.cleanup()
@@ -730,7 +730,7 @@ def test_generate_report():
artifacts_folder_object = tempfile.TemporaryDirectory(prefix="test_reportsizedeltas-")
try:
- distutils.dir_util.copy_tree(src=str(sketches_report_path), dst=artifacts_folder_object.name)
+ shutil.copytree(src=str(sketches_report_path), dst=artifacts_folder_object.name, dirs_exist_ok=True)
except Exception: # pragma: no cover
artifacts_folder_object.cleanup()
raise
@@ -768,6 +768,7 @@ def test_comment_report():
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
report_size_deltas.http_request = unittest.mock.MagicMock()
+ report_size_deltas.get_previous_comment = unittest.mock.Mock(return_value=None)
report_size_deltas.comment_report(pr_number=pr_number, report_markdown=report_markdown)
@@ -778,9 +779,41 @@ def test_comment_report():
report_size_deltas.http_request.assert_called_once_with(
url="https://api.github.com/repos/" + repository_name + "/issues/" + str(pr_number) + "/comments",
data=report_data,
+ method=None,
)
+def test_get_previous_comment():
+ pr_number = 42
+ repository_name = "test_user/test_repo"
+ url = f"https://api.github.com/repos/{repository_name}/issues/{pr_number}"
+
+ report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
+
+ json_comments = json.loads((test_data_path / "test_get_previous_comment" / "comments.json").read_bytes())
+
+ def side_effect(url: str):
+ ret_val = {"page": 1}
+ if url.endswith("/comments"):
+ return {"json_data": json_comments, **ret_val}
+ return {"json_data": {"comments": len(json_comments)}, **ret_val}
+
+ report_size_deltas.http_request = unittest.mock.Mock()
+ report_size_deltas.get_json_response = unittest.mock.Mock(side_effect=side_effect)
+
+ comment_url = report_size_deltas.get_previous_comment(url=url)
+ assert comment_url == json_comments[3]["url"]
+
+ for comment in json_comments[:3]:
+ if comment["body"].startswith(report_size_deltas.report_key_beginning):
+ report_size_deltas.http_request.assert_any_call(url=comment["url"], method="DELETE")
+
+ # It would be nicer to assert that a call has not been made.
+ # Here, we just assert that the first 3 out of 4 bot comments were deleted.
+ # Implicitly, this also means the non-bot comment (`json_comment[4]`) was not deleted.
+ assert report_size_deltas.http_request.call_count == 3
+
+
def test_api_request():
response_data = {"json_data": {"foo": "bar"}, "additional_pages": False, "page_count": 1}
request = "test_request"
@@ -868,7 +901,7 @@ def test_http_request():
report_size_deltas.http_request(url=url, data=data)
- report_size_deltas.raw_http_request.assert_called_once_with(url=url, data=data)
+ report_size_deltas.raw_http_request.assert_called_once_with(url=url, data=data, method=None)
def test_raw_http_request(mocker):
@@ -896,6 +929,7 @@ def add_unredirected_header(self):
urllib.request.Request.assert_called_once_with(
url=url,
data=data,
+ method=None,
)
request.add_unredirected_header.assert_has_calls(
calls=[
From ade0b2ff4fb38a2aa2ea88ea15924850db731912 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 20 May 2024 17:23:55 -0700
Subject: [PATCH 3/5] add new input `update-comment`
defaults to false for old behavior
---
action.yml | 3 +++
reportsizedeltas/reportsizedeltas.py | 6 ++++--
reportsizedeltas/tests/test_reportsizedeltas.py | 10 ++++++++--
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/action.yml b/action.yml
index d241747..4031d4c 100644
--- a/action.yml
+++ b/action.yml
@@ -7,6 +7,9 @@ inputs:
github-token:
description: "GitHub access token used to comment the memory usage comparison results to the PR thread"
default: ${{ github.token }}
+ update-comment:
+ description: "when posting a report, set this to true to only update the previous report (if one exists)"
+ default: false
runs:
using: "docker"
image: "Dockerfile"
diff --git a/reportsizedeltas/reportsizedeltas.py b/reportsizedeltas/reportsizedeltas.py
index 2892b6e..4df7069 100644
--- a/reportsizedeltas/reportsizedeltas.py
+++ b/reportsizedeltas/reportsizedeltas.py
@@ -32,6 +32,7 @@ def main() -> None:
repository_name=os.environ["GITHUB_REPOSITORY"],
sketches_reports_source=os.environ["INPUT_SKETCHES-REPORTS-SOURCE"],
token=os.environ["INPUT_GITHUB-TOKEN"],
+ update_comment=os.environ["INPUT_UPDATE-COMMENT"] == "true",
)
report_size_deltas.report_size_deltas()
@@ -87,10 +88,11 @@ class ReportKeys:
sketches = "sketches"
compilation_success = "compilation_success"
- def __init__(self, repository_name: str, sketches_reports_source: str, token: str) -> None:
+ def __init__(self, repository_name: str, sketches_reports_source: str, token: str, update_comment: bool) -> None:
self.repository_name = repository_name
self.sketches_reports_source = sketches_reports_source
self.token = token
+ self.update_comment = update_comment
def report_size_deltas(self) -> None:
"""Comment a report of memory usage change to pull request(s)."""
@@ -572,7 +574,7 @@ def comment_report(self, pr_number: int, report_markdown: str) -> None:
report_data = json.dumps(obj={"body": report_markdown}).encode(encoding="utf-8")
url = f"https://api.github.com/repos/{self.repository_name}/issues/{pr_number}"
- comment_url = self.get_previous_comment(url)
+ comment_url = None if not self.update_comment else self.get_previous_comment(url)
url = comment_url or url + "/comments"
method = "PATCH" if comment_url else None
diff --git a/reportsizedeltas/tests/test_reportsizedeltas.py b/reportsizedeltas/tests/test_reportsizedeltas.py
index 78976d3..7a93eff 100644
--- a/reportsizedeltas/tests/test_reportsizedeltas.py
+++ b/reportsizedeltas/tests/test_reportsizedeltas.py
@@ -22,6 +22,7 @@ def get_reportsizedeltas_object(
repository_name: str = "FooOwner/BarRepository",
sketches_reports_source: str = "foo-artifact-pattern",
token: str = "foo token",
+ update_comment: bool = False,
) -> reportsizedeltas.ReportSizeDeltas:
"""Return a reportsizedeltas.ReportSizeDeltas object to use in tests.
@@ -32,7 +33,10 @@ def get_reportsizedeltas_object(
token -- GitHub access token
"""
return reportsizedeltas.ReportSizeDeltas(
- repository_name=repository_name, sketches_reports_source=sketches_reports_source, token=token
+ repository_name=repository_name,
+ sketches_reports_source=sketches_reports_source,
+ token=token,
+ update_comment=update_comment,
)
@@ -106,10 +110,12 @@ class ActionInputs:
repository_name = "GoldenOwner/GoldenRepository"
sketches_reports_source = "golden-source-pattern"
token = "golden-github-token"
+ update_comment = "false"
monkeypatch.setenv("GITHUB_REPOSITORY", ActionInputs.repository_name)
monkeypatch.setenv("INPUT_SKETCHES-REPORTS-SOURCE", ActionInputs.sketches_reports_source)
monkeypatch.setenv("INPUT_GITHUB-TOKEN", ActionInputs.token)
+ monkeypatch.setenv("INPUT_UPDATE-COMMENT", ActionInputs.update_comment)
return ActionInputs()
@@ -132,6 +138,7 @@ def report_size_deltas(self):
repository_name=setup_environment_variables.repository_name,
sketches_reports_source=setup_environment_variables.sketches_reports_source,
token=setup_environment_variables.token,
+ update_comment=setup_environment_variables.update_comment == "true",
)
ReportSizeDeltas.report_size_deltas.assert_called_once()
@@ -768,7 +775,6 @@ def test_comment_report():
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
report_size_deltas.http_request = unittest.mock.MagicMock()
- report_size_deltas.get_previous_comment = unittest.mock.Mock(return_value=None)
report_size_deltas.comment_report(pr_number=pr_number, report_markdown=report_markdown)
From 0bfa42d4c823f4c5dbf7c05cb5a33abbca3bd870 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Wed, 21 Feb 2024 22:38:43 -0800
Subject: [PATCH 4/5] adapt `report_exists()` for new input
update tests accordingly
replaces `get_previous_comment()` which was almost identical to `report_exists()`
---
reportsizedeltas/reportsizedeltas.py | 81 +++++++------------
.../comments.json | 0
.../tests/test_reportsizedeltas.py | 66 ++++++++-------
3 files changed, 63 insertions(+), 84 deletions(-)
rename reportsizedeltas/tests/data/{test_get_previous_comment => test_delete_previous_comment}/comments.json (100%)
diff --git a/reportsizedeltas/reportsizedeltas.py b/reportsizedeltas/reportsizedeltas.py
index 4df7069..c626e91 100644
--- a/reportsizedeltas/reportsizedeltas.py
+++ b/reportsizedeltas/reportsizedeltas.py
@@ -8,7 +8,6 @@
import sys
import tempfile
import time
-import typing
import urllib.error
import urllib.parse
import urllib.request
@@ -170,19 +169,32 @@ def report_size_deltas_from_workflow_artifacts(self) -> None:
page_number += 1
page_count = api_data["page_count"]
- def report_exists(self, pr_number: int, pr_head_sha: str) -> bool:
+ def report_exists(self, pr_number: int, pr_head_sha: str = "") -> str | None:
"""Return whether a report has already been commented to the pull request thread for the latest workflow run.
- Keyword arguments:
- pr_number -- number of the pull request to check
- pr_head_sha -- PR's head branch hash
+ If `pr_head_sha` is a blank str, then all thread comments are traversed. Additionally,
+ any report comment found will be deleted if it is not the first report comment found.
+ This is designed to support the action input `update-comment` when asserted.
+
+ If `pr_head_sha` is not a blank str, then thread comments are traversed
+ until a report comment that corresponds to the commit is found.
+ No comments are deleted in this scenario.
+
+ Arguments:
+ pr_number: number of the pull request to check
+ pr_head_sha: PR's head branch hash
+ Returns:
+ - A URL str to use for PATCHing the first applicable report comment.
+ - None if no applicable report comments exist.
"""
- # Get the pull request's comments
+ comment_url: str | None = None
+ request_uri = f"repos/{self.repository_name}/issues/{pr_number}/comments"
page_number = 1
page_count = 1
while page_number <= page_count:
+ # Get the pull request's comments
api_data = self.api_request(
- request="repos/" + self.repository_name + "/issues/" + str(pr_number) + "/comments",
+ request=request_uri,
page_number=page_number,
)
@@ -190,13 +202,20 @@ def report_exists(self, pr_number: int, pr_head_sha: str) -> bool:
for comment_data in comments_data:
# Check if the comment is a report for the PR's head SHA
if comment_data["body"].startswith(self.report_key_beginning + pr_head_sha):
- return True
+ if pr_head_sha:
+ return comment_data["url"]
+ # else: pr_head_sha == ""
+ if comment_url is None:
+ comment_url = comment_data["url"]
+ else: # found another report
+ # delete report comment if it is not the first report found
+ self.http_request(url=comment_data["url"], method="DELETE")
page_number += 1
page_count = api_data["page_count"]
# No reports found for the PR's head SHA
- return False
+ return comment_url
def get_artifacts_data_for_sha(self, pr_user_login: str, pr_head_ref: str, pr_head_sha: str):
"""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:
return value
- def get_previous_comment(self, url: str) -> str | None:
- """Get a previous comment to update.
-
- Arguments:
- url -- The URL used to traverse existing comments of a PR thread.
- To get the comment total, this str should be in the form:
- "{GITHUB_API_URL}/repos/{GITHUB_REPOSITORY}/issues/{PR_NUMBER}"
- Returns:
- - A URL str to use for PATCHing the latest applicable comment.
- - None if no previous/applicable comments exist.
- """
- comment_url: str | None = None
-
- pr_info = self.get_json_response(url)
- comment_count = typing.cast(typing.Dict[str, int], pr_info["json_data"])["comments"]
-
- comments_api_url = url + "/comments"
- comments_response = self.get_json_response(url=comments_api_url)
- while comment_count:
- comments = typing.cast(
- typing.List[typing.Dict[str, typing.Any]],
- comments_response["json_data"],
- )
- for comment in comments:
- if typing.cast(str, comment["body"]).startswith(self.report_key_beginning):
- if comment_url is not None: # we have more than 1 old comment
- # delete old comment
- self.http_request(url=comment_url, method="DELETE")
-
- # keep track of latest posted comment only
- comment_url = typing.cast(str, comment["url"])
- comment_count -= len(comments)
- next_page = comments_response["page"] + 1
- comments_response = self.get_json_response(url=f"{comments_api_url}/?page={next_page}")
-
- return comment_url
-
def comment_report(self, pr_number: int, report_markdown: str) -> None:
"""Submit the report as a comment on the PR thread.
@@ -572,13 +554,12 @@ def comment_report(self, pr_number: int, report_markdown: str) -> None:
"""
print("::debug::Adding deltas report comment to pull request")
report_data = json.dumps(obj={"body": report_markdown}).encode(encoding="utf-8")
- url = f"https://api.github.com/repos/{self.repository_name}/issues/{pr_number}"
+ url = "https://api.github.com/repos/" + self.repository_name + "/issues/" + str(pr_number) + "/comments"
- comment_url = None if not self.update_comment else self.get_previous_comment(url)
- url = comment_url or url + "/comments"
+ comment_url = None if not self.update_comment else self.report_exists(pr_number=pr_number)
method = "PATCH" if comment_url else None
- self.http_request(url=url, data=report_data, method=method)
+ self.http_request(url=comment_url or url, data=report_data, method=method)
def api_request(self, request: str, request_parameters: str = "", page_number: int = 1):
"""Do a GitHub API request. Return a dictionary containing:
diff --git a/reportsizedeltas/tests/data/test_get_previous_comment/comments.json b/reportsizedeltas/tests/data/test_delete_previous_comment/comments.json
similarity index 100%
rename from reportsizedeltas/tests/data/test_get_previous_comment/comments.json
rename to reportsizedeltas/tests/data/test_delete_previous_comment/comments.json
diff --git a/reportsizedeltas/tests/test_reportsizedeltas.py b/reportsizedeltas/tests/test_reportsizedeltas.py
index 7a93eff..6d8f3dd 100644
--- a/reportsizedeltas/tests/test_reportsizedeltas.py
+++ b/reportsizedeltas/tests/test_reportsizedeltas.py
@@ -367,18 +367,47 @@ def test_report_exists():
report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
- json_data = [{"body": "foo123"}, {"body": report_size_deltas.report_key_beginning + pr_head_sha + "foo"}]
+ json_data = [
+ {"body": "foo123"},
+ {"body": report_size_deltas.report_key_beginning + pr_head_sha + "foo", "url": "some/url"},
+ ]
report_size_deltas.api_request = unittest.mock.MagicMock(
return_value={"json_data": json_data, "additional_pages": False, "page_count": 1}
)
- assert report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha=pr_head_sha)
+ assert json_data[1]["url"] == report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha=pr_head_sha)
report_size_deltas.api_request.assert_called_once_with(
request="repos/" + repository_name + "/issues/" + str(pr_number) + "/comments", page_number=1
)
- assert not report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha="asdf")
+ assert report_size_deltas.report_exists(pr_number=pr_number, pr_head_sha="asdf") is None
+
+
+def test_delete_previous_comment():
+ pr_number = 42
+ repository_name = "test_user/test_repo"
+
+ report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
+
+ json_comments = json.loads((test_data_path / "test_delete_previous_comment" / "comments.json").read_bytes())
+
+ report_size_deltas.http_request = unittest.mock.Mock()
+ report_size_deltas.get_json_response = unittest.mock.Mock(
+ return_value={"json_data": json_comments, "page_count": 1},
+ )
+
+ comment_url = report_size_deltas.report_exists(pr_number=pr_number)
+ assert comment_url == json_comments[0]["url"]
+
+ for comment in json_comments[1:4]:
+ if comment["body"].startswith(report_size_deltas.report_key_beginning):
+ report_size_deltas.http_request.assert_any_call(url=comment["url"], method="DELETE")
+
+ # It would be nicer to assert that a call has not been made.
+ # Here, we just assert that only the last 3 out of 4 bot comments were deleted.
+ # Implicitly, this also means the non-bot comment (`json_comment[4]`) was not deleted.
+ assert report_size_deltas.http_request.call_count == 3
def test_get_artifacts_data_for_sha():
@@ -789,37 +818,6 @@ def test_comment_report():
)
-def test_get_previous_comment():
- pr_number = 42
- repository_name = "test_user/test_repo"
- url = f"https://api.github.com/repos/{repository_name}/issues/{pr_number}"
-
- report_size_deltas = get_reportsizedeltas_object(repository_name=repository_name)
-
- json_comments = json.loads((test_data_path / "test_get_previous_comment" / "comments.json").read_bytes())
-
- def side_effect(url: str):
- ret_val = {"page": 1}
- if url.endswith("/comments"):
- return {"json_data": json_comments, **ret_val}
- return {"json_data": {"comments": len(json_comments)}, **ret_val}
-
- report_size_deltas.http_request = unittest.mock.Mock()
- report_size_deltas.get_json_response = unittest.mock.Mock(side_effect=side_effect)
-
- comment_url = report_size_deltas.get_previous_comment(url=url)
- assert comment_url == json_comments[3]["url"]
-
- for comment in json_comments[:3]:
- if comment["body"].startswith(report_size_deltas.report_key_beginning):
- report_size_deltas.http_request.assert_any_call(url=comment["url"], method="DELETE")
-
- # It would be nicer to assert that a call has not been made.
- # Here, we just assert that the first 3 out of 4 bot comments were deleted.
- # Implicitly, this also means the non-bot comment (`json_comment[4]`) was not deleted.
- assert report_size_deltas.http_request.call_count == 3
-
-
def test_api_request():
response_data = {"json_data": {"foo": "bar"}, "additional_pages": False, "page_count": 1}
request = "test_request"
From 24ba1022136b616380b739a491d7e33390fe6b0b Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Wed, 28 May 2025 15:59:46 -0700
Subject: [PATCH 5/5] prefix comments with unique identifying marker
avoids treating user comments as a bot comment
---
reportsizedeltas/reportsizedeltas.py | 2 +-
.../data/test_delete_previous_comment/comments.json | 10 +++++-----
reportsizedeltas/tests/test_reportsizedeltas.py | 1 +
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/reportsizedeltas/reportsizedeltas.py b/reportsizedeltas/reportsizedeltas.py
index c626e91..0fb8045 100644
--- a/reportsizedeltas/reportsizedeltas.py
+++ b/reportsizedeltas/reportsizedeltas.py
@@ -65,7 +65,7 @@ class ReportSizeDeltas:
token -- GitHub access token
"""
- report_key_beginning = "**Memory usage change @ "
+ report_key_beginning = "\n**Memory usage change @ "
not_applicable_indicator = "N/A"
class ReportKeys:
diff --git a/reportsizedeltas/tests/data/test_delete_previous_comment/comments.json b/reportsizedeltas/tests/data/test_delete_previous_comment/comments.json
index 627b000..fbb69eb 100644
--- a/reportsizedeltas/tests/data/test_delete_previous_comment/comments.json
+++ b/reportsizedeltas/tests/data/test_delete_previous_comment/comments.json
@@ -1,22 +1,22 @@
[
{
"url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1953679626",
- "body": "**Memory usage change @ 525def8e855e5f227a4b4a0b6f84c34cd288a5ea**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ "body": "\n**Memory usage change @ 525def8e855e5f227a4b4a0b6f84c34cd288a5ea**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
},
{
"url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1953996601",
- "body": "**Memory usage change @ 862a917fe24c6f737abc336b681b7326c0fcceec**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ "body": "\n**Memory usage change @ 862a917fe24c6f737abc336b681b7326c0fcceec**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
},
{
"url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1954284300",
- "body": "**Memory usage change @ 0098017901c516c6cd49e248f1aabd6b30c91aa9**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ "body": "\n**Memory usage change @ 0098017901c516c6cd49e248f1aabd6b30c91aa9**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
},
{
"url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1955441026",
- "body": "**Memory usage change @ f9881f578cf28800a2076ae709434249e9cb9d67**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
+ "body": "\n**Memory usage change @ f9881f578cf28800a2076ae709434249e9cb9d67**\n\nBoard|flash|%|RAM for global variables|%\n-|-|-|-|-\n`arduino:avr:nano`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n`arduino:samd:mkrzero`|0 - 0|0.0 - 0.0|0 - 0|0.0 - 0.0\n\n\nClick for full report table
\n\nBoard|`examples/Getting_Started_SimpleClient_Mesh`
flash|%|`examples/Getting_Started_SimpleClient_Mesh`
RAM for global variables|%|`examples/Getting_Started_SimpleServer_Mesh`
flash|%|`examples/Getting_Started_SimpleServer_Mesh`
RAM for global variables|%|`examples/InteractiveServer_Mesh`
flash|%|`examples/InteractiveServer_Mesh`
RAM for global variables|%|`examples/MQTT/mqtt_basic`
flash|%|`examples/MQTT/mqtt_basic`
RAM for global variables|%|`examples/MQTT/mqtt_basic_2`
flash|%|`examples/MQTT/mqtt_basic_2`
RAM for global variables|%|`examples/SimpleClient_Mesh`
flash|%|`examples/SimpleClient_Mesh`
RAM for global variables|%\n-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-\n`arduino:avr:nano`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n`arduino:samd:mkrzero`|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0|0|0.0\n\n \n\n\nClick for full report CSV
\n\n```\nBoard,examples/Getting_Started_SimpleClient_Mesh
flash,%,examples/Getting_Started_SimpleClient_Mesh
RAM for global variables,%,examples/Getting_Started_SimpleServer_Mesh
flash,%,examples/Getting_Started_SimpleServer_Mesh
RAM for global variables,%,examples/InteractiveServer_Mesh
flash,%,examples/InteractiveServer_Mesh
RAM for global variables,%,examples/MQTT/mqtt_basic
flash,%,examples/MQTT/mqtt_basic
RAM for global variables,%,examples/MQTT/mqtt_basic_2
flash,%,examples/MQTT/mqtt_basic_2
RAM for global variables,%,examples/SimpleClient_Mesh
flash,%,examples/SimpleClient_Mesh
RAM for global variables,%\narduino:avr:nano,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\narduino:samd:mkrzero,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0\n```\n "
},
{
"url": "https://api.github.com/repos/test-user/test-repo/issues/comments/1955465432",
- "body": "NOT A BOT COMMENT"
+ "body": "**Memory usage change @ NOT A BOT COMMENT"
}
]
diff --git a/reportsizedeltas/tests/test_reportsizedeltas.py b/reportsizedeltas/tests/test_reportsizedeltas.py
index 6d8f3dd..e668ad8 100644
--- a/reportsizedeltas/tests/test_reportsizedeltas.py
+++ b/reportsizedeltas/tests/test_reportsizedeltas.py
@@ -735,6 +735,7 @@ def test_add_detailed_report_row(report_data, fqbn_data, expected_report_data):
def test_generate_report():
sketches_report_path = test_data_path.joinpath("size-deltas-reports-new")
expected_deltas_report = (
+ "\n"
"**Memory usage change @ d8fd302**\n\n"
"Board|flash|%|RAM for global variables|%\n"
"-|-|-|-|-\n"