Skip to content

Commit c2d1d79

Browse files
committed
Better message in the annotations
1 parent 53024ed commit c2d1d79

2 files changed

Lines changed: 25 additions & 10 deletions

File tree

‎Lib/test/libregrtest/testresult.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,8 @@ def printErrorList(self, flavour, errors):
137137
return
138138
for test, err in errors:
139139
# Precede each failure report with a GitHub Actions annotation,
140-
# so that the annotation links to the report in the job log. The
141-
# report follows: don't repeat it in the annotation.
142-
self.stream.writeln(github_annotation(str(test), err,
143-
include_message=False))
140+
# so that the annotation links to the report in the job log
141+
self.stream.writeln(github_annotation(str(test), err))
144142
super().printErrorList(flavour, [(test, err)])
145143

146144
def get_xml_element(self):

‎Lib/test/libregrtest/utils.py‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,30 @@ def traceback_location(traceback: str) -> dict[str, str | int] | None:
175175
return location
176176

177177

178-
def github_annotation(title: str, message: str, *,
179-
include_message: bool = True) -> str:
178+
def traceback_exception(traceback: str) -> str:
179+
"""The exception which ends a traceback: type, message and notes.
180+
181+
Return traceback unchanged if it has no frame.
182+
"""
183+
lines = traceback.splitlines()
184+
for index in reversed(range(len(lines))):
185+
if lines[index].startswith(' File "'):
186+
break
187+
else:
188+
return traceback
189+
# Skip the frame's indented source line and ~^ markers
190+
index += 1
191+
while index < len(lines) and lines[index].startswith(" "):
192+
index += 1
193+
return "\n".join(lines[index:])
194+
195+
196+
def github_annotation(title: str, message: str) -> str:
180197
"""Format a GitHub Actions error annotation.
181198
182-
Locate it at the last frame of the traceback in message, if any. If
183-
include_message is false, the annotation only has the location and the
184-
title.
199+
message is a traceback or a failure description. Locate the annotation at
200+
the last frame of the traceback, if any, and only keep the exception which
201+
ends the traceback: the job log has the full traceback.
185202
"""
186203
def escape(text: str) -> str:
187204
return (text.replace("%", "%25").replace("\r", "%0D")
@@ -202,7 +219,7 @@ def escape_property(text: str) -> str:
202219
props["title"] = title
203220
# The job log only shows the message, not the properties: start the
204221
# message with the location and the title
205-
message = f"{header}\n{message}" if include_message else header
222+
message = f"{header}\n{traceback_exception(message).strip()}"
206223
props_text = ",".join(f"{key}={escape_property(str(value))}"
207224
for key, value in props.items())
208225
return f"::error {props_text}::{escape(message)}"

0 commit comments

Comments
 (0)