diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2a0de62be..e19f0517b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -371,6 +371,38 @@ build_esp_matter_examples: --parallel-index ${CI_NODE_INDEX:-1} parallel: 2 +build_nopytest_remaining_examples_manual: + extends: + - .build_examples_template + rules: + - if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push" + when: on_success + - if: $CI_COMMIT_BRANCH != "main" + when: manual + allow_failure: true + needs: + - job: build_image + optional: true + artifacts: + paths: + - "examples/**/build*/size.json" + - "examples/**/build*/build_log.txt" + - "examples/**/build*/*.bin" + - "examples/**/build*/flasher_args.json" + - "examples/**/build*/config/sdkconfig.json" + - "examples/**/build*/bootloader/*.bin" + - "examples/**/build*/partition_table/*.bin" + when: always + expire_in: 4 days + script: + - cd ${ESP_MATTER_PATH} + - pip install -r tools/ci/requirements-build.txt + - python tools/ci/build_apps.py ./examples --no_pytest_remaining + --parallel-count ${CI_NODE_TOTAL:-1} + --parallel-index ${CI_NODE_INDEX:-1} + parallel: 2 + + build_esp_matter_examples_pytest_C3_idf_v4_4: extends: - .build_examples_template diff --git a/tools/ci/build_apps.py b/tools/ci/build_apps.py index 1a36d09da..43a82a166 100644 --- a/tools/ci/build_apps.py +++ b/tools/ci/build_apps.py @@ -47,6 +47,43 @@ MAINFEST_FILES = [ str(PROJECT_ROOT / 'examples' / '.build-rules.yml'), ] +# Exclude list for no-pytest apps in CI on merge request or branch pipelines. +# The below examples will be built on main branch pipeline. +NO_PYTEST_REMAINING_APPS = [ + {"target": "esp32c2", "name": "light_switch"}, + {"target": "esp32c6", "name": "light_switch"}, + {"target": "esp32h2", "name": "light_switch"}, + {"target": "esp32" , "name": "light_switch"}, + {"target": "esp32c2", "name": "generic_switch"}, + {"target": "esp32c6", "name": "generic_switch"}, + {"target": "esp32h2", "name": "generic_switch"}, + {"target": "esp32h2", "name": "multiple_on_off_plugin_units"}, + {"target": "esp32c3", "name": "multiple_on_off_plugin_units"}, + {"target": "esp32" , "name": "multiple_on_off_plugin_units"}, + {"target": "esp32s3", "name": "multiple_on_off_plugin_units"}, + {"target": "esp32" , "name": "room_air_conditioner"}, + {"target": "esp32c3", "name": "room_air_conditioner"}, + {"target": "esp32c2", "name": "room_air_conditioner"}, + {"target": "esp32c6", "name": "room_air_conditioner"}, + {"target": "esp32h2", "name": "room_air_conditioner"}, + {"target": "esp32" , "name": "door_lock"}, + {"target": "esp32c3", "name": "door_lock"}, + {"target": "esp32c2", "name": "door_lock"}, + {"target": "esp32c6", "name": "door_lock"}, + {"target": "esp32h2", "name": "door_lock"}, + {"target": "esp32s3", "name": "ota_provider"}, + {"target": "esp32c3", "name": "sensors"}, + {"target": "esp32" , "name": "refrigerator"}, + {"target": "esp32c3", "name": "refrigerator"}, + {"target": "esp32c2", "name": "refrigerator"}, + {"target": "esp32c6", "name": "refrigerator"}, + {"target": "esp32h2", "name": "refrigerator"}, + {"target": "esp32" , "name": "demo/badge"}, +] +MAINFEST_FILES = [ + str(PROJECT_ROOT / 'examples' / '.build-rules.yml'), +] + def _is_c6_pytest_app(app: App) -> bool: print(app.name, app.target) for pytest_app in PYTEST_C6_APPS: @@ -73,6 +110,13 @@ def _is_c2_pytest_app(app: App) -> bool: return True return False +# Function to check for no_pytest excluded list apps. +def _is_no_pytest_remaining_app(app: App) -> bool: + for no_pytest_app in NO_PYTEST_REMAINING_APPS: + if app.name == no_pytest_app["name"] and app.target == no_pytest_app["target"]: + return True + return False + def get_cmake_apps( paths: List[str], target: str, @@ -97,7 +141,7 @@ def main(args: argparse.Namespace) -> None: # no_pytest and only_pytest can not be both True assert not (args.no_pytest and args.pytest_c6 and args.pytest_h2 and args.pytest_c3 and args.pytest_c2) if args.no_pytest: - apps_for_build = [app for app in apps if not (_is_c6_pytest_app(app) or _is_h2_pytest_app(app))] + apps_for_build = [app for app in apps if not (_is_c6_pytest_app(app) or _is_h2_pytest_app(app) or _is_no_pytest_remaining_app(app))] elif args.pytest_c6: apps_for_build = [app for app in apps if _is_c6_pytest_app(app)] elif args.pytest_h2: @@ -106,6 +150,8 @@ def main(args: argparse.Namespace) -> None: apps_for_build = [app for app in apps if _is_c3_pytest_app(app)] elif args.pytest_c2: apps_for_build = [app for app in apps if _is_c2_pytest_app(app)] + elif args.no_pytest_remaining: + apps_for_build = [app for app in apps if _is_no_pytest_remaining_app(app)] else: apps_for_build = apps[:] @@ -164,7 +210,12 @@ if __name__ == '__main__': parser.add_argument( '--no_pytest', action="store_true", - help='Exclude pytest apps, definded in PYTEST_H2_APPS and PYTEST_C6_APPS', + help='Exclude pytest apps definded in PYTEST_H2_APPS and PYTEST_C6_APPS and some optional no-pytest apps', + ) + parser.add_argument( + '--no_pytest_remaining', + action="store_true", + help='Build the excluded no-pytest apps using manual trigger.', ) parser.add_argument( '--pytest_c6',