Merge branch 'feature/README_updated' into 'master'
update README and CI check. See merge request ae_group/esp-box!89
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
.config
|
||||
*.o
|
||||
*.pyc
|
||||
*.orig
|
||||
|
||||
# gtags
|
||||
GTAGS
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
stages:
|
||||
- pre_check
|
||||
- build
|
||||
- deploy
|
||||
|
||||
@@ -36,5 +37,6 @@ before_script:
|
||||
|
||||
include:
|
||||
- '.gitlab/ci/rules.yml'
|
||||
- '.gitlab/ci/pre_check.yml'
|
||||
- '.gitlab/ci/build.yml'
|
||||
- '.gitlab/ci/deploy.yml'
|
||||
@@ -0,0 +1,19 @@
|
||||
check_readme_links:
|
||||
extends:
|
||||
- .rules:pre_check:readme
|
||||
stage: pre_check
|
||||
image: python:3.9
|
||||
tags: ["build", "amd64", "internet"]
|
||||
allow_failure: true
|
||||
script:
|
||||
- python ${CI_PROJECT_DIR}/tools/ci/check_readme_links.py
|
||||
|
||||
check_copyright:
|
||||
stage: pre_check
|
||||
image: python:3.9
|
||||
tags: ["build", "amd64", "internet"]
|
||||
allow_failure: true
|
||||
before_script:
|
||||
- pip install git+https://github.com/espressif/check-copyright.git@master
|
||||
script:
|
||||
- python -m check_copyright --verbose --dry-run --ignore tools/ci/ignore_list_copyright.txt --config tools/ci/check_copyright_config.yaml .
|
||||
+16
-1
@@ -37,6 +37,9 @@
|
||||
.patterns-example_watering_demo: &patterns-example_watering_demo
|
||||
- "examples/watering_demo/**/*"
|
||||
|
||||
.patterns-docs_md: &patterns-docs_md
|
||||
- "**/*.md"
|
||||
|
||||
##############
|
||||
# if anchors #
|
||||
##############
|
||||
@@ -52,6 +55,9 @@
|
||||
.if-label-build: &if-label-build
|
||||
if: '$CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-pre_check: &if-label-pre_check
|
||||
if: '$BOT_LABEL_PRE_CHECK || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*pre_check(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
# rules for examples
|
||||
.rules:build:example_chatgpt_demo:
|
||||
rules:
|
||||
@@ -141,4 +147,13 @@
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-components_bsp
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_watering_demo
|
||||
changes: *patterns-example_watering_demo
|
||||
|
||||
.rules:pre_check:readme:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-pre_check
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-components_bsp
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docs_md
|
||||
|
||||
@@ -22,4 +22,4 @@ repos:
|
||||
rev: v1.0.3
|
||||
hooks:
|
||||
- id: check-copyright
|
||||
args: ['--config', 'check_copyright_config.yaml']
|
||||
args: ['--config', 'tools/ci/check_copyright_config.yaml', '--ignore', 'tools/ci/ignore_list_copyright.txt']
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
**Important Note:**
|
||||
|
||||
> Upon receiving the ESP32-S3-BOX and ESP32-S3-BOX-Lite, we advise updating the [built-in factory firmware](./docs/firmware_update.md) to ensure you have the latest bug fixes. In the master branch, we will gradually offer limited support for these two development boards. For further information, kindly refer to the examples readme.
|
||||
> Upon receiving the ESP32-S3-BOX-3, we advise updating the built-in factory firmware to ensure you have the latest bugfixes via Espressif's online firmware flashing tool ESP Launchpad. Up till now, the latest version is **ESP-BOX-3_Demo_V1.2.3**. To verify the software version, please go to the 'About Us' Page.
|
||||
|
||||
The ESP-BOX is an advanced AIoT, Edge AI, and IIoT applications development platform released by Espressif Systems. The ESP32-S3-BOX, ESP32-S3-BOX-Lite, and ESP32-S3-BOX-3 are a series of development boards designed for this platform, they are built on Espressif’s powerful ESP32-S3 Wi-Fi + Bluetooth 5 (LE) SoC and feature compact and beautiful enclosures. Leveraging the multi-functional accessories and reliable examples from the repo’s, these development boards cater to both prototyping new projects and building complex IoT systems, providing a perfect balance of form and function.
|
||||
|
||||
@@ -32,11 +32,11 @@ ESP-BOX provides a platform for developing applications in various domains, incl
|
||||
|
||||
| Product Name | Product Figure | Marketing Status |
|
||||
| :-----: | :---------------------: |:---------------------: |
|
||||
| [ESP32-S3-BOX](docs/hardware_overview/esp32_s3_box/hardware_overview_for_box.md) | <img src="docs/_static/esp32_s3_box.png" width="200px" /> |End of Life <br> [User Guide](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started.md) |
|
||||
| [ESP32-S3-BOX-Lite](docs/hardware_overview/esp32_s3_box_lite/hardware_overview_for_lite.md) | <img src="docs/_static/esp32_s3_box_lite.png" width="200px" /> |[Active](https://www.aliexpress.com/item/1005004441701974.html?spm=a2g0o.store_pc_groupList.8148356.15.378130cf2Qwt87&pdp_npi=3%40dis%21HKD%21HKD273.50%21HKD273.50%21%21%21%21%21%40210318cb16926755466344763e3593%2112000029194032303%21sh%21HK%213721963538) <br> [User Guide](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started.md)|
|
||||
| [ESP32-S3-BOX<sup> **1** </sup>](docs/hardware_overview/esp32_s3_box/hardware_overview_for_box.md) | <img src="docs/_static/esp32_s3_box.png" width="200px" /> |End of Life <br> [User Guide](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started.md) |
|
||||
| [ESP32-S3-BOX-Lite<sup> **1** </sup>](docs/hardware_overview/esp32_s3_box_lite/hardware_overview_for_lite.md) | <img src="docs/_static/esp32_s3_box_lite.png" width="200px" /> |[Active](https://www.aliexpress.com/item/1005004441701974.html?spm=a2g0o.store_pc_groupList.8148356.15.378130cf2Qwt87&pdp_npi=3%40dis%21HKD%21HKD273.50%21HKD273.50%21%21%21%21%21%40210318cb16926755466344763e3593%2112000029194032303%21sh%21HK%213721963538) <br> [User Guide](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started.md)|
|
||||
| [ESP32-S3-BOX-3](docs/hardware_overview/esp32_s3_box_3/hardware_overview_for_box_3.md) | <img src="docs/_static/esp32_s3_box_3.png" width="200px" /> |[Active](https://www.aliexpress.com/item/1005005920207976.html) <br> [User Guide](./docs/getting_started.md)|
|
||||
|
||||
|
||||
**Note 1**: Upon receiving the ESP32-S3-BOX and ESP32-S3-BOX-Lite, we advise updating the [built-in factory firmware](./docs/firmware_update.md) to ensure you have the latest bug fixes. In the master branch, we will gradually offer limited support for these two development boards. For further information, kindly refer to the examples readme.
|
||||
## Versions
|
||||
|
||||
| ESP-BOX | Dependent ESP-IDF | Branch Note | Support State |
|
||||
|
||||
+4
-3
@@ -23,7 +23,7 @@
|
||||
</a>
|
||||
|
||||
**重要提醒:**
|
||||
> 对于 ESP32-S3-BOX 和 ESP32-S3-BOX-Lite,我们建议您更新内置的[出厂应用固件](./docs/firmware_update_cn.md)以确保拥有最新的 bug 修复。在 Master 分支,我们将逐步对这两款开发板提供有限的支持。有关更多信息,请阅读各例程的 README。
|
||||
> 在收到 ESP32-S3-BOX-3 后,我们建议您更新内置的出厂固件,以确保拥有最新的 bug 修复。您可以使用乐鑫在线固件烧录工具 ESP Launchpad 进行此操作。截止目前,最新版本为 **ESP-BOX-3_Demo_V1.2.3**。请前往“About Us”页面验证设备出厂固件版本。
|
||||
|
||||
ESP-BOX 是乐鑫科技推出的面向 AIoT、边缘 AI 和 IIoT 应用的开发平台。ESP32-S3-BOX、ESP32-S3-BOX-Lite 和 ESP32-S3-BOX-3 是为该平台设计的系列开发板,它们基于乐鑫强大的 ESP32-S3 Wi-Fi + Bluetooth 5(LE) SoC 构建,并拥有紧凑美观的外壳结构。借助多功能配件和 ESP-BOX 项目内的可靠例程,这些开发板既适用于构建新项目原型,也适用于打造复杂的物联网系统,提供了形式上和功能上的完美平衡。
|
||||
|
||||
@@ -32,10 +32,11 @@ ESP-BOX 为各个领域的应用提供了开发资源,包括离线语音助手
|
||||
|
||||
| 产品名称 | 产品图 | 市场状态 |
|
||||
| :-----: | :---------------------: |:---------------------: |
|
||||
| [ESP32-S3-BOX](docs/hardware_overview/esp32_s3_box/hardware_overview_for_box_cn.md) | <img src="docs/_static/esp32_s3_box.png" width="200px" /> |寿命终止 <br> [用户指南](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started_cn.md) |
|
||||
| [ESP32-S3-BOX-Lite](docs/hardware_overview/esp32_s3_box_lite/hardware_overview_for_lite_cn.md) | <img src="docs/_static/esp32_s3_box_lite.png" width="200px" /> |[在售](https://item.taobao.com/item.htm?spm=a312a.7700824.w4002-8715811646.9.4048605fNqggSF&id=658634202331) <br> [用户指南](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started_cn.md)|
|
||||
| [ESP32-S3-BOX<sup> **1** </sup>](docs/hardware_overview/esp32_s3_box/hardware_overview_for_box_cn.md) | <img src="docs/_static/esp32_s3_box.png" width="200px" /> |寿命终止 <br> [用户指南](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started_cn.md) |
|
||||
| [ESP32-S3-BOX-Lite<sup> **1** </sup>](docs/hardware_overview/esp32_s3_box_lite/hardware_overview_for_lite_cn.md) | <img src="docs/_static/esp32_s3_box_lite.png" width="200px" /> |寿命终止[(仅剩裸板在售)](https://item.taobao.com/item.htm?spm=a312a.7700824.w4002-8715811646.9.4048605fNqggSF&id=658634202331) <br> [用户指南](https://github.com/espressif/esp-box/blob/v0.5.0/docs/getting_started_cn.md)|
|
||||
| [ESP32-S3-BOX-3](docs/hardware_overview/esp32_s3_box_3/hardware_overview_for_box_3_cn.md) | <img src="docs/_static/esp32_s3_box_3.png" width="200px" /> |[在售](https://item.taobao.com/item.htm?ft=t&id=732842971319) <br> [用户指南](./docs/getting_started_cn.md)|
|
||||
|
||||
**Note 1**: 对于 ESP32-S3-BOX 和 ESP32-S3-BOX-Lite,我们建议您更新内置的[出厂应用固件](./docs/firmware_update_cn.md)以确保拥有最新的 bug 修复。在 Master 分支,我们将逐步对这两款开发板提供有限的支持。有关更多信息,请阅读各例程的 README。
|
||||
|
||||
## 版本信息
|
||||
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@ esp_toml_version = 1.0
|
||||
firmware_images_url = "https://dl.espressif.com/AE/esp-box/"
|
||||
|
||||
supported_apps = [
|
||||
"ESP-BOX-3_Demo_V1_1_1",
|
||||
"ESP-BOX-3_Demo_V1_2_3",
|
||||
"ESP-BOX-3_ChatGPT_Demo_V1_0",
|
||||
"ESP-BOX-3_USB_Headset_V0_0_1",
|
||||
"ESP-BOX-3_USB_Camera_V0_0_1",
|
||||
@@ -82,9 +82,9 @@ image.esp32-s3 = "ESP-BOX-Lite_Demo_EN_V0.5.0.bin"
|
||||
android_app_url = ""
|
||||
ios_app_url = ""
|
||||
|
||||
[ESP-BOX-3_Demo_V1_1_1]
|
||||
[ESP-BOX-3_Demo_V1_2_3]
|
||||
chipsets = ["ESP32-S3"]
|
||||
image.esp32-s3 = "ESP-BOX-3_Demo_V1.2.1.bin"
|
||||
image.esp32-s3 = "ESP-BOX-3_Demo_V1.2.3.bin"
|
||||
android_app_url = ""
|
||||
ios_app_url = ""
|
||||
|
||||
|
||||
@@ -40,3 +40,20 @@ ignore: # You can also select ignoring files here
|
||||
perform_check: no # Don't check files from that block
|
||||
include:
|
||||
- docs/
|
||||
- hardware/
|
||||
- examples/matter_switch/main/gui/image/
|
||||
- examples/matter_switch/main/gui/font/
|
||||
- examples/matter_switch/main/gui/lv_symbol_extra_def.h
|
||||
- examples/factory_demo/main/gui/font/
|
||||
- examples/factory_demo/main/gui/image/
|
||||
- examples/factory_demo/components/espressif__button/
|
||||
- examples/chatgpt_demo/main/ui/images/
|
||||
- examples/chatgpt_demo/main/ui/fonts/
|
||||
- examples/chatgpt_demo/main/ui/
|
||||
- examples/chatgpt_demo/components/chmorgan__esp-audio-player/
|
||||
- examples/chatgpt_demo/squareline/
|
||||
- examples/chatgpt_demo/factory_nvs/squareline/assets/
|
||||
- examples/chatgpt_demo/factory_nvs/main/ui/
|
||||
- examples/usb_camera_lcd_display/components/esp_jpeg/
|
||||
- examples/watering_demo/main/gui/font/
|
||||
- examples/watering_demo/main/gui/image/
|
||||
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Checks that all links in the readme markdown files are valid
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from collections import defaultdict, namedtuple
|
||||
from pathlib import Path
|
||||
|
||||
EXCLUDE_DOCS_LIST = []
|
||||
|
||||
# The apple apps links are not accessible from the company network for some reason
|
||||
EXCLUDE_URL_LIST = ["https://lvgl.io/",
|
||||
"https://www.espressif.com/zh-hans/products/socs/esp32",
|
||||
"http://www.espressif.com/zh-hans/support/download/all",
|
||||
"https://www.espressif.com/zh-hans/support/download/all",
|
||||
"https://github.com/lvgl/lv_examples/blob/master/src/lv_demo_printer/screenshot1.gif?raw=true"]
|
||||
|
||||
Link = namedtuple('Link', ['file', 'url'])
|
||||
|
||||
|
||||
class ReadmeLinkError(Exception):
|
||||
def __init__(self, file, url):
|
||||
self.file = file
|
||||
self.url = url
|
||||
|
||||
|
||||
class RelativeLinkError(ReadmeLinkError):
|
||||
def __str__(self):
|
||||
return 'Relative link error, file - {} not found, linked from {}'.format(self.url, self.file)
|
||||
|
||||
|
||||
class UrlLinkError(ReadmeLinkError):
|
||||
def __init__(self, file, url, error_code):
|
||||
self.error_code = error_code
|
||||
super().__init__(file, url)
|
||||
|
||||
def __str__(self):
|
||||
files = [str(f) for f in self.file]
|
||||
return 'URL error, url - {} in files - {} is not accessible, request returned {}'.format(self.url, ', '.join(files), self.error_code)
|
||||
|
||||
|
||||
# we do not want a failed test just due to bad network conditions, for non 404 errors we simply print a warning
|
||||
def check_url(url, files, timeout):
|
||||
try:
|
||||
with urllib.request.urlopen(url, timeout=timeout):
|
||||
return
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
raise UrlLinkError(files, url, str(e))
|
||||
else:
|
||||
print('Unable to access {}, err = {}'.format(url, str(e)))
|
||||
except Exception as e:
|
||||
print('Unable to access {}, err = {}'.format(url, str(e)))
|
||||
|
||||
|
||||
def check_web_links(web_links):
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
||||
errors = []
|
||||
future_to_url = {executor.submit(check_url, url, files, timeout=30): (url, files) for url, files in web_links.items()}
|
||||
for future in concurrent.futures.as_completed(future_to_url):
|
||||
try:
|
||||
future.result()
|
||||
except UrlLinkError as e:
|
||||
errors.append(e)
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def check_file_links(file_links):
|
||||
errors = []
|
||||
|
||||
for link in file_links:
|
||||
link_path = link.file.parent / link.url
|
||||
|
||||
if not Path.exists(link_path):
|
||||
errors.append(RelativeLinkError(link.file, link.url))
|
||||
|
||||
print('Found {} errors with relative links'.format(len(errors)))
|
||||
return errors
|
||||
|
||||
|
||||
def get_md_links(folder):
|
||||
MD_LINK_RE = r'\[.+?\]\((.+?)(#.+)?\)'
|
||||
|
||||
path = Path(os.getenv('ESP_BOX_PATH'))
|
||||
links = []
|
||||
|
||||
for path in (path / folder).rglob('*.md'):
|
||||
if any([path.match(exclude_doc) for exclude_doc in EXCLUDE_DOCS_LIST]):
|
||||
print('{} - excluded'.format(path))
|
||||
continue
|
||||
|
||||
print('-open {}'.format(path))
|
||||
with path.open(encoding='utf8') as f:
|
||||
content = f.read()
|
||||
|
||||
for url in re.findall(MD_LINK_RE, content):
|
||||
link = Link(path, url[0].lstrip())
|
||||
# Ignore "local" links
|
||||
if not link.url.startswith('#'):
|
||||
links.append(link)
|
||||
|
||||
return links
|
||||
|
||||
|
||||
def check_readme_links(args):
|
||||
|
||||
# Get all links from the readme files
|
||||
links = get_md_links('')
|
||||
print('Found {} links'.format(len(links)))
|
||||
|
||||
errors = []
|
||||
|
||||
web_links = defaultdict(list)
|
||||
file_links = []
|
||||
|
||||
# Sort links into file and web links
|
||||
for link in links:
|
||||
if link.url.startswith('http'):
|
||||
web_links[link.url].append(link.file)
|
||||
else:
|
||||
file_links.append(link)
|
||||
|
||||
for url in EXCLUDE_URL_LIST:
|
||||
if url in web_links:
|
||||
del web_links[url]
|
||||
|
||||
errors.extend(check_file_links(file_links))
|
||||
|
||||
if not args.skip_weburl:
|
||||
errors.extend(check_web_links(web_links))
|
||||
|
||||
print('Found {} errors:'.format(len(errors)))
|
||||
for e in errors:
|
||||
print(e)
|
||||
|
||||
return 1 if len(errors) > 0 else 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser(description='check_readme_links.py: Checks for dead links in example READMEs', prog='check_readme_links.py')
|
||||
parser.add_argument('--skip-weburl', '-w', action='store_true', help='Skip checking of web URLs, only check links to local files')
|
||||
args = parser.parse_args()
|
||||
|
||||
sys.exit(check_readme_links(args))
|
||||
@@ -0,0 +1 @@
|
||||
./docs/
|
||||
Reference in New Issue
Block a user