77
88import json
99import os
10+ import re
1011import subprocess as sp
1112import sys
1213from dataclasses import dataclass
6869 "libm/src/math/arch/intrinsics.rs" ,
6970]
7071
72+ # libm PR CI takes a long time and doesn't need to run unless relevant files have been
73+ # changed. Anything matching this regex pattern will trigger a run.
74+ TRIGGER_LIBM_PR_CI = ".*(libm|musl).*"
75+
7176TYPES = ["f16" , "f32" , "f64" , "f128" ]
7277
7378
@@ -116,7 +121,6 @@ class FunctionDef(TypedDict):
116121 type : str
117122
118123
119- @dataclass
120124class Context :
121125 gh_ref : str | None
122126 changed : list [Path ]
@@ -142,7 +146,7 @@ def _init_change_list(self):
142146 # the PR number), and sets this as `GITHUB_REF`.
143147 ref = self .gh_ref
144148 eprint (f"using ref `{ ref } `" )
145- if ref is None or "merge" not in ref :
149+ if not self . is_pr () :
146150 # If the ref is not for `merge` then we are not in PR CI
147151 eprint ("No diff available for ref" )
148152 return
@@ -170,6 +174,10 @@ def _init_change_list(self):
170174 )
171175 self .changed = [Path (p ) for p in textlist .splitlines ()]
172176
177+ def is_pr (self ) -> bool :
178+ """Check if we are looking at a PR rather than a push."""
179+ return self .gh_ref is not None and "merge" in self .gh_ref
180+
173181 @staticmethod
174182 def _ignore_file (fname : str ) -> bool :
175183 return any (fname .startswith (pfx ) for pfx in IGNORE_FILES )
@@ -196,7 +204,16 @@ def changed_routines(self) -> dict[str, list[str]]:
196204
197205 return ret
198206
199- def make_workflow_output (self ) -> str :
207+ def may_skip_libm_ci (self ) -> bool :
208+ """If this is a PR and no libm files were changed, allow skipping libm
209+ jobs."""
210+
211+ if self .is_pr ():
212+ return all (not re .match (TRIGGER_LIBM_PR_CI , str (f )) for f in self .changed )
213+
214+ return False
215+
216+ def emit_workflow_output (self ):
200217 """Create a JSON object a list items for each type's changed files, if any
201218 did change, and the routines that were affected by the change.
202219 """
@@ -216,9 +233,10 @@ def make_workflow_output(self) -> str:
216233 eprint ("Skipping all extensive tests" )
217234
218235 changed = self .changed_routines ()
219- ret = []
236+ matrix = []
220237 total_to_test = 0
221238
239+ # Figure out which extensive tests need to run
222240 for ty in TYPES :
223241 ty_changed = changed .get (ty , [])
224242 ty_to_test = [] if skip_tests else ty_changed
@@ -230,9 +248,14 @@ def make_workflow_output(self) -> str:
230248 "to_test" : "," .join (ty_to_test ),
231249 }
232250
233- ret .append (item )
234- output = json .dumps ({"matrix" : ret }, separators = ("," , ":" ))
235- eprint (f"output: { output } " )
251+ matrix .append (item )
252+
253+ ext_matrix = json .dumps ({"extensive_matrix" : matrix }, separators = ("," , ":" ))
254+ may_skip = str (self .may_skip_libm_ci ()).lower ()
255+ print (f"extensive_matrix={ ext_matrix } " )
256+ print (f"may_skip_libm_ci={ may_skip } " )
257+ eprint (f"extensive_matrix={ ext_matrix } " )
258+ eprint (f"may_skip_libm_ci={ may_skip } " )
236259 eprint (f"total extensive tests: { total_to_test } " )
237260
238261 if error_on_many_tests and total_to_test > MANY_EXTENSIVE_THRESHOLD :
@@ -242,8 +265,6 @@ def make_workflow_output(self) -> str:
242265 )
243266 exit (1 )
244267
245- return output
246-
247268
248269def locate_baseline (flags : list [str ]) -> None :
249270 """Find the most recent baseline from CI, download it if specified.
@@ -398,8 +419,7 @@ def main():
398419 match sys .argv [1 :]:
399420 case ["generate-matrix" ]:
400421 ctx = Context ()
401- output = ctx .make_workflow_output ()
402- print (f"matrix={ output } " )
422+ ctx .emit_workflow_output ()
403423 case ["locate-baseline" , * flags ]:
404424 locate_baseline (flags )
405425 case ["check-regressions" , * args ]:
0 commit comments