1919CI_EXTRA_SKIP_LABELS = ["documentation" ]
2020CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions
2121
22+ # Docker images for building toolchains and dependencies
23+ DOCKER_BUILD_IMAGES = [
24+ {"name" : "build" , "arch" : "x86_64" },
25+ {"name" : "build.cross" , "arch" : "x86_64" },
26+ {"name" : "build.cross-riscv64" , "arch" : "x86_64" },
27+ {"name" : "gcc" , "arch" : "x86_64" },
28+ ]
29+
2230
2331def meets_conditional_version (version : str , min_version : str ) -> bool :
2432 return Version (version ) >= Version (min_version )
@@ -89,26 +97,50 @@ def should_include_entry(entry: dict[str, str], filters: dict[str, set[str]]) ->
8997 return True
9098
9199
92- def generate_matrix_entries (
100+ def generate_docker_matrix_entries (
101+ runners : dict [str , Any ],
102+ platform_filter : Optional [str ] = None ,
103+ ) -> list [dict [str , str ]]:
104+ """Generate matrix entries for docker image builds."""
105+ if platform_filter and platform_filter != "linux" :
106+ return []
107+
108+ matrix_entries = []
109+ for image in DOCKER_BUILD_IMAGES :
110+ # Find appropriate runner for Linux platform with the specified architecture
111+ runner = find_runner (runners , "linux" , image ["arch" ])
112+
113+ entry = {
114+ "name" : image ["name" ],
115+ "arch" : image ["arch" ],
116+ "runner" : runner ,
117+ }
118+ matrix_entries .append (entry )
119+
120+ return matrix_entries
121+
122+
123+ def generate_python_build_matrix_entries (
93124 config : dict [str , Any ],
94125 runners : dict [str , Any ],
95126 platform_filter : Optional [str ] = None ,
96127 label_filters : Optional [dict [str , set [str ]]] = None ,
97128) -> list [dict [str , str ]]:
129+ """Generate matrix entries for python builds."""
98130 matrix_entries = []
99131
100132 for platform , platform_config in config .items ():
101133 if platform_filter and platform != platform_filter :
102134 continue
103135
104136 for target_triple , target_config in platform_config .items ():
105- add_matrix_entries_for_config (
137+ add_python_build_entries_for_config (
106138 matrix_entries ,
107139 target_triple ,
108140 target_config ,
109141 platform ,
110142 runners ,
111- label_filters .get ("directives" , set ()),
143+ label_filters .get ("directives" , set ()) if label_filters else set () ,
112144 )
113145
114146 # Apply label filters if present
@@ -144,14 +176,15 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
144176 raise RuntimeError (f"No runner found for platform { platform !r} and arch { arch !r} " )
145177
146178
147- def add_matrix_entries_for_config (
179+ def add_python_build_entries_for_config (
148180 matrix_entries : list [dict [str , str ]],
149181 target_triple : str ,
150182 config : dict [str , Any ],
151183 platform : str ,
152184 runners : dict [str , Any ],
153185 directives : set [str ],
154186) -> None :
187+ """Add python build matrix entries for a specific target configuration."""
155188 python_versions = config ["python_versions" ]
156189 build_options = config ["build_options" ]
157190 arch = config ["arch" ]
@@ -233,6 +266,12 @@ def parse_args() -> argparse.Namespace:
233266 action = "store_true" ,
234267 help = "If only free runners should be used." ,
235268 )
269+ parser .add_argument (
270+ "--matrix-type" ,
271+ choices = ["python-build" , "docker-build" , "all" ],
272+ default = "all" ,
273+ help = "Which matrix types to generate (default: all)" ,
274+ )
236275 return parser .parse_args ()
237276
238277
@@ -254,36 +293,59 @@ def main() -> None:
254293 if runner_config .get ("free" )
255294 }
256295
257- entries = generate_matrix_entries (
258- config ,
259- runners ,
260- args .platform ,
261- labels ,
262- )
263-
264- if args .max_shards :
265- matrix = {}
266- shards = (len (entries ) // CI_MATRIX_SIZE_LIMIT ) + 1
267- if shards > args .max_shards :
268- print (
269- f"error: matrix of size { len (entries )} requires { shards } shards, but the maximum is { args .max_shards } ; consider increasing `--max-shards`" ,
270- file = sys .stderr ,
271- )
272- sys .exit (1 )
273- for shard in range (args .max_shards ):
274- shard_entries = entries [
275- shard * CI_MATRIX_SIZE_LIMIT : (shard + 1 ) * CI_MATRIX_SIZE_LIMIT
276- ]
277- matrix [str (shard )] = {"include" : shard_entries }
278- else :
279- if len (entries ) > CI_MATRIX_SIZE_LIMIT :
280- print (
281- f"warning: matrix of size { len (entries )} exceeds limit of { CI_MATRIX_SIZE_LIMIT } but sharding is not enabled; consider setting `--max-shards`" ,
282- file = sys .stderr ,
296+ result = {}
297+
298+ # Generate python-build matrix if requested
299+ python_entries = []
300+ if args .matrix_type in ["python-build" , "all" ]:
301+ python_entries = generate_python_build_matrix_entries (
302+ config ,
303+ runners ,
304+ args .platform ,
305+ labels ,
306+ )
307+
308+ if args .max_shards :
309+ python_build_matrix = {}
310+ shards = (len (python_entries ) // CI_MATRIX_SIZE_LIMIT ) + 1
311+ if shards > args .max_shards :
312+ print (
313+ f"error: python-build matrix of size { len (python_entries )} requires { shards } shards, but the maximum is { args .max_shards } ; consider increasing `--max-shards`" ,
314+ file = sys .stderr ,
315+ )
316+ sys .exit (1 )
317+ for shard in range (args .max_shards ):
318+ shard_entries = python_entries [
319+ shard * CI_MATRIX_SIZE_LIMIT : (shard + 1 ) * CI_MATRIX_SIZE_LIMIT
320+ ]
321+ python_build_matrix [str (shard )] = {"include" : shard_entries }
322+ result ["python-build" ] = python_build_matrix
323+ else :
324+ if len (python_entries ) > CI_MATRIX_SIZE_LIMIT :
325+ print (
326+ f"warning: python-build matrix of size { len (python_entries )} exceeds limit of { CI_MATRIX_SIZE_LIMIT } but sharding is not enabled; consider setting `--max-shards`" ,
327+ file = sys .stderr ,
328+ )
329+ result ["python-build" ] = {"include" : python_entries }
330+
331+ # Generate docker-build matrix if requested
332+ # Only include docker builds if there are Linux python builds
333+ if args .matrix_type in ["docker-build" , "all" ]:
334+ # Check if we have any Linux python builds
335+ has_linux_builds = any (
336+ entry .get ("platform" ) == "linux" for entry in python_entries
337+ )
338+
339+ # If no platform filter or explicitly requesting docker-build only, include docker builds
340+ # Otherwise, only include if there are Linux python builds
341+ if args .matrix_type == "docker-build" or has_linux_builds :
342+ docker_entries = generate_docker_matrix_entries (
343+ runners ,
344+ args .platform ,
283345 )
284- matrix = {"include" : entries }
346+ result [ "docker-build" ] = {"include" : docker_entries }
285347
286- print (json .dumps (matrix ))
348+ print (json .dumps (result ))
287349
288350
289351if __name__ == "__main__" :
0 commit comments