Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
学习笔记
新手学习
RT-Thread 中的 Github Actions
发布于 2023-05-29 01:15:06 浏览:450
订阅该版
[tocm] # RT-Thread中的Github Actions rt-thread中一共有五个Github Action([rt-thread/.github/workflow](https://github.com/RT-Thread/rt-thread/tree/master/.github/workflows)),分别是: * **RT-Thread BSP build check**(.github/workflows/action.yml) * **ToolsCI**(.github/workflows/action_tools.yml) * **AutoTestCI**(.github/workflows/action_utest.yml) * **Check File Format and License**(.github/workflows/file_check.yml) * **Static code analysis**(.github/workflows/static_code_analysis.yml) 下面分别讲解这五个Github Action。 ## **RT-Thread BSP build check** 总的来说,这个Action会通过`matrix`尝试编译多个BSP,并记录编译成功和失败的信息。执行脚本中的每个BSP编译步骤都在日志中创建了一个分组,以便在编译成功或失败时可以更好地显示和记录相关信息。 `matrix`列表中每个元素有三个属性,分别是 * RTT_BSP:这组BSP的名字,后续输出日志时会用到 * RTT_TOOL_CHAIN:编译这组BSP使用的工具链 * SUB_RTT_BSP:各个BSP的目录 ### **RT-Thread BSP build check的第一步:** * 首先先安装gcc和menuconfig依赖的包 * 调用tools目录下的menuconfig的`touch_env` * 这个函数主要是创建一系列后续会使用到的文件夹,并且拉取远程的packages * 以及修改Kconfig * 设置一些RT-Thread自己的环境遍历,供后续使用 ```bash name: Install Tools shell: bash run: | sudo apt-get update sudo apt-get -qq install gcc-multilib libncurses5 libncurses5-dev libncursesw5-dev scons sudo python -m pip install --upgrade pip -qq pip install requests -qq git config --global http.postBuffer 524288000 python -c "import tools.menuconfig; tools.menuconfig.touch_env()" echo "RTT_ROOT=${{ github.workspace }}" >> $GITHUB_ENV echo "RTT_CC=gcc" >> $GITHUB_ENV ``` ### **RT-Thread BSP build check的第二步:** * 会根据`matrix.legs.RTT_TOOL_CHAIN`判断需要安装什么工具链 ### **RT-Thread BSP build check的第三步:** 第三步是这次BSP编译测试的核心 * 首先会遍历所有的`SUB_RTT_BSP` * 根据scons命令执行的成功与否(`||`前一个命令执行失败、`&&`前一个命令执行成功)来判断执行成功还是失败的逻辑 * 输出的时候会在GitHub Actions日志中创建一个分组,用于显示BSP编译的信息 * 计算总共花费的时间,输出BSP编译成功或者失败的信息,输出至`$GITHUB_STEP_SUMMARY` ```bash name: Bsp Scons Compile if: ${{ success() }} shell: bash env: RTT_BSP: ${{ matrix.legs.RTT_BSP }} RTT_TOOL_CHAIN: ${{ matrix.legs.RTT_TOOL_CHAIN }} SRTT_BSP: ${{ join(matrix.legs.SUB_RTT_BSP, ',') }} run: | source ~/.env/env.sh failed=0 count=0 for bsp in $(echo $SRTT_BSP | tr ',' '\n'); do count=$((count+1)) echo "::group::Compiling BSP: ==$count=== $bsp ====" echo bsp/$bsp pushd bsp/$bsp && pkgs --update && popd scons -C bsp/$bsp -j$(nproc) --debug=time | tee output.log || \ { total_time=$(grep "Total command execution time" output.log | awk '{print $5}'); \ failed=$((failed+1)) ; echo "::endgroup::" ; echo "::error::build $bsp failed" ; \ echo "- ❌ build $bsp failed in $total_time seconds " >> $GITHUB_STEP_SUMMARY ; } && \ { total_time=$(grep "Total command execution time" output.log | awk '{print $5}'); \ echo "- ✅ build $bsp success in $total_time seconds " >> $GITHUB_STEP_SUMMARY ; echo "::endgroup::" ; } done exit $failed ``` ## ToolsCI 总的来说,ToolsCI这个Action比较简单,会去尝试Build一个BSP、生成其它工程文件等等,用来测试使用。 关于scons一些参数的使用可以参考:[SCons (rt-thread.org)](https://www.rt-thread.org/document/site/#/development-tools/build-config-system/SCons) ```bash name: ToolsCI # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: # Runs at 16:00 UTC (BeiJing 00:00) on the 1st of every month schedule: - cron: '0 16 1 * *' push: branches: - master paths-ignore: - documentation/** - '**/README.md' - '**/README_zh.md' - '**/*.c' - '**/*.h' - '**/*.cpp' pull_request: branches: - master paths-ignore: - documentation/** - '**/README.md' - '**/README_zh.md' - '**/*.c' - '**/*.h' - '**/*.cpp' permissions: contents: read # to fetch code (actions/checkout) jobs: test: runs-on: ubuntu-latest name: Tools strategy: fail-fast: false env: TEST_BSP_ROOT: bsp/stm32/stm32f407-atk-explorer steps: - uses: actions/checkout@v3 - name: Install Tools shell: bash run: | sudo apt-get update sudo apt-get -yqq install scons - name: Install Arm ToolChains if: ${{ success() }} shell: bash run: | wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.3/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt /opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version echo "RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin" >> $GITHUB_ENV - name: Build Tools run: | scons --pyconfig-silent -C $TEST_BSP_ROOT scons -j$(nproc) -C $TEST_BSP_ROOT - name: Project generate Tools if: ${{ success() }} run: | echo "Test to generate eclipse project" scons --target=eclipse -s -C $TEST_BSP_ROOT echo "Test to generate cmake project" scons --target=cmake -s -C $TEST_BSP_ROOT echo "Test to generate makefile project" scons --target=makefile -s -C $TEST_BSP_ROOT - name: Project dist Tools if: ${{ success() }} run: | echo "Test to dist project" scons --dist -C $TEST_BSP_ROOT scons --dist-ide -C $TEST_BSP_ROOT ls $TEST_BSP_ROOT ls $TEST_BSP_ROOT/dist scons -C $TEST_BSP_ROOT/dist/project scons -C $TEST_BSP_ROOT/rt-studio-project ``` ## AutoTestCI 总的来说,这个Action的主要目标是根据`matrix`中的不同参数组合,安装必要的工具链、构建和测试代码。具体的步骤包括检出代码、安装所需工具、设置环境变量、构建代码,然后在qemu中运行测试并输出日志。根据参数的不同,这个工作流可以自动处理多个平台和架构的测试。 `matrix`列表中每个元素有五个属性,分别是 * `UTEST`:这组BSP的名字,后续输出日志时会用到 * `RTT_BSP`:测试使用的BSP * `QEMU_ARCH`:QEMU使用的平台架构 * `QEMU_MACHINE`:选择QEMU的板级支持包 * `CONFIG_FILE`:RT-Thread条件编译使用的CONFIG * `SD_FILE`:使用的sd.bin * `RUN`:是否启动 ### AutoTestCI的第一步: * 安装必要的工具:scons、qemu、git ### AutoTestCI的第二步: * 根据`matrix`的属性选择安装相应的编译工具链 * 比如要测试arm架构和rtsmart/arm时,我们就选择安装arm-linux-musleabi_for_x86_64-pc-linux-g工具链 ```bash name: Install Arm Musl ToolChains if: ${{ matrix.legs.QEMU_ARCH == 'arm' && matrix.legs.UTEST == 'rtsmart/arm' && success() }} shell: bash run: | wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/arm-linux-musleabi_for_x86_64-pc-linux-g sudo tar xjf arm-linux-musleabi_for_x86_64-pc-linux-gnu_stable.tar.bz2 -C /opt /opt/arm-linux-musleabi_for_x86_64-pc-linux-gnu/bin/arm-linux-musleabi-gcc --version echo "RTT_EXEC_PATH=/opt/arm-linux-musleabi_for_x86_64-pc-linux-gnu/bin" >> $GITHUB_ENV echo "RTT_CC_PREFIX=arm-linux-musleabi-" >> $GITHUB_ENV ``` ### AutoTestCI的第三步: * 第三步主要完成`$TEST_BSP_ROOT`下BSP的编译,以供后续在qemu上使用 ```bash name: Build BSP run: | echo CONFIG_RT_USING_UTESTCASES=y >> $TEST_BSP_ROOT/.config cat examples/utest/configs/$TEST_CONFIG_FILE >> $TEST_BSP_ROOT/.config scons --pyconfig-silent -C $TEST_BSP_ROOT scons -j$(nproc) --strict -C $TEST_BSP_ROOT ``` ### AutoTestCI的第四步: 第四步也是最重要的一步,开始测试相关用例 * 拉取RT-Thread自动化测试机器人 * 制作sd.bin * 使用需要测试的BSP启动qemu * 最后输出相关日志 ```bash name: Start run Test if: ${{matrix.legs.RUN == 'yes' && success() }} run: | git clone https://github.com/armink/UtestRunner.git pushd $TEST_BSP_ROOT dd if=/dev/zero of=sd.bin bs=1024 count=65536 popd pushd UtestRunner if [ $TEST_SD_FILE != "None" ]; then python3 qemu_runner.py --system $TEST_QEMU_ARCH --machine $TEST_QEMU_MACHINE --elf ../$TEST_BSP_ROOT/rtthread else python3 qemu_runner.py --system $TEST_QEMU_ARCH --machine $TEST_QEMU_MACHINE --elf ../$TEST_BSP_ROOT/rtthread fi cat rtt_console.log popd ``` ## Check File Format and License 这个Action主要是用来检查文件的格式化和版权信息的,主要工作都由tools/ci/file_check.py完成,在此之前主要先检出当前仓库的代码和安装Python脚本依赖的包。 ```yaml name: Check File Format and License on: [pull_request] jobs: scancode_job: runs-on: ubuntu-latest name: Scan code format and license steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v3 with: python-version: 3.8 - name: Check Format and License shell: bash run: | pip install click chardet PyYaml python tools/ci/file_check.py check 'https://github.com/RT-Thread/rt-thread' 'master' ``` ### file_check.py 我们可以先忽略使用的click命令行库,或者也可以从命名和使用方式猜测出它们的功能。 因为这个文件比较简单,所以我们可以猜测函数的入口就是`check()`。主函数里的逻辑是十分简单的,可以看到通过`checkout.get_new_file()`获得了一个文件列表,然后传递给了`FormatCheck`和`LicenseCheck`,它们又分别调用了自身的`check`函数,最后根据它们返回值判断是否检查出错误。 ```py def check(check_license, repo, branch): """ check files license and format. """ init_logger() # get modified files list checkout = CheckOut(repo, branch) file_list = checkout.get_new_file() if file_list is None: logging.error("checkout files fail") sys.exit(1) # check modified files format format_check = FormatCheck(file_list) format_check_result = format_check.check() license_check_result = True if check_license: license_check = LicenseCheck(file_list) license_check_result = license_check.check() if not format_check_result or not license_check_result: logging.error("file format check or license check fail.") sys.exit(1) logging.info("check success.") sys.exit(0) ``` `checkout.get_new_file()`获得的文件列表是需要检查的文件列表,而`FormatCheck`和`LicenseCheck`执行各自的检查逻辑。 首先是`get_new_file`,具体的逻辑也比较简单: 1. 通过git命令获得新增和修改的文件列表 2. 然后遍历这个文件列表 3. 遍历这个文件列表中的文件路径的每一层目录,看是否存在.ignore_format.yml文件 4. 然后根据.ignore_format.yml的属性来判断当前文件是否需要被检查 而`FormatCheck`主要完成的工作是: 1. 搜索所有.c和.h文件 2. 然后检查行首、行尾以及tab 而`LicenseCheck`的逻辑也比较简单,主要就是判断当前的Copyright的年份是否正确。 ```py if 'Copyright' in file[1] and 'SPDX-License-Identifier: Apache-2.0' in file[3]: try: license_year = re.search(r'2006-\d{4}', file[1]).group() true_year = '2006-{}'.format(current_year) if license_year != true_year: logging.warning("[{0}]: license year: {} is not true: {}, please update.".fo else: logging.info("[{0}]: license check success.".format(file_path)) except Exception as e: logging.error(e) else: logging.error("[{0}]: license check fail.".format(file_path)) check_result = False ``` ## Static code analysis 这个Action和Check File Format and License是很类似的,主要流程都是相同的。 最重要的就是利用cppcheck完成静态代码检查的功能: 1. 从文件列表中再一次过滤出C/C++相关文件 2. 然后使用cppcheck逐个检查文件列表,并且捕获标准错误流 ```py class CPPCheck: def __init__(self, file_list): self.file_list = file_list def check(self): file_list_filtered = [file for file in self.file_list if file.endswith(('.c', '.cpp', '.cc', '.cxx'))] logging.info("Start to static code analysis.") check_result = True for file in file_list_filtered: result = subprocess.run(['cppcheck', '--enable=warning', 'performance', 'portability', '--inline-suppr', '--error-exitcode=1', '--force', file], stdout = subprocess.PIPE, stderr = subprocess.PIPE) logging.info(result.stdout.decode()) logging.info(result.stderr.decode()) if result.stderr: check_result = False return check_result @click.group() @click.pass_context def cli(ctx): pass @cli.command() def check(): """ static code analysis(cppcheck). """ format_ignore.init_logger() # get modified files list checkout = format_ignore.CheckOut() file_list = checkout.get_new_file() if file_list is None: logging.error("checkout files fail") sys.exit(1) # use cppcheck cpp_check = CPPCheck(file_list) cpp_check_result = cpp_check.check() if not cpp_check_result: logging.error("static code analysis(cppcheck) fail.") sys.exit(1) logging.info("check success.") sys.exit(0) if __name__ == '__main__': cli() ``` ---
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
dejavudwh
这家伙很懒,什么也没写!
文章
7
回答
0
被采纳
0
关注TA
发私信
相关文章
1
大神们,rt-thread启用WDT了,但是还是没启动,怎么办?
2
求一个师傅带带队,有偿交学费 肯吃苦
3
自己按照官方手册 在drv_gpio.c里面找不到PIN脚信息
4
rtt studio f4默认生成的代码无法使用
5
官方例程中的 USB设置配置不成功
6
STM32F4的虚拟串口 的USB时钟如何配置
7
AT24CXX 软件包函数 at24cxx的问题
8
rtthread studio和bsp文件之间生成的区别和联系?
9
pwm根据手册修改为对应的引脚后无效
10
文件系统挂实验 ls命令异常
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部