From 79bc66b323e0a1586f64fd69c114224dbe6a9c86 Mon Sep 17 00:00:00 2001 From: Fu Hanxi Date: Thu, 31 Aug 2023 12:55:28 +0800 Subject: [PATCH] ci: upload to minio server instead of gitlab artifacts for pytest jobs --- .gitlab/ci/README.md | 77 ++++ .gitlab/ci/assign-test.yml | 9 +- .gitlab/ci/build.yml | 126 ++---- .gitlab/ci/common.yml | 28 +- .gitlab/ci/rules.yml | 48 ++ .gitlab/ci/target-test.yml | 589 +++++++++++++++++-------- tools/ci/artifacts_handler.py | 187 ++++++++ tools/ci/ci_get_mr_info.py | 16 +- tools/ci/exclude_check_tools_files.txt | 1 + tools/ci/utils.sh | 5 + tools/requirements/requirements.ci.txt | 1 + 11 files changed, 769 insertions(+), 318 deletions(-) create mode 100644 tools/ci/artifacts_handler.py diff --git a/.gitlab/ci/README.md b/.gitlab/ci/README.md index e37dbf3384..76820f0788 100644 --- a/.gitlab/ci/README.md +++ b/.gitlab/ci/README.md @@ -22,6 +22,11 @@ - [Manifest File to Control the Build/Test apps](#manifest-file-to-control-the-buildtest-apps) - [Grammar](#grammar) - [Special Rules](#special-rules) + - [Upload/Download Artifacts to Internal Minio Server](#uploaddownload-artifacts-to-internal-minio-server) + - [Env Vars](#env-vars) + - [Artifacts Types and File Patterns](#artifacts-types-and-file-patterns) + - [Upload](#upload) + - [Download](#download) ## General Workflow @@ -245,3 +250,75 @@ In ESP-IDF CI, there's a few more special rules are additionally supported to di - Add MR labels `BUILD_AND_TEST_ALL_APPS` - Run in protected branches + +## Upload/Download Artifacts to Internal Minio Server + +### Users Without Access to Minio + +If you don't have access to the internal Minio server, you can still download the artifacts from the shared link in the job log. + +The log will look like this: + +```shell +Pipeline ID : 587355 +Job name : build_clang_test_apps_esp32 +Job ID : 40272275 +Created archive file: 40272275.zip, uploading as 587355/build_dir_without_map_and_elf_files/build_clang_test_apps_esp32/40272275.zip +Please download the archive file includes build_dir_without_map_and_elf_files from [INTERNAL_URL] +``` + +### Users With Access to Minio + +#### Env Vars for Minio + +Minio takes these env vars to connect to the server: + +- `IDF_S3_SERVER` +- `IDF_S3_ACCESS_KEY` +- `IDF_S3_SECRET_KEY` +- `IDF_S3_BUCKET` + +#### Artifacts Types and File Patterns + +The artifacts types and corresponding file patterns are defined in tools/ci/artifacts_handler.py, inside `ArtifactType` and `TYPE_PATTERNS_DICT`. + +#### Upload + +```shell +python tools/ci/artifacts_handler.py upload +``` + + will upload the files that match the file patterns to minio object storage with name: + +`///.zip` + +For example, job 39043328 will upload these four files: + +- `575500/map_and_elf_files/build_pytest_examples_esp32/39043328.zip` +- `575500/build_dir_without_map_and_elf_files/build_pytest_examples_esp32/39043328.zip` +- `575500/logs/build_pytest_examples_esp32/39043328.zip` +- `575500/size_reports/build_pytest_examples_esp32/39043328.zip` + +#### Download + +You may run + +```shell +python tools/ci/artifacts_handler.py download --pipeline_id +``` + +to download all files of the pipeline, or + +```shell +python tools/ci/artifacts_handler.py download --pipeline_id --job_name +``` + +to download all files with the specified job name or pattern, or + +```shell +python tools/ci/artifacts_handler.py download --pipeline_id --job_name --type ... +``` + +to download all files with the specified job name or pattern and artifact type(s). + +You may check all detailed documentation with `python tools/ci/artifacts_handler.py download -h` diff --git a/.gitlab/ci/assign-test.yml b/.gitlab/ci/assign-test.yml index c40b6943f2..8cedd8a0c0 100644 --- a/.gitlab/ci/assign-test.yml +++ b/.gitlab/ci/assign-test.yml @@ -3,16 +3,9 @@ stage: assign_test tags: - assign_test + dependencies: [] variables: SUBMODULES_TO_FETCH: "none" - artifacts: - paths: - - ${TEST_DIR}/test_configs/ - - artifact_index.json - when: always - expire_in: 1 week - script: - - run_cmd python tools/ci/python_packages/ttfw_idf/IDFAssignTest.py $TEST_TYPE $TEST_DIR -c $CI_TARGET_TEST_CONFIG_FILE -o $TEST_DIR/test_configs assign_integration_test: extends: diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index e0250d3f0a..0da53ba88e 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -16,7 +16,7 @@ extends: - .build_template - .before_script:build - - .after_script:build:ccache-upload + - .after_script:build:ccache dependencies: # set dependencies to null to avoid missing artifacts issue needs: - job: fast_template_app @@ -25,22 +25,14 @@ optional: true # only MR pipelines would have this artifacts: paths: - - "**/build*/size.json" + # The other artifacts patterns are defined under tools/ci/artifacts_handler.py + # Now we're uploading/downloading the binary files from our internal storage server + # + # keep the log file to help debug - "**/build*/build_log.txt" - - "**/build*/*.bin" - # upload to s3 server to save the artifacts size - # - "**/build*/*.map" - # ttfw tests require elf files - - "**/build*/*.elf" - - "**/build*/flasher_args.json" - - "**/build*/flash_project_args" - - "**/build*/config/sdkconfig.json" - # ttfw tests require sdkconfig file - - "**/build*/sdkconfig" - - "**/build*/bootloader/*.bin" - - "**/build*/partition_table/*.bin" - - list_job_*.txt + # keep the size info to help track the binary size - size_info.txt + - "**/build*/size.json" when: always expire_in: 4 days script: @@ -56,6 +48,7 @@ examples/wifi/iperf --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} + - upload_artifacts_to_s3 .build_cmake_clang_template: extends: @@ -74,41 +67,27 @@ --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} $TEST_BUILD_OPTS_EXTRA + - upload_artifacts_to_s3 .build_pytest_template: extends: - .build_cmake_template - - .before_script:build - artifacts: - paths: - - "**/build*/size.json" - - "**/build*/build_log.txt" - - "**/build*/*.bin" - # upload to s3 server to save the artifacts size - # - "**/build*/*.map" - # - "**/build*/*.elf" - - "**/build*/flasher_args.json" - - "**/build*/flash_project_args" - - "**/build*/config/sdkconfig.json" - - "**/build*/bootloader/*.bin" - - "**/build*/partition_table/*.bin" - - list_job_*.txt - - size_info.txt - when: always - expire_in: 4 days script: # CI specific options start from "--parallel-count xxx". could ignore when running locally - run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v -t $IDF_TARGET + -m \"not host_test\" --pytest-apps --parallel-count ${CI_NODE_TOTAL:-1} --parallel-index ${CI_NODE_INDEX:-1} --collect-app-info "list_job_${CI_JOB_NAME_SLUG}.txt" --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} + - upload_artifacts_to_s3 .build_pytest_no_jtag_template: - extends: .build_pytest_template + extends: + - .build_cmake_template script: # CI specific options start from "--parallel-count xxx". could ignore when running locally - run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v @@ -120,28 +99,11 @@ --collect-app-info "list_job_${CI_JOB_NAME_SLUG}.txt" --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} + - upload_artifacts_to_s3 .build_pytest_jtag_template: extends: - .build_cmake_template - - .before_script:build - artifacts: - paths: - - "**/build*/size.json" - - "**/build*/build_log.txt" - - "**/build*/*.bin" - # upload to s3 server to save the artifacts size - # - "**/build*/*.map" - - "**/build*/*.elf" # need elf for gdb - - "**/build*/flasher_args.json" - - "**/build*/flash_project_args" - - "**/build*/config/sdkconfig.json" - - "**/build*/bootloader/*.bin" - - "**/build*/partition_table/*.bin" - - list_job_*.txt - - size_info.txt - when: always - expire_in: 4 days script: # CI specific options start from "--parallel-count xxx". could ignore when running locally - run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v @@ -153,6 +115,7 @@ --collect-app-info "list_job_${CI_JOB_NAME_SLUG}.txt" --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} + - upload_artifacts_to_s3 build_pytest_examples_esp32: extends: @@ -199,17 +162,9 @@ build_pytest_examples_esp32c2: IDF_TARGET: esp32c2 TEST_DIR: examples -build_pytest_examples_jtag: # for all targets - extends: - - .build_pytest_jtag_template - - .rules:build:example_test-esp32 - variables: - IDF_TARGET: all - TEST_DIR: examples - build_pytest_examples_esp32c6: extends: - - .build_pytest_template + - .build_pytest_no_jtag_template - .rules:build:example_test-esp32c6 parallel: 2 variables: @@ -218,13 +173,21 @@ build_pytest_examples_esp32c6: build_pytest_examples_esp32h2: extends: - - .build_pytest_template + - .build_pytest_no_jtag_template - .rules:build:example_test-esp32h2 parallel: 2 variables: IDF_TARGET: esp32h2 TEST_DIR: examples +build_pytest_examples_jtag: # for all targets + extends: + - .build_pytest_jtag_template + - .rules:build:example_test + variables: + IDF_TARGET: all + TEST_DIR: examples + build_pytest_components_esp32: extends: - .build_pytest_template @@ -302,33 +265,11 @@ build_only_components_apps: --parallel-index ${CI_NODE_INDEX:-1} --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} - -.build_pytest_test_apps_template: - extends: .build_pytest_template - artifacts: - paths: - - "**/build*/size.json" - - "**/build*/build_log.txt" - - "**/build*/*.bin" - # upload to s3 server to save the artifacts size - # - "**/build*/*.map" - # pytest test apps requires elf files for coredump tests - - "**/build*/*.elf" - - "**/build*/flasher_args.json" - - "**/build*/flash_project_args" - - "**/build*/config/sdkconfig.json" - - "**/build*/bootloader/*.elf" - - "**/build*/bootloader/*.bin" - - "**/build*/partition_table/*.bin" - - "**/build*/project_description.json" - - list_job_*.txt - - size_info.txt - when: always - expire_in: 4 days + - upload_artifacts_to_s3 build_pytest_test_apps_esp32: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32 variables: IDF_TARGET: esp32 @@ -336,7 +277,7 @@ build_pytest_test_apps_esp32: build_pytest_test_apps_esp32s2: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32s2 variables: IDF_TARGET: esp32s2 @@ -344,7 +285,7 @@ build_pytest_test_apps_esp32s2: build_pytest_test_apps_esp32s3: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32s3 parallel: 2 variables: @@ -353,7 +294,7 @@ build_pytest_test_apps_esp32s3: build_pytest_test_apps_esp32c3: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32c3 variables: IDF_TARGET: esp32c3 @@ -361,7 +302,7 @@ build_pytest_test_apps_esp32c3: build_pytest_test_apps_esp32c2: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32c2 variables: IDF_TARGET: esp32c2 @@ -369,7 +310,7 @@ build_pytest_test_apps_esp32c2: build_pytest_test_apps_esp32c6: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32c6 variables: IDF_TARGET: esp32c6 @@ -377,7 +318,7 @@ build_pytest_test_apps_esp32c6: build_pytest_test_apps_esp32h2: extends: - - .build_pytest_test_apps_template + - .build_pytest_template - .rules:build:custom_test-esp32h2 variables: IDF_TARGET: esp32h2 @@ -396,6 +337,7 @@ build_only_tools_test_apps: --parallel-index ${CI_NODE_INDEX:-1} --modified-components ${MR_MODIFIED_COMPONENTS} --modified-files ${MR_MODIFIED_FILES} + - upload_artifacts_to_s3 .build_template_app_template: extends: diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index a2f4364a9d..8efbca34ee 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -21,7 +21,7 @@ variables: # GitLab-CI environment - # XXX_ATTEMPTS variables (https://docs.gitlab.com/ce/ci/yaml/README.html#job-stages-attempts) are not defined here. + # XXX_ATTEMPTS variables (https://docs.gitlab.com/ee/ci/runners/configure_runners.html#job-stages-attempts) are not defined here. # Use values from "CI / CD Settings" - "Variables". # GIT_STRATEGY is not defined here. @@ -178,27 +178,6 @@ variables: # Show ccache statistics if enabled globally test "$CI_CCACHE_STATS" == 1 && test -n "$(which ccache)" && ccache --show-stats || true -.upload_built_binaries_to_s3: &upload_built_binaries_to_s3 | - # upload the binary files to s3 server - echo -e "\e[0Ksection_start:`date +%s`:upload_binaries_to_s3_server[collapsed=true]\r\e[0KUploading binaries to s3 Server" - shopt -s globstar - # use || true to bypass the no-file error - zip ${CI_JOB_ID}.zip **/build*/*.bin || true - zip ${CI_JOB_ID}.zip **/build*/*.elf || true - zip ${CI_JOB_ID}.zip **/build*/*.map || true - zip ${CI_JOB_ID}.zip **/build*/flasher_args.json || true - zip ${CI_JOB_ID}.zip **/build*/flash_project_args || true - zip ${CI_JOB_ID}.zip **/build*/config/sdkconfig.json || true - zip ${CI_JOB_ID}.zip **/build*/sdkconfig || true - zip ${CI_JOB_ID}.zip **/build*/bootloader/*.bin || true - zip ${CI_JOB_ID}.zip **/build*/partition_table/*.bin || true - shopt -u globstar - mc cp ${CI_JOB_ID}.zip shiny-s3/idf-artifacts/${CI_PIPELINE_ID}/${CI_JOB_ID}.zip || true - echo -e "\e[0Ksection_end:`date +%s`:upload_binaries_to_s3_server\r\e[0K" - echo "Please download the full binary files (including *.elf and *.map files) from the following share link" - # would be clean up after 4 days - mc share download shiny-s3/idf-artifacts/${CI_PIPELINE_ID}/${CI_JOB_ID}.zip --expire=96h - .before_script:minimal: before_script: - *common-before_scripts @@ -226,11 +205,6 @@ variables: after_script: - *show_ccache_statistics -.after_script:build:ccache-upload: - after_script: - - *show_ccache_statistics - - *upload_built_binaries_to_s3 - ############# # `default` # ############# diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 7456c46636..6183322ae5 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -1190,6 +1190,54 @@ - <<: *if-dev-push changes: *patterns-submodule +.rules:build:example_test: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-example_test-ota-include_nightly_run-rule + - <<: *if-label-build + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32 + - <<: *if-label-example_test_esp32c2 + - <<: *if-label-example_test_esp32c3 + - <<: *if-label-example_test_esp32c6 + - <<: *if-label-example_test_esp32h2 + - <<: *if-label-example_test_esp32p4 + - <<: *if-label-example_test_esp32s2 + - <<: *if-label-example_test_esp32s3 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-build-example_test + - <<: *if-dev-push + changes: *patterns-build_components + - <<: *if-dev-push + changes: *patterns-build_system + - <<: *if-dev-push + changes: *patterns-downloadable-tools + - <<: *if-dev-push + changes: *patterns-example_test + - <<: *if-dev-push + changes: *patterns-example_test-adc + - <<: *if-dev-push + changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac + - <<: *if-dev-push + changes: *patterns-example_test-sdio + - <<: *if-dev-push + changes: *patterns-example_test-usb + - <<: *if-dev-push + changes: *patterns-example_test-wifi + - <<: *if-dev-push + changes: *patterns-target_test-adc + - <<: *if-dev-push + changes: *patterns-target_test-ecdsa + - <<: *if-dev-push + changes: *patterns-target_test-wifi + .rules:build:example_test-esp32: rules: - <<: *if-revert-branch diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 42d05b84e4..2d93fccd53 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -2,6 +2,7 @@ image: $TARGET_TEST_ENV_IMAGE stage: target_test timeout: 1 hour + dependencies: [] variables: GIT_DEPTH: 1 SUBMODULES_TO_FETCH: "none" @@ -32,6 +33,15 @@ # Runner tags are comma separated, replace the comma with " and " for markers - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) - markers=$(echo $job_tags | sed -e "s/,/ and /g") + - if [ -n "$BUILD_JOB_NAME" ]; then + job_name=$BUILD_JOB_NAME; + else + job_name=${BUILD_JOB_PREFIX}$(python tools/ci/ci_get_mr_info.py target_in_tags $job_tags); + fi + - run_cmd python tools/ci/artifacts_handler.py download --job-name "$job_name" --type build_dir_without_map_and_elf_files + - if [ -n "$REQUIRES_ELF_FILES" ]; then + run_cmd python tools/ci/artifacts_handler.py download --job-name "$job_name" --type map_and_elf_files; + fi - run_cmd pytest $TEST_DIR -m \"${markers}\" --junitxml=XUNIT_RESULT.xml @@ -45,13 +55,25 @@ extends: .pytest_template variables: TEST_DIR: examples + BUILD_JOB_PREFIX: build_pytest_examples_ + +.pytest_examples_dir_jtag_template: + extends: .pytest_examples_dir_template + needs: + - job: build_pytest_examples_jtag + artifacts: false + variables: + BUILD_JOB_NAME: build_pytest_examples_jtag + REQUIRES_ELF_FILES: "1" + PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32_generic: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, generic ] parallel: 3 @@ -60,7 +82,8 @@ pytest_examples_esp32_esp32eco3: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, esp32eco3 ] pytest_examples_esp32_ir_transceiver: @@ -68,7 +91,8 @@ pytest_examples_esp32_ir_transceiver: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ir_transceiver ] pytest_examples_esp32_twai_transceiver: @@ -76,7 +100,8 @@ pytest_examples_esp32_twai_transceiver: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, twai_transceiver ] pytest_examples_esp32_twai_network: @@ -84,25 +109,23 @@ pytest_examples_esp32_twai_network: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, twai_network ] pytest_examples_esp32_jtag: extends: - - .pytest_examples_dir_template + - .pytest_examples_dir_jtag_template - .rules:test:example_test-esp32 - needs: - - build_pytest_examples_jtag tags: [ esp32, jtag ] - variables: - PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32_ccs811: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ccs811 ] pytest_examples_esp32_sdio: @@ -110,7 +133,8 @@ pytest_examples_esp32_sdio: - .pytest_examples_dir_template - .rules:test:example_test-esp32-sdio needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, sdio_master_slave ] pytest_examples_esp32s2_generic: @@ -118,45 +142,40 @@ pytest_examples_esp32s2_generic: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2 needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, generic ] parallel: 3 pytest_examples_esp32s2_jtag: extends: - - .pytest_examples_dir_template + - .pytest_examples_dir_jtag_template - .rules:test:example_test-esp32s2 - needs: - - build_pytest_examples_jtag tags: [ esp32s2, jtag ] - variables: - PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32s3_generic: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3 needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, generic ] parallel: 3 pytest_examples_esp32s3_usb_serial_jtag: extends: - - .pytest_examples_dir_template + - .pytest_examples_dir_jtag_template - .rules:test:example_test-esp32s3 - needs: - - build_pytest_examples_jtag tags: [ esp32s3, usb_serial_jtag ] - variables: - PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32s3_f4r8: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3 needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F4R8 ] pytest_examples_esp32c2_generic: @@ -164,45 +183,40 @@ pytest_examples_esp32c2_generic: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2 needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, generic, xtal_40mhz ] parallel: 3 pytest_examples_esp32c2_jtag: extends: - - .pytest_examples_dir_template + - .pytest_examples_dir_jtag_template - .rules:test:example_test-esp32c2 - needs: - - build_pytest_examples_jtag tags: [ esp32c2, jtag ] - variables: - PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32c3_generic: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3 needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, generic ] parallel: 3 pytest_examples_esp32c3_usb_serial_jtag: extends: - - .pytest_examples_dir_template + - .pytest_examples_dir_jtag_template - .rules:test:example_test-esp32c3 - needs: - - build_pytest_examples_jtag tags: [ esp32c3, usb_serial_jtag ] - variables: - PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" pytest_examples_esp32c3_flash_suspend: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3 needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, flash_suspend ] pytest_examples_esp32c6_generic: @@ -210,7 +224,8 @@ pytest_examples_esp32c6_generic: - .pytest_examples_dir_template - .rules:test:example_test-esp32c6 needs: - - build_pytest_examples_esp32c6 + - job: build_pytest_examples_esp32c6 + artifacts: false tags: [ esp32c6, generic ] pytest_examples_esp32h2_generic: @@ -218,7 +233,8 @@ pytest_examples_esp32h2_generic: - .pytest_examples_dir_template - .rules:test:example_test-esp32h2 needs: - - build_pytest_examples_esp32h2 + - job: build_pytest_examples_esp32h2 + artifacts: false tags: [ esp32h2, generic ] pytest_examples_esp32_ethernet_ota: @@ -226,7 +242,8 @@ pytest_examples_esp32_ethernet_ota: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ethernet needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ethernet_ota ] pytest_examples_esp32_wifi_high_traffic: @@ -234,7 +251,8 @@ pytest_examples_esp32_wifi_high_traffic: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, wifi_high_traffic ] pytest_examples_esp32_flash_encryption_wifi_high_traffic: @@ -242,7 +260,8 @@ pytest_examples_esp32_flash_encryption_wifi_high_traffic: - .pytest_examples_dir_template - .rules:test:example_test-esp32-include_nightly_run-rule needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, flash_encryption_wifi_high_traffic ] pytest_examples_esp32c3_flash_encryption_wifi_high_traffic: @@ -250,7 +269,8 @@ pytest_examples_esp32c3_flash_encryption_wifi_high_traffic: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-include_nightly_run-rule needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, flash_encryption_wifi_high_traffic ] pytest_examples_esp32_ethernet: @@ -258,7 +278,8 @@ pytest_examples_esp32_ethernet: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ethernet needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ethernet] pytest_examples_esp32_ethernet_httpbin: @@ -266,7 +287,8 @@ pytest_examples_esp32_ethernet_httpbin: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ethernet needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, httpbin] pytest_examples_esp32_8mb_flash: @@ -274,7 +296,8 @@ pytest_examples_esp32_8mb_flash: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ethernet_flash_8m ] pytest_examples_esp32_wifi_ap: @@ -282,7 +305,8 @@ pytest_examples_esp32_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, wifi_ap ] pytest_examples_esp32c3_wifi_ap: @@ -290,7 +314,8 @@ pytest_examples_esp32c3_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-wifi needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, wifi_ap ] pytest_examples_esp32s3_wifi_ap: @@ -298,7 +323,8 @@ pytest_examples_esp32s3_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3-wifi needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, wifi_ap ] pytest_examples_esp32s2_wifi_ap: @@ -306,7 +332,8 @@ pytest_examples_esp32s2_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2-wifi needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, wifi_ap ] pytest_examples_esp32c2_wifi_ap: @@ -314,7 +341,8 @@ pytest_examples_esp32c2_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-wifi needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, wifi_ap, xtal_40mhz ] pytest_examples_esp32c2_26m_wifi_ap: @@ -322,7 +350,8 @@ pytest_examples_esp32c2_26m_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-wifi needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, wifi_ap, xtal_26mhz ] pytest_examples_esp32c6_wifi_ap: @@ -330,7 +359,8 @@ pytest_examples_esp32c6_wifi_ap: - .pytest_examples_dir_template - .rules:test:example_test-esp32c6-wifi needs: - - build_pytest_examples_esp32c6 + - job: build_pytest_examples_esp32c6 + artifacts: false tags: [ esp32c6, wifi_ap ] pytest_examples_esp32_wifi_router: @@ -338,7 +368,8 @@ pytest_examples_esp32_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, wifi_router ] pytest_examples_esp32c3_wifi_router: @@ -346,7 +377,8 @@ pytest_examples_esp32c3_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-wifi needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, wifi_router ] pytest_examples_esp32s3_wifi_router: @@ -354,7 +386,8 @@ pytest_examples_esp32s3_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3-wifi needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, wifi_router ] pytest_examples_esp32s2_wifi_router: @@ -362,7 +395,8 @@ pytest_examples_esp32s2_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2-wifi needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, wifi_router ] pytest_examples_esp32c2_wifi_router: @@ -370,7 +404,8 @@ pytest_examples_esp32c2_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-wifi needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, wifi_router, xtal_40mhz ] pytest_examples_esp32c2_26m_wifi_router: @@ -378,7 +413,8 @@ pytest_examples_esp32c2_26m_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-wifi needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, wifi_router, xtal_26mhz ] pytest_examples_esp32c6_wifi_router: @@ -386,16 +422,17 @@ pytest_examples_esp32c6_wifi_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32c6-wifi needs: - - build_pytest_examples_esp32c6 + - job: build_pytest_examples_esp32c6 + artifacts: false tags: [ esp32c6, wifi_router ] - pytest_examples_esp32_wifi_iperf: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, Example_ShieldBox_Basic ] pytest_examples_esp32_wifi_wlan: @@ -403,7 +440,8 @@ pytest_examples_esp32_wifi_wlan: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, wifi_wlan ] pytest_examples_esp32_ethernet_router: @@ -411,7 +449,8 @@ pytest_examples_esp32_ethernet_router: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ethernet needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ethernet_router ] pytest_examples_esp32_ethernet_vlan: @@ -419,7 +458,8 @@ pytest_examples_esp32_ethernet_vlan: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ethernet needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ethernet_vlan ] pytest_examples_esp32_ethernet_ip101: @@ -427,15 +467,17 @@ pytest_examples_esp32_ethernet_ip101: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, ip101 ] -example_test_pytest_esp32_ethernet_bridge: +pytest_examples_esp32_ethernet_bridge: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, eth_w5500 ] variables: PYTEST_EXTRA_FLAGS: "--dev-passwd ${ETHERNET_TEST_PASSWORD} --dev-user ${ETHERNET_TEST_USER}" @@ -445,7 +487,8 @@ pytest_examples_esp32_flash_encryption: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, flash_encryption ] pytest_examples_esp32_wifi_two_dut: @@ -453,7 +496,8 @@ pytest_examples_esp32_wifi_two_dut: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, wifi_two_dut ] pytest_examples_esp32c3_wifi_two_dut: @@ -461,7 +505,8 @@ pytest_examples_esp32c3_wifi_two_dut: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-wifi needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, wifi_two_dut ] pytest_examples_esp32s3_wifi_two_dut: @@ -469,7 +514,8 @@ pytest_examples_esp32s3_wifi_two_dut: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3-wifi needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, wifi_two_dut ] pytest_examples_esp32c2_wifi_two_dut: @@ -477,7 +523,8 @@ pytest_examples_esp32c2_wifi_two_dut: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-wifi needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, wifi_two_dut, xtal_26mhz ] pytest_examples_esp32c3_flash_encryption: @@ -485,7 +532,8 @@ pytest_examples_esp32c3_flash_encryption: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3 needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, flash_encryption ] pytest_examples_esp32c3_nvs_encr_hmac: @@ -493,7 +541,8 @@ pytest_examples_esp32c3_nvs_encr_hmac: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-nvs_encr_hmac needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, nvs_encr_hmac ] pytest_examples_esp32s2_usb_device: @@ -501,7 +550,8 @@ pytest_examples_esp32s2_usb_device: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2-usb needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, usb_device ] pytest_examples_esp32_sdmmc: @@ -509,7 +559,8 @@ pytest_examples_esp32_sdmmc: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, sdcard_sdmode ] pytest_examples_esp32_sdspi: @@ -517,7 +568,8 @@ pytest_examples_esp32_sdspi: - .pytest_examples_dir_template - .rules:test:example_test-esp32-sdio needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, sdcard_spimode ] pytest_examples_esp32s2_sdspi: @@ -525,7 +577,8 @@ pytest_examples_esp32s2_sdspi: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2-sdio needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, sdcard_spimode ] pytest_examples_esp32c3_sdspi: @@ -533,7 +586,8 @@ pytest_examples_esp32c3_sdspi: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-sdio needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, sdcard_spimode ] pytest_examples_esp32_extflash: @@ -541,7 +595,8 @@ pytest_examples_esp32_extflash: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, external_flash ] pytest_examples_esp32_adc: @@ -549,7 +604,8 @@ pytest_examples_esp32_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32-adc needs: - - build_pytest_examples_esp32 + - job: build_pytest_examples_esp32 + artifacts: false tags: [ esp32, adc ] pytest_examples_esp32s2_adc: @@ -557,7 +613,8 @@ pytest_examples_esp32s2_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32s2-adc needs: - - build_pytest_examples_esp32s2 + - job: build_pytest_examples_esp32s2 + artifacts: false tags: [ esp32s2, adc ] pytest_examples_esp32s3_adc: @@ -565,7 +622,8 @@ pytest_examples_esp32s3_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3-adc needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, adc ] pytest_examples_esp32c3_adc: @@ -573,7 +631,8 @@ pytest_examples_esp32c3_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-adc needs: - - build_pytest_examples_esp32c3 + - job: build_pytest_examples_esp32c3 + artifacts: false tags: [ esp32c3, adc ] pytest_examples_esp32c2_adc: @@ -581,7 +640,8 @@ pytest_examples_esp32c2_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32c2-adc needs: - - build_pytest_examples_esp32c2 + - job: build_pytest_examples_esp32c2 + artifacts: false tags: [ esp32c2, adc, xtal_26mhz] pytest_examples_esp32c6_adc: @@ -589,7 +649,8 @@ pytest_examples_esp32c6_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32c6-adc needs: - - build_pytest_examples_esp32c6 + - job: build_pytest_examples_esp32c6 + artifacts: false tags: [ esp32c6, adc ] pytest_examples_esp32h2_adc: @@ -597,28 +658,32 @@ pytest_examples_esp32h2_adc: - .pytest_examples_dir_template - .rules:test:example_test-esp32h2-adc needs: - - build_pytest_examples_esp32h2 + - job: build_pytest_examples_esp32h2 + artifacts: false tags: [ esp32h2, adc ] -example_test_pytest_esp32s3_emmc: +pytest_examples_esp32s3_emmc: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32s3 needs: - - build_pytest_examples_esp32s3 + - job: build_pytest_examples_esp32s3 + artifacts: false tags: [ esp32s3, emmc ] .pytest_components_dir_template: extends: .pytest_template variables: TEST_DIR: components + BUILD_JOB_PREFIX: build_pytest_components_ pytest_components_esp32_generic: extends: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, generic ] parallel: 7 @@ -627,7 +692,8 @@ pytest_components_esp32_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, generic_multi_device ] pytest_components_esp32_wifi_two_dut: @@ -635,7 +701,8 @@ pytest_components_esp32_wifi_two_dut: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, wifi_two_dut ] pytest_components_esp32_adc: @@ -643,7 +710,8 @@ pytest_components_esp32_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32-adc needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, adc ] pytest_components_esp32_sdio: @@ -651,7 +719,8 @@ pytest_components_esp32_sdio: - .pytest_components_dir_template - .rules:test:component_ut-esp32-sdio needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, sdio_master_slave ] pytest_components_esp32_ip101: @@ -659,56 +728,64 @@ pytest_components_esp32_ip101: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, ip101 ] pytest_components_esp32_lan8720: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_lan8720 ] pytest_components_esp32_rtl8201: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_rtl8201 ] pytest_components_esp32_w5500: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_w5500 ] pytest_components_esp32_ksz8851snl: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_ksz8851snl ] pytest_components_esp32_dm9051: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_dm9051 ] pytest_components_esp32_ksz8041: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_ksz8041 ] pytest_components_esp32_dp83848: extends: - .pytest_components_dir_template needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, eth_dp83848 ] pytest_components_esp32_ethernet: @@ -716,7 +793,8 @@ pytest_components_esp32_ethernet: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, ethernet ] pytest_components_esp32_flash_encryption: @@ -724,7 +802,8 @@ pytest_components_esp32_flash_encryption: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, flash_encryption ] pytest_components_esp32_flash_multi: @@ -732,7 +811,8 @@ pytest_components_esp32_flash_multi: - .pytest_components_dir_template - .rules:test:component_ut-esp32-flash_multi needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, flash_multi ] pytest_components_esp32_xtal32k: @@ -740,7 +820,8 @@ pytest_components_esp32_xtal32k: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, xtal32k ] pytest_components_esp32_no32kXtal: @@ -748,7 +829,8 @@ pytest_components_esp32_no32kXtal: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, no32kXtal ] pytest_components_esp32_rs485_multi: @@ -756,7 +838,8 @@ pytest_components_esp32_rs485_multi: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, multi_dut_modbus_rs485 ] pytest_components_esp32_psramv0: @@ -764,7 +847,8 @@ pytest_components_esp32_psramv0: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, psramv0 ] pytest_components_esp32s2_generic: @@ -772,7 +856,8 @@ pytest_components_esp32s2_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32s2 needs: - - build_pytest_components_esp32s2 + - job: build_pytest_components_esp32s2 + artifacts: false tags: [ esp32s2, generic ] parallel: 5 @@ -781,7 +866,8 @@ pytest_components_esp32s2_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32s2 needs: - - build_pytest_components_esp32s2 + - job: build_pytest_components_esp32s2 + artifacts: false tags: [ esp32s2, generic_multi_device ] pytest_components_esp32s2_adc: @@ -789,7 +875,8 @@ pytest_components_esp32s2_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32s2-adc needs: - - build_pytest_components_esp32s2 + - job: build_pytest_components_esp32s2 + artifacts: false tags: [ esp32s2, adc ] pytest_components_esp32s2_flash_multi: @@ -797,7 +884,8 @@ pytest_components_esp32s2_flash_multi: - .pytest_components_dir_template - .rules:test:component_ut-esp32s2-flash_multi needs: - - build_pytest_components_esp32s2 + - job: build_pytest_components_esp32s2 + artifacts: false tags: [ esp32s2, flash_multi ] pytest_components_esp32s3_generic: @@ -805,7 +893,8 @@ pytest_components_esp32s3_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, generic ] parallel: 5 @@ -814,7 +903,8 @@ pytest_components_esp32s3_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, generic_multi_device ] pytest_components_esp32s3_adc: @@ -822,7 +912,8 @@ pytest_components_esp32s3_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3-adc needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, adc ] pytest_components_esp32s3_octal_psram: @@ -830,7 +921,8 @@ pytest_components_esp32s3_octal_psram: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, octal_psram ] pytest_components_esp32s3_quad_psram: @@ -838,7 +930,8 @@ pytest_components_esp32s3_quad_psram: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, quad_psram ] pytest_components_esp32s3_flash_encryption_f4r8: @@ -846,7 +939,8 @@ pytest_components_esp32s3_flash_encryption_f4r8: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, flash_encryption_f4r8 ] pytest_components_esp32s3_flash_encryption_f8r8: @@ -854,7 +948,8 @@ pytest_components_esp32s3_flash_encryption_f8r8: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, flash_encryption_f8r8 ] pytest_components_esp32s3_flash_multi: @@ -862,7 +957,8 @@ pytest_components_esp32s3_flash_multi: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3-flash_multi needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, flash_multi ] pytest_components_esp32s3_mspi_f4r4: @@ -870,7 +966,8 @@ pytest_components_esp32s3_mspi_f4r4: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F4R4 ] pytest_components_esp32s3_mspi_f4r8: @@ -878,7 +975,8 @@ pytest_components_esp32s3_mspi_f4r8: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F4R8 ] pytest_components_esp32s3_mspi_f8r8: @@ -886,7 +984,8 @@ pytest_components_esp32s3_mspi_f8r8: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3 needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F8R8 ] pytest_components_esp32s3_usb_serial_jtag: @@ -902,7 +1001,8 @@ pytest_components_esp32c2_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32c2 needs: - - build_pytest_components_esp32c2 + - job: build_pytest_components_esp32c2 + artifacts: false tags: [ esp32c2, generic, xtal_40mhz ] parallel: 3 @@ -911,7 +1011,8 @@ pytest_components_esp32c2_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32c2-adc needs: - - build_pytest_components_esp32c2 + - job: build_pytest_components_esp32c2 + artifacts: false tags: [ esp32c2, adc, xtal_26mhz ] pytest_components_esp32c2_generic_multi_device: @@ -919,7 +1020,8 @@ pytest_components_esp32c2_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32c2 needs: - - build_pytest_components_esp32c2 + - job: build_pytest_components_esp32c2 + artifacts: false tags: [ esp32c2, generic_multi_device, xtal_40mhz ] pytest_components_esp32c2_xtal_26mhz: @@ -927,7 +1029,8 @@ pytest_components_esp32c2_xtal_26mhz: - .pytest_components_dir_template - .rules:test:component_ut-esp32c2 needs: - - build_pytest_components_esp32c2 + - job: build_pytest_components_esp32c2 + artifacts: false tags: [ esp32c2, generic, xtal_26mhz ] pytest_components_esp32c3_generic: @@ -935,7 +1038,8 @@ pytest_components_esp32c3_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3 needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, generic ] parallel: 3 @@ -944,7 +1048,8 @@ pytest_components_esp32c3_i2c_oled: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3 needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, i2c_oled ] pytest_components_esp32c3_generic_multi_device: @@ -952,7 +1057,8 @@ pytest_components_esp32c3_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3 needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, generic_multi_device ] pytest_components_esp32c3_wifi_two_dut: @@ -960,7 +1066,8 @@ pytest_components_esp32c3_wifi_two_dut: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3-wifi needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, wifi_two_dut ] pytest_components_esp32c3_usb_serial_jtag: @@ -976,7 +1083,8 @@ pytest_components_esp32s3_wifi_two_dut: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3-wifi needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, wifi_two_dut ] pytest_components_esp32c2_wifi_two_dut: @@ -984,7 +1092,8 @@ pytest_components_esp32c2_wifi_two_dut: - .pytest_components_dir_template - .rules:test:component_ut-esp32c2-wifi needs: - - build_pytest_components_esp32c2 + - job: build_pytest_components_esp32c2 + artifacts: false tags: [ esp32c2, wifi_two_dut, xtal_26mhz ] pytest_components_esp32c3_adc: @@ -992,7 +1101,8 @@ pytest_components_esp32c3_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3-adc needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, adc ] pytest_components_esp32c3_flash_encryption: @@ -1000,7 +1110,8 @@ pytest_components_esp32c3_flash_encryption: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3 needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, flash_encryption ] pytest_components_esp32c3_nvs_encr_hmac: @@ -1008,7 +1119,8 @@ pytest_components_esp32c3_nvs_encr_hmac: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3-nvs_encr_hmac needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, nvs_encr_hmac ] pytest_components_esp32c3_flash_multi: @@ -1016,7 +1128,8 @@ pytest_components_esp32c3_flash_multi: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3-flash_multi needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, flash_multi ] pytest_components_esp32_sdmmc: @@ -1024,7 +1137,8 @@ pytest_components_esp32_sdmmc: - .pytest_components_dir_template - .rules:test:component_ut-esp32 needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, sdcard_sdmode ] pytest_components_esp32_sdspi: @@ -1032,7 +1146,8 @@ pytest_components_esp32_sdspi: - .pytest_components_dir_template - .rules:test:component_ut-esp32-sdio needs: - - build_pytest_components_esp32 + - job: build_pytest_components_esp32 + artifacts: false tags: [ esp32, sdcard_spimode ] pytest_components_esp32s2_sdspi: @@ -1040,7 +1155,8 @@ pytest_components_esp32s2_sdspi: - .pytest_components_dir_template - .rules:test:component_ut-esp32s2-sdio needs: - - build_pytest_components_esp32s2 + - job: build_pytest_components_esp32s2 + artifacts: false tags: [ esp32s2, sdcard_spimode ] pytest_components_esp32c3_sdspi: @@ -1048,7 +1164,8 @@ pytest_components_esp32c3_sdspi: - .pytest_components_dir_template - .rules:test:component_ut-esp32c3-sdio needs: - - build_pytest_components_esp32c3 + - job: build_pytest_components_esp32c3 + artifacts: false tags: [ esp32c3, sdcard_spimode ] pytest_components_esp32c6_generic: @@ -1056,7 +1173,8 @@ pytest_components_esp32c6_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32c6 needs: - - build_pytest_components_esp32c6 + - job: build_pytest_components_esp32c6 + artifacts: false tags: [ esp32c6, generic ] parallel: 2 @@ -1073,7 +1191,8 @@ pytest_components_esp32h2_generic: - .pytest_components_dir_template - .rules:test:component_ut-esp32h2 needs: - - build_pytest_components_esp32h2 + - job: build_pytest_components_esp32h2 + artifacts: false tags: [ esp32h2, generic ] parallel: 2 @@ -1082,7 +1201,8 @@ pytest_components_esp32h2_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32h2 needs: - - build_pytest_components_esp32h2 + - job: build_pytest_components_esp32h2 + artifacts: false tags: [ esp32h2, generic_multi_device ] pytest_components_esp32h2_adc: @@ -1090,15 +1210,17 @@ pytest_components_esp32h2_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32h2-adc needs: - - build_pytest_components_esp32h2 + - job: build_pytest_components_esp32h2 + artifacts: false tags: [ esp32h2, adc ] -component_ut_pytest_esp32h2_ecdsa: +pytest_components_esp32h2_ecdsa: extends: - .pytest_components_dir_template - .rules:test:component_ut-esp32h2-ecdsa needs: - - build_pytest_components_esp32h2 + - job: build_pytest_components_esp32h2 + artifacts: false tags: [ esp32h2, ecdsa_efuse ] pytest_components_esp32h2_usb_serial_jtag: @@ -1114,7 +1236,8 @@ pytest_components_esp32c6_generic_multi_device: - .pytest_components_dir_template - .rules:test:component_ut-esp32c6 needs: - - build_pytest_components_esp32c6 + - job: build_pytest_components_esp32c6 + artifacts: false tags: [ esp32c6, generic_multi_device ] pytest_components_esp32c6_adc: @@ -1122,7 +1245,8 @@ pytest_components_esp32c6_adc: - .pytest_components_dir_template - .rules:test:component_ut-esp32c6-adc needs: - - build_pytest_components_esp32c6 + - job: build_pytest_components_esp32c6 + artifacts: false tags: [ esp32c6, adc ] pytest_components_esp32c6_i154: @@ -1130,7 +1254,8 @@ pytest_components_esp32c6_i154: - .pytest_components_dir_template - .rules:test:component_ut-esp32c6-i154 needs: - - build_pytest_components_esp32c6 + - job: build_pytest_components_esp32c6 + artifacts: false tags: [ esp32c6, ieee802154 ] pytest_examples_openthread_br: @@ -1138,63 +1263,132 @@ pytest_examples_openthread_br: - .pytest_examples_dir_template - .rules:test:example_test-i154 needs: - - build_pytest_examples_esp32s3 - - build_pytest_examples_esp32c6 - - build_pytest_examples_esp32h2 - tags: - - esp32c6 - - openthread_br + - job: build_pytest_examples_esp32s3 + artifacts: false + - job: build_pytest_examples_esp32c6 + artifacts: false + - job: build_pytest_examples_esp32h2 + artifacts: false + tags: [ esp32c6, openthread_br ] + script: + - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases + # get runner env config file + - retry_failed git clone $TEST_ENV_CONFIG_REPO + - python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs + # using runner tags as markers to filter the test cases + # Runner tags are comma separated, replace the comma with " and " for markers + - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) + - markers=$(echo $job_tags | sed -e "s/,/ and /g") + # download the artifacts, requires s3, c6, h2 chips + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32s3" + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32c6" + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32h2" + - run_cmd pytest $TEST_DIR + -m \"${markers}\" + --junitxml=XUNIT_RESULT.xml + --ignore-result-files known_failure_cases/known_failure_cases.txt + --parallel-count ${CI_NODE_TOTAL:-1} + --parallel-index ${CI_NODE_INDEX:-1} + ${PYTEST_EXTRA_FLAGS} + --app-info-filepattern \"list_job_*.txt\" pytest_examples_openthread_bbr: extends: - .pytest_examples_dir_template - .rules:test:example_test-i154 needs: - - build_pytest_examples_esp32s3 - - build_pytest_examples_esp32c6 - - build_pytest_examples_esp32h2 - tags: - - esp32c6 - - openthread_bbr + - job: build_pytest_examples_esp32s3 + artifacts: false + - job: build_pytest_examples_esp32c6 + artifacts: false + - job: build_pytest_examples_esp32h2 + artifacts: false + tags: [ esp32c6, openthread_bbr ] + script: + - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases + # get runner env config file + - retry_failed git clone $TEST_ENV_CONFIG_REPO + - python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs + # using runner tags as markers to filter the test cases + # Runner tags are comma separated, replace the comma with " and " for markers + - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) + - markers=$(echo $job_tags | sed -e "s/,/ and /g") + # download the artifacts, requires s3, c6, h2 chips + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32s3" + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32c6" + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32h2" + - run_cmd pytest $TEST_DIR + -m \"${markers}\" + --junitxml=XUNIT_RESULT.xml + --ignore-result-files known_failure_cases/known_failure_cases.txt + --parallel-count ${CI_NODE_TOTAL:-1} + --parallel-index ${CI_NODE_INDEX:-1} + ${PYTEST_EXTRA_FLAGS} + --app-info-filepattern \"list_job_*.txt\" pytest_examples_openthread_sleep: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32h2 needs: - - build_pytest_examples_esp32c6 - - build_pytest_examples_esp32h2 + - job: build_pytest_examples_esp32c6 + artifacts: false + - job: build_pytest_examples_esp32h2 + artifacts: false tags: [ esp32c6, openthread_sleep ] + script: + - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases + # get runner env config file + - retry_failed git clone $TEST_ENV_CONFIG_REPO + - python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs + # using runner tags as markers to filter the test cases + # Runner tags are comma separated, replace the comma with " and " for markers + - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) + - markers=$(echo $job_tags | sed -e "s/,/ and /g") + # download the artifacts, requires c6, h2 chips + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32c6" + - run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_examples_esp32h2" + - run_cmd pytest $TEST_DIR + -m \"${markers}\" + --junitxml=XUNIT_RESULT.xml + --ignore-result-files known_failure_cases/known_failure_cases.txt + --parallel-count ${CI_NODE_TOTAL:-1} + --parallel-index ${CI_NODE_INDEX:-1} + ${PYTEST_EXTRA_FLAGS} + --app-info-filepattern \"list_job_*.txt\" -pytest_examples_zigbee: +pytest_examples_esp32h2_zigbee: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32h2 needs: - - build_pytest_examples_esp32h2 - tags: - - esp32h2 - - zigbee_multi_dut + - job: build_pytest_examples_esp32h2 + artifacts: false + tags: [ esp32h2, zigbee_multi_dut ] pytest_components_esp32s3_usb_host: extends: - .pytest_components_dir_template - .rules:test:component_ut-esp32s3-usb needs: - - build_pytest_components_esp32s3 + - job: build_pytest_components_esp32s3 + artifacts: false tags: [ esp32s3, usb_host_flash_disk ] .pytest_test_apps_dir_template: extends: .pytest_template variables: TEST_DIR: tools/test_apps + BUILD_JOB_PREFIX: build_pytest_test_apps_ + REQUIRES_ELF_FILES: "1" pytest_test_apps_esp32_generic: extends: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32 needs: - - build_pytest_test_apps_esp32 + - job: build_pytest_test_apps_esp32 + artifacts: false tags: [ esp32, generic ] pytest_test_apps_esp32_jtag: @@ -1202,8 +1396,9 @@ pytest_test_apps_esp32_jtag: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32 needs: - - build_pytest_test_apps_esp32 - tags: [ esp32, jtag] + - job: build_pytest_test_apps_esp32 + artifacts: false + tags: [ esp32, jtag ] variables: PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG" @@ -1212,7 +1407,8 @@ pytest_test_apps_esp32_ethernet: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32 needs: - - build_pytest_test_apps_esp32 + - job: build_pytest_test_apps_esp32 + artifacts: false tags: [ esp32, ethernet ] pytest_test_apps_esp32s2_generic: @@ -1220,7 +1416,8 @@ pytest_test_apps_esp32s2_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s2 needs: - - build_pytest_test_apps_esp32s2 + - job: build_pytest_test_apps_esp32s2 + artifacts: false tags: [ esp32s2, generic ] pytest_test_apps_esp32s3_generic: @@ -1228,7 +1425,8 @@ pytest_test_apps_esp32s3_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s3 needs: - - build_pytest_test_apps_esp32s3 + - job: build_pytest_test_apps_esp32s3 + artifacts: false tags: [ esp32s3, generic ] pytest_test_apps_esp32c2_generic: @@ -1236,7 +1434,8 @@ pytest_test_apps_esp32c2_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32c2 needs: - - build_pytest_test_apps_esp32c2 + - job: build_pytest_test_apps_esp32c2 + artifacts: false tags: [ esp32c2, generic, xtal_40mhz ] pytest_test_apps_esp32c3_generic: @@ -1244,7 +1443,8 @@ pytest_test_apps_esp32c3_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32c3 needs: - - build_pytest_test_apps_esp32c3 + - job: build_pytest_test_apps_esp32c3 + artifacts: false tags: [ esp32c3, generic ] pytest_test_apps_esp32c6_generic: @@ -1252,7 +1452,8 @@ pytest_test_apps_esp32c6_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32c6 needs: - - build_pytest_test_apps_esp32c6 + - job: build_pytest_test_apps_esp32c6 + artifacts: false tags: [ esp32c6, generic ] pytest_test_apps_esp32h2_generic: @@ -1260,7 +1461,8 @@ pytest_test_apps_esp32h2_generic: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32h2 needs: - - build_pytest_test_apps_esp32h2 + - job: build_pytest_test_apps_esp32h2 + artifacts: false tags: [ esp32h2, generic ] pytest_test_apps_esp32s3_mspi_f8r8: @@ -1268,7 +1470,8 @@ pytest_test_apps_esp32s3_mspi_f8r8: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s3 needs: - - build_pytest_test_apps_esp32s3 + - job: build_pytest_test_apps_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F8R8 ] pytest_test_apps_esp32s3_mspi_f4r8: @@ -1276,7 +1479,8 @@ pytest_test_apps_esp32s3_mspi_f4r8: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s3 needs: - - build_pytest_test_apps_esp32s3 + - job: build_pytest_test_apps_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F4R8 ] pytest_test_apps_esp32s3_mspi_f4r4: @@ -1284,7 +1488,8 @@ pytest_test_apps_esp32s3_mspi_f4r4: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s3 needs: - - build_pytest_test_apps_esp32s3 + - job: build_pytest_test_apps_esp32s3 + artifacts: false tags: [ esp32s3, MSPI_F4R4 ] pytest_test_apps_esp32s2_wifi_two_dut: @@ -1292,7 +1497,8 @@ pytest_test_apps_esp32s2_wifi_two_dut: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s2-wifi needs: - - build_pytest_test_apps_esp32s2 + - job: build_pytest_test_apps_esp32s2 + artifacts: false tags: [ esp32s2, wifi_two_dut ] pytest_test_apps_esp32s3_wifi_two_dut: @@ -1300,7 +1506,8 @@ pytest_test_apps_esp32s3_wifi_two_dut: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32s3-wifi needs: - - build_pytest_test_apps_esp32s3 + - job: build_pytest_test_apps_esp32s3 + artifacts: false tags: [ esp32s3, wifi_two_dut ] pytest_test_apps_esp32c2_wifi_two_dut: @@ -1308,7 +1515,8 @@ pytest_test_apps_esp32c2_wifi_two_dut: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32c2-wifi needs: - - build_pytest_test_apps_esp32c2 + - job: build_pytest_test_apps_esp32c2 + artifacts: false tags: [ esp32c2, wifi_two_dut, xtal_26mhz ] pytest_test_apps_esp32c3_wifi_two_dut: @@ -1316,7 +1524,8 @@ pytest_test_apps_esp32c3_wifi_two_dut: - .pytest_test_apps_dir_template - .rules:test:custom_test-esp32c3-wifi needs: - - build_pytest_test_apps_esp32c3 + - job: build_pytest_test_apps_esp32c3 + artifacts: false tags: [ esp32c3, wifi_two_dut] # for parallel jobs, CI_JOB_NAME will be "job_name index/total" (for example, "IT_001 1/2") diff --git a/tools/ci/artifacts_handler.py b/tools/ci/artifacts_handler.py new file mode 100644 index 0000000000..051bffa962 --- /dev/null +++ b/tools/ci/artifacts_handler.py @@ -0,0 +1,187 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import fnmatch +import glob +import os +import typing as t +from enum import Enum +from pathlib import Path +from zipfile import ZipFile + +import urllib3 +from minio import Minio + + +class ArtifactType(str, Enum): + MAP_AND_ELF_FILES = 'map_and_elf_files' + BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES = 'build_dir_without_map_and_elf_files' + + LOGS = 'logs' + SIZE_REPORTS = 'size_reports' + + +TYPE_PATTERNS_DICT = { + ArtifactType.MAP_AND_ELF_FILES: [ + '**/build*/**/*.map', + '**/build*/**/*.elf', + ], + ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES: [ + '**/build*/build_log.txt', + '**/build*/**/*.bin', + '**/build*/flasher_args.json', + '**/build*/flash_project_args', + '**/build*/config/sdkconfig.json', + '**/build*/project_description.json', + 'list_job_*.txt', + ], + ArtifactType.LOGS: [ + '**/build*/build_log.txt', + ], + ArtifactType.SIZE_REPORTS: [ + '**/build*/size.json', + 'size_info.txt', + ], +} + + +def getenv(env_var: str) -> str: + try: + return os.environ[env_var] + except KeyError as e: + raise Exception(f'Environment variable {env_var} not set') from e + + +def _download_files( + pipeline_id: int, + *, + artifact_type: t.Optional[ArtifactType] = None, + job_name: t.Optional[str] = None, + job_id: t.Optional[int] = None, +) -> None: + if artifact_type: + prefix = f'{pipeline_id}/{artifact_type.value}/' + else: + prefix = f'{pipeline_id}/' + + for obj in client.list_objects(getenv('IDF_S3_BUCKET'), prefix=prefix, recursive=True): + obj_name = obj.object_name + obj_p = Path(obj_name) + # ///.zip + if len(obj_p.parts) != 4: + print(f'Invalid object name: {obj_name}') + continue + + if job_name: + # could be a pattern + if not fnmatch.fnmatch(obj_p.parts[2], job_name): + print(f'Job name {job_name} does not match {obj_p.parts[2]}') + continue + + if job_id: + if obj_p.parts[3] != f'{job_id}.zip': + print(f'Job ID {job_id} does not match {obj_p.parts[3]}') + continue + + client.fget_object(getenv('IDF_S3_BUCKET'), obj_name, obj_name) + print(f'Downloaded {obj_name}') + + if obj_name.endswith('.zip'): + with ZipFile(obj_name, 'r') as zr: + zr.extractall() + print(f'Extracted {obj_name}') + + os.remove(obj_name) + + +def _upload_files( + pipeline_id: int, + *, + artifact_type: ArtifactType, + job_name: str, + job_id: str, +) -> None: + has_file = False + with ZipFile(f'{job_id}.zip', 'w') as zw: + for pattern in TYPE_PATTERNS_DICT[artifact_type]: + for file in glob.glob(pattern, recursive=True): + zw.write(file) + has_file = True + + try: + if has_file: + obj_name = f'{pipeline_id}/{artifact_type.value}/{job_name.split(" ")[0]}/{job_id}.zip' + print(f'Created archive file: {job_id}.zip, uploading as {obj_name}') + + client.fput_object(getenv('IDF_S3_BUCKET'), obj_name, f'{job_id}.zip') + url = client.get_presigned_url('GET', getenv('IDF_S3_BUCKET'), obj_name) + print(f'Please download the archive file which includes {artifact_type.value} from {url}') + finally: + os.remove(f'{job_id}.zip') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Download or upload files from/to S3, the object name would be ' + '[PIPELINE_ID]/[ACTION_TYPE]/[JOB_NAME]/[JOB_ID].zip.' + '\n' + 'For example: 123456/binaries/build_pytest_examples_esp32/123456789.zip', + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + common_args = argparse.ArgumentParser(add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter) + common_args.add_argument('--pipeline-id', type=int, help='Pipeline ID') + common_args.add_argument( + '--type', type=str, nargs='+', choices=[a.value for a in ArtifactType], help='Types of files to download' + ) + + action = parser.add_subparsers(dest='action', help='Download or Upload') + download = action.add_parser('download', help='Download files from S3', parents=[common_args]) + upload = action.add_parser('upload', help='Upload files to S3', parents=[common_args]) + + download.add_argument('--job-name', type=str, help='Job name pattern') + download.add_argument('--job-id', type=int, help='Job ID') + + upload.add_argument('--job-name', type=str, help='Job name') + upload.add_argument('--job-id', type=int, help='Job ID') + + args = parser.parse_args() + + client = Minio( + getenv('IDF_S3_SERVER').replace('https://', ''), + access_key=getenv('IDF_S3_ACCESS_KEY'), + secret_key=getenv('IDF_S3_SECRET_KEY'), + http_client=urllib3.PoolManager( + timeout=urllib3.Timeout.DEFAULT_TIMEOUT, + retries=urllib3.Retry( + total=5, + backoff_factor=0.2, + status_forcelist=[500, 502, 503, 504], + ), + ), + ) + + ci_pipeline_id = args.pipeline_id or getenv('CI_PIPELINE_ID') # required + if args.action == 'download': + method = _download_files + ci_job_name = args.job_name # optional + ci_job_id = args.job_id # optional + else: + method = _upload_files # type: ignore + ci_job_name = args.job_name or getenv('CI_JOB_NAME') # required + ci_job_id = args.job_id or getenv('CI_JOB_ID') # required + + if args.type: + types = [ArtifactType(t) for t in args.type] + else: + types = list(ArtifactType) + + print(f'{"Pipeline ID":15}: {ci_pipeline_id}') + if ci_job_name: + print(f'{"Job name":15}: {ci_job_name}') + if ci_job_id: + print(f'{"Job ID":15}: {ci_job_id}') + + for _t in types: + method(ci_pipeline_id, artifact_type=_t, job_name=ci_job_name, job_id=ci_job_id) # type: ignore diff --git a/tools/ci/ci_get_mr_info.py b/tools/ci/ci_get_mr_info.py index c87e64b621..4df7a05ab3 100644 --- a/tools/ci/ci_get_mr_info.py +++ b/tools/ci/ci_get_mr_info.py @@ -3,7 +3,7 @@ # internal use only for CI # get latest MR information by source branch # -# SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # @@ -73,6 +73,16 @@ def get_mr_components(source_branch: str) -> t.List[str]: return list(components) +def get_target_in_tags(tags: str) -> str: + from idf_pytest.constants import TARGET_MARKERS + + for x in tags.split(','): + if x in TARGET_MARKERS: + return x + + raise RuntimeError(f'No target marker found in {tags}') + + def _print_list(_list: t.List[str], separator: str = '\n') -> None: print(separator.join(_list)) @@ -88,6 +98,8 @@ if __name__ == '__main__': actions.add_parser('files', parents=[common_args]) actions.add_parser('commits', parents=[common_args]) actions.add_parser('components', parents=[common_args]) + target = actions.add_parser('target_in_tags') + target.add_argument('tags', help='comma separated tags, e.g., esp32,generic') args = parser.parse_args() @@ -99,5 +111,7 @@ if __name__ == '__main__': _print_list([commit.id for commit in get_mr_commits(args.src_branch)]) elif args.action == 'components': _print_list(get_mr_components(args.src_branch)) + elif args.action == 'target_in_tags': + print(get_target_in_tags(args.tags)) else: raise NotImplementedError('not possible to get here') diff --git a/tools/ci/exclude_check_tools_files.txt b/tools/ci/exclude_check_tools_files.txt index e9521402f2..be2d0a1868 100644 --- a/tools/ci/exclude_check_tools_files.txt +++ b/tools/ci/exclude_check_tools_files.txt @@ -40,3 +40,4 @@ tools/templates/sample_component/include/main.h tools/templates/sample_component/main.c tools/ci/cleanup_ignore_lists.py tools/ci/idf_pytest/**/* +tools/ci/artifacts_handler.py diff --git a/tools/ci/utils.sh b/tools/ci/utils.sh index f860fef110..d49f5bda5b 100644 --- a/tools/ci/utils.sh +++ b/tools/ci/utils.sh @@ -49,6 +49,11 @@ function set_component_ut_vars() { echo "exported variables COMPONENT_UT_DIRS, COMPONENT_UT_EXCLUDES" } +function upload_artifacts_to_s3() { + # for detailed documents, please refer to .gitlab/ci/README.md#uploaddownload-artifacts-to-internal-minio-server + python tools/ci/artifacts_handler.py upload +} + function error() { printf "\033[0;31m%s\n\033[0m" "${1}" >&2 } diff --git a/tools/requirements/requirements.ci.txt b/tools/requirements/requirements.ci.txt index 615932b1ae..0e5c231133 100644 --- a/tools/requirements/requirements.ci.txt +++ b/tools/requirements/requirements.ci.txt @@ -10,3 +10,4 @@ python-gitlab pyyaml SimpleWebSocketServer pylint-gitlab +minio