
RIOT OS 持续集成体系全解从 Murdock 构建集群到 GitHub Actions 工作流【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOTRIOT 是面向物联网的操作系统支持数百种开发板其代码质量与跨平台可用性依赖一套双引擎驱动的持续集成CI体系自托管的 Murdock 构建与测试集群以及基于 GitHub Actions 的十余个自动化检查工作流。本文以 doc/guides/misc/ci.md 为骨架结合仓库内.murdock、.murdock.yml、dist/tools/ci/与.github/workflows/下的真实源码完整讲解 RIOT 的 CI 工作方式、标签控制机制、构建缩减策略以及每个工作流的具体职责。读完本文你将能理解为什么 PR 开了不会自动构建各种CI:标签分别控制什么并能在提交代码时主动配合这套流水线让构建与评审更顺畅。RIOT CI 体系总览Murdock GitHub Actions 双引擎RIOT 的构建系统由两大组件构成Murdock与GitHub Action Workflows。Murdock是 RIOT 自研的 CI 系统承担主构建与测试任务为每个拉取请求PR编译代码并对 master 分支与发布分支执行 Nightly夜间构建。GitHub Action Workflows在代码进入 Murdock 之前先行运行一批测试与检查commit 消息规范、标签合法性、静态检查、文档构建等从而把宝贵的算力留给真正需要大规模编译的任务。需要注意Murdock 的全部算力由 RIOT OS 项目的支持者捐赠提供文档也明确提醒请谨慎、负责任地使用这些资源。这也解释了为什么构建流程被设计得如此吝啬——能少编译就少编译能用标签控制就不盲目全量构建。MurdockRIOT 自研的持续集成系统Murdock 与 GitHub 的集成对用户而言几乎是透明的PR 第一次构建完成后riot-ci机器人会在 PR 下发布一条状态消息汇总成功与失败的构建任务数、执行耗时并附上最新构建任务的链接。所有构建任务可以在 CI 主页查看此外还部署了一个独立的 staging 实例专门用于 Murdock 自身的变更与更新验证。从仓库根目录的 .murdock 脚本可以看到 Murdock 的工程化程度它本质上是一个由dwqc/dwq分布式工作队列工具驱动的任务调度脚本通过get_jobs、get_compile_jobs、compile、test_job、run_test等函数生成应用 × 开发板 × 工具链的组合矩阵并分发给 worker。构建矩阵的生成逻辑.murdock中定义了三种关键配置QUICKBUILD_BOARDS快速构建时覆盖的代表性开发板子集例如adafruit-itsybitsy-m4、atmega256rfr2-xpro、esp32-wroom-32、frdm-k64f、native32/native64、nrf52840dk、samr21-xpro、stm32f429i-disc1等覆盖不同 CPU 架构以尽早发现问题。TEST_BOARDS_LLVM_COMPILE额外用 LLVM 工具链编译的开发板如iotlab-m3、nrf52dk、nucleo-f401re避免 CI 时间翻倍的同时保留回归测试覆盖。TEST_WITH_CONFIG_SUPPORTED使用test-with-config方式测试的应用如examples/advanced/suit_update与tests/drivers/at86rf2xx_aes。compile()函数中可以看到构建细节每个任务独立设置BINDIR$(pwd)/build构建前清理目录启用 ccache将缓存临时目录放在 tmpfs 上以降低磁盘 IO随后执行make -C${appdir} all test-input-hash -j${JOBS:-4}。构建成功后若满足条件RUN_TESTS1或目标板为 native32/native64/模拟板还会调用make test或make test-murdock将测试任务投递到测试队列。用 GitHub Labels 控制 Murdock打开 PR 后构建不会自动开始。维护者会先快速检查 PR 是否安全、是否有意义再手动打上标签来触发构建。仓库中相关标签及其作用如下标签作用触发机制CI: ready for build启动 Murdock 构建只构建部分代表性开发板维护者手动设置CI: full build对每一个应用 × 每一个开发板做全量构建维护者手动设置构建完成后应移除CI: no fast fail将失败中止上限从 1 提升到 500让流水线继续跑完维护者手动设置CI: skip compile test跳过所有代码编译适用于纯文档改动维护者手动设置CI: run tests在 Pi fleet树莓派硬件测试集群上显式运行硬件测试维护者手动设置CI: disable test cache禁用测试结果缓存强制重新执行测试维护者手动设置见 .murdockCI: ready for build —— 快速构建与can_fast_ci_run.py该标签只对部分开发板构建代码所选开发板被期望能代表所有受支持开发板的横截面以便尽早发现潜在问题。真正决定构建范围的是 dist/tools/ci/can_fast_ci_run.py它通过git diff --numstat HEAD..upstreambranch分析 PR 改动的文件并按照正则规则分类为other构建系统、公共头文件、Kconfig、文档、CI 配置等、modulescore/cpu/drivers/sys、pkgs、boards、apps五类。若改动涉及构建系统、Kconfig、公共头文件、模块或包则判定必须全量构建sys.exit(1)。若只改了少量应用或开发板则输出BOARDS_CHANGED.../APPS_CHANGED...供 .murdock 的update_changed_modules()通过eval消费从而把构建范围缩小到改动的板只构建改动的应用或改动的应用在所有板上构建。还有一个巧妙细节对于.c/.h文件only_comment_change()会先用gcc -fpreprocessed -dD -E -P去掉注释再比较哈希纯注释改动不会被算作实质性变更。CI: full build —— 合并前的全量验证设置该标签会执行与合并前完全一致的构建每个应用在每个开发板上编译资源消耗极大应尽量少用——例如上次合并失败、重试前需要完整基线时。全量构建完成后务必移除该标签。从 .murdock 源码看FULL_BUILD变量在 Nightly 构建或该标签存在时被置为 1否则为 0且 full build 时QUICK_BUILD不会被设置构建范围不再被缩减。CI: no fast fail —— 关闭快速失败默认情况下构建在第一个失败任务后即中止以节省算力并避免系统性错误产生又长又无用的失败日志。但有时开发者想看到首个失败之后还有哪些会挂此时设置CI: no fast fail把中止上限从 1 个失败提升到500 个失败让尽可能多的任务跑完再汇总。CI: skip compile test —— 纯文档改动跳过编译对只影响文档等内容的 PR无需构建任何代码。若can_fast_ci_run.py尚未把这类改动识别出来它确实把doc/.*、*.md、*.txt归为doc类维护者可用该标签强制跳过编译。注意该标签不影响合并构建——如果can_fast_ci_run.py判定需要全量构建合并时仍会执行全量构建。CI: run tests —— 显式触发硬件测试要在 Pi fleet 上为某个 PR 显式运行硬件测试设置CI: run tests。否则测试只会在下一次 Nightly 构建时运行。.murdock 中的逻辑与此对应当RUN_TESTS未被外部显式传入时若NIGHTLY1或检测到该标签则RUN_TESTS1否则为 0。测试结果缓存test cache为节省算力Murdock 引入测试结果缓存构建时会生成test-input-hash.sha1再通过sha1sum汇总得到test_hash。run_test()成功后会把哈希写入 Redistest_cache_put下次遇到相同哈希时直接跳过测试test_cache_get命中。相关逻辑见 .murdock 与test_job/run_test函数。Murdock 的配置与 Nightly 构建.murdock 与 .murdock.yml仓库根目录的 .murdock.yml 是 Murdock 的总配置push: branches: # these two enable potential bors support: - ^staging$ - ^trying$ # github merge trains: - ^gh-readonly-queue/ pr: enable_comments: true sticky_comment: true comment_artifacts: - name: doc-preview/ readable_name: Documentation preview commit: skip_keywords: [ci_skip, murdock_skip, [ci skip] ] artifacts: - output.txt - doc-preview/它声明了 push 触发的分支含 GitHub merge trains 的gh-readonly-queue/、PR 评论与文档预览产物doc-preview/以及可跳过构建的 commit 关键字ci_skip、murdock_skip、[ci skip]。而 .murdock 则是 worker 端脚本定义了构建矩阵、FULL_BUILD/QUICK_BUILD/RUN_TESTS的推导逻辑、测试缓存与静态测试入口static_tests()。Nightly 构建文档将 Nightly 构建一节标注为待扩展但从 .murdock 源码可以确认其行为NIGHTLY${NIGHTLY:-0}当NIGHTLY1时强制FULL_BUILD1并关闭PKG_USE_MIRROR直接拉取上游包而非镜像同时默认RUN_TESTS1——也就是说夜间构建是对 master 与发布分支的全量编译 全量测试Pi fleet 的硬件测试也在此执行。GitHub Action Workflows 逐个拆解GitHub 为开源项目提供免费算力RIOT 用它来跑各类轻量检查。以下是.github/workflows/下各工作流的职责梳理均为仓库内确认存在的 workflow 文件check-commits提交信息守门人该工作流检查 PR 的 commit 消息由两个子任务 一个汇总任务组成见 check-commits.ymlcommit-msg 检查check-commits [commit-msg]调用 dist/tools/commit-msg/check.sh校验摘要行长度符合 50/72 规则首行 ≤50 字符、正文每行 ≤72 字符。pr_check 检查check-commits [pr_check]调用 dist/tools/pr_check/check.sh对照 dist/tools/pr_check/no_merge_keywords 中的No Merge Keywords正则表如SQUASH、FIX、WIP、TEMP、DO NOT MERGE、DELETE ME、Apply suggestions from ...等检测 PR 是否尚未准备合并。check-commits-success通过re-actors/alls-green汇总前两项结果任一失败即为阻塞态。check-labels标签与评审状态检查该工作流检查 PR 的标签与评审状态是否满足可合并条件使用RIOT-OS/check-labels-action。具体规则写在 check-labels.yml 中unset_labels: CI: needs squashing,State: waiting for CI update,State: waiting for other PR,Process: blocked by feature freeze cond_labels: (Process: needs 1 ACK,review.approvals1),(Area: RDM,review.approvals2) missing_approvals_label: Process: missing approvals即存在CI: needs squashing等标签时不可合并Process: needs 1 ACK要求至少 1 个 review 通过、Area: RDM要求至少 2 个缺少批准时会自动打上Process: missing approvals标签。deploy-guides文档部署每次合并后将更新后的 Starlight 文档推送到 RIOT OS 指南服务器。与之配套的还有test-guides工作流——每次 PR 构建 Starlight 文档以发现破坏性变更目前不提供指南预览。first-contribution新手友好提示检测 PR/issue 是否来自首次贡献者若是则输出额外信息帮助新人快速上手 RIOT 的贡献流程。labeler自动打标签根据 PR 改动的文件自动打上Area:、Platform:等标签。映射规则全部在 .github/labeler.yml 中定义例如改动sys/arduino/**打Area: arduino API改动pkg/nimble/**、sys/net/ble/**打Area: BLE改动boards/**打Area: boards改动Makefile.*、makefiles/**、**/*.mk打Area: build system改动.github/**/*.yml、.murdock、.murdock.yml打Area: CI。这为维护者快速判断 PR 影响范围提供了依据。pr-ai-disclosureAI 披露检查检查新 PR 是否包含 AI 披露声明RIOT 要求使用 AI 辅助生成的贡献需明确披露。若缺失会在 PR 上添加评论告知作者并打上相应标签。release-test发布回归保障每周以及对每个 RCrelease candidate与 release 标签运行发布规格测试确保受支持的版本即使在 CI 基础设施变更或工具升级后依然能正常构建。static-test静态检查套件该工作流在每次 PR 与 master 合并时通过make static-test运行一组 lint、风格与拼写检查器。仓库内的执行入口是 dist/tools/ci/static_tests.shCI 侧由 static-test.yml 在riot/static-test-toolsDocker 镜像中执行。其检查项包括源码中以run调用依次列出whitespacecheck基于 git 的空白检查licenses校验改动文件是否包含合规的 SPDX 许可证头如SPDX-License-Identifier: LGPL-2.1-onlydoccheck对代码运行 Doxygen任何未排除的 warning 都会报错externc检查 C 头文件是否包含供 C 兼容的extern C声明vera运行 Vera 风格检查器coccinelle运行 Coccinelle 语义匹配与转换引擎以及flake8、headerguards、buildsystem_sanity_check、feature_resolution、boards_supported、board_doc_check、codespell、cargo-checks、uncrustify、shellcheck等。值得注意的是static_tests.sh中的依赖声明每个检查器所需的命令如doxygen、vera、spatch、uncrustify、shellcheck缺失时会以警告形式标记失败clang-format 目前仅为 advisoryERROR_EXIT_CODE0。sync-codeberg仓库镜像同步将代码库从 GitHub 单向镜像同步到 Codeberg目前为单向镜像直至迁移工作继续推进。test-on-iotlab真实硬件测试在 FIT IoT-Lab 测试床提供的开发板上运行 dist/tools/compile_and_test_for_board/compile_and_test_for_board.py验证代码在真实硬件上的可用性。该工作流只覆盖有限的测试与开发板。tools-buildtest 与 tools-test工具链自检tools-buildtest对dist/tools下需要编译的辅助工具做构建测试每个 PR、master 分支及 release 标签。tools-test测试dist/tools与dist/pythonlibs下的辅助脚本和库无需编译覆盖范围同上。二者互为补充确保 CI 工具自身不退化。贡献者视角如何配合 RIOT 的 CI基于上述机制向 RIOT 提交 PR 时可以从以下几点主动配合保证 commit 消息规范摘要行控制在 50 字符内避免WIP、SQUASH、FIX等 No Merge Keywords避免触发check-commits的pr_check阻塞。理解标签是必经之路PR 默认不构建由维护者评估后设置CI: ready for build纯文档改动可等待CI: skip compile test跨模块或构建系统改动会被can_fast_ci_run.py判定为需要全量构建耐心等待即可。静态检查先行合并前static-test会跑完整套 lint/风格/文档检查本地可先用make static-test预演基于 master 分支基线减少在 CI 上反复排队。AI 辅助贡献记得披露PR 中若使用 AI 工具务必填写 AI 披露声明否则pr-ai-disclosure会拦截。珍惜捐赠的算力避免无意义地触发全量构建或重复测试测试结果缓存test cache就是为降低重复开销而设计的。小结RIOT 的持续集成体系是一个分层守门的经典工程实践GitHub Actions 在入口处做低成本、高频率的格式与静态检查Murdock 则负责重量级的跨平台编译矩阵与硬件测试两者通过CI:系列标签与can_fast_ci_run.py的变更分类协同在算力捐赠的约束下做到该省的全省、该测的全测。本文涉及的核心配置与脚本均可在仓库内找到对应文件标签与构建逻辑见 .murdock 与 .murdock.yml变更缩减见 dist/tools/ci/can_fast_ci_run.py静态检查见 dist/tools/ci/static_tests.sh工作流定义见 .github/workflows。理解这套机制既是向 RIOT 贡献代码的前提也是设计大规模嵌入式项目 CI 流水线时值得借鉴的范本。【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考