add hil_ci_set_matrix.py, starting to support hil with additional build flags
This commit is contained in:
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build-system: 'cmake'
|
build-system: 'cmake'
|
||||||
toolchain: ${{ matrix.toolchain }}
|
toolchain: ${{ matrix.toolchain }}
|
||||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||||
one-per-family: ${{ github.event_name == 'push' }}
|
one-per-family: ${{ github.event_name == 'push' }}
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
@@ -89,7 +89,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build-system: 'make'
|
build-system: 'make'
|
||||||
toolchain: ${{ matrix.toolchain }}
|
toolchain: ${{ matrix.toolchain }}
|
||||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||||
one-per-family: true
|
one-per-family: true
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
needs: set-matrix
|
needs: set-matrix
|
||||||
runs-on: [self-hosted, Linux, X64, hifiphile]
|
runs-on: [self-hosted, Linux, X64, hifiphile]
|
||||||
env:
|
env:
|
||||||
BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'].family, ' ') }}
|
BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'], ' ') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workspace
|
- name: Clean workspace
|
||||||
run: |
|
run: |
|
||||||
|
2
.github/workflows/ci_set_matrix.py
vendored
2
.github/workflows/ci_set_matrix.py
vendored
@@ -62,7 +62,7 @@ def set_matrix_json():
|
|||||||
hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']]
|
hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']]
|
||||||
filtered_families = filtered_families + hfp_boards
|
filtered_families = filtered_families + hfp_boards
|
||||||
|
|
||||||
matrix[toolchain] = {"family": filtered_families}
|
matrix[toolchain] = filtered_families
|
||||||
|
|
||||||
print(json.dumps(matrix))
|
print(json.dumps(matrix))
|
||||||
|
|
||||||
|
7
.github/workflows/hil_test.yml
vendored
7
.github/workflows/hil_test.yml
vendored
@@ -32,10 +32,7 @@ jobs:
|
|||||||
- name: Generate matrix json
|
- name: Generate matrix json
|
||||||
id: set-matrix-json
|
id: set-matrix-json
|
||||||
run: |
|
run: |
|
||||||
MATRIX_ARMGCC=$(jq -c '{ "arm-gcc": { "family": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py)
|
||||||
MATRIX_ESP=$(jq -c '{ "esp-idf": { "family": [.boards[] | select(.flasher == "esptool") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
|
||||||
MATRIX_RISCV=$(jq -c '{ "riscv-gcc": { "family": [.boards[] | select(.flasher == "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}")
|
|
||||||
MATRIX_JSON=$(jq -nc --argjson arm "$MATRIX_ARMGCC" --argjson esp "$MATRIX_ESP" --argjson riscv "$MATRIX_RISCV" '$arm + $esp + $riscv')
|
|
||||||
echo "matrix=$MATRIX_JSON"
|
echo "matrix=$MATRIX_JSON"
|
||||||
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
@@ -55,7 +52,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build-system: 'cmake'
|
build-system: 'cmake'
|
||||||
toolchain: ${{ matrix.toolchain }}
|
toolchain: ${{ matrix.toolchain }}
|
||||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
||||||
one-per-family: true
|
one-per-family: true
|
||||||
upload-artifacts: true
|
upload-artifacts: true
|
||||||
|
|
||||||
|
42
test/hil/hil_ci_set_matrix.py
Normal file
42
test/hil/hil_ci_set_matrix.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('config_file', help='Configuration JSON file')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
config_file = args.config_file
|
||||||
|
|
||||||
|
# if config file is not found, try to find it in the same directory as this script
|
||||||
|
if not os.path.exists(config_file):
|
||||||
|
config_file = os.path.join(os.path.dirname(__file__), config_file)
|
||||||
|
with open(config_file) as f:
|
||||||
|
config = json.load(f)
|
||||||
|
|
||||||
|
matrix = {
|
||||||
|
'arm-gcc': [],
|
||||||
|
'esp-idf': []
|
||||||
|
}
|
||||||
|
for board in config['boards']:
|
||||||
|
name = board['name']
|
||||||
|
if board['flasher'] == 'esptool':
|
||||||
|
toolchain = 'esp-idf'
|
||||||
|
else:
|
||||||
|
toolchain = 'arm-gcc'
|
||||||
|
|
||||||
|
if 'build_flags_on' in board:
|
||||||
|
for f in board['build_flags_on']:
|
||||||
|
if f == '':
|
||||||
|
matrix[toolchain].append(f'-b {name}')
|
||||||
|
else:
|
||||||
|
matrix[toolchain].append(f'-b {name}-{f.replace(" ", "_")}')
|
||||||
|
else:
|
||||||
|
matrix[toolchain].append(f'-b {name}')
|
||||||
|
|
||||||
|
print(json.dumps(matrix))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@@ -424,37 +424,45 @@ def test_board(board):
|
|||||||
test_list.append('device/board_test')
|
test_list.append('device/board_test')
|
||||||
|
|
||||||
err_count = 0
|
err_count = 0
|
||||||
for test in test_list:
|
flags_opt_list = [""]
|
||||||
fw_dir = f'cmake-build/cmake-build-{name}/{test}'
|
if 'build_flags_on' in board:
|
||||||
if not os.path.exists(fw_dir):
|
flags_opt_list = board['build_flags_on']
|
||||||
fw_dir = f'examples/cmake-build-{name}/{test}'
|
|
||||||
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
|
||||||
print(f'{name:25} {test:30} ... ', end='')
|
|
||||||
|
|
||||||
if not os.path.exists(fw_dir):
|
for flags_opt in flags_opt_list:
|
||||||
print('Skip (no binary)')
|
flags_opt_str = ""
|
||||||
continue
|
if flags_opt != "":
|
||||||
|
flags_opt_str = '-' + flags_opt.replace(' ', '-')
|
||||||
|
for test in test_list:
|
||||||
|
fw_dir = f'cmake-build/cmake-build-{name}{flags_opt_str}/{test}'
|
||||||
|
if not os.path.exists(fw_dir):
|
||||||
|
fw_dir = f'examples/cmake-build-{name}{flags_opt_str}/{test}'
|
||||||
|
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
||||||
|
print(f'{name+flags_opt_str:40} {test:30} ... ', end='')
|
||||||
|
|
||||||
|
if not os.path.exists(fw_dir):
|
||||||
|
print('Skip (no binary)')
|
||||||
|
continue
|
||||||
|
|
||||||
|
# flash firmware. It may fail randomly, retry a few times
|
||||||
|
for i in range(3):
|
||||||
|
ret = globals()[f'flash_{flasher}'](board, fw_name)
|
||||||
|
if ret.returncode == 0:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f'Flashing failed, retry {i+1}')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
# flash firmware. It may fail randomly, retry a few times
|
|
||||||
for i in range(3):
|
|
||||||
ret = globals()[f'flash_{flasher}'](board, fw_name)
|
|
||||||
if ret.returncode == 0:
|
if ret.returncode == 0:
|
||||||
break
|
try:
|
||||||
|
ret = globals()[f'test_{test.replace("/", "_")}'](board)
|
||||||
|
print('OK')
|
||||||
|
except Exception as e:
|
||||||
|
err_count += 1
|
||||||
|
print(STATUS_FAILED)
|
||||||
|
print(f' {e}')
|
||||||
else:
|
else:
|
||||||
print(f'Flashing failed, retry {i+1}')
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
if ret.returncode == 0:
|
|
||||||
try:
|
|
||||||
ret = globals()[f'test_{test.replace("/", "_")}'](board)
|
|
||||||
print('OK')
|
|
||||||
except Exception as e:
|
|
||||||
err_count += 1
|
err_count += 1
|
||||||
print(STATUS_FAILED)
|
print(f'Flash {STATUS_FAILED}')
|
||||||
print(f' {e}')
|
|
||||||
else:
|
|
||||||
err_count += 1
|
|
||||||
print(f'Flash {STATUS_FAILED}')
|
|
||||||
return err_count
|
return err_count
|
||||||
|
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@ build_format = '| {:30} | {:40} | {:16} | {:5} |'
|
|||||||
build_separator = '-' * 95
|
build_separator = '-' * 95
|
||||||
build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED]
|
build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED]
|
||||||
|
|
||||||
|
verbose = False
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Helper
|
# Helper
|
||||||
@@ -38,6 +39,9 @@ def run_cmd(cmd):
|
|||||||
else:
|
else:
|
||||||
print(title)
|
print(title)
|
||||||
print(r.stdout.decode("utf-8"))
|
print(r.stdout.decode("utf-8"))
|
||||||
|
elif verbose:
|
||||||
|
print(cmd)
|
||||||
|
print(r.stdout.decode("utf-8"))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
@@ -75,10 +79,17 @@ def print_build_result(board, example, status, duration):
|
|||||||
# -----------------------------
|
# -----------------------------
|
||||||
# CMake
|
# CMake
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
def cmake_board(board, toolchain):
|
def cmake_board(board, toolchain, build_flags_on):
|
||||||
ret = [0, 0, 0]
|
ret = [0, 0, 0]
|
||||||
start_time = time.monotonic()
|
start_time = time.monotonic()
|
||||||
build_dir = f"cmake-build/cmake-build-{board}"
|
|
||||||
|
build_dir = f'cmake-build/cmake-build-{board}'
|
||||||
|
build_flags = ''
|
||||||
|
if len(build_flags_on) > 0:
|
||||||
|
build_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on)
|
||||||
|
build_flags = f'-DCFLAGS_CLI="{build_flags}"'
|
||||||
|
build_dir += '-' + '-'.join(build_flags_on)
|
||||||
|
|
||||||
family = find_family(board)
|
family = find_family(board)
|
||||||
if family == 'espressif':
|
if family == 'espressif':
|
||||||
# for espressif, we have to build example individually
|
# for espressif, we have to build example individually
|
||||||
@@ -87,12 +98,14 @@ def cmake_board(board, toolchain):
|
|||||||
if build_utils.skip_example(example, board):
|
if build_utils.skip_example(example, board):
|
||||||
ret[2] += 1
|
ret[2] += 1
|
||||||
else:
|
else:
|
||||||
rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board}')
|
rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" '
|
||||||
|
f'-DBOARD={board} {build_flags}')
|
||||||
if rcmd.returncode == 0:
|
if rcmd.returncode == 0:
|
||||||
rcmd = run_cmd(f'cmake --build {build_dir}/{example}')
|
rcmd = run_cmd(f'cmake --build {build_dir}/{example}')
|
||||||
ret[0 if rcmd.returncode == 0 else 1] += 1
|
ret[0 if rcmd.returncode == 0 else 1] += 1
|
||||||
else:
|
else:
|
||||||
rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}')
|
rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel '
|
||||||
|
f'-DTOOLCHAIN={toolchain} {build_flags}')
|
||||||
if rcmd.returncode == 0:
|
if rcmd.returncode == 0:
|
||||||
rcmd = run_cmd(f"cmake --build {build_dir}")
|
rcmd = run_cmd(f"cmake --build {build_dir}")
|
||||||
ret[0 if rcmd.returncode == 0 else 1] += 1
|
ret[0 if rcmd.returncode == 0 else 1] += 1
|
||||||
@@ -144,12 +157,12 @@ def make_board(board, toolchain):
|
|||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Build Family
|
# Build Family
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
def build_boards_list(boards, toolchain, build_system):
|
def build_boards_list(boards, toolchain, build_system, build_flags_on):
|
||||||
ret = [0, 0, 0]
|
ret = [0, 0, 0]
|
||||||
for b in boards:
|
for b in boards:
|
||||||
r = [0, 0, 0]
|
r = [0, 0, 0]
|
||||||
if build_system == 'cmake':
|
if build_system == 'cmake':
|
||||||
r = cmake_board(b, toolchain)
|
r = cmake_board(b, toolchain, build_flags_on)
|
||||||
elif build_system == 'make':
|
elif build_system == 'make':
|
||||||
r = make_board(b, toolchain)
|
r = make_board(b, toolchain)
|
||||||
ret[0] += r[0]
|
ret[0] += r[0]
|
||||||
@@ -158,7 +171,7 @@ def build_boards_list(boards, toolchain, build_system):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def build_family(family, toolchain, build_system, one_per_family, boards):
|
def build_family(family, toolchain, build_system, build_flags_on, one_per_family, boards):
|
||||||
all_boards = []
|
all_boards = []
|
||||||
for entry in os.scandir(f"hw/bsp/{family}/boards"):
|
for entry in os.scandir(f"hw/bsp/{family}/boards"):
|
||||||
if entry.is_dir() and entry.name != 'pico_sdk':
|
if entry.is_dir() and entry.name != 'pico_sdk':
|
||||||
@@ -174,7 +187,7 @@ def build_family(family, toolchain, build_system, one_per_family, boards):
|
|||||||
return ret
|
return ret
|
||||||
all_boards = [random.choice(all_boards)]
|
all_boards = [random.choice(all_boards)]
|
||||||
|
|
||||||
ret = build_boards_list(all_boards, toolchain, build_system)
|
ret = build_boards_list(all_boards, toolchain, build_system, build_flags_on)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@@ -182,19 +195,25 @@ def build_family(family, toolchain, build_system, one_per_family, boards):
|
|||||||
# Main
|
# Main
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
def main():
|
def main():
|
||||||
|
global verbose
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('families', nargs='*', default=[], help='Families to build')
|
parser.add_argument('families', nargs='*', default=[], help='Families to build')
|
||||||
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build')
|
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build')
|
||||||
parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc')
|
parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc')
|
||||||
parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake')
|
parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake')
|
||||||
|
parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system')
|
||||||
parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family')
|
parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family')
|
||||||
|
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
families = args.families
|
families = args.families
|
||||||
boards = args.board
|
boards = args.board
|
||||||
toolchain = args.toolchain
|
toolchain = args.toolchain
|
||||||
build_system = args.build_system
|
build_system = args.build_system
|
||||||
|
build_flags_on = args.build_flags_on
|
||||||
one_per_family = args.one_per_family
|
one_per_family = args.one_per_family
|
||||||
|
verbose = args.verbose
|
||||||
|
|
||||||
if len(families) == 0 and len(boards) == 0:
|
if len(families) == 0 and len(boards) == 0:
|
||||||
print("Please specify families or board to build")
|
print("Please specify families or board to build")
|
||||||
@@ -217,13 +236,13 @@ def main():
|
|||||||
|
|
||||||
# succeeded, failed, skipped
|
# succeeded, failed, skipped
|
||||||
for f in all_families:
|
for f in all_families:
|
||||||
r = build_family(f, toolchain, build_system, one_per_family, boards)
|
r = build_family(f, toolchain, build_system, build_flags_on, one_per_family, boards)
|
||||||
result[0] += r[0]
|
result[0] += r[0]
|
||||||
result[1] += r[1]
|
result[1] += r[1]
|
||||||
result[2] += r[2]
|
result[2] += r[2]
|
||||||
|
|
||||||
# build boards
|
# build boards
|
||||||
r = build_boards_list(boards, toolchain, build_system)
|
r = build_boards_list(boards, toolchain, build_system, build_flags_on)
|
||||||
result[0] += r[0]
|
result[0] += r[0]
|
||||||
result[1] += r[1]
|
result[1] += r[1]
|
||||||
result[2] += r[2]
|
result[2] += r[2]
|
||||||
|
Reference in New Issue
Block a user