stages:
  - build
  - unit_test
  - test
  - test_report
  - deploy

before_script:
  # 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

  # Set IS_PRIVATE or IS_PUBLIC depending on if our branch is public or not
  #
  # (the same regular expressions are used to set these are used in 'only:' sections below
  - source make/configure_ci_environment.sh

  # fetch all submodules
  - git submodule update --init --recursive

build_template_app:
  stage: build
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - build

  variables:
    IDF_PATH: "$CI_PROJECT_DIR"
    GIT_STRATEGY: clone
    BATCH_BUILD: "1"
    IDF_CI_BUILD: "1"

  script:
    - git clone https://github.com/espressif/esp-idf-template.git
    - cd esp-idf-template
    # Try to use the same branch name for esp-idf-template that we're
    # using on esp-idf. If it doesn't exist then just stick to the default
    # branch
    - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
    # Test debug build (default)
    - make all V=1
    # Now test release build
    - make clean
    - sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
    - make all V=1
    # Check if there are any stray printf/ets_printf references in WiFi libs
    - cd ../components/esp32/lib
    - test $(xtensa-esp32-elf-nm *.a | grep -w printf | wc -l) -eq 0
    - test $(xtensa-esp32-elf-nm *.a | grep -w ets_printf | wc -l) -eq 0


.build_template: &build_template
  stage: build
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - build

  variables:
    IDF_PATH: "$CI_PROJECT_DIR"
    GIT_STRATEGY: clone
    BATCH_BUILD: "1"
    V: "0"

build_ssc:
  <<: *build_template
  artifacts:
    paths:
      - ./SSC/ssc_bin
    expire_in: 6 mos

  script:
    - git clone $GITLAB_SSH_SERVER/yinling/SSC.git
    - cd SSC
    - git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..."
    - make defconfig
    - ./gen_misc_ng.sh

build_at:
  <<: *build_template
  script:
    - git clone $GITLAB_SSH_SERVER/application/esp-at.git
    - cd esp-at
    - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-at default branch..."
    - make defconfig
    - make

build_esp_idf_tests:
  <<: *build_template
  artifacts:
    paths:
      - ./tools/unit-test-app/build/*.bin
      - ./tools/unit-test-app/build/*.elf
      - ./tools/unit-test-app/build/*.map
      - ./tools/unit-test-app/build/bootloader/*.bin
      - ./components/idf_test/unit_test/TestCaseAll.yml
      - ./components/idf_test/unit_test/CIConfigs/*.yml
    expire_in: 6 mos

  script:
    - cd tools/unit-test-app
    - make TESTS_ALL=1
    - python tools/UnitTestParser.py

build_examples:
  <<: *build_template
  artifacts:
    paths:
      - build_examples/*/*/build/*.bin
      - build_examples/*/*/build/*.elf
      - build_examples/*/*/build/*.map
      - build_examples/*/*/build/bootloader/*.bin
    expire_in: 6 mos

  script:
    # it's not possible to build 100% out-of-tree and have the "artifacts"
    # mechanism work, but this is the next best thing
    - mkdir build_examples
    - cd build_examples
    - ${IDF_PATH}/make/build_examples.sh

build_docs:
  stage: build
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - build_docs
  script:
    - cd docs
    - doxygen
    # If not building master branch, and there are Doxygen warnings, print them and bail out
    - test -n $IS_PRIVATE && test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
    - make gh-linkcheck
    - make html
  artifacts:
    paths:
      - docs/_build/html
    expire_in: 1 mos

test_nvs_on_host:
  stage: test
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - nvs_host_test
  script:
    - cd components/nvs_flash/test_nvs_host
    - make test

test_wl_on_host:
  stage: test
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - wl_host_test
  artifacts:
    paths:
      - components/wear_levelling/test_wl_host/coverage_report.zip
  script:
    - cd components/wear_levelling/test_wl_host
    - make test

test_build_system:
  stage: test
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - build_test
  variables:
    IDF_PATH: "$CI_PROJECT_DIR"
  script:
    - ./make/test_configure_ci_environment.sh
    - ./make/test_build_system.sh

test_report:
  stage: test_report
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - report
  only:
    - master
    - triggers
    - /^release\/v/
    - /^v\d+\.\d+(\.\d+)?($|-)/
  variables:
    LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
    TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
    REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
    MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"
  artifacts:
    when: always
    paths:
      - $REPORT_PATH
      - $LOG_PATH
    expire_in: 12 mos
  script:
    # calc log path
    - VER_NUM=`git rev-list HEAD | wc -l | awk '{print $1}'`
    - SHA_ID=`echo $CI_BUILD_REF | cut -c 1-7`
    - REVISION="${VER_NUM}_${SHA_ID}"
    # replace / to _ in branch name
    - ESCAPED_BRANCH_NAME=`echo $CI_BUILD_REF_NAME | sed 's/\//___/g'`
    # result path and artifacts path
    - RESULT_PATH="$CI_PROJECT_NAME/$ESCAPED_BRANCH_NAME/$REVISION"
    - ARTIFACTS_PATH="$GITLAB_HTTP_SERVER/idf/esp-idf/builds/$CI_BUILD_ID/artifacts/browse/$CI_BUILD_REF"
    # clone test bench
    - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
    - cd auto_test_script
    # generate report
    - TEST_RESULT=Pass
    - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail
    # commit to CI-test-result project
    - git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
    - rm -rf CI-test-result/RawData/$RESULT_PATH
    - cp -R $CI_PROJECT_NAME CI-test-result/RawData
    - cd CI-test-result
    # config git user
    - git config --global user.email "ci-test-result@espressif.com"
    - git config --global user.name "ci-test-result"
    # commit test result
    - git add .
    - git commit . -m "update test result for $CI_PROJECT_NAME/$CI_BUILD_REF_NAME/$CI_BUILD_REF, pipeline ID $CI_PIPELINE_ID" || exit 0
    - git push origin master
    - test "${TEST_RESULT}" = "Pass" || exit 1

push_master_to_github:
  before_script:
    - echo "Not setting up GitLab key, not fetching submodules"
  stage: deploy
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - deploy
  only:
    - master
    - /^release\/v/
    - /^v\d+\.\d+(\.\d+)?($|-)/
  when: on_success
  variables:
    GIT_STRATEGY: clone
    GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master
  script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo -n $GH_PUSH_KEY > ~/.ssh/id_rsa_base64
    - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
    - git remote add github git@github.com:espressif/esp-idf.git
    # What the next line of script does: goes through the list of refs for all branches we push to github,
    # generates a snippet of shell which is evaluated. The snippet checks CI_BUILD_REF against the SHA
    # (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch
    # and then pushes that ref to a corresponding github branch
    #
    # NB: In gitlab 9.x, CI_BUILD_REF was deprecated. New name is CI_COMMIT_REF. If below command suddenly
    # generates bash syntax errors, this is probably why.
    - eval $(git for-each-ref --shell bash --format 'if [ $CI_BUILD_REF == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)


deploy_docs:
  before_script:
    - echo "Not setting up GitLab key, not fetching submodules"
  stage: deploy
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - deploy
  only:
   - master
   - /^release\/v/
   - /^v\d+\.\d+(\.\d+)?($|-)/
   - triggers
  script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64
    - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config
    - export GIT_VER=$(git describe --always)
    - cd docs/_build/
    - mv html $GIT_VER
    - tar czvf $GIT_VER.tar.gz $GIT_VER
    - scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH
    - ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"

check_doc_links:
  stage: test
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - check_doc_links
  only:
    # can only be triggered
    - triggers
  script:
    # must be triggered with CHECK_LINKS=Yes, otherwise exit without test
    - test "$CHECK_LINKS" = "Yes" || exit 0
    # can only run on master branch (otherwise the commit is not on Github yet)
    - test "${CI_BUILD_REF_NAME}" = "master" || exit 0
    - cd docs
    - make linkcheck
  artifacts:
    paths:
      - docs/_build/linkcheck
    expire_in: 1 mos

check_commit_msg:
  stage: deploy
  image: $CI_DOCKER_REGISTRY/esp32-ci-env
  tags:
    - build
  except:
    - master
    - /^release\/v/
    - /^v\d+\.\d+(\.\d+)?($|-)/
  before_script:
    - echo "skip update submodule"
  script:
    - git checkout ${CI_BUILD_REF_NAME}
    # commit start with "WIP: " need to be squashed before merge
    - 'git log --pretty=%s master..${CI_BUILD_REF_NAME} | grep "^WIP: " || exit 0 && exit 1'

# template for test jobs
.test_template: &test_template
  stage: test
  when: on_success
  only:
    - master
    - /^release\/v/
    - /^v\d+\.\d+(\.\d+)?($|-)/
    - triggers
  allow_failure: true

  variables:
    LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
    BIN_PATH: "$CI_PROJECT_DIR/SSC/ssc_bin/SSC"
    APP_NAME: "ssc"
    LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
    # append test level folder to TEST_CASE_FILE_PATH in before_script of test job
    TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test"
    # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
    MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"

  artifacts:
    when: always
    paths:
      - $LOG_PATH
    expire_in: 6 mos

  script:
    # remove artifacts from last stage (UT logs)
    - rm -rf $LOG_PATH
    # 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
    # clone local test env configs
    - git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
    # clone test bench
    - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
    - cd auto_test_script
    # run test
    - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH


# template for overnight test jobs
.test_template_night: &test_template_night
  <<: *test_template
  only:
    # can only be triggered
    - triggers
  script:
    # remove artifacts from last stage (UT logs)
    - rm -rf $LOG_PATH
    # must be night build triggers, otherwise exit without test
    - test $NIGHT_BUILD = "Yes" || exit 0
    # 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
    # clone local test env configs
    - git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
    # clone test bench
    - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
    - cd auto_test_script
    # run test
    - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH

# template for unit test jobs
.unit_test_template: &unit_test_template
  <<: *test_template
  allow_failure: false
  stage: unit_test

  variables:
    LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
    BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/"
    LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
    APP_NAME: "ut"
    TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
    MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"
  
  dependencies:
    - build_esp_idf_tests

UT_Function_SYS_01:
  <<: *unit_test_template
  tags:
    - ESP32_IDF
    - UT_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml

UT_Function_SYS_02:
  <<: *unit_test_template
  tags:
    - ESP32_IDF
    - UT_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_02.yml

IT_Function_SYS_01:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml

IT_Function_WIFI_01:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml

IT_Function_WIFI_02:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml

IT_Function_TCPIP_01:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml

IT_Function_TCPIP_02:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml

IT_Function_TCPIP_03:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml

IT_Function_TCPIP_04:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml

IT_Function_TCPIP_05:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml

IT_Stress_WIFI_01:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T5_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_WIFI_01.yml

IT_Stress_TCPIP_01:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_01.yml

IT_Stress_TCPIP_02:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_02.yml

IT_Stress_TCPIP_03:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_03.yml

IT_Stress_TCPIP_04:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_04.yml

IT_Stable_TCPIP_01:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T5_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_01.yml

IT_Stable_TCPIP_02:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_02.yml

IT_Stable_TCPIP_03:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T5_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_03.yml

IT_Function_TCPIP_06:
  <<: *test_template_night
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml

IT_Function_WIFI_03:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_APC
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml

IT_Function_WIFI_04:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T3_PhyMode
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml

IT_Function_WIFI_05:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_WEP
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml

IT_Function_WIFI_06:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T2_PhyMode
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml

IT_Function_TCPIP_07:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T1_2
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml

IT_Function_TCPIP_08:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T2_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml

IT_Function_TCPIP_09:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T1_2
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml

IT_Function_TCPIP_10:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
    - SSC_T1_2
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml

IT_Function_TCPIP_11:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml

IT_Function_TCPIP_12:
  <<: *test_template
  tags:
    - ESP32_IDF
    - SSC_T1_1
  before_script:
    - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml

