Move to CircleCI for Builds and Tests (#631)

* Initial CircleCI

* Restyled by shellharden

* Restyled by shfmt

* Appeasing our restyle.io overlord

* testing

* Trying to figure out this run_if.sh problem

* Feedback from Rob W

* Restyled by shfmt

* Typo

* Updating restyled to match editorconfig tab spacing

* Updating devcontainer

* Restyled by shfmt

* Adding simple restyle merge

* Restyled by shellharden

Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/.circleci/.gitattributes b/.circleci/.gitattributes
new file mode 100644
index 0000000..2dd06ee
--- /dev/null
+++ b/.circleci/.gitattributes
@@ -0,0 +1 @@
+config.yml linguist-generated
diff --git a/.circleci/.gitignore b/.circleci/.gitignore
new file mode 100644
index 0000000..3018b3a
--- /dev/null
+++ b/.circleci/.gitignore
@@ -0,0 +1 @@
+.tmp/
diff --git a/.circleci/Makefile b/.circleci/Makefile
new file mode 100644
index 0000000..c47f94d
--- /dev/null
+++ b/.circleci/Makefile
@@ -0,0 +1,95 @@
+# Set SHELL to 'strict mode' without using .SHELLFLAGS for max compatibility.
+# See https://fieldnotes.tech/how-to-shell-for-compatible-makefiles/
+SHELL := /usr/bin/env bash -euo pipefail -c
+
+# CONFIG is the name of the make target someone
+# would invoke to update the main config file (config.yml).
+CONFIG ?= ci-config
+# VERIFY is the name of the make target someone
+# would invoke to verify the config file.
+VERIFY ?= ci-verify
+
+CIRCLECI := circleci --skip-update-check
+ifeq ($(DEBUG_CIRCLECI_CLI),YES)
+CIRCLECI += --debug
+endif
+
+# For config processing, always refer to circleci.com not self-hosted circleci,
+# because self-hosted does not currently support the necessary API.
+CIRCLECI_CLI_HOST := https://circleci.com
+export CIRCLECI_CLI_HOST
+
+# Set up some documentation/help message variables.
+# We do not attempt to install the CircleCI CLI from this Makefile.
+CCI_INSTALL_LINK := https://circleci.com/docs/2.0/local-cli/\#installation
+CCI_INSTALL_MSG := Please install CircleCI CLI. See $(CCI_INSTALL_LINK)
+CCI_VERSION := $(shell $(CIRCLECI) version 2> /dev/null)
+ifeq ($(CCI_VERSION),)
+# Attempting to use the CLI fails with installation instructions.
+CIRCLECI := echo '$(CCI_INSTALL_MSG)'; exit 1; \#
+endif
+
+SOURCE_DIR     := config
+SOURCE_YML     := $(shell [ ! -d $(SOURCE_DIR) ] || find $(SOURCE_DIR) -name '*.yml')
+CONFIG_SOURCE  := Makefile $(SOURCE_YML) | $(SOURCE_DIR)
+OUT            := config.yml
+TMP            := .tmp/config-processed
+CONFIG_PACKED  := .tmp/config-packed
+
+default: help
+
+help:
+	@echo "Usage:"
+	@echo "  make $(CONFIG): recompile config.yml from $(SOURCE_DIR)/"
+	@echo "  make $(VERIFY): verify that config.yml is a true mapping from $(SOURCE_DIR)/"
+	@echo
+	@echo "Diagnostics:"
+	@[ -z "$(CCI_VERSION)" ] || echo "  circleci-cli version $(CCI_VERSION)"
+	@[ -n "$(CCI_VERSION)" ] || echo "  $(CCI_INSTALL_MSG)"
+
+$(SOURCE_DIR):
+	@echo No source directory $(SOURCE_DIR) found.; exit 1
+
+# Make sure our .tmp dir exists.
+$(shell [ -d .tmp ] || mkdir .tmp)
+
+.PHONY: $(CONFIG)
+$(CONFIG): $(OUT)
+
+.PHONY: $(VERIFY)
+$(VERIFY): config-up-to-date
+	@$(CIRCLECI) config validate $(OUT)
+
+define GENERATED_FILE_HEADER
+### ***
+### WARNING: DO NOT manually EDIT or MERGE this file, it is generated by 'make $(CONFIG)'.
+### INSTEAD: Edit or merge the source in $(SOURCE_DIR)/ then run 'make $(CONFIG)'.
+### ***
+endef
+export GENERATED_FILE_HEADER
+
+# GEN_CONFIG writes the config to a temporary file. If the whole process succeeds,
+# it them moves that file to $@. This makes it an atomic operation, so if it fails
+# make doesn't consider a half-baked file up to date.
+define GEN_CONFIG
+	@$(CIRCLECI) config pack $(SOURCE_DIR) > $(CONFIG_PACKED)
+	@echo "$$GENERATED_FILE_HEADER" > $@.tmp || { rm -f $@; exit 1; }
+	@$(CIRCLECI) config process $(CONFIG_PACKED) >> $@.tmp || { rm -f $@.tmp; exit 1; }
+	@mv -f $@.tmp $@
+endef
+
+$(OUT): $(CONFIG_SOURCE) 
+	$(GEN_CONFIG)
+	@echo "$@ updated"
+
+$(TMP): $(CONFIG_SOURCE) 
+	$(GEN_CONFIG)
+
+.PHONY: config-up-to-date
+config-up-to-date: $(TMP) # Note this must not depend on $(OUT)!
+	@if diff -w $(OUT) $<; then \
+		echo "Generated $(OUT) is up to date!"; \
+	else \
+		echo "Generated $(OUT) is out of date, run make $(CONFIG) to update."; \
+		exit 1; \
+	fi
diff --git a/.circleci/README.md b/.circleci/README.md
new file mode 100644
index 0000000..1ec75ca
--- /dev/null
+++ b/.circleci/README.md
@@ -0,0 +1,130 @@
+# How to use CircleCI multi-file config
+
+This README and the Makefile should be in your `.circleci` directory,
+in the root of your repository.
+All path references in this README assume we are in this `.circleci` directory.
+
+The `Makefile` in this directory generates `./config.yml` in CircleCI 2.0 syntax,
+from the tree rooted at `./config/`, which contains files in CircleCI 2.0 or 2.1 syntax.
+
+
+## Quickstart
+
+The basic workflow is:
+
+- Edit source files in `./config/`
+- When you are done, run `make ci-config` to update `./config.yml`
+- Commit this entire `.circleci` directory, including that generated file together.
+- Run `make ci-verify` to ensure the current `./config.yml` is up to date with the source.
+
+When merging this `.circleci` directory:
+
+- Do not merge the generated `./config.yml` file, instead:
+- Merge the source files under `./config/`, and then
+- Run `make ci-config` to re-generate the merged `./config.yml`
+
+And that's it, for more detail, read on!
+
+
+## How does it work, roughly?
+
+CircleCI supports [generating a single config file from many],
+using the `$ circleci config pack` command.
+It also supports [expanding 2.1 syntax to 2.0 syntax]
+using the `$ circleci config process` command.
+We use these two commands, stitched together using the `Makefile`
+to implement the workflow.
+
+[generating a single config file from many]: https://circleci.com/docs/2.0/local-cli/#packing-a-config
+[expanding 2.1 syntax to 2.0 syntax]: https://circleci.com/docs/2.0/local-cli/#processing-a-config
+
+
+## Prerequisites
+
+You will need the [CircleCI CLI tool] installed and working,
+at least version `0.1.5607`.
+You can [download this tool directly from GitHub Releases].
+
+```
+$ circleci version
+0.1.5607+f705856
+```
+
+[CircleCI CLI tool]: https://circleci.com/docs/2.0/local-cli/
+[download this tool directly from GitHub Releases]: https://github.com/CircleCI-Public/circleci-cli/releases
+
+
+## Updating the config source
+
+Before making changes, be sure to understand the layout
+of the `./config/` file tree, as well as circleci 2.1 syntax.
+See the [Syntax and layout] section below.
+
+To update the config, you should edit, add or remove files
+in the `./config/` directory,
+and then run `make ci-config`.
+If that's successful,
+you should then commit every `*.yml` file in the tree rooted in this directory.
+That is: you should commit both the source under `./config/`
+and the generated file `./config.yml` at the same time, in the same commit.
+The included git pre-commit hook will help with this.
+Do not edit the `./config.yml` file directly, as you will lose your changes
+next time `make ci-config` is run.
+
+[Syntax and layout]: #syntax-and-layout
+
+
+### Verifying `./config.yml`
+
+To check whether or not the current `./config.yml` is up to date with the source
+and valid, run `$ make ci-verify`.
+Note that `$ make ci-verify` should be run in CI,
+in case not everyone has the git pre-commit hook set up correctly.
+
+
+#### Example shell session
+
+```sh
+$ make ci-config
+config.yml updated 
+$ git add -A . # The -A makes sure to include deletions/renames etc.
+$ git commit -m "ci: blah blah blah"
+Changes detected in .circleci/, running 'make -C .circleci ci-verify'
+--> Generated config.yml is up to date!
+--> Config file at config.yml is valid.
+```
+
+
+### Syntax and layout
+
+It is important to understand the layout of the config directory.
+Read the documentation on [packing a config] for a full understanding
+of how multiple YAML files are merged by the circleci CLI tool.
+
+[packing a config]: https://circleci.com/docs/2.0/local-cli/#packing-a-config
+
+Here is an example file tree (with comments added afterwards):
+
+```sh
+$ tree . 
+.
+├── Makefile
+├── README.md # This file.
+├── config    # The source code for config.yml is rooted here.
+│   ├── @config.yml # Files beginning with @ are treated specially by `circleci config pack`
+│   ├── commands    # Subdirectories of config become top-level keys.
+│   │   └── go_test.yml  # Filenames (minus .yml) become top-level keys under
+│   │   └── go_build.yml # their parent (in this case "commands").
+│   │                    # The contents of go_test.yml therefore are placed at: .commands.go_test:
+│   └── jobs             # jobs also becomes a top-level key under config...
+│       ├── build.yml    # ...and likewise filenames become keys under their parent.
+│       └── test.yml
+└── config.yml # The generated file in 2.0 syntax.
+```
+
+About those `@` files... Preceding a filename with `@`
+indicates to `$ circleci config pack` that the contents of this YAML file
+should be at the top-level, rather than underneath a key named after their filename.
+This naming convention is unfortunate as it breaks autocompletion in bash,
+but there we go.
+
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..fe10785
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,518 @@
+### ***
+### WARNING: DO NOT manually EDIT or MERGE this file, it is generated by 'make ci-config'.
+### INSTEAD: Edit or merge the source in config/ then run 'make ci-config'.
+### ***
+version: 2
+jobs:
+  Run Tests [docker-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: docker-build
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-docker-build-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-docker-build-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/tools/run_if.sh "mbedtls-build" "$BUILD_TYPE" scripts/tests/mbedtls_tests.sh
+        name: Run mbedTLS Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build mbedtls-build" "$BUILD_TYPE" scripts/tests/crypto_tests.sh
+        name: Run Crypto Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build ubuntu-16-lts" "$BUILD_TYPE" scripts/tests/setup_payload_tests.sh
+        name: Run Setup Payload Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/openssl_tests.sh
+        name: OpenSSL Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/all_tests.sh
+        name: Run All Unit & Functional Tests
+  Run Tests [mbedtls-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: mbedtls-build
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-mbedtls-build-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-mbedtls-build-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/tools/run_if.sh "mbedtls-build" "$BUILD_TYPE" scripts/tests/mbedtls_tests.sh
+        name: Run mbedTLS Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build mbedtls-build" "$BUILD_TYPE" scripts/tests/crypto_tests.sh
+        name: Run Crypto Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build ubuntu-16-lts" "$BUILD_TYPE" scripts/tests/setup_payload_tests.sh
+        name: Run Setup Payload Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/openssl_tests.sh
+        name: OpenSSL Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/all_tests.sh
+        name: Run All Unit & Functional Tests
+  Build Examples [nRF]:
+    docker:
+    - image: connectedhomeip/chip-build-nrf-platform:0.2.11
+    environment:
+    - BUILD_TYPE: nrf-build
+    steps:
+    - checkout
+    - run:
+        command: scripts/examples/nrf_lock_app.sh
+        name: Build example nRF5 Lock App
+  Deploy [docker-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: docker-build
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-docker-build-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-docker-build-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/build/distribution_check.sh
+        name: Deployment Check
+  Code Coverage [docker-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: docker-build
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-docker-build-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-docker-build-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/tools/codecoverage.sh
+        name: Run Code Coverage
+    - run:
+        command: bash <(curl -s https://codecov.io/bash)
+        name: Upload Code Coverage
+  Build CHIP [mbedtls-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: mbedtls-build
+    steps:
+    - checkout
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/build/bootstrap.sh
+        name: Bootstrap
+    - save_cache:
+        key: bootstrapped-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-mbedtls-build-built
+        paths:
+        - .
+    - run:
+        command: scripts/build/default.sh
+        name: Build
+    - save_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-mbedtls-build-built
+        paths:
+        - .
+    - save_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-mbedtls-build-built
+        paths:
+        - build/downloads
+  Build CHIP [ubuntu-16-lts]:
+    machine:
+      image: ubuntu-1604:202004-01
+    environment:
+    - BUILD_TYPE: ubuntu-16-lts
+    steps:
+    - checkout
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/build/bootstrap.sh
+        name: Bootstrap
+    - save_cache:
+        key: bootstrapped-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-ubuntu-16-lts-built
+        paths:
+        - .
+    - run:
+        command: scripts/build/default.sh
+        name: Build
+    - save_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-ubuntu-16-lts-built
+        paths:
+        - .
+    - save_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-ubuntu-16-lts-built
+        paths:
+        - build/downloads
+  Build Examples [ESP32]:
+    docker:
+    - image: connectedhomeip/chip-build-esp32:0.2.11
+    environment:
+    - BUILD_TYPE: esp32-build
+    steps:
+    - checkout
+    - run:
+        command: scripts/examples/esp_echo_app.sh
+        name: Build example Echo App
+  Deploy [mbedtls-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: mbedtls-build
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-mbedtls-build-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-mbedtls-build-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/build/distribution_check.sh
+        name: Deployment Check
+  Run Tests [ubuntu-16-lts]:
+    machine:
+      image: ubuntu-1604:202004-01
+    environment:
+    - BUILD_TYPE: ubuntu-16-lts
+    steps:
+    - restore_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-ubuntu-16-lts-built
+    - restore_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-ubuntu-16-lts-built
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/tools/run_if.sh "mbedtls-build" "$BUILD_TYPE" scripts/tests/mbedtls_tests.sh
+        name: Run mbedTLS Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build mbedtls-build" "$BUILD_TYPE" scripts/tests/crypto_tests.sh
+        name: Run Crypto Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build ubuntu-16-lts" "$BUILD_TYPE" scripts/tests/setup_payload_tests.sh
+        name: Run Setup Payload Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/openssl_tests.sh
+        name: OpenSSL Tests
+    - run:
+        command: scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE" scripts/tests/all_tests.sh
+        name: Run All Unit & Functional Tests
+  Build CHIP [docker-build]:
+    docker:
+    - image: connectedhomeip/chip-build:0.2.11
+    environment:
+    - BUILD_TYPE: docker-build
+    steps:
+    - checkout
+    - run:
+        command: scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo scripts/setup/linux/install_packages.sh
+        name: Setup Environment
+    - run:
+        command: scripts/build/bootstrap.sh
+        name: Bootstrap
+    - save_cache:
+        key: bootstrapped-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-docker-build-built
+        paths:
+        - .
+    - run:
+        command: scripts/build/default.sh
+        name: Build
+    - save_cache:
+        key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-docker-build-built
+        paths:
+        - .
+    - save_cache:
+        key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1 }}-docker-build-built
+        paths:
+        - build/downloads
+workflows:
+  Main:
+    jobs:
+    - Build CHIP [docker-build]
+    - Build CHIP [mbedtls-build]
+    - Build CHIP [ubuntu-16-lts]
+    - Run Tests [docker-build]:
+        requires:
+        - Build CHIP [docker-build]
+    - Run Tests [mbedtls-build]:
+        requires:
+        - Build CHIP [mbedtls-build]
+    - Run Tests [ubuntu-16-lts]:
+        requires:
+        - Build CHIP [ubuntu-16-lts]
+    - Code Coverage [docker-build]:
+        requires:
+        - Build CHIP [docker-build]
+    - Deploy [docker-build]:
+        requires:
+        - Run Tests [docker-build]
+    - Deploy [mbedtls-build]:
+        requires:
+        - Run Tests [mbedtls-build]
+    - Build Examples [nRF]
+    - Build Examples [ESP32]
+  version: 2
+
+# Original config.yml file:
+# commands:
+#   bootstrap:
+#     description: Bootstrap the source tree
+#     steps:
+#     - run:
+#         command: scripts/build/bootstrap.sh
+#         name: Bootstrap
+#   load-bootstrapped-tree:
+#     description: Load the bootstrapped tree
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - restore_cache:
+#         key: bootstrapped-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1
+#           }}-<< parameters.builder>>-built
+#   load-build-environment:
+#     description: Load the build environment
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - restore_cache:
+#         key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1
+#           }}-<< parameters.builder>>-built
+#   load-built-tree:
+#     description: Load the built tree
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - restore_cache:
+#         key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-<< parameters.builder>>-built
+#   save-bootstrapped-tree:
+#     description: Save the bootstrapped tree
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - save_cache:
+#         key: bootstrapped-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1
+#           }}-<< parameters.builder>>-built
+#         paths:
+#         - .
+#   save-build-environment:
+#     description: Save the build environment
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - save_cache:
+#         key: build-environment-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1
+#           }}-<< parameters.builder>>-built
+#         paths:
+#         - build/downloads
+#   save-built-tree:
+#     description: Save the built tree
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - save_cache:
+#         key: built-tree-{{ arch }}-{{ .Branch}}-{{.Environment.CIRCLE_SHA1}}-<< parameters.builder>>-built
+#         paths:
+#         - .
+#   setup-environment:
+#     description: Setup Environment
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - run:
+#         command: scripts/tools/run_if.sh \"ubuntu-16-lts\" \"$BUILD_TYPE\" sudo scripts/setup/linux/install_packages.sh
+#         name: Setup Environment
+# executors:
+#   docker-build:
+#     docker:
+#     - image: connectedhomeip/chip-build:0.2.11
+#   esp32-build:
+#     docker:
+#     - image: connectedhomeip/chip-build-esp32:0.2.11
+#   mbedtls-build:
+#     docker:
+#     - image: connectedhomeip/chip-build:0.2.11
+#   nrf-build:
+#     docker:
+#     - image: connectedhomeip/chip-build-nrf-platform:0.2.11
+#   ubuntu-16-lts:
+#     machine:
+#       image: ubuntu-1604:202004-01
+# jobs:
+#   build:
+#     environment:
+#       BUILD_TYPE: << parameters.builder >>
+#     executor: << parameters.builder >>
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - checkout
+#     - setup-environment:
+#         builder: << parameters.builder >>
+#     - bootstrap
+#     - save-bootstrapped-tree:
+#         builder: << parameters.builder >>
+#     - run:
+#         command: scripts/build/default.sh
+#         name: Build
+#     - save-built-tree:
+#         builder: << parameters.builder >>
+#     - save-build-environment:
+#         builder: << parameters.builder >>
+#   code-coverage:
+#     environment:
+#       BUILD_TYPE: << parameters.builder >>
+#     executor: << parameters.builder >>
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - load-built-tree:
+#         builder: << parameters.builder >>
+#     - load-build-environment:
+#         builder: << parameters.builder >>
+#     - setup-environment:
+#         builder: << parameters.builder >>
+#     - run:
+#         command: scripts/tools/codecoverage.sh
+#         name: Run Code Coverage
+#     - run:
+#         command: bash <(curl -s https://codecov.io/bash)
+#         name: Upload Code Coverage
+#   deploy:
+#     environment:
+#       BUILD_TYPE: << parameters.builder >>
+#     executor: << parameters.builder >>
+#     parameters:
+#       builder:
+#         type: string
+#     steps:
+#     - load-built-tree:
+#         builder: << parameters.builder >>
+#     - load-build-environment:
+#         builder: << parameters.builder >>
+#     - setup-environment:
+#         builder: << parameters.builder >>
+#     - run:
+#         command: scripts/build/distribution_check.sh
+#         name: Deployment Check
+#   examples_esp32:
+#     environment:
+#       BUILD_TYPE: esp32-build
+#     executor: esp32-build
+#     steps:
+#     - checkout
+#     - run:
+#         command: scripts/examples/esp_echo_app.sh
+#         name: Build example Echo App
+#   examples_nrf:
+#     environment:
+#       BUILD_TYPE: nrf-build
+#     executor: nrf-build
+#     steps:
+#     - checkout
+#     - run:
+#         command: scripts/examples/nrf_lock_app.sh
+#         name: Build example nRF5 Lock App
+#   test:
+#     environment:
+#       BUILD_TYPE: << parameters.builder >>
+#     executor: << parameters.builder >>
+#     parameters:
+#       builder:
+#         type: string
+#       run_setup_payload_tests:
+#         default: true
+#         type: boolean
+#     steps:
+#     - load-built-tree:
+#         builder: << parameters.builder >>
+#     - load-build-environment:
+#         builder: << parameters.builder >>
+#     - setup-environment:
+#         builder: << parameters.builder >>
+#     - run:
+#         command: scripts/tools/run_if.sh \"mbedtls-build\" \"$BUILD_TYPE\" scripts/tests/mbedtls_tests.sh
+#         name: Run mbedTLS Tests
+#     - run:
+#         command: scripts/tools/run_if.sh \"docker-build mbedtls-build\" \"$BUILD_TYPE\"
+#           scripts/tests/crypto_tests.sh
+#         name: Run Crypto Tests
+#     - run:
+#         command: scripts/tools/run_if.sh \"docker-build ubuntu-16-lts\" \"$BUILD_TYPE\"
+#           scripts/tests/setup_payload_tests.sh
+#         name: Run Setup Payload Tests
+#     - run:
+#         command: scripts/tools/run_if.sh \"docker-build\" \"$BUILD_TYPE\" scripts/tests/openssl_tests.sh
+#         name: OpenSSL Tests
+#     - run:
+#         command: scripts/tools/run_if.sh \"docker-build\" \"$BUILD_TYPE\" scripts/tests/all_tests.sh
+#         name: Run All Unit & Functional Tests
+# version: 2.1
+# workflows:
+#   Main:
+#     jobs:
+#     - build:
+#         matrix:
+#           parameters:
+#             builder:
+#             - docker-build
+#             - mbedtls-build
+#             - ubuntu-16-lts
+#         name: Build CHIP [<< matrix.builder >>]
+#     - test:
+#         matrix:
+#           parameters:
+#             builder:
+#             - docker-build
+#             - mbedtls-build
+#             - ubuntu-16-lts
+#         name: Run Tests [<< matrix.builder >>]
+#         requires:
+#         - Build CHIP [<< matrix.builder >>]
+#     - code-coverage:
+#         matrix:
+#           parameters:
+#             builder:
+#             - docker-build
+#         name: Code Coverage [<< matrix.builder >>]
+#         requires:
+#         - Build CHIP [<< matrix.builder >>]
+#     - deploy:
+#         matrix:
+#           parameters:
+#             builder:
+#             - docker-build
+#             - mbedtls-build
+#         name: Deploy [<< matrix.builder >>]
+#         requires:
+#         - Run Tests [<< matrix.builder >>]
+#     - examples_nrf:
+#         name: Build Examples [nRF]
+#     - examples_esp32:
+#         name: Build Examples [ESP32]
\ No newline at end of file
diff --git a/.circleci/config/@config.yml b/.circleci/config/@config.yml
new file mode 100644
index 0000000..3879be9
--- /dev/null
+++ b/.circleci/config/@config.yml
@@ -0,0 +1 @@
+version: 2.1
diff --git a/.circleci/config/commands/@commands.yml b/.circleci/config/commands/@commands.yml
new file mode 100644
index 0000000..cab9607
--- /dev/null
+++ b/.circleci/config/commands/@commands.yml
@@ -0,0 +1,89 @@
+bootstrap:
+    description: Bootstrap the source tree
+    steps:
+        - run:
+              command: scripts/build/bootstrap.sh
+              name: Bootstrap
+save-build-environment:
+    description: Save the build environment
+    parameters:
+        builder:
+            type: string
+    steps:
+        - save_cache:
+              key:
+                  build-environment-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1 }}-<<
+                  parameters.builder>>-built
+              paths:
+                  - build/downloads
+save-bootstrapped-tree:
+    description: Save the bootstrapped tree
+    parameters:
+        builder:
+            type: string
+    steps:
+        - save_cache:
+              key:
+                  bootstrapped-tree-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1 }}-<<
+                  parameters.builder>>-built
+              paths:
+                  - .
+load-bootstrapped-tree:
+    description: Load the bootstrapped tree
+    parameters:
+        builder:
+            type: string
+    steps:
+        - restore_cache:
+              key:
+                  bootstrapped-tree-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1 }}-<<
+                  parameters.builder>>-built
+save-built-tree:
+    description: Save the built tree
+    parameters:
+        builder:
+            type: string
+    steps:
+        - save_cache:
+              key:
+                  built-tree-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1}}-<<
+                  parameters.builder>>-built
+              paths:
+                  - .
+load-build-environment:
+    description: Load the build environment
+    parameters:
+        builder:
+            type: string
+    steps:
+        - restore_cache:
+              key:
+                  build-environment-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1 }}-<<
+                  parameters.builder>>-built
+load-built-tree:
+    description: Load the built tree
+    parameters:
+        builder:
+            type: string
+    steps:
+        - restore_cache:
+              key:
+                  built-tree-{{ arch }}-{{
+                  .Branch}}-{{.Environment.CIRCLE_SHA1}}-<<
+                  parameters.builder>>-built
+setup-environment:
+    description: Setup Environment
+    parameters:
+        builder:
+            type: string
+    steps:
+        - run:
+              name: Setup Environment
+              command:
+                  scripts/tools/run_if.sh "ubuntu-16-lts" "$BUILD_TYPE" sudo
+                  scripts/setup/linux/install_packages.sh
diff --git a/.circleci/config/executors/@executors.yml b/.circleci/config/executors/@executors.yml
new file mode 100644
index 0000000..38c1b67
--- /dev/null
+++ b/.circleci/config/executors/@executors.yml
@@ -0,0 +1,15 @@
+docker-build:
+    docker:
+        - image: connectedhomeip/chip-build:0.2.11
+nrf-build:
+    docker:
+        - image: connectedhomeip/chip-build-nrf-platform:0.2.11
+esp32-build:
+    docker:
+        - image: connectedhomeip/chip-build-esp32:0.2.11
+mbedtls-build:
+    docker:
+        - image: connectedhomeip/chip-build:0.2.11
+ubuntu-16-lts:
+    machine:
+        image: ubuntu-1604:202004-01
diff --git a/.circleci/config/jobs/build.yml b/.circleci/config/jobs/build.yml
new file mode 100644
index 0000000..d073155
--- /dev/null
+++ b/.circleci/config/jobs/build.yml
@@ -0,0 +1,20 @@
+parameters:
+    builder:
+        type: string
+environment:
+    BUILD_TYPE: "<< parameters.builder >>"
+executor: << parameters.builder >>
+steps:
+    - checkout
+    - setup-environment:
+          builder: << parameters.builder >>
+    - bootstrap
+    - save-bootstrapped-tree:
+          builder: << parameters.builder >>
+    - run:
+          name: Build
+          command: scripts/build/default.sh
+    - save-built-tree:
+          builder: << parameters.builder >>
+    - save-build-environment:
+          builder: << parameters.builder >>
diff --git a/.circleci/config/jobs/code-coverage.yml b/.circleci/config/jobs/code-coverage.yml
new file mode 100644
index 0000000..0d66a8f
--- /dev/null
+++ b/.circleci/config/jobs/code-coverage.yml
@@ -0,0 +1,19 @@
+parameters:
+    builder:
+        type: string
+environment:
+    BUILD_TYPE: << parameters.builder >>
+executor: << parameters.builder >>
+steps:
+    - load-built-tree:
+          builder: << parameters.builder >>
+    - load-build-environment:
+          builder: << parameters.builder >>
+    - setup-environment:
+          builder: << parameters.builder >>
+    - run:
+          name: Run Code Coverage
+          command: scripts/tools/codecoverage.sh
+    - run:
+          name: Upload Code Coverage
+          command: bash <(curl -s https://codecov.io/bash)
diff --git a/.circleci/config/jobs/deploy.yml b/.circleci/config/jobs/deploy.yml
new file mode 100644
index 0000000..3fd1c33
--- /dev/null
+++ b/.circleci/config/jobs/deploy.yml
@@ -0,0 +1,16 @@
+parameters:
+    builder:
+        type: string
+environment:
+    BUILD_TYPE: << parameters.builder >>
+executor: << parameters.builder >>
+steps:
+    - load-built-tree:
+          builder: << parameters.builder >>
+    - load-build-environment:
+          builder: << parameters.builder >>
+    - setup-environment:
+          builder: << parameters.builder >>
+    - run:
+          name: Deployment Check
+          command: scripts/build/distribution_check.sh
diff --git a/.circleci/config/jobs/examples_esp32.yml b/.circleci/config/jobs/examples_esp32.yml
new file mode 100644
index 0000000..798530e
--- /dev/null
+++ b/.circleci/config/jobs/examples_esp32.yml
@@ -0,0 +1,8 @@
+environment:
+    BUILD_TYPE: esp32-build
+executor: esp32-build
+steps:
+    - checkout
+    - run:
+          name: Build example Echo App
+          command: scripts/examples/esp_echo_app.sh
diff --git a/.circleci/config/jobs/examples_nrf.yml b/.circleci/config/jobs/examples_nrf.yml
new file mode 100644
index 0000000..4c30ad8
--- /dev/null
+++ b/.circleci/config/jobs/examples_nrf.yml
@@ -0,0 +1,8 @@
+environment:
+    BUILD_TYPE: nrf-build
+executor: nrf-build
+steps:
+    - checkout
+    - run:
+          name: Build example nRF5 Lock App
+          command: scripts/examples/nrf_lock_app.sh
diff --git a/.circleci/config/jobs/test.yml b/.circleci/config/jobs/test.yml
new file mode 100644
index 0000000..3110093
--- /dev/null
+++ b/.circleci/config/jobs/test.yml
@@ -0,0 +1,41 @@
+parameters:
+    builder:
+        type: string
+    run_setup_payload_tests:
+        type: boolean
+        default: true
+environment:
+    BUILD_TYPE: << parameters.builder >>
+executor: << parameters.builder >>
+steps:
+    - load-built-tree:
+          builder: << parameters.builder >>
+    - load-build-environment:
+          builder: << parameters.builder >>
+    - setup-environment:
+          builder: << parameters.builder >>
+    - run:
+          name: Run mbedTLS Tests
+          command:
+              scripts/tools/run_if.sh "mbedtls-build" "$BUILD_TYPE"
+              scripts/tests/mbedtls_tests.sh
+    - run:
+          name: Run Crypto Tests
+          command:
+              scripts/tools/run_if.sh "docker-build mbedtls-build" "$BUILD_TYPE"
+              scripts/tests/crypto_tests.sh
+    - run:
+          name: Run Setup Payload Tests
+          command:
+              scripts/tools/run_if.sh "docker-build ubuntu-16-lts" "$BUILD_TYPE"
+              scripts/tests/setup_payload_tests.sh
+    - run:
+          name: OpenSSL Tests
+          command:
+              scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE"
+              scripts/tests/openssl_tests.sh
+    - run:
+          name: Run All Unit & Functional Tests
+          command:
+              scripts/tools/run_if.sh "docker-build" "$BUILD_TYPE"
+              scripts/tests/all_tests.sh
diff --git a/.circleci/config/workflows/Main.yml b/.circleci/config/workflows/Main.yml
new file mode 100644
index 0000000..d203f5b
--- /dev/null
+++ b/.circleci/config/workflows/Main.yml
@@ -0,0 +1,31 @@
+jobs:
+    - build:
+          name: Build CHIP [<< matrix.builder >>]
+          matrix:
+              parameters:
+                  builder: ["docker-build", "mbedtls-build", "ubuntu-16-lts"]
+    - test:
+          name: Run Tests [<< matrix.builder >>]
+          matrix:
+              parameters:
+                  builder: ["docker-build", "mbedtls-build", "ubuntu-16-lts"]
+          requires:
+              - Build CHIP [<< matrix.builder >>]
+    - code-coverage:
+          name: Code Coverage [<< matrix.builder >>]
+          matrix:
+              parameters:
+                  builder: ["docker-build"]
+          requires:
+              - Build CHIP [<< matrix.builder >>]
+    - deploy:
+          name: Deploy [<< matrix.builder >>]
+          matrix:
+              parameters:
+                  builder: ["docker-build", "mbedtls-build"]
+          requires:
+              - Run Tests [<< matrix.builder >>]
+    - examples_nrf:
+          name: Build Examples [nRF]
+    - examples_esp32:
+          name: Build Examples [ESP32]
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 1724c65..6c53cbf 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,7 +1,7 @@
 ARG BUILD_VERSION
 
 # All tools required for compilation belong in chip-build, forms "truth" for CHIP build tooling
-FROM connectedhomeip/chip-build:${BUILD_VERSION}
+FROM connectedhomeip/chip-build-vscode:${BUILD_VERSION}
 
 # This Dockerfile contains things useful for an interactive development environment
 ARG USERNAME=vscode
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 8e48a17..30e7a2e 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,12 +1,14 @@
 {
     "name": "CHIP Ubuntu Development Environment",
     "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
-    "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
+    "mounts": [
+        "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
+    ],
     "build": {
         "dockerfile": "Dockerfile",
         "args": {
             //  "BUILD_VERSION": "$(cat integrations/docker/images/chip-build/version)" // trying to get this to work
-            "BUILD_VERSION": "0.2.10"
+            "BUILD_VERSION": "0.2.11"
         }
     },
     "remoteUser": "vscode",
@@ -22,7 +24,10 @@
         "aaron-bond.better-comments",
         "foxundermoon.shell-format",
         "editorconfig.editorconfig",
-        "esbenp.prettier-vscode"
+        "esbenp.prettier-vscode",
+        "redhat.vscode-yaml",
+        "christian-kohler.path-intellisense",
+        "knisterpeter.vscode-github"
     ],
     // Use 'settings' to set *default* container specific settings.json values on container create.
     // You can edit these settings after create using File > Preferences > Settings > Remote.
diff --git a/.gitignore b/.gitignore
index 34b1d93..fafa826 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,9 @@
 # Example specific rules
 examples/**/sdkconfig
 
+# Temporary Directories
+.tmp/
+
 # Xcode
 *.pbxuser
 *.mode1v3
diff --git a/.restyled.yaml b/.restyled.yaml
index 54af825..f232635 100644
--- a/.restyled.yaml
+++ b/.restyled.yaml
@@ -100,6 +100,16 @@
     - name: shfmt
       image: restyled/restyler-shfmt:v3.0.1
       enabled: true
+      command:
+          - shfmt
+          - "-w"
+      arguments:
+          - "-i"
+          - "4"
+          - "-ci"
+      interpreters:
+          - sh
+          - bash
       include:
           - "**/*.sh"
           - "**/*.bash"
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index de8fd13..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-language: minimal
-
-branches:
-    except:
-        - /^restyled.*$/
-
-services:
-    - docker
-
-script:
-    - ./integrations/ci-tools/travis.sh
-
-# Note: To add new job types, add it to the matrix below, with a unique
-#  TASK varable, then update travis.sh to do what you want during that task
-
-jobs:
-    include:
-        - stage: Build
-          name: "Build Ubuntu Linux Xenial LTS"
-          env: TASK="build-ubuntu-linux"
-        - stage: Build
-          name: "Build NRF Example Lock App"
-          env: TASK="build-nrf-example-lock-app"
-        - stage: Build
-          name: "Build ESP32 Echo Example"
-          env: TASK="build-esp-example-echo-app"
-        - stage: Tests
-          name: "Unit & Functional Tests"
-          env: TASK="run-unit-and-functional-tests"
-        - stage: Tests
-          name: "Crypto Tests"
-          env: TASK="run-crypto-tests"
-        - stage: Tests
-          name: "Setup Payload Tests"
-          env: TASK="run-setup-payload-tests"
-        - stage: Tests
-          name: "mbedTLS Crypto Tests"
-          env: TASK="run-mbedtls-crypto-tests"
-        - stage: Deployment Checks
-          name: "Run Code Coverage"
-          env: ENV=CODECOV_TOKEN TASK="run-code-coverage"
-        - stage: Deployment Checks
-          name: "Distribution Check"
-          env: TASK="build-distribution-check"
diff --git a/examples/lock-app/nrf5/start-gdb.sh b/examples/lock-app/nrf5/start-gdb.sh
index 8dd43b5..fe6e67e 100755
--- a/examples/lock-app/nrf5/start-gdb.sh
+++ b/examples/lock-app/nrf5/start-gdb.sh
@@ -7,16 +7,16 @@
 STARTUP_CMDS=$SCRIPT_ROOT/gdb-startup-cmds.txt
 
 if [[ $# -eq 0 ]]; then
-  APP=$DEFAULT_APP
+    APP=$DEFAULT_APP
 else
-  APP=$1
+    APP=$1
 fi
 
 EXTRA_STARTUP_CMDS=()
 if [[ -n $OPENTHREAD_ROOT ]]; then
-  EXTRA_STARTUP_CMDS+=(
-    "set substitute-path /build/KNGP-TOLL1-JOB1/openthread/examples/.. $OPENTHREAD_ROOT"
-  )
+    EXTRA_STARTUP_CMDS+=(
+        "set substitute-path /build/KNGP-TOLL1-JOB1/openthread/examples/.. $OPENTHREAD_ROOT"
+    )
 fi
 
 exec "$GDB" -q -x "$STARTUP_CMDS" "${EXTRA_STARTUP_CMDS[@]/#/-ex=}" "$APP"
diff --git a/examples/lock-app/nrf5/start-jlink-gdb-server.sh b/examples/lock-app/nrf5/start-jlink-gdb-server.sh
index 67255df..ba38ca9 100755
--- a/examples/lock-app/nrf5/start-jlink-gdb-server.sh
+++ b/examples/lock-app/nrf5/start-jlink-gdb-server.sh
@@ -5,14 +5,14 @@
 RTT_PORT=19021
 
 command -v "$JLINK_GDB_SERVER" || {
-  echo "ERROR: $JLINK_GDB_SERVER not found"
-  echo "Please install SEGGER J-Link software package"
-  exit 1
+    echo "ERROR: $JLINK_GDB_SERVER not found"
+    echo "Please install SEGGER J-Link software package"
+    exit 1
 }
 
 command -v nc || {
-  echo "ERROR: nc command not found"
-  exit 1
+    echo "ERROR: nc command not found"
+    exit 1
 }
 
 # Launch JLink GDB Server in background; redirect output thru sed to add prefix.
@@ -22,20 +22,20 @@
 # Repeatedly open a connection to the GDB server's RTT port until
 # the user kills the GDB server with an interrupt character.
 while true; do
-  # Wait for GDB server to begin listening on RTT port
-  while ! lsof -nP -i4TCP:"$RTT_PORT" -sTCP:LISTEN >/dev/null; do
-    # Quit if the GDB server exits.
-    if ! kill -0 "$GDB_SERVER_PID" >/dev/null 2>&1; then
-      echo ""
-      exit
-    fi
+    # Wait for GDB server to begin listening on RTT port
+    while ! lsof -nP -i4TCP:"$RTT_PORT" -sTCP:LISTEN >/dev/null; do
+        # Quit if the GDB server exits.
+        if ! kill -0 "$GDB_SERVER_PID" >/dev/null 2>&1; then
+            echo ""
+            exit
+        fi
 
-    # Wait a bit.
-    sleep 0.1
+        # Wait a bit.
+        sleep 0.1
 
-  done
+    done
 
-  # Connect to RTT port.
-  nc localhost "$RTT_PORT"
+    # Connect to RTT port.
+    nc localhost "$RTT_PORT"
 
 done
diff --git a/examples/wifi-echo/esp32/idf.sh b/examples/wifi-echo/esp32/idf.sh
index 301e3c5..b72c266 100644
--- a/examples/wifi-echo/esp32/idf.sh
+++ b/examples/wifi-echo/esp32/idf.sh
@@ -22,14 +22,14 @@
 # This file can also be used as an executable
 me=${0##*/}
 die() {
-  echo "$me: *** ERROR: " "${*}"
-  exit 1
+    echo "$me: *** ERROR: " "${*}"
+    exit 1
 }
 idf() {
-  [[ -d $IDF_PATH && -r $IDF_PATH/export.sh ]] || die "can't find IDF's export.sh"
-  . "$IDF_PATH/export.sh"
-  "$@"
+    [[ -d $IDF_PATH && -r $IDF_PATH/export.sh ]] || die "can't find IDF's export.sh"
+    . "$IDF_PATH/export.sh"
+    "$@"
 }
 if [[ ${0} == ${BASH_SOURCE[0]} ]]; then
-  idf "${@}"
+    idf "${@}"
 fi
diff --git a/examples/wifi-echo/esp32/third_party/connectedhomeip b/examples/wifi-echo/esp32/third_party/connectedhomeip
index 20fa3af..11a54ed 120000
--- a/examples/wifi-echo/esp32/third_party/connectedhomeip
+++ b/examples/wifi-echo/esp32/third_party/connectedhomeip
@@ -1 +1 @@
-../../../../../connectedhomeip/
\ No newline at end of file
+../../../../
\ No newline at end of file
diff --git a/integrations/ci-tools/travis.sh b/integrations/ci-tools/travis.sh
index 5f734aa..8ed2d45 100755
--- a/integrations/ci-tools/travis.sh
+++ b/integrations/ci-tools/travis.sh
@@ -17,19 +17,19 @@
 here=$(cd "$(dirname "$0")" && pwd)
 
 die() {
-  echo "$me: *** ERROR: " "${*}"
-  exit 1
+    echo "$me: *** ERROR: " "${*}"
+    exit 1
 }
 
 # move to ToT, I don't work anywhere else
 cd "$here/../.." || die 'ack!, where am I?!?'
 
 docker_run_command() {
-  integrations/docker/images/"${IMAGE:-chip-build}"/run.sh "${ENV[@]}" -- "$@"
+    integrations/docker/images/"${IMAGE:-chip-build}"/run.sh "${ENV[@]}" -- "$@"
 }
 
 docker_run_bash_command() {
-  docker_run_command bash -c "$1"
+    docker_run_command bash -c "$1"
 }
 
 # convert ENV to an array of words: X,Y,Z => ( X Y Z )
@@ -39,63 +39,63 @@
 
 case "$TASK" in
 
-  self-test)
-    docker_run_bash_command 'echo looks ok to me && echo compound commands look good'
-    ;;
+    self-test)
+        docker_run_bash_command 'echo looks ok to me && echo compound commands look good'
+        ;;
 
-  self-test-env)
-    docker_run_command bash -c "echo run me with ENV=HI=THERE,; env | echo HI=$'$'HI"
-    ;;
+    self-test-env)
+        docker_run_command bash -c "echo run me with ENV=HI=THERE,; env | echo HI=$'$'HI"
+        ;;
 
-  # You can add more tasks here, the top one shows an example of running
-  #  a build inside our build container
-  build-ubuntu-linux)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/build/default.sh'
-    ;;
+    # You can add more tasks here, the top one shows an example of running
+    #  a build inside our build container
+    build-ubuntu-linux)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/build/default.sh'
+        ;;
 
-  build-nrf-example-lock-app)
-    docker_run_command 'scripts/examples/nrf_lock_app.sh'
-    ;;
+    build-nrf-example-lock-app)
+        docker_run_command 'scripts/examples/nrf_lock_app.sh'
+        ;;
 
-  build-esp-example-echo-app)
-    docker_run_command 'scripts/examples/esp_echo_app.sh'
-    ;;
+    build-esp-example-echo-app)
+        docker_run_command 'scripts/examples/esp_echo_app.sh'
+        ;;
 
-  build-distribution-check)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/build/distribution_check.sh'
-    ;;
+    build-distribution-check)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/build/distribution_check.sh'
+        ;;
 
-  run-unit-and-functional-tests)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/tests/all_tests.sh'
-    ;;
+    run-unit-and-functional-tests)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/tests/all_tests.sh'
+        ;;
 
-  run-code-coverage)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/tools/codecoverage.sh'
-    docker_run_bash_command 'bash <(curl -s https://codecov.io/bash)'
-    ;;
+    run-code-coverage)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/tools/codecoverage.sh'
+        docker_run_bash_command 'bash <(curl -s https://codecov.io/bash)'
+        ;;
 
-  run-crypto-tests)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/tests/crypto_tests.sh'
-    ;;
+    run-crypto-tests)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/tests/crypto_tests.sh'
+        ;;
 
-  run-setup-payload-tests)
-    docker_run_command 'scripts/build/bootstrap.sh'
-    docker_run_command 'scripts/tests/setup_payload_tests.sh'
-    ;;
+    run-setup-payload-tests)
+        docker_run_command 'scripts/build/bootstrap.sh'
+        docker_run_command 'scripts/tests/setup_payload_tests.sh'
+        ;;
 
-  run-mbedtls-crypto-tests)
-    docker_run_command 'scripts/build/bootstrap_mbedtls.sh'
-    docker_run_command 'scripts/tests/mbedtls_tests.sh'
-    docker_run_command 'scripts/tests/crypto_tests.sh'
-    ;;
+    run-mbedtls-crypto-tests)
+        docker_run_command 'scripts/build/bootstrap_mbedtls.sh'
+        docker_run_command 'scripts/tests/mbedtls_tests.sh'
+        docker_run_command 'scripts/tests/crypto_tests.sh'
+        ;;
 
-  *)
-    die "Unknown task: $TASK."
-    ;;
+    *)
+        die "Unknown task: $TASK."
+        ;;
 
 esac
diff --git a/integrations/docker/build.sh b/integrations/docker/build.sh
index 7b56fd9..275f25a 100755
--- a/integrations/docker/build.sh
+++ b/integrations/docker/build.sh
@@ -18,8 +18,8 @@
 VERSION=${DOCKER_BUILD_VERSION:-$(cat version)}
 
 [[ ${*/--help//} != "${*}" ]] && {
-  set +x
-  echo "Usage: $me <OPTIONS>
+    set +x
+    echo "Usage: $me <OPTIONS>
 
   Build and (optionally tag as latest, push) a docker image from Dockerfile in CWD
 
@@ -29,29 +29,52 @@
    --help     get this message
 
 "
-  exit 0
+    exit 0
 }
 
 die() {
-  echo "$me: *** ERROR: $*"
-  exit 1
+    echo "$me: *** ERROR: $*"
+    exit 1
 }
 
 set -ex
 
 [[ -n $VERSION ]] || die "version cannot be empty"
 
-docker build -t "$ORG/$IMAGE:$VERSION" .
+BUILD_ARGS=""
+if [[ ${*/--no-cache//} != "${*}" ]]; then
+    BUILD_ARGS+=" --no-cache "
+fi
+
+docker build "$BUILD_ARGS" -t "$ORG/$IMAGE:$VERSION" .
 
 [[ ${*/--latest//} != "${*}" ]] && {
-  docker tag "$ORG"/"$IMAGE":"$VERSION" "$ORG"/"$IMAGE":latest
+    docker tag "$ORG"/"$IMAGE":"$VERSION" "$ORG"/"$IMAGE":latest
 }
 
 [[ ${*/--push//} != "${*}" ]] && {
-  docker push "$ORG"/"$IMAGE":"$VERSION"
-  [[ ${*/--latest//} != "${*}" ]] && {
-    docker push "$ORG"/"$IMAGE":latest
-  }
+    docker push "$ORG"/"$IMAGE":"$VERSION"
+    [[ ${*/--latest//} != "${*}" ]] && {
+        docker push "$ORG"/"$IMAGE":latest
+    }
 }
 
+for filename in ./variants/*; do
+    echo "Variant Filename: $filename"
+    VARIANT=${filename##*.}
+    docker build "$BUILD_ARGS" -f "$filename" --build-arg VERSION="$VERSION" -t "$ORG/$IMAGE-$VARIANT:$VERSION" ./variants/
+
+    [[ ${*/--latest//} != "${*}" ]] && {
+        docker tag "$ORG"/"$IMAGE-$VARIANT":"$VERSION" "$ORG"/"$IMAGE-$VARIANT":latest
+    }
+
+    [[ ${*/--push//} != "${*}" ]] && {
+        docker push "$ORG"/"$IMAGE-$VARIANT":"$VERSION"
+        [[ ${*/--latest//} != "${*}" ]] && {
+            docker push "$ORG"/"$IMAGE-$VARIANT":latest
+        }
+    }
+
+done
+
 exit 0
diff --git a/integrations/docker/images/chip-build/Dockerfile b/integrations/docker/images/chip-build/Dockerfile
index af9be79..9d15c27 100644
--- a/integrations/docker/images/chip-build/Dockerfile
+++ b/integrations/docker/images/chip-build/Dockerfile
@@ -37,68 +37,3 @@
     libpixman-1-dev \
     && rm -rf /var/lib/apt/lists/ \
     && : # last line
-
-# Install specific release of openssl
-RUN set -x \
-    && cd /tmp && wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.zip \
-    && mkdir -p /tmp/openssl && cd /tmp/openssl && unzip ../OpenSSL_1_1_1f.zip \
-    && cd /tmp/openssl/openssl-OpenSSL_1_1_1f && ./config && make && make install \
-    && rm -rf /tmp/OpenSSL_1_1_1f.zip \
-    && : # last line
-
-# nRF5 SDK, needed for building Nordic Platform code
-RUN set -x \
-    && curl -o /tmp/nRF5SDKforThreadandZigbee.zip \
-    https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5-SDK-for-Thread/nRF5-SDK-for-Thread-and-Zigbee/nRF5SDKforThreadandZigbeev400dc7186b.zip \
-    && (mkdir /var/nRF5_SDK_for_Thread_and_Zigbee \
-    && cd /var/nRF5_SDK_for_Thread_and_Zigbee \
-    && unzip /tmp/nRF5SDKforThreadandZigbee.zip) \
-    && rm -rf /tmp/nRF5SDKforThreadandZigbee.zip \
-    && : # last line
-
-# Tools for flashing software on Nordic devices, and accessing device logs
-RUN set -x \
-    && (mkdir /var/nRF5_tools && cd /var/nRF5_tools \
-    && curl https://www.nordicsemi.com/-/media/Software-and-other-downloads/Desktop-software/nRF-command-line-tools/sw/Versions-10-x-x/10-7-0/nRFCommandLineTools1070Linuxamd64tar.gz \
-    | tar zxvf - \
-    && dpkg -i JLink_Linux_*.deb \
-    && dpkg -i nRF-Command-Line-Tools_*.deb \
-    && tar zxvf nRF-Command-Line-Tools_*.tar.gz) \
-    && rm -rf /var/nRF5_tools/*.tar.gz \
-    && rm -rf /var/nRF5_tools/*.deb \
-    && : # last line
-
-# GNU ARM Embedded toolchain, cross compiler for various platform builds
-RUN set -x \
-    && (cd /var \
-    && curl https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 \
-    | tar jxvf -) \
-    && : # last line
-
-ENV NRF5_SDK_ROOT=/var/nRF5_SDK_for_Thread_and_Zigbee
-ENV NRF5_TOOLS_ROOT=/var/nRF5_tools
-ENV ARM_GCC_INSTALL_ROOT=/var/gcc-arm-none-eabi-9-2019-q4-major/bin/
-
-# Setup the ESP-IDF
-RUN set -x \
-    && cd /var \
-    && git clone --progress -b release/v4.0 https://github.com/espressif/esp-idf.git \
-    && cd esp-idf \
-    && git submodule update --init --progress \
-    && IDF_TOOLS_PATH=/var/.espressif ./install.sh \
-    && : # last line
-
-ENV IDF_PATH=/var/esp-idf/
-ENV IDF_TOOLS_PATH=/var/.espressif
-
-# Setup QEMU emulator for ESP32 platform
-RUN set -x \
-    && cd /var \
-    && git clone --progress https://github.com/espressif/qemu.git qemu_esp32 \
-    && (cd /var/qemu_esp32 \
-    && ./configure --target-list=xtensa-softmmu --enable-debug --enable-sanitizers --disable-strip --disable-user --disable-capstone --disable-vnc --disable-sdl --disable-gtk \
-    && make -j8) \
-    && : # last line
-
-ENV QEMU_ESP32_DIR=/var/qemu_esp32
-ENV QEMU_ESP32=/var/qemu_esp32/xtensa-softmmu/qemu-system-xtensa
diff --git a/integrations/docker/images/chip-build/variants/Dockerfile.esp32 b/integrations/docker/images/chip-build/variants/Dockerfile.esp32
new file mode 100644
index 0000000..5c1170e
--- /dev/null
+++ b/integrations/docker/images/chip-build/variants/Dockerfile.esp32
@@ -0,0 +1,14 @@
+ARG VERSION=latest
+FROM connectedhomeip/chip-build:${VERSION}
+
+# Setup the ESP-IDF
+RUN set -x \
+    && cd /var \
+    && git clone --progress -b release/v4.0 https://github.com/espressif/esp-idf.git \
+    && cd esp-idf \
+    && git submodule update --init --progress \
+    && IDF_TOOLS_PATH=/var/.espressif ./install.sh \
+    && : # last line
+
+ENV IDF_PATH=/var/esp-idf/
+ENV IDF_TOOLS_PATH=/var/.espressif
diff --git a/integrations/docker/images/chip-build/variants/Dockerfile.esp32-qemu b/integrations/docker/images/chip-build/variants/Dockerfile.esp32-qemu
new file mode 100644
index 0000000..31116d6
--- /dev/null
+++ b/integrations/docker/images/chip-build/variants/Dockerfile.esp32-qemu
@@ -0,0 +1,14 @@
+ARG VERSION=latest
+FROM connectedhomeip/chip-build-esp32:${VERSION}
+
+# Setup QEMU emulator for ESP32 platform
+RUN set -x \
+    && cd /var \
+    && git clone --progress https://github.com/espressif/qemu.git qemu_esp32 \
+    && (cd /var/qemu_esp32 \
+    && ./configure --target-list=xtensa-softmmu --enable-debug --enable-sanitizers --disable-strip --disable-user --disable-capstone --disable-vnc --disable-sdl --disable-gtk \
+    && make -j8) \
+    && : # last line
+
+ENV QEMU_ESP32_DIR=/var/qemu_esp32
+ENV QEMU_ESP32=/var/qemu_esp32/xtensa-softmmu/qemu-system-xtensa
diff --git a/integrations/docker/images/chip-build/variants/Dockerfile.nrf-platform b/integrations/docker/images/chip-build/variants/Dockerfile.nrf-platform
new file mode 100644
index 0000000..261d5da
--- /dev/null
+++ b/integrations/docker/images/chip-build/variants/Dockerfile.nrf-platform
@@ -0,0 +1,35 @@
+ARG VERSION=latest
+FROM connectedhomeip/chip-build:${VERSION}
+
+# nRF5 SDK, needed for building Nordic Platform code
+RUN set -x \
+    && curl -o /tmp/nRF5SDKforThreadandZigbee.zip \
+    https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5-SDK-for-Thread/nRF5-SDK-for-Thread-and-Zigbee/nRF5SDKforThreadandZigbeev400dc7186b.zip \
+    && (mkdir /var/nRF5_SDK_for_Thread_and_Zigbee \
+    && cd /var/nRF5_SDK_for_Thread_and_Zigbee \
+    && unzip /tmp/nRF5SDKforThreadandZigbee.zip) \
+    && rm -rf /tmp/nRF5SDKforThreadandZigbee.zip \
+    && : # last line
+
+# Tools for flashing software on Nordic devices, and accessing device logs
+RUN set -x \
+    && (mkdir /var/nRF5_tools && cd /var/nRF5_tools \
+    && curl https://www.nordicsemi.com/-/media/Software-and-other-downloads/Desktop-software/nRF-command-line-tools/sw/Versions-10-x-x/10-7-0/nRFCommandLineTools1070Linuxamd64tar.gz \
+    | tar zxvf - \
+    && dpkg -i JLink_Linux_*.deb \
+    && dpkg -i nRF-Command-Line-Tools_*.deb \
+    && tar zxvf nRF-Command-Line-Tools_*.tar.gz) \
+    && rm -rf /var/nRF5_tools/*.tar.gz \
+    && rm -rf /var/nRF5_tools/*.deb \
+    && : # last line
+
+# GNU ARM Embedded toolchain, cross compiler for various platform builds
+RUN set -x \
+    && (cd /var \
+    && curl https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 \
+    | tar jxvf -) \
+    && : # last line
+
+ENV NRF5_SDK_ROOT=/var/nRF5_SDK_for_Thread_and_Zigbee
+ENV NRF5_TOOLS_ROOT=/var/nRF5_tools
+ENV ARM_GCC_INSTALL_ROOT=/var/gcc-arm-none-eabi-9-2019-q4-major/bin/
diff --git a/integrations/docker/images/chip-build/variants/Dockerfile.openssl b/integrations/docker/images/chip-build/variants/Dockerfile.openssl
new file mode 100644
index 0000000..9d1a0d4
--- /dev/null
+++ b/integrations/docker/images/chip-build/variants/Dockerfile.openssl
@@ -0,0 +1,10 @@
+ARG VERSION=latest
+FROM connectedhomeip/chip-build:${VERSION}
+
+# Install specific release of openssl
+RUN set -x \
+    && cd /tmp && wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.zip \
+    && mkdir -p /tmp/openssl && cd /tmp/openssl && unzip ../OpenSSL_1_1_1f.zip \
+    && cd /tmp/openssl/openssl-OpenSSL_1_1_1f && ./config && make && make install \
+    && rm -rf /tmp/OpenSSL_1_1_1f.zip \
+    && : # last line
diff --git a/integrations/docker/images/chip-build/variants/Dockerfile.vscode b/integrations/docker/images/chip-build/variants/Dockerfile.vscode
new file mode 100644
index 0000000..f6630b0
--- /dev/null
+++ b/integrations/docker/images/chip-build/variants/Dockerfile.vscode
@@ -0,0 +1,6 @@
+ARG VERSION=latest
+FROM connectedhomeip/chip-build:${VERSION}
+FROM connectedhomeip/chip-build-openssl:${VERSION}
+FROM connectedhomeip/chip-build-nrf-platform:${VERSION}
+FROM connectedhomeip/chip-build-esp32:${VERSION}
+FROM connectedhomeip/chip-build-esp32-qemu:${VERSION}
diff --git a/integrations/docker/images/chip-build/version b/integrations/docker/images/chip-build/version
index 13dead7..d3b5ba4 100644
--- a/integrations/docker/images/chip-build/version
+++ b/integrations/docker/images/chip-build/version
@@ -1 +1 @@
-0.2.10
+0.2.11
diff --git a/integrations/docker/run.sh b/integrations/docker/run.sh
index b7309b5..b0f30eb 100755
--- a/integrations/docker/run.sh
+++ b/integrations/docker/run.sh
@@ -9,8 +9,8 @@
 me=$(basename "$0")
 
 die() {
-  echo "$me: *** ERROR: $*"
-  exit 1
+    echo "$me: *** ERROR: $*"
+    exit 1
 }
 
 ORG=${DOCKER_RUN_ORG:-connectedhomeip}
@@ -20,7 +20,7 @@
 
 # version
 VERSION=${DOCKER_RUN_VERSION:-$(cat "$here/version")} ||
-  die "please run me from an image directory or set environment variables:
+    die "please run me from an image directory or set environment variables:
           DOCKER_RUN_ORG
           DOCKER_RUN_IMAGE
           DOCKER_RUN_VERSION"
@@ -29,8 +29,8 @@
 RUN_DIR=${DOCKER_RUN_DIR:-$(pwd)}
 
 help() {
-  set +x
-  echo "Usage: $me [RUN_OPTIONS -- ] command
+    set +x
+    echo "Usage: $me [RUN_OPTIONS -- ] command
 
   Run a command in a docker image described by $here
 
@@ -60,29 +60,29 @@
 
 # extract run options
 for arg in "$@"; do
-  case "$arg" in
-    --help)
-      help
-      exit
-      ;;
+    case "$arg" in
+        --help)
+            help
+            exit
+            ;;
 
-    --)
-      shift
-      break
-      ;;
+        --)
+            shift
+            break
+            ;;
 
-    -*)
-      runargs+=("$arg")
-      shift
-      ;;
+        -*)
+            runargs+=("$arg")
+            shift
+            ;;
 
-    *)
-      ((!${#runargs[*]})) && break
-      runargs+=("$arg")
-      shift
-      ;;
+        *)
+            ((!${#runargs[*]})) && break
+            runargs+=("$arg")
+            shift
+            ;;
 
-  esac
+    esac
 done
 
 docker run "${runargs[@]}" --rm -w "$RUN_DIR" -v "$RUN_DIR:$RUN_DIR" "$ORG/$IMAGE${VERSION:+:${VERSION}}" "$@"
diff --git a/scripts/build/bootstrap.sh b/scripts/build/bootstrap.sh
index f6a2b88..671f819 100755
--- a/scripts/build/bootstrap.sh
+++ b/scripts/build/bootstrap.sh
@@ -1,11 +1,11 @@
 #!/bin/bash
 
 if [[ ! -f build/default/config.status ]]; then
-  mkdir -p build/default
-  (cd build/default &&
-    ../../bootstrap-configure -C --enable-debug --enable-coverage)
+    mkdir -p build/default
+    (cd build/default &&
+        ../../bootstrap-configure -C --enable-debug --enable-coverage)
 elif [[ configure.ac -nt configure ]]; then
-  ./bootstrap
+    ./bootstrap
 else
-  ./bootstrap -w make
+    ./bootstrap -w make
 fi
diff --git a/scripts/helpers/clang-format-check.sh b/scripts/helpers/clang-format-check.sh
index 69fa0af..874c07d 100755
--- a/scripts/helpers/clang-format-check.sh
+++ b/scripts/helpers/clang-format-check.sh
@@ -7,8 +7,8 @@
 #
 
 die() {
-  echo " *** ERROR: $*"
-  exit 1
+    echo " *** ERROR: $*"
+    exit 1
 }
 
 # from `man diff`:
diff --git a/scripts/helpers/clang-format.sh b/scripts/helpers/clang-format.sh
index 18a67a3..3cea201 100755
--- a/scripts/helpers/clang-format.sh
+++ b/scripts/helpers/clang-format.sh
@@ -3,22 +3,22 @@
 CLANG_FORMAT_VERSION="clang-format version 9.0"
 
 die() {
-  echo " *** ERROR: $*"
-  exit 1
+    echo " *** ERROR: $*"
+    exit 1
 }
 
 if command -v clang-format-9 >/dev/null; then
-  alias clang-format=clang-format-9
+    alias clang-format=clang-format-9
 elif command -v clang-format >/dev/null; then
-  case "$(clang-format --version)" in
-    "$CLANG_FORMAT_VERSION"*) ;;
+    case "$(clang-format --version)" in
+        "$CLANG_FORMAT_VERSION"*) ;;
 
-    *)
-      die "$(clang-format --version); \"$CLANG_FORMAT_VERSION\" required"
-      ;;
-  esac
+        *)
+            die "$(clang-format --version); \"$CLANG_FORMAT_VERSION\" required"
+            ;;
+    esac
 else
-  die "$CLANG_FORMAT_VERSION required"
+    die "$CLANG_FORMAT_VERSION required"
 fi
 
 clang-format "$@" || die "format failed"
@@ -26,17 +26,17 @@
 # ensure EOF newline
 REPLACE=no
 for arg; do
-  case $arg in
-    -i)
-      REPLACE=yes
-      ;;
-  esac
+    case $arg in
+        -i)
+            REPLACE=yes
+            ;;
+    esac
 done
 
 file=$arg
 
 [[ $REPLACE != yes ]] || {
-  [[ -z $(tail -c1 "$file") ]] || echo >>"$file"
+    [[ -z $(tail -c1 "$file") ]] || echo >>"$file"
 }
 
 exit 0
diff --git a/scripts/helpers/restyle_merge.sh b/scripts/helpers/restyle_merge.sh
new file mode 100755
index 0000000..a6b1db5
--- /dev/null
+++ b/scripts/helpers/restyle_merge.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+git remote add upstream https://github.com/project-chip/connectedhomeip.git
+git fetch upstream pull/"$1"/head
+git merge --ff-only FETCH_HEAD
+git push
diff --git a/scripts/helpers/shellcheck_tree.sh b/scripts/helpers/shellcheck_tree.sh
index 419aaeb..0e1fc45 100755
--- a/scripts/helpers/shellcheck_tree.sh
+++ b/scripts/helpers/shellcheck_tree.sh
@@ -4,14 +4,14 @@
 
 # Run shellcheck on all the shell-ish files in the tree
 patterns=('*.bash*' 'bash*'
-  '*.ksh*' 'ksh*'
-  '*.zsh*' 'zsh*'
-  '.zlogin*' 'zlogin*'
-  '.zlogout*' 'zlogout*'
-  '.zprofile*' 'zprofile*'
-  '*.sh' '.shlib*' 'shlib*'
-  '.profile*' 'profile*'
-  'suid_profile')
+    '*.ksh*' 'ksh*'
+    '*.zsh*' 'zsh*'
+    '.zlogin*' 'zlogin*'
+    '.zlogout*' 'zlogout*'
+    '.zprofile*' 'zprofile*'
+    '*.sh' '.shlib*' 'shlib*'
+    '.profile*' 'profile*'
+    'suid_profile')
 
 # excluding these directories (e.g. third_party/* )
 excludes=()
@@ -20,7 +20,7 @@
 [[ -f .shellcheck_tree ]] && . .shellcheck_tree
 
 [[ ${*/--help//} != "${*}" ]] && {
-  echo "Usage: $me <OPTIONS>
+    echo "Usage: $me <OPTIONS>
 
   Shellcheck all scripts in the tree.
 
@@ -29,32 +29,32 @@
    --help     get this message
 
 "
-  exit 0
+    exit 0
 }
 
 if [[ ${*/--git//} != "${*}" ]]; then
-  #
-  #  To run on git-files only
-  #
-  git ls-files -- "${patterns[@]}" | while read -r file; do
-    for exclude in "${excludes[@]}"; do
-      [[ $file =~ $exclude ]] && continue 2
+    #
+    #  To run on git-files only
+    #
+    git ls-files -- "${patterns[@]}" | while read -r file; do
+        for exclude in "${excludes[@]}"; do
+            [[ $file =~ $exclude ]] && continue 2
+        done
+        shellcheck -f gcc "$file"
     done
-    shellcheck -f gcc "$file"
-  done
 else
-  #
-  # use find
-  #
-  exclude_args=()
-  for exclude in "${excludes[@]}"; do
-    exclude_args+=('!' -path "./$exclude" -a)
-  done
+    #
+    # use find
+    #
+    exclude_args=()
+    for exclude in "${excludes[@]}"; do
+        exclude_args+=('!' -path "./$exclude" -a)
+    done
 
-  pattern_args=()
-  for pattern in "${patterns[@]}"; do
-    pattern_args+=(-o -name "$pattern")
-  done
+    pattern_args=()
+    for pattern in "${patterns[@]}"; do
+        pattern_args+=(-o -name "$pattern")
+    done
 
-  find . "${exclude_args[@]}" '(' "${pattern_args[@]:1}" ')' -exec shellcheck -f gcc {} +
+    find . "${exclude_args[@]}" '(' "${pattern_args[@]:1}" ')' -exec shellcheck -f gcc {} +
 fi
diff --git a/scripts/setup/install_packages.sh b/scripts/setup/install_packages.sh
new file mode 100755
index 0000000..a9bf588
--- /dev/null
+++ b/scripts/setup/install_packages.sh
@@ -0,0 +1 @@
+#!/bin/bash
diff --git a/scripts/setup/linux/install_packages.sh b/scripts/setup/linux/install_packages.sh
new file mode 100755
index 0000000..eebbd0f
--- /dev/null
+++ b/scripts/setup/linux/install_packages.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+set -x
+apt-get update
+apt-get install -fy \
+    git \
+    curl \
+    jq \
+    make \
+    autoconf \
+    automake \
+    libtool \
+    pkg-config \
+    g++ \
+    clang-9 \
+    clang-format-9 \
+    clang-tidy-9 \
+    lcov \
+    shellcheck \
+    libssl-dev \
+    unzip \
+    wget \
+    libmbedtls-dev
+
+if [[ ! -f 'build/downloads/open_ssl_1.1.1f_installed' ]]; then
+    mkdir -p build/downloads
+    cd build/downloads
+    wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.zip
+    mkdir openssl
+    cd openssl
+    unzip ../OpenSSL_1_1_1f.zip
+    cd openssl-OpenSSL_1_1_1f
+    ./config
+    make
+
+    rm -rf ../OpenSSL_1_1_1f.zip
+
+    cd ~/project
+    touch build/downloads/open_ssl_1.1.1f_installed
+    chown -R circleci:circleci build
+fi
+
+cd ~/project/build/downloads/openssl/openssl-OpenSSL_1_1_1f
+make install_sw install_ssldirs
diff --git a/scripts/tools/build_esp32_flash_image.sh b/scripts/tools/build_esp32_flash_image.sh
index 51cb162..e4f244b 100755
--- a/scripts/tools/build_esp32_flash_image.sh
+++ b/scripts/tools/build_esp32_flash_image.sh
@@ -22,8 +22,8 @@
 #
 
 [[ $# -eq 2 ]] || {
-  echo "Usage: $0 <app-image.bin> <output-flash-image.bin>"
-  exit 1
+    echo "Usage: $0 <app-image.bin> <output-flash-image.bin>"
+    exit 1
 }
 
 here=$(cd "$(dirname "$0")" && pwd)
diff --git a/scripts/tools/esp32_qemu_run.sh b/scripts/tools/esp32_qemu_run.sh
index 9b9aa0a..145e81b 100755
--- a/scripts/tools/esp32_qemu_run.sh
+++ b/scripts/tools/esp32_qemu_run.sh
@@ -23,19 +23,19 @@
 #
 
 usage() {
-  exitcode=0
-  if [[ -n "$1" ]]; then
-    exitcode=1
-    echo "*** Error: $*"
-  fi
-  echo "Usage: $0 <flash image file>"
-  exit "$exitcode"
+    exitcode=0
+    if [[ -n "$1" ]]; then
+        exitcode=1
+        echo "*** Error: $*"
+    fi
+    echo "Usage: $0 <flash image file>"
+    exit "$exitcode"
 }
 
 me=$(basename "$0")
 die() {
-  echo "$me: *** ERROR: " "${*}"
-  exit 1
+    echo "$me: *** ERROR: " "${*}"
+    exit 1
 }
 
 [[ $# -eq 1 ]] || usage "Incorrect number of arguments"
diff --git a/scripts/tools/flash_image_builder.sh b/scripts/tools/flash_image_builder.sh
index 3fee0a9..409cc98 100755
--- a/scripts/tools/flash_image_builder.sh
+++ b/scripts/tools/flash_image_builder.sh
@@ -23,13 +23,13 @@
 #
 
 usage() {
-  exitcode=0
-  if [[ -n "$1" ]]; then
-    exitcode=1
-    echo "Error: $*"
-  fi
-  echo "Usage: $0 <image-size> <output-file> <offset1=input-file1> [<offset2=input-file2> ..]"
-  exit "$exitcode"
+    exitcode=0
+    if [[ -n "$1" ]]; then
+        exitcode=1
+        echo "Error: $*"
+    fi
+    echo "Usage: $0 <image-size> <output-file> <offset1=input-file1> [<offset2=input-file2> ..]"
+    exit "$exitcode"
 }
 
 [[ $# -ge 3 ]] || usage "Incorrect number of arguments"
@@ -46,17 +46,17 @@
 
 # Argument 3 onwards have input files and corresponding offsets
 for item in "${@:3}"; do
-  IFS='=' read -r start file <<<"$item"
+    IFS='=' read -r start file <<<"$item"
 
-  offset=$((start))
-  [[ $? -eq 0 ]] || usage "Offset ($start) must be a number"
+    offset=$((start))
+    [[ $? -eq 0 ]] || usage "Offset ($start) must be a number"
 
-  [[ -r $file ]] || usage "Cannot read file $file"
-  [[ $written -le $offset ]] || usage "Writing $file at $offset will overwrite previous segment"
+    [[ -r $file ]] || usage "Cannot read file $file"
+    [[ $written -le $offset ]] || usage "Writing $file at $offset will overwrite previous segment"
 
-  filesize=$(stat -c%s "$file")
-  written=$((written + filesize))
-  [[ $written -lt $image_size ]] || usage "Writing $file at $offset will overflow image"
+    filesize=$(stat -c%s "$file")
+    written=$((written + filesize))
+    [[ $written -lt $image_size ]] || usage "Writing $file at $offset will overflow image"
 
-  dd if="$file" of="$2" conv=notrunc bs="$offset" seek=1
+    dd if="$file" of="$2" conv=notrunc bs="$offset" seek=1
 done
diff --git a/scripts/tools/run_if.sh b/scripts/tools/run_if.sh
new file mode 100755
index 0000000..b53096d
--- /dev/null
+++ b/scripts/tools/run_if.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+if [[ $1 == *"$2"* ]]; then
+    shift
+    shift
+    "$@"
+fi