stages:
    - check_typos
    - cleanup
    - docker_build
    - build
    - target_test
    - docs

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH

variables:
    ESP_MATTER_PATH: "$CI_PROJECT_DIR"
    BR_PATH: "$CI_PROJECT_DIR/esp-thread-br"
    ESP_RMAKER_PATH: "$CI_PROJECT_DIR/esp-rainmaker"
    IDF_GITHUB_ASSETS: "dl.espressif.com/github_assets"
    GIT_STRATEGY: fetch
    GIT_SUBMODULE_STRATEGY: none
    IDF_SKIP_CHECK_SUBMODULES: 1
    # This folder was on the runner host
    MATTER_CACHE_DIR: /cache/matter_build
    # This variable represents the latest idf version supported for the target branch.
    # Note: Do change this variable in case of idf version change MR.
    IDF_CHECKOUT_REF: "v5.4.1"
    # This variable represents the short hash of the connectedhomeip submodule.
    # Note: Do change this short hash on submodule update MRs.
    CHIP_SHORT_HASH: "cf84d0360c"
    DOCKER_IMAGE_NAME: "espressif/chip-idf"

.add_gitlab_ssh_key: &add_gitlab_ssh_key |
  mkdir -p ~/.ssh
  chmod 700 ~/.ssh
  echo -n $GITLAB_KEY >> ~/.ssh/id_rsa_base64
  base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
  chmod 600 ~/.ssh/id_rsa
  echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

.get_build_caches: &get_build_caches
  - |
    if [ -d ${MATTER_CACHE_DIR}/ ]; then
      echo "get matter_build cache ..."
      mkdir -p .git/modules/
      mkdir -p ~/.cache/pip/
      mkdir -p ~/.cipd-cache-dir/
      mkdir -p ~/.espressif/dist/
      time rsync -a ${MATTER_CACHE_DIR}/git_modules/ .git/modules/ || true
      time rsync -a ${MATTER_CACHE_DIR}/cache_pip/ ~/.cache/pip/ || true
      time rsync -a ${MATTER_CACHE_DIR}/cipd_cache_dir/ ~/.cipd-cache-dir/ || true
      time rsync -a ${MATTER_CACHE_DIR}/espressif_dist/ ~/.espressif/dist/ || true
    fi

.update_build_caches: &update_build_caches
  - |
    if [ -d ${MATTER_CACHE_DIR}/ ]; then
      echo "update matter_build cache ..."
      time rsync -a .git/modules/ ${MATTER_CACHE_DIR}/git_modules/ || true
      time rsync -a ~/.cache/pip/ ${MATTER_CACHE_DIR}/cache_pip/ || true
      time rsync -a ~/.cipd-cache-dir/ ${MATTER_CACHE_DIR}/cipd_cache_dir/ || true
      time rsync -a ~/.espressif/dist/ ${MATTER_CACHE_DIR}/espressif_dist/ || true
    fi

.setup_ot_rcp: &setup_ot_rcp
  - cd ${IDF_PATH}
  - ./install.sh
  - . ./export.sh
  # fetch submodules
  - export PYTHONPATH=${IDF_PATH}/tools/ci/python_packages/:${PYTHONPATH}
  - pip install python-gitlab
  - cd examples/openthread/ot_rcp
  - idf.py set-target esp32h2
  - idf.py build

.setup_idf: &setup_idf
  - source ${IDF_PATH}/export.sh
  - export PYTHONPATH=${IDF_PATH}/tools/ci/python_packages/:${PYTHONPATH}
  - pip install python-gitlab
  - cd ${IDF_PATH}

.setup_matter: &setup_matter
   - cd ${ESP_MATTER_PATH}
   - ./install.sh --no-host-tool --no-bootstrap
   - rm -rf connectedhomeip/connectedhomeip  # Remove submodule directory
   - ln -s ${CHIP_SUBMODULE_PATH} connectedhomeip/connectedhomeip  # Create symlink to specified CHIP_SUBMODULE_PATH
   - cd ${ESP_MATTER_PATH}
   - . ./export.sh

.setup_rainmaker: &setup_rainmaker
  - cd ${CI_PROJECT_DIR}
  - git clone --depth 1 --recurse-submodules --shallow-submodules https://github.com/espressif/esp-rainmaker.git
  - cd ${ESP_RMAKER_PATH}/examples/matter/

.build_matter_examples: &build_matter_examples
    - export MATTER_EXAMPLES_PATH=$ESP_MATTER_PATH/connectedhomeip/connectedhomeip/examples
    - cd $ESP_MATTER_PATH/connectedhomeip/connectedhomeip
    # Enter the Matter venv
    - source scripts/activate.sh
    - cd $MATTER_EXAMPLES_PATH/all-clusters-app/esp32
    - idf.py build
    - cd $MATTER_EXAMPLES_PATH/temperature-measurement-app/esp32
    - idf.py build
    - cd $MATTER_EXAMPLES_PATH/lock-app/esp32
    - idf.py build
    - cd $MATTER_EXAMPLES_PATH/pigweed-app/esp32
    - idf.py build
    # TODO:Remove persistent-storage example build because of the compilation errors of upstream repo

.build_external_platform_example: &build_external_platform_example
    - rm -rf ${ESP_MATTER_PATH}/../platform
    - mkdir -p ${ESP_MATTER_PATH}/../platform
    - cp -r ${CHIP_SUBMODULE_PATH}/src/platform/ESP32 $ESP_MATTER_PATH/../platform/ESP32_custom
    # We have modified the ESP32SecureCertDataProvider.h file to include the ESP32FactoryDataProvider.h
    # So copying all files from the external_platform directory.
    - cp ${ESP_MATTER_PATH}/examples/common/external_platform/* $ESP_MATTER_PATH/../platform/ESP32_custom/
    - cd ${ESP_MATTER_PATH}/examples/light
    - cp sdkconfig.defaults sdkconfig.defaults.backup
    - cp sdkconfig.defaults.ext_plat_ci sdkconfig.defaults
    - idf.py set-target esp32
    - idf.py build
    - cp sdkconfig.defaults.backup sdkconfig.defaults

.build_esp32c6_thread_example: &build_esp32c6_thread_example
    - cd $ESP_MATTER_PATH/examples/light
    - cp sdkconfig.defaults.esp32c6 sdkconfig.defaults.c6_backup
    - cp sdkconfig.defaults.c6_thread sdkconfig.defaults.esp32c6
    - idf.py set-target esp32c6
    - idf.py build
    - cp sdkconfig.defaults.c6_backup sdkconfig.defaults.esp32c6

.build_esp32c6_wifi_thread_example: &build_esp32c6_wifi_thread_example
    - cd $ESP_MATTER_PATH/examples/light
    - cp sdkconfig.defaults.esp32c6 sdkconfig.defaults.c6_backup
    - cp sdkconfig.defaults.c6_wifi_thread sdkconfig.defaults.esp32c6
    - idf.py set-target esp32c6
    - idf.py build
    - cp sdkconfig.defaults.c6_backup sdkconfig.defaults.esp32c6

.build_controller_otbr_example: &build_controller_otbr_example
    - cd $ESP_MATTER_PATH/examples/controller
    - idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.otbr" set-target esp32s3 build

.build_lit_icd_example: &build_lit_icd_example
    - cd $ESP_MATTER_PATH/examples/icd_app
    - idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.esp32c6.lit" set-target esp32c6 build

cancel_redundant_pipelines:
  stage: cleanup
  image: python:3.12-slim
  tags:
    - cancel-pipeline
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'
  script:
    - pip install --no-cache-dir requests
    - python tools/ci/cancel_pipelines.py

build_image:
  stage: docker_build
  image: espressif/dind:1
  tags:
    - amd64
    - dind
    - internet
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main"
  before_script:
    - mkdir -p $HOME/.docker
    - echo $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json
  script:
    - cd ${ESP_MATTER_PATH}
    - chip_head_commit=$(git rev-parse HEAD:connectedhomeip/connectedhomeip)
    - chip_head_in_readme=$(awk -F'[][]' '/commit \[.* of connectedhomeip/{print $2}' README.md)

    # Check both conditions and collect errors
    - validation_error=0
    - |
      if echo "$chip_head_commit" | grep -q "^${chip_head_in_readme}"; then
          echo "README.md is in sync with the connectedhomeip submodule"
      else
          echo "ERROR:Please update the README.md file with the latest commit hash of the connectedhomeip submodule"
          validation_error=1
      fi

    - |
      if echo "${chip_head_commit}" | grep -q "^${CHIP_SHORT_HASH}"; then
          echo "The CHIP_SHORT_HASH variable is set to correct value. Matches with current head commit"
      else
          echo "ERROR: The CHIP_SHORT_HASH seems to be incorrect or you have updated the submodule but not the CHIP_SHORT_HASH variable above"
          validation_error=1
      fi

    # Validate if we have the latest ZAP common and cluster select files
    # python3 is not installed in dind image, so we need to install it
    - apk add --no-cache python3
    # update the submodule to so that script runs based on that submodule
    - git submodule update --init --depth 1 connectedhomeip/connectedhomeip
    - python3 components/esp_matter/zap_common/generate_zap_common_files.py
    - python3 components/esp_matter/utils/cluster_select/generate_cluster_select_files.py
    - |
      if git diff --quiet components/esp_matter/zap_common; then
          echo "ZAP common files are up to date."
      else
          echo "ERROR: ZAP common files are not up to date."
          echo "       Please run ./components/esp_matter/zap_common/generate_zap_common_files.py and commit the changes."
          validation_error=1
      fi
    - |
      if git diff --quiet components/esp_matter/utils/cluster_select; then
          echo "Cluster select files are up to date."
      else
          echo "ERROR: Cluster select files are not up to date."
          echo "       Please run ./components/esp_matter/utils/cluster_select/generate_cluster_select_files.py and commit the changes."
          validation_error=1
      fi

    # Exit with collected error status
    - if [ $validation_error -ne 0 ]; then exit 1; fi

    - TAG="chip_${CHIP_SHORT_HASH}_idf_${IDF_VERSION}"
    - echo $TAG
    - |
      url="https://hub.docker.com/v2/repositories/${DOCKER_IMAGE_NAME}/tags/${TAG}"
      if wget -q --spider "$url"; then
          echo "No Differences detected. The docker image with ${TAG} is present in docker hub. Skipping docker build "
      else
          echo "Differences detected. The docker image with ${TAG} is not present on docker hub. Triggering docker build due to submdoule update or idf version change in CI."
          cd ${ESP_MATTER_PATH}/tools/docker/chip_idf
          docker build --build-arg CHIP_CHECKOUT_REF=${chip_head_commit} --build-arg IDF_CHECKOUT_REF=${IDF_VERSION} --tag ${DOCKER_IMAGE_NAME}:${TAG} .
          docker push ${DOCKER_IMAGE_NAME}:${TAG}
      fi
  parallel:
    matrix:
      # Change the idf version here in case of idf version change MR.
      - IDF_VERSION:
          - "v4.4.3"
          - "v5.4.1"

.build_examples_template:
  stage: build
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" ||  $CI_PIPELINE_SOURCE == "push" || $CI_COMMIT_BRANCH == "main"
  needs:
    - job: build_image
      optional: true
    - job: check_typos
  tags:
    - build
    # runner: `sudo mkdir -p /cache/matter_build/`
    # gitlab-runner config: `volumes = ["/cache:/cache:rw"]`
    - brew
  before_script:
    - *add_gitlab_ssh_key
    - *get_build_caches
    - *setup_idf
    - cd ${ESP_MATTER_PATH}
    - mkdir -p ${REPOS_PATH}
    - *setup_matter
    # update caches only when setup succeed
    - *update_build_caches
  variables:
    REPOS_PATH: "$CI_PROJECT_DIR/repos"
    IDF_CCACHE_ENABLE: 1


.build_managed_component_light_example:
  stage: build
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" ||  $CI_PIPELINE_SOURCE == "push" || $CI_COMMIT_BRANCH == "main"
  tags:
    - build
    - brew
  before_script:
    - *add_gitlab_ssh_key
    - *get_build_caches
    - *setup_idf
    - cd ${ESP_MATTER_PATH}
    - mkdir -p ${REPOS_PATH}
    - *update_build_caches
  variables:
    REPOS_PATH: "$CI_PROJECT_DIR/repos"
    IDF_CCACHE_ENABLE: 1

build_esp_matter_examples_pytest_C6:
  resource_group: build_esp_matter_examples_pytest_C6
  extends:
        - .build_examples_template
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.map"
      - "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 --pytest_c6

build_esp_matter_examples_pytest_H2:
  resource_group: build_esp_matter_examples_pytest_H2
  extends:
        - .build_examples_template
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.map"
      - "examples/**/build*/*.bin"
      - "examples/**/build*/flasher_args.json"
      - "examples/**/build*/config/sdkconfig.json"
      - "examples/**/build*/bootloader/*.bin"
      - "examples/**/build*/partition_table/*.bin"
      - "${IDF_PATH}/examples/openthread/ot_rcp/build/*.bin"
      - "${IDF_PATH}/examples/openthread/ot_rcp/build/partition_table/*.bin"
      - "${IDF_PATH}/examples/openthread/ot_rcp/build/bootloader/*.bin"
      - "${IDF_PATH}/examples/openthread/ot_rcp/build/config/sdkconfig.json"
      - "${IDF_PATH}/examples/openthread/ot_rcp/build/flasher_args.json"
    when: always
    expire_in: 15 days
  script:
    - *setup_ot_rcp
    - cd ${ESP_MATTER_PATH}/examples/thread_border_router
    - touch main/MatterProjConfig.h
    # Use different discriminators for TBR and light examples
    - echo "#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xE00" >> main/MatterProjConfig.h
    - echo "CONFIG_CHIP_PROJECT_CONFIG=\"main/MatterProjConfig.h\"" >> sdkconfig.defaults
    - cd ${ESP_MATTER_PATH}/examples/light
    - echo "CONFIG_ENABLE_MEMORY_PROFILING=y" >> sdkconfig.defaults
    - cd ${ESP_MATTER_PATH}
    - pip install -r tools/ci/requirements-build.txt
    - python tools/ci/build_apps.py ./examples --pytest_h2
    - |
      if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
        python tools/ci/memory_analyzer.py --chip esp32h2 --job_name "build_esp_matter_examples_pytest_H2" --ref_map_file light_mr_base.map --example "light"
      fi

build_esp_matter_examples_pytest_C2:
  resource_group: build_esp_matter_examples_pytest_C2
  extends:
        - .build_examples_template
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.map"
      - "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: 15 days
  script:
    - cd ${ESP_MATTER_PATH}/examples/light
    - echo "CONFIG_ENABLE_MEMORY_PROFILING=y" >> sdkconfig.defaults
    - cd ${ESP_MATTER_PATH}
    - pip install -r tools/ci/requirements-build.txt
    - echo "${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
    - python tools/ci/build_apps.py ./examples --pytest_c2
    - |
      if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
        python tools/ci/memory_analyzer.py --chip esp32c2 --job_name "build_esp_matter_examples_pytest_C2" --ref_map_file light_mr_base.map --example "light"
      fi


build_override_sdkconfig_examples:
  resource_group: build_override_sdkconfig_examples
  extends:
        - .build_examples_template
  script:
    - *build_external_platform_example
    - *build_esp32c6_thread_example
    - *build_esp32c6_wifi_thread_example
    - *build_controller_otbr_example
    - *build_lit_icd_example

build_zap_light_example:
  resource_group: build_zap_light_example
  extends:
        - .build_examples_template
  script:
    - cd ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip
    - source ./scripts/activate.sh

    - cd ${ESP_MATTER_PATH}/examples/zap_light
    - idf.py set-target esp32c3 build
    - idf.py set-target esp32h2 build

build_esp_matter_examples:
  resource_group: build_esp_matter_examples_${CI_NODE_INDEX}
  extends:
        - .build_examples_template
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.bin"
      - "examples/**/build*/*.map"
      - "examples/**/build*/flasher_args.json"
      - "examples/**/build*/config/sdkconfig.json"
      - "examples/**/build*/bootloader/*.bin"
      - "examples/**/build*/partition_table/*.bin"
    when: always
    expire_in: 15 days
  script:
     # mfg_test_app needs an secure boot signing key, generating one here
    - cd ${ESP_MATTER_PATH}/examples/mfg_test_app
    - openssl genrsa -out secure_boot_signing_key.pem 3072

    - cd ${ESP_MATTER_PATH}/examples/light
    - echo "CONFIG_ENABLE_MEMORY_PROFILING=y" >> sdkconfig.defaults

    # steps for external platform build for blemesh_bridge app
    - cd ${ESP_MATTER_PATH}/examples/bridge_apps/blemesh_bridge
    - cp sdkconfig.defaults sdkconfig.defaults.backup
    - cp sdkconfig.defaults.ext_plat_ci sdkconfig.defaults

    - cd ${ESP_MATTER_PATH}
    - pip install -r tools/ci/requirements-build.txt
    - python tools/ci/build_apps.py ./examples --no_pytest
      --parallel-count ${CI_NODE_TOTAL:-1}
      --parallel-index ${CI_NODE_INDEX:-1}
    - |
      if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ] && [ "${CI_NODE_INDEX:-1}" -eq 2 ]; then
        python tools/ci/memory_analyzer.py --chip esp32c3 --job_name "build_esp_matter_examples 2/2" --ref_map_file light_mr_base.map --example "light"
      fi
  parallel: 2

build_nopytest_remaining_examples_manual:
  resource_group: build_nopytest_remaining_examples_manual_${CI_NODE_INDEX}
  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
  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_idf_v4_4:
  resource_group: build_esp_matter_examples_idf_v4_4
  extends:
        - .build_examples_template
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  allow_failure: true
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.map"
      - "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}
    # idf v4.4 requires jinja < 3.1 so lets install the dependencies for idf v4.4
    - pip install -r requirements_idf_v4.4.txt
    # hack the construct==2.10.54 to make it work with idf-v4.4, Python3.12
    # imp is not present in Python3.12 so remove it
    - wget https://files.pythonhosted.org/packages/30/2f/e2e6bad1b80f744cf5c2a6d622e3dee698b43e6c040f980ae0ac0edd5e54/construct-2.10.54.tar.gz
    - tar -xvzf construct-2.10.54.tar.gz
    - sed -i 's/, imp$//g' construct-2.10.54/construct/core.py
    - python3 -m pip install ./construct-2.10.54
    - rm -rf construct-2.10.54*
    - cd ${ESP_MATTER_PATH}/examples/light
    - idf.py set-target esp32c3
    - idf.py build
  variables:
    IDF_CHECKOUT_REF: "v4.4.3"


build_esp_matter_examples_pytest_C3:
  resource_group: build_esp_matter_examples_pytest_C3
  extends:
        - .build_examples_template
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  artifacts:
    paths:
      - "examples/**/build*/size.json"
      - "examples/**/build*/build_log.txt"
      - "examples/**/build*/*.map"
      - "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 --pytest_c3


pytest_esp32c3_esp_matter_dut:
  stage: target_test
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
  needs:
    - build_esp_matter_examples_pytest_C3
  script:
    - cd ${ESP_MATTER_PATH}
    - rm -rf connectedhomeip/connectedhomeip
    - ln -s ${CHIP_SUBMODULE_PATH} connectedhomeip/connectedhomeip
    - pip install -r tools/ci/requirements-pytest.txt
    - pytest examples/ --target esp32c3 -m esp_matter_dut --junitxml=XUNIT_RESULT.xml
  tags: ["esp32c3", "esp_matter_dut"]

pytest_esp32c6_esp_matter_dut:
  stage: target_test
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event' ||  $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
  needs:
    - build_esp_matter_examples_pytest_C6
  script:
    - cd ${ESP_MATTER_PATH}
    - rm -rf connectedhomeip/connectedhomeip
    - ln -s ${CHIP_SUBMODULE_PATH} connectedhomeip/connectedhomeip
    - cd connectedhomeip/connectedhomeip
    - source out/py-env/bin/activate
    - cd ${ESP_MATTER_PATH}
    - cp ${ESP_MATTER_PATH}/tools/ci/extended_color_light_wifi_pics_code.txt $ESP_MATTER_PATH/connectedhomeip/connectedhomeip/src/python_testing/
    - pip install -r tools/ci/requirements-pytest.txt
    - python3 -c "import os; os.environ['TEST_CHUNK'] = '$TEST_CHUNK'"
    - pytest examples/ --target esp32c6 -m esp_matter_dut --junitxml=XUNIT_RESULT.xml --certification-json=$ESP_MATTER_PATH/tools/ci/certification_test_commands.json
  tags: ["esp32c6", "esp_matter_dut"]
  parallel:
    matrix:
      - TEST_CHUNK:
          - "1"
          - "2"

pytest_esp32c2_esp_matter_dut:
  stage: target_test
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event' ||  $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
  needs:
    - build_esp_matter_examples_pytest_C2
  script:
    - cd ${ESP_MATTER_PATH}
    - rm -rf connectedhomeip/connectedhomeip
    - ln -s ${CHIP_SUBMODULE_PATH} connectedhomeip/connectedhomeip
    - pip install -r tools/ci/requirements-pytest.txt
    - pytest examples/ --target esp32c2 -m esp_matter_dut --junitxml=XUNIT_RESULT.xml --baud 74880 | tee pytest_c2.log
    - |
      if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
        python tools/ci/memory_analyzer.py --log_file pytest_c2.log --chip esp32c2 --example "light"
      fi
  tags: ["esp32c2", "esp_matter_dut"]

pytest_esp32h2_esp_matter_dut:
  stage: target_test
  image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
  needs:
    - build_esp_matter_examples_pytest_H2
  script:
    - cd ${ESP_MATTER_PATH}
    - rm -rf connectedhomeip/connectedhomeip
    - ln -s ${CHIP_SUBMODULE_PATH} connectedhomeip/connectedhomeip
    - pip install -r tools/ci/requirements-pytest.txt
    - pytest examples/ --target esp32h2 -m esp_matter_dut --junitxml=XUNIT_RESULT.xml | tee pytest_h2.log
    - |
      if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then
        python tools/ci/memory_analyzer.py --log_file pytest_h2.log --chip esp32h2 --example "light"
      fi
  tags: ["esp32h2", "esp_matter_dut"]

build_upstream_examples:
    resource_group: build_upstream_examples
    extends:
        - .build_examples_template
    when: manual
    script:
        - *build_matter_examples

build_managed_component_light:
    resource_group: build_managed_component_light
    extends:
        - .build_managed_component_light_example
    needs:
      - job: build_image
        optional: true
      - job: check_typos
    script:
        - cd ${ESP_MATTER_PATH}/examples/managed_component_light
        - idf.py set-target esp32c3
        - idf.py build

# This job is allowed to fail due to a circular dependency with esp-rainmaker.
build_esp_rainmaker_apps:
    resource_group: build_esp_rainmaker_apps
    stage: build
    image: ${DOCKER_IMAGE_NAME}:chip_${CHIP_SHORT_HASH}_idf_${IDF_CHECKOUT_REF}
    # Allow failures to avoid circular dependency with any breaking changes in the Esp-Matter SDK.
    allow_failure: true

    tags:
      - build

    needs:
      - job: build_image
        optional: true
      - job: check_typos

    artifacts:
        paths:
            - ${ESP_RMAKER_PATH}/examples/matter/*/*build/*.bin
        when: always
        expire_in: 1 week

    before_script:
      - *setup_idf
      - *setup_matter
      - *setup_rainmaker
    script:
        - cd ${ESP_RMAKER_PATH}/examples/matter/matter_light
        - idf.py set-target esp32c3 build

        - cd ${ESP_RMAKER_PATH}/examples/matter/matter_switch
        # Flash overflows on esp32c6, few optimizations
        - echo "CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=2" >> sdkconfig.defaults.esp32c6
        - echo "CONFIG_NEWLIB_NANO_FORMAT=y" >> sdkconfig.defaults.esp32c6
        - echo "CONFIG_ENABLE_CHIP_SHELL=n" >> sdkconfig.defaults.esp32c6
        - idf.py set-target esp32c6 build

        # just build controller example
        - cd ${ESP_RMAKER_PATH}/examples/matter/matter_controller
        - idf.py set-target esp32s3 build
        - rm -rf sdkconfig

        # build controller with TBR support
        # thread lib changed the default number of ipv6 addresses to 12 so match that in the controller example
        - echo "CONFIG_LWIP_IPV6_NUM_ADDRESSES=12" >> sdkconfig.defaults.otbr
        - idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.otbr" -B ot_br_build set-target esp32s3 build

build_docs:
    stage: build
    image: $CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.5:3-1
    rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
    tags:
        - build
    needs:
      - job: check_typos
    variables:
        ESP_DOCS_LATEST_BRANCH_NAME: "main"
    artifacts:
        when: always
        paths:
            - docs/_build/*/*/*.txt
            - docs/_build/*/*/html/*
            - docs/_build/*/*/latex/*
        expire_in: 1 days
    script:
        - cd docs
        - pip install -r requirements.txt
        - build-docs -bs html latex -t esp32 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2 esp32p4 esp32c5 esp32c61 -l en
        # disable link checks for now, as it is failing due to some links taking longer time to respond
        # - build-docs -t esp32 -l en linkcheck

.deploy_docs_template:
    stage: docs
    image: $CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.5:3-1
    tags:
        - docs
    needs:
        - build_docs
    variables:
        ESP_DOCS_LATEST_BRANCH_NAME: "main"
    script:
        - source ${CI_PROJECT_DIR}/docs/utils.sh
        - add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
        - export GIT_VER=$(git describe --always)
        - pip install -r ${CI_PROJECT_DIR}/docs/requirements.txt
        - deploy-docs

deploy_docs_preview:
    extends:
        - .deploy_docs_template
    rules:
      - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "push"
    variables:
        TYPE: "preview"
        DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/"
        DOCS_DEPLOY_PRIVATEKEY: "$DOCS_PREVIEW_DEPLOY_KEY"
        DOCS_DEPLOY_SERVER: "$DOCS_PREVIEW_SERVER"
        DOCS_DEPLOY_SERVER_USER: "$DOCS_PREVIEW_SERVER_USER"
        DOCS_DEPLOY_PATH: "$DOCS_PREVIEW_PATH"
        DOCS_DEPLOY_URL_BASE: "https://$DOCS_PREVIEW_SERVER_URL/$DOCS_PREVIEW_PATH"

deploy_docs_production:
    extends:
        - .deploy_docs_template
    only:
      refs:
        - main
        - /^release\/v.*$/
    variables:
        TYPE: "preview"
        DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/"
        DOCS_DEPLOY_PRIVATEKEY: "$DOCS_PROD_DEPLOY_KEY"
        DOCS_DEPLOY_SERVER: "$DOCS_PROD_SERVER"
        DOCS_DEPLOY_SERVER_USER: "$DOCS_PROD_SERVER_USER"
        DOCS_DEPLOY_PATH: "$DOCS_PROD_PATH"
        DOCS_DEPLOY_URL_BASE: "https://$DOCS_PROD_SERVER/$DOCS_PROD_PATH"

check_typos:
  image: $CI_DOCKER_REGISTRY/esp-env-v6.0:1
  stage: check_typos
  script:
    - pip install codespell
    - git fetch origin main
    - |
      FILES=$(git diff --name-only origin/main...HEAD)
      echo "change files: $FILES"
      if [ -n "$FILES" ]; then
        ./tools/check_typos.sh $FILES
      fi
  tags:
    - build
