如何快速向RT-Thread提一个PR:以CI为例

06/06 17:53
阅读数 59

PR方法(Git操作)








01
Fork

首先将官方仓库 fork 到我们自己的账号下,点击一下 fork 按钮,按照提示操作即可。

回到自己的仓库中,将仓库clone到本地。

git clone https://github.com/yourusername/rt-thread.git

如果是较早之前fork的仓库,可以先和上游的仓库同步一下:

1. 先在仓库页面Update branch

2. 在本地仓库git fetch & git merge


02
Commit & Push

一般来说,一个issue或者PR对应一个新的分支,所以需要创建一个分支

git checkout -b <branchname>

更改相应的代码,然后提交代码

git add .

git commit -m "message"

git push origin test-branch


03
Pull Request

在仓库首页按操作提起一个PR


04
Rollback

如果提交有误或者需要修改,可以进行回滚,然后重新push

git reset HEAD^(回退到上一个版本)


05
CI

查看CI结果,根据结果对代码进行修改



功能的修改和增加:以CI(issue 7458)为例





01
理解issue

[CI][cppcheck] 需要根据ignore_format 过滤掉不需要扫描的文件夹 · Issue #7458 · RT-Thread/rt-thread (github.com)
https://github.com/RT-Thread/rt-thread/issues/7458

对问题本身的理解十分重要,issue里可能会有其他人对这个需求的或者问题详细讨论和思路的提供,所以仔细查看issue非常重要。

根据这个issue的描述,主要是添加忽略一些文件和目录进行静态检查的功能。

具体需求是:

1. 添加对.ignore_format.yml配置文件检查

2. 如果新更新的文件在dir_path属性的目录下或者在file_path属性中

3. 对这个文件就不启用静态检查

并且这个issue中也提供了一种思路:

1. 遍历一下ignore_format.yml文件找到所有需要忽略的文件夹,搞个大数组,然后过滤

2. 参考一下

https://github.com/RT-Thread/rt-thread/blob/master/tools/file_check.py


02
代码定位

代码定位是对功能的修改和增加的第一步,对于Bug fix来说,代码定位可能比较困难,但是对于功能的修改和增加来说,是比较简单的。

首先可以看出来这个issue的工作主要是CI这块,那么我们需要先了解github的CI工具:Github Action。最好的文档肯定就是GitHub Actions文档 - GitHub 文档。我们不需要全部了解之后再动手,只要了解一些基本概念之后就可以先动手。

根据文档的描述,我们可以了解到github workflow使用yml来描述,并且放在了.github/workflow目录下,所以第一步可以定位到.github/workflow下的static_code_analysis.yml。

在这个目录我们可以看到static_code_analysis.yml是直接在yaml中用shell编写工作流程,而还有其它文件如file_check.yml使用调用其它Python脚本来完成工作流程。所以基本可以确定我们需要修改或者增加的地方就在.github/workflow和tools/ci下。


03
代码阅读

在这里,我们参考file_check.yml的实现。所以需要先理解file_check.yml的整体实现。

file_check.yml主要先使用shell按照了Pyhon脚本中必须使用的库然后直接调用Python脚本,我们直接跳入这个被调用的脚本查看。

代码阅读个人比较喜欢也觉得比较快速的方式是:先了解代码的某一部分(需要控制精度)的大致结构和功能,不关注其具体实现,之后再深入理解具体实现。在这个过程中有需要去猜测别人是如何写的代码,并且在一步步阅读代码的过程当中验证和纠正自己的想法。

我们来看file_check.py。

我们可以先忽略使用的click命令行库,或者也可以从命名和使用方式猜测出它们的功能。

因为这个文件比较简单,所以我们可以猜测函数的入口就是check()。主函数里的逻辑是十分简单的,可以看到通过checkout.get_new_file()获得了一个文件列表,然后传递给了FormatCheckLicenseCheck,它们又分别调用了自身的check函数,最后根据它们返回值判断是否检查出错误。

所以我们可以猜测checkout.get_new_file()获得的文件列表是需要检查的文件列表,而FormatCheckLicenseCheck执行各自的检查逻辑,我们可以不用关注。

get_new_file的就需要深入代码看具体实现,具体的逻辑也比较简单。

1. 通过git命令获得新增和修改的文件列表

2. 然后遍历这个文件列表

3. 遍历这个文件列表中的文件路径的每一层目录,看是否存在.ignore_format.yml文件

4. 然后根据.ignore_format.yml的属性来判断当前文件是否需要被检查

所以我们实现的重点就是对需要检查的代码进行静态代码检查。


04
功能增加

首先,因为获得需要检查的文件列表这个功能是可能会被多次利用,可以先提取出来作为一个独立功能,并且可以做一些优化(在获得新增和修改的文件列表时的写法可以优化)。

其次,最重要的就是利用cppcheck完成静态代码检查的功能:

1. 从文件列表中再一次过滤出C/C++相关文件

2. 然后使用cppcheck逐个检查文件列表,并且捕获标准错误流

 1class CPPCheck:
2    def __init__(self, file_list):
3        self.file_list = file_list
4    def check(self):
5        file_list_filtered = [file for file in self.file_list if file.endswith(('.c''.cpp''.cc''.cxx'))]
6        logging.info("Start to static code analysis.")
7        check_result = True
8        for file in file_list_filtered:
9            result = subprocess.run(['cppcheck''--enable=warning''performance''portability''--inline-suppr''--error-exitcode=1''--force', file], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
10            logging.info(result.stdout.decode())
11            logging.info(result.stderr.decode())
12            if result.stderr:
13                check_result = False
14        return check_result
15@click.group()
16@click.pass_context
17def cli(ctx):
18    pass
19@cli.command()
20def check():
21    """
22    static code analysis(cppcheck).
23    """

24    format_ignore.init_logger()
25    # get modified files list
26    checkout = format_ignore.CheckOut()
27    file_list = checkout.get_new_file()
28    if file_list is None:
29        logging.error("checkout files fail")
30        sys.exit(1)
31    # use cppcheck
32    cpp_check = CPPCheck(file_list)
33    cpp_check_result = cpp_check.check()
34    if not cpp_check_result:
35        logging.error("static code analysis(cppcheck) fail.")
36        sys.exit(1)
37    logging.info("check success.")
38    sys.exit(0)
39if __name__ == '__main__':
40    cli()


05
功能测试

完成代码的修改之后最重要的就是通过测试,最基本也是最简单的测试就是功能测试。所以我们可以给这次的修改安排三个测试:

修改cppcheck会出现错误的文件:

case 1:不将文件加入.ignore_format.yml,CI报错

case 2:将文件加入.ignore_format.yml的file_path,CI不报错

case 3:将文件加入.ignore_format.yml的dir_path,CI不报错



PR心得








这次PR的提交有以下两个小心得。

01
仔细沟通

第一点,也是最重要的一点就是和主动社区的前辈进行交流,对issue的问题和需求进行讨论。在这个PR被merge之前我就完成了其余两版,但是因为缺乏沟通,不是很适合当前的RT-Thread。


02
Github Action 本地测试

在修改CI部分时,每次都需要推送到远端才能执行相关的action,这样比较麻烦。可以使用nektos/act: Run your GitHub Actions locally 🚀工具在本地跑Github action。

原文:https://club.rt-thread.org/ask/article/0b4c0d3b999554d0.html

———————End———————


RT-Thread线下入门培训

6月 - 深圳


1.免费 2.动手实验+理论 3.主办方免费提供开发板 4.自行携带电脑,及插线板用于笔记本电脑充电 5.参与者需要有C语言、单片机(ARM Cortex-M核)基础,请提前安装好RT-Thread Studio 开发环境



立即扫码报名



报名链接

https://jinshuju.net/f/UYxS2k

巡回城市:青岛、北京、西安、成都、武汉、郑州、杭州、深圳、上海、南京


你可以添加微信:rtthread2020 为好友,注明:公司+姓名,拉进RT-Thread官方微信交流群!



👊点击阅读原文,进入RT-Thread 官网


本文分享自微信公众号 - RTThread物联网操作系统(RTThread)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部