2
2
import argparse
3
3
import itertools
4
4
import json
5
- import re
5
+ from pathlib import Path
6
+ from dataclasses import dataclass
7
+
8
+ THIS_DIR = Path (__file__ ).parent .resolve ()
9
+
10
+ @dataclass
11
+ class Config :
12
+ architecture : list [dict ]
13
+ os : list [dict ]
14
+ build_type : list [str ]
15
+ cmake_args : list [str ]
6
16
7
17
'''
8
18
Generate a strategy matrix for GitHub Actions CI.
18
28
- Certain Debian Bookworm configurations will change the reference fee, enable
19
29
codecov, and enable voidstar in PRs.
20
30
'''
21
- def generate_strategy_matrix (all : bool , architecture : list [ dict ], os : list [ dict ], build_type : list [ str ], cmake_args : list [ str ] ) -> dict :
31
+ def generate_strategy_matrix (all : bool , config : Config ) -> list :
22
32
configurations = []
23
- for architecture , os , build_type , cmake_args in itertools .product (architecture , os , build_type , cmake_args ):
33
+ for architecture , os , build_type , cmake_args in itertools .product (config . architecture , config . os , config . build_type , config . cmake_args ):
24
34
# The default CMake target is 'all' for Linux and MacOS and 'install'
25
35
# for Windows, but it can get overridden for certain configurations.
26
36
cmake_target = 'install' if os ["distro_name" ] == 'windows' else 'all'
@@ -35,7 +45,7 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict]
35
45
# Only generate a subset of configurations in PRs.
36
46
if not all :
37
47
# Debian:
38
- # - Bookworm using GCC 13: Release and Unity on linux/arm64 , set
48
+ # - Bookworm using GCC 13: Release and Unity on linux/amd64 , set
39
49
# the reference fee to 500.
40
50
# - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable
41
51
# code coverage (which will be done below).
@@ -47,7 +57,7 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict]
47
57
if os ['distro_name' ] == 'debian' :
48
58
skip = True
49
59
if os ['distro_version' ] == 'bookworm' :
50
- if f'{ os ['compiler_name' ]} -{ os ['compiler_version' ]} ' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture ['platform' ] == 'linux/arm64 ' :
60
+ if f'{ os ['compiler_name' ]} -{ os ['compiler_version' ]} ' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture ['platform' ] == 'linux/amd64 ' :
51
61
cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=500 { cmake_args } '
52
62
skip = False
53
63
if f'{ os ['compiler_name' ]} -{ os ['compiler_version' ]} ' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture ['platform' ] == 'linux/amd64' :
@@ -158,21 +168,30 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict]
158
168
'architecture' : architecture ,
159
169
})
160
170
161
- return {'include' : configurations }
171
+ return configurations
172
+
173
+
174
+ def read_config (file : Path ) -> Config :
175
+ config = json .loads (file .read_text ())
176
+ if config ['architecture' ] is None or config ['os' ] is None or config ['build_type' ] is None or config ['cmake_args' ] is None :
177
+ raise Exception ('Invalid configuration file.' )
178
+
179
+ return Config (** config )
162
180
163
181
164
182
if __name__ == '__main__' :
165
183
parser = argparse .ArgumentParser ()
166
184
parser .add_argument ('-a' , '--all' , help = 'Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).' , action = "store_true" )
167
- parser .add_argument ('-c' , '--config' , help = 'Path to the JSON file containing the strategy matrix configurations.' , required = True , type = str )
185
+ parser .add_argument ('-c' , '--config' , help = 'Path to the JSON file containing the strategy matrix configurations.' , required = False , type = Path )
168
186
args = parser .parse_args ()
169
187
170
- # Load the JSON configuration file.
171
- config = None
172
- with open (args .config , 'r' ) as f :
173
- config = json .load (f )
174
- if config ['architecture' ] is None or config ['os' ] is None or config ['build_type' ] is None or config ['cmake_args' ] is None :
175
- raise Exception ('Invalid configuration file.' )
188
+ matrix = []
189
+ if args .config is None or args .config == '' :
190
+ matrix += generate_strategy_matrix (args .all , read_config (THIS_DIR / "linux.json" ))
191
+ matrix += generate_strategy_matrix (args .all , read_config (THIS_DIR / "macos.json" ))
192
+ matrix += generate_strategy_matrix (args .all , read_config (THIS_DIR / "windows.json" ))
193
+ else :
194
+ matrix += generate_strategy_matrix (args .all , read_config (args .config ))
176
195
177
196
# Generate the strategy matrix.
178
- print (f'matrix={ json .dumps (generate_strategy_matrix ( args . all , config [ 'architecture' ], config [ 'os' ], config [ 'build_type' ], config [ 'cmake_args' ]) )} ' )
197
+ print (f'matrix={ json .dumps ({ "include" : matrix } )} ' )
0 commit comments