@@ -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