@@ -116,26 +116,24 @@ def set_output(name: str, value):
116116 print (f"Would set GitHub actions output { name } to '{ value } '" )
117117
118118
119- def set_boards (build_all : bool ):
120- # Get boards in json format
121- boards_info_json = build_board_info .get_board_mapping ()
119+ def set_boards (build_all = False ):
122120 all_board_ids = set ()
123- port_to_boards = {}
121+ boards_to_build = all_board_ids if build_all else set ()
122+
124123 board_to_port = {}
125- board_settings = {}
126- for board_id in boards_info_json :
127- info = boards_info_json [board_id ]
128- if info .get ("alias" , False ):
124+ port_to_board = {}
125+ board_setting = {}
126+
127+ for id , info in build_board_info .get_board_mapping ().items ():
128+ if info .get ("alias" ):
129129 continue
130- all_board_ids .add (board_id )
131130 port = info ["port" ]
132- if port not in port_to_boards :
133- port_to_boards [port ] = set ()
134- port_to_boards [port ].add (board_id )
135- board_to_port [board_id ] = port
131+ all_board_ids .add (id )
132+ board_to_port [id ] = port
133+ port_to_board .setdefault (port , set ()).add (id )
136134
137135 def compute_board_settings (boards ):
138- need = set (boards ) - set (board_settings .keys ())
136+ need = set (boards ) - set (board_setting .keys ())
139137 if not need :
140138 return
141139
@@ -146,86 +144,84 @@ def get_settings(board):
146144 )
147145
148146 with ThreadPoolExecutor (max_workers = os .cpu_count ()) as ex :
149- board_settings .update (ex .map (get_settings , need ))
150-
151- boards_to_build = all_board_ids
147+ board_setting .update (ex .map (get_settings , need ))
152148
153149 if not build_all :
154- boards_to_build = set ()
155- board_pattern = re .compile (r"^ports/[^/]+/boards/([^/]+)/" )
156- port_pattern = re .compile (r"^ports/([^/]+)/" )
157- module_pattern = re .compile (
150+ pattern_port = re .compile (r"^ports/([^/]+)/" )
151+ pattern_board = re .compile (r"^ports/[^/]+/boards/([^/]+)/" )
152+ pattern_module = re .compile (
158153 r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/"
159154 )
160- for p in changed_files :
155+
156+ for file in changed_files :
157+ if len (all_board_ids ) == len (boards_to_build ):
158+ break
159+
160+ if any ([file .startswith (path ) for path in IGNORE_BOARD ]):
161+ continue
162+
161163 # See if it is board specific
162- board_matches = board_pattern .search (p )
164+ board_matches = pattern_board .search (file )
163165 if board_matches :
164- board = board_matches .group (1 )
165- boards_to_build .add (board )
166+ boards_to_build .add (board_matches .group (1 ))
166167 continue
167168
168169 # See if it is port specific
169- port_matches = port_pattern .search (p )
170+ port_matches = pattern_port .search (file )
171+ module_matches = pattern_module .search (file )
170172 port = port_matches .group (1 ) if port_matches else None
171- module_matches = module_pattern .search (p )
172173 if port and not module_matches :
173174 if port != "unix" :
174- boards_to_build .update (port_to_boards [port ])
175- continue
176-
177- if any ([p .startswith (d ) for d in IGNORE_BOARD ]):
175+ boards_to_build .update (port_to_board [port ])
178176 continue
179177
180178 # As a (nearly) last resort, for some certain files, we compute the settings from the
181- # makefile for each board and determine whether to build them that way.
182- if p .startswith ("frozen" ) or p .startswith ("supervisor" ) or module_matches :
183- if port :
184- board_ids = port_to_boards [port ]
185- else :
186- board_ids = all_board_ids
187- compute_board_settings (board_ids )
188- for board in board_ids :
189- settings = board_settings [board ]
190-
191- # Check frozen files to see if they are in each board.
192- frozen = settings .get ("FROZEN_MPY_DIRS" , "" )
193- if frozen and p .startswith ("frozen" ) and p in frozen :
194- boards_to_build .add (board )
195- continue
196-
197- # Check supervisor files. This is useful for limiting workflow changes to the
198- # relevant boards.
199- supervisor = settings ["SRC_SUPERVISOR" ]
200- if p .startswith ("supervisor" ):
201- if p in supervisor :
179+ # makefile for each board and determine whether to build them that way
180+ if file .startswith ("frozen" ) or file .startswith ("supervisor" ) or module_matches :
181+ boards = port_to_board [port ] if port else all_board_ids
182+ compute_board_settings (boards )
183+
184+ for board in boards :
185+ settings = board_setting [board ]
186+
187+ # Check frozen files to see if they are in each board
188+ if file .startswith ("frozen" ):
189+ if file in settings .get ("FROZEN_MPY_DIRS" , "" ):
202190 boards_to_build .add (board )
203191 continue
204192
205- web_workflow = settings ["CIRCUITPY_WEB_WORKFLOW" ]
206- while web_workflow .startswith ("$(" ):
207- web_workflow = settings [web_workflow [2 :- 1 ]]
208- if (
209- p .startswith ("supervisor/shared/web_workflow/static/" )
210- and web_workflow != "0"
211- ):
193+ # Check supervisor files
194+ # This is useful for limiting workflow changes to the relevant boards
195+ if file .startswith ("supervisor" ):
196+ if file in settings ["SRC_SUPERVISOR" ]:
212197 boards_to_build .add (board )
213198 continue
214199
200+ if file .startswith ("supervisor/shared/web_workflow/static/" ):
201+ web_workflow = settings ["CIRCUITPY_WEB_WORKFLOW" ]
202+
203+ while web_workflow .startswith ("$(" ):
204+ web_workflow = settings [web_workflow [2 :- 1 ]]
205+
206+ if web_workflow != "0" :
207+ boards_to_build .add (board )
208+ continue
209+
215210 # Check module matches
216211 if module_matches :
217212 module = module_matches .group (2 ) + "/"
218213 if module in settings ["SRC_PATTERNS" ]:
219214 boards_to_build .add (board )
220215 continue
216+
221217 continue
222218
223219 # Otherwise build it all
224220 boards_to_build = all_board_ids
225221 break
226222
227223 # Append previously failed boards
228- boards_to_build .update (last_failed_jobs .get ("ports" ) or [] )
224+ boards_to_build .update (last_failed_jobs .get ("ports" , []) )
229225
230226 print ("Building boards:" , bool (boards_to_build ))
231227
@@ -249,64 +245,54 @@ def get_settings(board):
249245 set_output ("ports" , json .dumps (port_to_boards_to_build ))
250246
251247
252- def set_docs (build_doc : bool ):
253- if not build_doc :
254- if last_failed_jobs .get ("docs" ):
255- build_doc = True
256- else :
257- doc_pattern = re .compile (PATTERN_DOCS )
258- github_workspace = os .environ .get ("GITHUB_WORKSPACE" ) or ""
259- github_workspace = github_workspace and github_workspace + "/"
260- for file in changed_files :
261- if doc_pattern .search (file ) and (
262- (
263- subprocess .run (
264- f"git diff -U0 $BASE_SHA...$HEAD_SHA { github_workspace + file } | grep -o -m 1 '^[+-]\/\/|'" ,
265- capture_output = True ,
266- shell = True ,
267- ).stdout
268- )
269- if file .endswith (".c" )
270- else True
271- ):
272- build_doc = True
273- break
248+ def set_docs (run = bool (last_failed_jobs .get ("docs" ))):
249+ if not run :
250+ pattern_doc = re .compile (PATTERN_DOCS )
251+ github_workspace = os .environ .get ("GITHUB_WORKSPACE" ) or ""
252+ github_workspace = github_workspace and github_workspace + "/"
253+ for file in changed_files :
254+ if pattern_doc .search (file ) and (
255+ (
256+ subprocess .run (
257+ f"git diff -U0 $BASE_SHA...$HEAD_SHA { github_workspace + file } | grep -o -m 1 '^[+-]\/\/|'" ,
258+ capture_output = True ,
259+ shell = True ,
260+ ).stdout
261+ )
262+ if file .endswith (".c" )
263+ else True
264+ ):
265+ run = True
266+ break
274267
275268 # Set the step outputs
276- print ("Building docs:" , build_doc )
277- set_output ("docs" , build_doc )
278-
279-
280- def set_windows (build_windows : bool ):
281- if not build_windows :
282- if last_failed_jobs .get ("windows" ):
283- build_windows = True
284- else :
285- for file in changed_files :
286- for pattern in PATTERN_WINDOWS :
287- if file .startswith (pattern ) and not any (
288- [file .startswith (d ) for d in IGNORE_BOARD ]
289- ):
290- build_windows = True
291- break
292- else :
293- continue
294- break
269+ print ("Building docs:" , run )
270+ set_output ("docs" , run )
271+
272+
273+ def set_windows (run = bool (last_failed_jobs .get ("windows" ))):
274+ if not run :
275+ for file in changed_files :
276+ for pattern in PATTERN_WINDOWS :
277+ if file .startswith (pattern ) and not any (
278+ [file .startswith (path ) for path in IGNORE_BOARD ]
279+ ):
280+ run = True
281+ break
282+ else :
283+ continue
284+ break
295285
296286 # Set the step outputs
297- print ("Building windows:" , build_windows )
298- set_output ("windows" , build_windows )
287+ print ("Building windows:" , run )
288+ set_output ("windows" , run )
299289
300290
301291def main ():
302- # Build all if no changed files
303- build_all = not changed_files
304- print ("Running: " + ("all" if build_all else "conditionally" ))
305-
306292 # Set jobs
307- set_docs (build_all )
308- set_windows (build_all )
309- set_boards (build_all )
293+ set_docs ()
294+ set_windows ()
295+ set_boards ()
310296
311297
312298if __name__ == "__main__" :
0 commit comments