19
19
CI_EXTRA_SKIP_LABELS = ["documentation" ]
20
20
CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions
21
21
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
+
22
30
23
31
def meets_conditional_version (version : str , min_version : str ) -> bool :
24
32
return Version (version ) >= Version (min_version )
@@ -89,26 +97,50 @@ def should_include_entry(entry: dict[str, str], filters: dict[str, set[str]]) ->
89
97
return True
90
98
91
99
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 (
93
124
config : dict [str , Any ],
94
125
runners : dict [str , Any ],
95
126
platform_filter : Optional [str ] = None ,
96
127
label_filters : Optional [dict [str , set [str ]]] = None ,
97
128
) -> list [dict [str , str ]]:
129
+ """Generate matrix entries for python builds."""
98
130
matrix_entries = []
99
131
100
132
for platform , platform_config in config .items ():
101
133
if platform_filter and platform != platform_filter :
102
134
continue
103
135
104
136
for target_triple , target_config in platform_config .items ():
105
- add_matrix_entries_for_config (
137
+ add_python_build_entries_for_config (
106
138
matrix_entries ,
107
139
target_triple ,
108
140
target_config ,
109
141
platform ,
110
142
runners ,
111
- label_filters .get ("directives" , set ()),
143
+ label_filters .get ("directives" , set ()) if label_filters else set () ,
112
144
)
113
145
114
146
# Apply label filters if present
@@ -144,14 +176,15 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
144
176
raise RuntimeError (f"No runner found for platform { platform !r} and arch { arch !r} " )
145
177
146
178
147
- def add_matrix_entries_for_config (
179
+ def add_python_build_entries_for_config (
148
180
matrix_entries : list [dict [str , str ]],
149
181
target_triple : str ,
150
182
config : dict [str , Any ],
151
183
platform : str ,
152
184
runners : dict [str , Any ],
153
185
directives : set [str ],
154
186
) -> None :
187
+ """Add python build matrix entries for a specific target configuration."""
155
188
python_versions = config ["python_versions" ]
156
189
build_options = config ["build_options" ]
157
190
arch = config ["arch" ]
@@ -233,6 +266,12 @@ def parse_args() -> argparse.Namespace:
233
266
action = "store_true" ,
234
267
help = "If only free runners should be used." ,
235
268
)
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
+ )
236
275
return parser .parse_args ()
237
276
238
277
@@ -254,36 +293,59 @@ def main() -> None:
254
293
if runner_config .get ("free" )
255
294
}
256
295
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 ,
283
345
)
284
- matrix = {"include" : entries }
346
+ result [ "docker-build" ] = {"include" : docker_entries }
285
347
286
- print (json .dumps (matrix ))
348
+ print (json .dumps (result ))
287
349
288
350
289
351
if __name__ == "__main__" :
0 commit comments