diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5ca57bbe1..7b34969fe 100755
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,9 +1,31 @@
 stages:
   - check
+  - build
+  - feature_test
   - deploy
 
+variables:
+  IDF_PATH: "$CI_PROJECT_DIR/esp-idf"
+  MAKEFLAGS:  "-j8"
+  ESPSIGMA_BRANCH: "master"
+  IDF_BRANCH: "master"
+  board: "esp32"
+
+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
+    
 check_lib_reversion:
   stage: check
+  only:
+      changes:
+          - esp32/lib{coexist,core,espnow,net80211,pp,smartconfig}.a
+          - esp32s2/lib{coexist,core,espnow,net80211,pp,smartconfig}.a
   except:
     - master
     - /^release\/v/
@@ -27,7 +49,6 @@ check_lib_reversion:
     - for dir in esp32 esp32s2; do if [ -e $dir/libwpa.a ]; then exit 1; fi; done;
     - for dir in esp32 esp32s2; do if [ -e $dir/libwpa2.a ]; then exit 1; fi; done;
 
-
 push_master_to_github:
   stage: deploy
   tags:
@@ -56,3 +77,7 @@ push_master_to_github:
     # 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)
+
+include:
+     - 'tools/ci/config/build.yml'
+     - 'tools/ci/config/feature_test.yml'
diff --git a/tools/ci/build_app.sh b/tools/ci/build_app.sh
new file mode 100644
index 000000000..b2bdbe8d4
--- /dev/null
+++ b/tools/ci/build_app.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This file is sourced in to the CI environment
+# in .gitlab-ci.yml file
+#
+
+set -x
+
+die() {
+    echo "${1:-"Unknown Error"}" 1>&2
+    exit 1
+}
+
+[ -z ${IDF_PATH} ] && die "IDF_PATH is not set."
+
+# Tool chain
+export PATH=/wifi_ci/xtensa-esp32-elf/bin:${PATH}
+
+# Sigma DUT
+echo Running make for espsigma dut app...
+cd ${CI_PROJECT_DIR}/espsigma/esp_sigma_dut
+make ${MAKEFLAGS} 
+
+# Copying binaries to create build tar ball
+cd $CI_PROJECT_DIR
+rm -rf ${board}-${CI_PIPELINE_ID}.debug
+mkdir -p ${board}-${CI_PIPELINE_ID}.debug/
+
+echo Creating ${board}-${VERSION} app binaries debug directory...
+cp ${CI_PROJECT_DIR}/espsigma/esp_sigma_dut/build/*.bin $board-${CI_PIPELINE_ID}.debug/ || { echo "Copy file Status: Failure"; exit 1; }
+cp ${CI_PROJECT_DIR}/espsigma/esp_sigma_dut/build/*.elf $board-${CI_PIPELINE_ID}.debug/ || { echo "Copy file Status: Failure"; exit 1; }
+cp ${CI_PROJECT_DIR}/espsigma/esp_sigma_dut/build/bootloader/bootloader.bin $board-${CI_PIPELINE_ID}.debug/ || { echo "Copy file Status: Failure"; exit 1; }
+
+# Creating tar file (debug)
+tar -zcvf $board-${CI_PIPELINE_ID}.debug.tar.gz $board-${CI_PIPELINE_ID}.debug || { echo "Create tar Status: Failure"; exit 1; }
diff --git a/tools/ci/config/build.yml b/tools/ci/config/build.yml
new file mode 100644
index 000000000..79df8105a
--- /dev/null
+++ b/tools/ci/config/build.yml
@@ -0,0 +1,32 @@
+build_espsigma:
+  stage: build
+  image: $CI_DOCKER_REGISTRY/esp32-ci-env
+  tags:
+     - wlan_feature
+
+  artifacts:
+    paths:
+     - ${board}-${CI_PIPELINE_ID}.debug.tar.gz
+    expire_in: 1 week
+  
+  only:
+    refs:
+     - triggers     
+   
+  script:
+    - rm -rf /tmp/esp_wifi_lib
+    - mkdir /tmp/esp_wifi_lib
+    - cp -rf * /tmp/esp_wifi_lib
+    - if git ls-remote ${GITLAB_SSH_SERVER}/idf/esp-idf.git | grep -sw ${CI_BUILD_REF_NAME} 2>&1>/dev/null; then IDF_BRANCH=${CI_BUILD_REF_NAME} ; fi
+    - if [[ "${BOT_CUSTOMIZED_REVISION}" ]] && [[ "$BOT_CUSTOMIZED_REVISION" == *"esp-idf"* ]]; then IDF_BRANCH=$(python -c 'import os;print eval(os.environ["BOT_CUSTOMIZED_REVISION"])["esp-idf"]') ; fi
+    - echo Cloning esp-idf - ${IDF_BRANCH} ...
+    - git clone --recursive --single-branch -b $IDF_BRANCH --dissociate ${GITLAB_SSH_SERVER}/idf/esp-idf.git     
+    - cd esp-idf
+    - wlan_lib_path=`grep -B 1 esp32-wifi-lib .gitmodules | grep path | cut -d' ' -f3`
+    - cd $CI_PROJECT_DIR
+    - rm -rf esp-idf/$wlan_lib_path/*
+    - cp -rf /tmp/esp_wifi_lib/* esp-idf/$wlan_lib_path/.
+    - if [[ "${BOT_CUSTOMIZED_REVISION}" ]] && [[ "$BOT_CUSTOMIZED_REVISION" == *"espsigma"* ]]; then ESPSIGMA_BRANCH=$(python -c 'import os;print eval(os.environ["BOT_CUSTOMIZED_REVISION"])["espsigma"]') ; fi
+    - echo Cloning espsigma - ${ESPSIGMA_BRANCH} ...
+    - git clone --recursive --single-branch -b $ESPSIGMA_BRANCH --dissociate ${GITLAB_SSH_SERVER}/espressif/espsigma.git
+    - sh tools/ci/build_app.sh
diff --git a/tools/ci/config/feature_test.yml b/tools/ci/config/feature_test.yml
new file mode 100644
index 000000000..16c69521c
--- /dev/null
+++ b/tools/ci/config/feature_test.yml
@@ -0,0 +1,25 @@
+PMF:
+  stage: feature_test
+  image: $CI_DOCKER_REGISTRY/esp32-ci-env
+  parallel: 5
+  tags:
+    - wlan_feature
+
+  artifacts:
+    paths:
+    - gitlabCI-${CI_PROJECT_NAME}-${CI_BUILD_ID}.tar.gz
+    
+    expire_in: 1 week
+    when: always
+  
+  only:
+    refs:       
+     - triggers     
+
+  script:
+     -  git clone ${GITLAB_SSH_SERVER}/app-frameworks/devops.git
+     -  tar -xzvf $board-${CI_PIPELINE_ID}.debug.tar.gz
+     -  python -u devops/automation/Runner.py wifi_pmf --id WIFI_PMF_${CI_NODE_INDEX} --build "$board-${CI_PIPELINE_ID}.debug"
+     -  tar -zcvf gitlabCI-${CI_PROJECT_NAME}-${CI_BUILD_ID}.tar.gz gitlabCI-${CI_PROJECT_NAME}-${CI_BUILD_ID}
+     -  exit "$(cat /tmp/gitlabCI-${CI_PROJECT_NAME}-${CI_BUILD_ID})"
+