55import json
66import re
77
8- def artifact_count (count , icon ):
8+ SKIP = - 1
9+ PASS = 0
10+ WARNING = 1
11+ ERROR = 2
12+ FAILURE = 3
13+
14+ TEST_STATUS = [
15+ ":green_circle:" ,
16+ ":yellow_circle:" ,
17+ ":red_circle:" ,
18+ ":fire:" ,
19+ ":new_moon:" # -1
20+ ]
21+
22+ BOARD_STATUS = [
23+ ":white_check_mark:" ,
24+ ":grey_exclamation:" ,
25+ ":x:" ,
26+ ":fire:" ,
27+ ":new_moon:" # -1
28+ }
29+
30+ def artifact_count (count , status , icons ):
931 """
1032 Formats a count and an icon for display. If count is 0,
1133 it returns an empty string for the count and replaces the icon with :new_moon:.
1234 """
13- if count == 0 :
35+ if not count or status == SKIP :
1436 count = ""
15- icon = ":new_moon:"
37+ status = SKIP
1638
17- return f"<code>{ count :>3} </code>{ icon } "
39+ return f"<code>{ count :>3} </code>{ icons [ status ] } "
1840
1941def example_name (sketch_name ):
2042 match = re .search (r'libraries/([^/]+)/(.*)' , sketch_name )
@@ -28,7 +50,7 @@ def example_name(sketch_name):
2850TEST_MATRIX = {}
2951BOARD_SUMMARY = {}
3052
31- def log_test (name , board , icon , issues , job_link = None ):
53+ def log_test (name , board , status , issues , job_link = None ):
3254 """
3355 Logs individual test results into the TEST_MATRIX dictionary.
3456 """
@@ -39,7 +61,7 @@ def log_test(name, board, icon, issues, job_link=None):
3961 'errors' : 0 ,
4062 'warnings' : 0 ,
4163 'job_link' : job_link ,
42- 'icon ' : ':white_check_mark:'
64+ 'status ' : 0
4365 }
4466
4567 board_info = BOARD_SUMMARY [board ]
@@ -48,22 +70,18 @@ def log_test(name, board, icon, issues, job_link=None):
4870 issues = [ issues ]
4971
5072 board_info ['tests' ] + = 1
51- if icon == ":fire:" :
52- board_info ['icon' ] = ":fire:"
53- elif icon == ":red_circle:" :
54- board_info ['icon' ] = ":x:"
55- board_info ['errors' ] += 1
56- elif icon == ":yellow_circle:" :
73+ if status == WARNING :
5774 board_info ['warnings' ] + = 1
58- # Only set to warning if not already an error
59- if not board_info ['icon' ]:
60- board_info ['icon' ] = ":white_check_mark::grey_exclamation:"
75+ elif status == ERROR :
76+ board_info ['errors' ] + = 1
77+
78+ board_info ['status' ] = max (board_info ['status' ], status )
6179
6280 if name not in TEST_MATRIX :
6381 TEST_MATRIX [name ] = {}
6482
6583 TEST_MATRIX [name ][board ] = {
66- 'icon ' : icon ,
84+ 'status ' : status ,
6785 'issues' : issues
6886 }
6987
@@ -86,24 +104,24 @@ def process_build_reports():
86104
87105 for board_data in ALL_BOARD_DATA :
88106 # Extract common fields
89- board = board_data . get ( 'board' )
90- variant = board_data . get ( 'variant' )
91- subarch = board_data . get ( 'subarch' )
107+ board = board_data [ 'board' ]
108+ variant = board_data [ 'variant' ]
109+ subarch = board_data [ 'subarch' ]
92110
93111 # Filename preparation
94112 REPORT_FILE = f"arduino-{ subarch } -{ board } .json"
95113
96114 # 5. Report File Check
97115 if not os .path .exists (REPORT_FILE ):
98- log_test ('CI test' , board , ":fire:" , "Report file not found." )
116+ log_test ('CI test' , board , FAILURE , "Report file not found." )
99117 continue # Skip to the next board
100118
101119 # 6. Process Report File
102120 try :
103121 with open (REPORT_FILE , 'r' ) as f :
104122 report_data = json .load (f )
105123 except Exception as e :
106- log_test ('CI test' , board , ":fire:" , f"Error reading report file: { e } " )
124+ log_test ('CI test' , board , FAILURE , f"Error reading report file: { e } " )
107125 continue # Skip to the next board
108126
109127 # Extract data from the report file
@@ -112,7 +130,7 @@ def process_build_reports():
112130
113131 reports = report_data .get ('boards' , [{}])[0 ].get ('sketches' , [])
114132 if not reports :
115- log_test ('CI test' , board , ":fire:" , "Test report is empty, check full log." , job_link )
133+ log_test ('CI test' , board , FAILURE , "Test report is empty, check full log." , job_link )
116134 continue # Skip to the next board
117135
118136 # 7. Sketch Loop: Iterate through individual sketch reports
@@ -126,17 +144,13 @@ def process_build_reports():
126144
127145 # Logic to update counters and DETAILS string
128146 if not compilation_success :
129- test_icon = ":red_circle:"
147+ status = ERROR
130148 elif len (sketch_issues ): # Implies warnings/non-critical issues
131- test_icon = ":yellow_circle:"
149+ status = WARNING
132150 else :
133- test_icon = ":green_circle:"
151+ status = PASS
134152
135- log_test (SKETCH_NAME , board , test_icon , sketch_issues , job_link )
136-
137- if not BOARD_SUMMARY [board ]['icon' ]:
138- # If no errors, set to green
139- BOARD_SUMMARY [board ]['icon' ] = ":white_check_mark:"
153+ log_test (SKETCH_NAME , board , status , sketch_issues , job_link )
140154
141155 artifacts = set (item ['artifact' ] for item in ALL_BOARD_DATA )
142156
@@ -154,25 +168,25 @@ def process_build_reports():
154168 board_name = board ['board' ]
155169 summary = BOARD_SUMMARY [board_name ]
156170 job_link = summary ['job_link' ]
157- board_icon = summary ['icon ' ]
171+ status = summary ['status ' ]
158172 board_link = f"<a href='{ job_link } '>{ board_name } </a>" if job_link else board_name
159173
160- print (f"<td><code>{ board_link } </code></td><td align='center'>{ board_icon } </td>" )
161- if board_icon == ":fire:" :
174+ print (f"<td><code>{ board_link } </code></td><td align='center'>{ BOARD_STATUS [ status ] } </td>" )
175+ if status == FAILURE :
162176 print (f"<td colspan=3>{ TEST_MATRIX ['CI test' ][board_name ]['issues' ][0 ]} </td></tr>" )
163177 else :
164178 print (f"<td align='right'>{ (summary ['tests' ] - summary ['errors' ]) or '-' } </td><td align='right'>{ summary ['warnings' ] or '-' } </td><td align='right'>{ summary ['errors' ] or '-' } </td></tr>" )
165179 print ("</table>\n " )
166180
167181 for artifact in sorted (list (artifacts ), reverse = True ):
168182 artifact_boards = [ item for item in ALL_BOARD_DATA
169- if item ['artifact' ] == artifact and BOARD_SUMMARY [item ['board' ]]['icon ' ] != ":fire:" ]
183+ if item ['artifact' ] == artifact and BOARD_SUMMARY [item ['board' ]]['status ' ] != FAILURE ]
170184
171185 if not artifact_boards :
172186 continue
173187
174188 print ("\n ---\n " )
175- print (f"<a id='# { artifact } '> \n \n ### `{ artifact } ` test results:\n </a> " )
189+ print (f"### `{ artifact } ` test results:" )
176190
177191 # Print the test matrix
178192
@@ -188,29 +202,24 @@ def process_build_reports():
188202 header_row += f"<th>{ header_col } </th>"
189203 header_row + = "</tr>"
190204
191- print ("<table>" )
205+ print ("<table id='#{artifact}' >" )
192206 print (header_row )
193207
194208 artifact_matrix = { sketch : results for sketch , results in TEST_MATRIX .items () if any (board_data ['board' ] in results for board_data in artifact_boards ) }
195209
196210 for sketch_name , board_results in artifact_matrix .items ():
197- sketch_icon = None
211+ sketch_status = SKIP
198212 row_data = ""
199213 for board_data in artifact_boards :
200214 board_name = board_data ['board' ]
201- test_result = board_results .get (board_name , {})
202- icon = test_result ['icon' ] if test_result else ":new_moon:"
203- if icon == ":fire:" or icon == ":red_circle:" :
204- sketch_icon = icon
205- elif icon == ":yellow_circle:" and not sketch_icon :
206- sketch_icon = icon
215+ test_result = board_results .get (board_name )
216+ status = test_result ['status' ] if test_result else SKIP
217+ sketch_status = max (sketch_status , status )
207218 issues = test_result ['issues' ] if test_result else ""
208219 sketch_id = sketch_name .replace ('/' , '_' ).replace (' ' , '_' ).replace ('-' , '_' )
209220 icon_link = f"<a href='#{ sketch_id } _{ board_name } '>{ icon } </a>" if issues else icon
210221 row_data += f"<td align='center'>{ icon_link } </a></td>"
211- if not sketch_icon :
212- sketch_icon = ":green_circle:"
213- print (f"<tr><td>{ sketch_icon } </td><td><code>{ example_name (sketch_name )} </code></td>{ row_data } </tr>" )
222+ print (f"<tr><td>{ TEST_STATUS [sketch_status ]} </td><td><code>{ example_name (sketch_name )} </code></td>{ row_data } </tr>" )
214223 print ("</table>\n " )
215224
216225 print (f"<details><summary><b>Error and warning logs for <code>{ artifact } </code></b></summary>\n " )
@@ -224,7 +233,7 @@ def process_build_reports():
224233 continue
225234
226235 test_result = board_results [board_name ]
227- icon = test_result ['icon' ]
236+ icon = TEST_STATUS [ test_result ['status' ] ]
228237 issues = test_result ['issues' ]
229238 if not issues :
230239 continue
0 commit comments