Skip to content

Commit 395bc0a

Browse files
committed
don't run all jobs if changed files is empty
1 parent ccd417c commit 395bc0a

File tree

1 file changed

+96
-110
lines changed

1 file changed

+96
-110
lines changed

tools/ci_set_matrix.py

Lines changed: 96 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -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

301291
def 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

312298
if __name__ == "__main__":

0 commit comments

Comments
 (0)