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" , "platform" : "linux64" },
25
+ {"name" : "build.cross" , "platform" : "linux64" },
26
+ {"name" : "build.cross-riscv64" , "platform" : "linux64" },
27
+ {"name" : "gcc" , "platform" : "linux64" },
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,51 @@ 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 based on platform
111
+ platform_arch = "aarch64" if image ["platform" ] == "linux_aarch64" else "x86_64"
112
+ runner = find_runner (runners , "linux" , platform_arch )
113
+
114
+ entry = {
115
+ "name" : image ["name" ],
116
+ "platform" : image ["platform" ],
117
+ "runner" : runner ,
118
+ }
119
+ matrix_entries .append (entry )
120
+
121
+ return matrix_entries
122
+
123
+
124
+ def generate_python_build_matrix_entries (
93
125
config : dict [str , Any ],
94
126
runners : dict [str , Any ],
95
127
platform_filter : Optional [str ] = None ,
96
128
label_filters : Optional [dict [str , set [str ]]] = None ,
97
129
) -> list [dict [str , str ]]:
130
+ """Generate matrix entries for python builds."""
98
131
matrix_entries = []
99
132
100
133
for platform , platform_config in config .items ():
101
134
if platform_filter and platform != platform_filter :
102
135
continue
103
136
104
137
for target_triple , target_config in platform_config .items ():
105
- add_matrix_entries_for_config (
138
+ add_python_build_entries_for_config (
106
139
matrix_entries ,
107
140
target_triple ,
108
141
target_config ,
109
142
platform ,
110
143
runners ,
111
- label_filters .get ("directives" , set ()),
144
+ label_filters .get ("directives" , set ()) if label_filters else set () ,
112
145
)
113
146
114
147
# Apply label filters if present
@@ -144,14 +177,15 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
144
177
raise RuntimeError (f"No runner found for platform { platform !r} and arch { arch !r} " )
145
178
146
179
147
- def add_matrix_entries_for_config (
180
+ def add_python_build_entries_for_config (
148
181
matrix_entries : list [dict [str , str ]],
149
182
target_triple : str ,
150
183
config : dict [str , Any ],
151
184
platform : str ,
152
185
runners : dict [str , Any ],
153
186
directives : set [str ],
154
187
) -> None :
188
+ """Add python build matrix entries for a specific target configuration."""
155
189
python_versions = config ["python_versions" ]
156
190
build_options = config ["build_options" ]
157
191
arch = config ["arch" ]
@@ -233,6 +267,12 @@ def parse_args() -> argparse.Namespace:
233
267
action = "store_true" ,
234
268
help = "If only free runners should be used." ,
235
269
)
270
+ parser .add_argument (
271
+ "--matrix-type" ,
272
+ choices = ["python-build" , "docker-build" , "all" ],
273
+ default = "all" ,
274
+ help = "Which matrix types to generate (default: all)" ,
275
+ )
236
276
return parser .parse_args ()
237
277
238
278
@@ -254,36 +294,59 @@ def main() -> None:
254
294
if runner_config .get ("free" )
255
295
}
256
296
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 ,
297
+ result = {}
298
+
299
+ # Generate python-build matrix if requested
300
+ python_entries = []
301
+ if args .matrix_type in ["python-build" , "all" ]:
302
+ python_entries = generate_python_build_matrix_entries (
303
+ config ,
304
+ runners ,
305
+ args .platform ,
306
+ labels ,
307
+ )
308
+
309
+ if args .max_shards :
310
+ python_build_matrix = {}
311
+ shards = (len (python_entries ) // CI_MATRIX_SIZE_LIMIT ) + 1
312
+ if shards > args .max_shards :
313
+ print (
314
+ f"error: python-build matrix of size { len (python_entries )} requires { shards } shards, but the maximum is { args .max_shards } ; consider increasing `--max-shards`" ,
315
+ file = sys .stderr ,
316
+ )
317
+ sys .exit (1 )
318
+ for shard in range (args .max_shards ):
319
+ shard_entries = python_entries [
320
+ shard * CI_MATRIX_SIZE_LIMIT : (shard + 1 ) * CI_MATRIX_SIZE_LIMIT
321
+ ]
322
+ python_build_matrix [str (shard )] = {"include" : shard_entries }
323
+ result ["python-build" ] = python_build_matrix
324
+ else :
325
+ if len (python_entries ) > CI_MATRIX_SIZE_LIMIT :
326
+ print (
327
+ 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`" ,
328
+ file = sys .stderr ,
329
+ )
330
+ result ["python-build" ] = {"include" : python_entries }
331
+
332
+ # Generate docker-build matrix if requested
333
+ # Only include docker builds if there are Linux python builds
334
+ if args .matrix_type in ["docker-build" , "all" ]:
335
+ # Check if we have any Linux python builds
336
+ has_linux_builds = any (
337
+ entry .get ("platform" ) == "linux" for entry in python_entries
338
+ )
339
+
340
+ # If no platform filter or explicitly requesting docker-build only, include docker builds
341
+ # Otherwise, only include if there are Linux python builds
342
+ if args .matrix_type == "docker-build" or has_linux_builds :
343
+ docker_entries = generate_docker_matrix_entries (
344
+ runners ,
345
+ args .platform ,
283
346
)
284
- matrix = {"include" : entries }
347
+ result [ "docker-build" ] = {"include" : docker_entries }
285
348
286
- print (json .dumps (matrix ))
349
+ print (json .dumps (result ))
287
350
288
351
289
352
if __name__ == "__main__" :
0 commit comments