ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

openpilot 发布工程全解析:从 Release Checklist 到 Prebuilt 构建流水线

openpilot 发布工程全解析:从 Release Checklist 到 Prebuilt 构建流水线 openpilot 发布工程全解析从 Release Checklist 到 Prebuilt 构建流水线【免费下载链接】openpilotopenpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars.项目地址: https://gitcode.com/GitHub_Trending/op/openpilotopenpilot 的每次版本发布都依赖一套「清单驱动 脚本驱动」的工程流程人工按 发布清单 执行 staging 与 release 两阶段操作而 build_stripped.sh 与 build_release.sh 两个脚本则分别承担「源码瘦身包」与「设备预构建二进制包」的生成。读完本文你将掌握 openpilot 版本从 master 到生产分发的完整链路分支管理、文件裁剪、大模型分块、onroad 测试门禁以及各环境变量BRANCH、RELEASE_BRANCH、INCLUDE_BIG_MODEL、PANDA_DEBUG_BUILD的实际作用。发布总览两阶段门禁模型openpilot 的发布过程分为两个明确阶段对应 发布清单 中的「Go to staging」与「Go to release」两节Staging 阶段从 master 切出发布分支回退风险提交构建并推送到 staging 分支供设备端 Jenkins 自动构建、测试Release 阶段完成回归测试矩阵升降级、全新安装、实车驾驶后打 tag、更新工厂配置最终对外发布。版本号的唯一权威来源是 version.h 中的COMMA_VERSION宏当前为0.11.2发布时需要同步更新该文件与 RELEASES.md 的发布说明——这是清单中「bump version on master」一项的具体落点。RELEASES.md 按版本倒序记录了每个 release 的模型更新、硬件改进与新增车型支持例如 0.11.2 版本的 880M 参数大模型、comma connect 实时流摄像头等。Staging 阶段构建发布候选分支清单「Go to staging」一节的操作步骤为建发布跟踪 issue在 GitHub 创建一个 issue把该清单作为 checklist 挂在上面用于跟踪整个发布过程创建 release master 分支从上游 master 创建一个以版本命名的分支清单中给出的命名示例是发布v0.10.2时创建zerotentwozero-ten-two 的口语化拼写回退风险提交revert risky commits并要求与 autonomy 团队二次确认推送新分支推送到 staging确认自己处于新建的 release master 分支上运行BRANCHdevel-staging tools/release/build_stripped.sh。随后 Jenkins 会在设备端自动完成构建运行test_onroad并更新 staging 分支在 master 上提升版本号修改openpilot/common/version.h与RELEASES.md在 Discord 通知并 release crew。build_stripped.sh为什么是「stripped」staging 走的是「源码推送 → 设备端构建」路线核心逻辑在 build_stripped.sh脚本先定位仓库根目录git rev-parse --show-toplevel目标目录默认用mktemp -d生成可用TARGET_DIR环境变量覆盖将仓库.git整体复制到目标目录然后git checkout --orphan tmp创建一个孤立项分支——即与任何历史无关联的全新分支这是「stripped」的关键release 分支不继承 master 的提交历史通过git submodule deinit -f --all与git rm -rf --cached .清空一切再执行find . -maxdepth 1 ... -exec rm -rf删除工作区文件只保留.git随后调用文件过滤脚本做有选择性的拷贝见下文并rm -rf .git/modules/彻底移除子模块元数据——发布产物中不允许存在任何子模块对超过 95MB 的.onnx模型文件逐个执行 file_chunker.py把它们切分为 45MB 的分片提交信息会内嵌源码 commit 哈希、commit 时间戳与构建日期例如openpilot v$VERSION release date: $DATETIME master commit: $GIT_HASH同时把哈希写入git_src_commit、时间戳写入git_src_commit_date文件方便设备端回溯「这个 release 是由哪个 master 构建的」最后做两道硬性校验git lfs ls-files非空则直接退出禁止 LFS 文件进入发布包find . -size 95M发现超大文件也报错退出——因为 GitHub 单文件上限是 100MB留 5MB 余量是刻意设计若设置了BRANCH环境变量staging 场景即devel-staging则以git -c pack.window0 -c pack.depth0 -c pack.compression0 push -f origin tmp:$BRANCH推送。注释里说明了这种「大 pack 直接上传」的选择在设备端跳过 pack 优化、写出更大对象比消耗 CPU 去压缩更快。release_files.py文件裁剪的黑白名单两个构建脚本都依赖 release_files.py 决定哪些文件进入发布包。它的逻辑是用git ls-files -z --recurse-submodules遍历所有被跟踪的文件黑名单正则排除以下内容.git/ .venv/ .github/workflows/ matlab.*.md .lfsconfig .gitattributes .git$ .gitmodules黑名单中专门针对 LFS 与子模块的文件.lfsconfig、.gitattributes、.gitmodules与 build 脚本的「no submodules or LFS」约束互为呼应有一个空的whitelist列表用于放行被误伤的黑名单文件特殊规则除非设置了INCLUDE_BIG_MODEL环境变量openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx这个大模型文件会被跳过。输出以 NUL 分隔两个 shell 脚本通过xargs -0 cp -pR --parents -t $TARGET_DIR --按原目录结构复制进发布目录。大模型分块file_chunker.py 的设计openpilot 的 driving model 体积远超 GitHub 的 100MB 单文件上限file_chunker.py 给出了解法CHUNK_SIZE 45 * 1024 * 1024注释明确写着「45MB, under GitHubs 50MB limit」chunk_file把原文件切成name.chunk01ofNN形式的分片另写一个name.chunkmanifest清单文件记录分片数量然后删除原文件get_existing_chunks/open_file_chunked提供还原能力读到 manifest 就按序打开各分片ChunkStream实现io.RawIOBase让上层代码像读取单个文件一样顺序读取分片流命令行入口python file_chunker.py path可直接对单个文件执行切分这正是 build_stripped.sh 中find openpilot/selfdrive/modeld/models -name *.onnx -size 95M -exec ./openpilot/common/file_chunker.py {} \;调用的形式。注意这里 95MB 的 find 阈值与 45MB 的分片大小配合只要文件超过 95MB 就必然被切成多个分片保证任何单文件都不会逼近 GitHub 上限。Release 阶段测试矩阵与正式分发清单「Go to release」一节要求在正式发布前完成以下测试从上一个 release 升级到新 releaseupdate from previous release - new release从新 release 降级回上一个 releaseupdate from new release - previous release用openpilot-test.comma.ai域名做全新安装fresh install全新安装后实际上车驾驶验证drive on fresh install确认发布包中没有子模块和 LFSno submodules or LFS检查 Sentry、MTBF 等线上指标生产环境的 stress test 通过。测试通过后按顺序执行发布博客 →git reset --hard origin/release-mici-staging→ 打 tag 并推送git tag v0.X.X commit-hash git push origin v0.X.X→ 创建 GitHub Release → 在openpilot.comma.ai上做最终测试安装 → 更新工厂预配置factory provisioning→ 关闭 milestone 和 issue → 在 Discord、X 等平台宣布。build_release.sh设备端 Prebuilt 构建与 staging 的「推源码、设备端现场构建」不同正式 release 走的是 build_release.sh 的预构建prebuilt路线构建产物直接提交为 git 对象推送给设备设备端只需git reset --hard即可完成升级省去设备端的编译耗时。脚本的关键环节前置条件必须设置RELEASE_BRANCH环境变量支持逗号分隔多个分支脚本会for branch in ${RELEASE_BRANCH//,/ }展开统一映射为release-mici-staging:目标分支的 refspec 强推worktree 构建目录以git worktree add --detach --no-checkout /data/openpilot创建独立构建区将 HEAD 切到release-mici-staging分支git symbolic-ref HEAD并用git read-tree --empty清空暂存区得到一个干净的空分支工作区文件拷贝与 stripped 流程相同经 release_files.py 过滤后cp -pR --parents入构建目录CPU 频率释放把各cpufreqpolicy 的scaling_max_freq提到硬件最大值以加速编译注释说明后续test_onroad.py会重置频率两级编译scons构建主体若设置了INCLUDE_BIG_MODEL则断言big_driving_tinygrad.pkl.chunkmanifest存在panda 固件构建未设置PANDA_DEBUG_BUILD时执行CERT/data/pandaextra/certs/release RELEASE1 scons panda/生成带 release 证书的正式固件否则普通scons panda/构建调试固件注释提示ALLOW_DEBUG1会启用 experimental longitudinal 等调试特性子模块断言git submodule--helper list若发现任何子模块立即exit 1把清单中「no submodules or LFS」的要求固化成脚本门禁产物清理删除.a、.o、.os、.pyc、__pycache__、.sconsign.dblite、Jenkinsfile、tools/release/自身以及openpilot/selfdrive/modeld/models/*.onnx*ONNX 模型不进 prebuilt 包运行时用的是 tinygrad pkl 格式prebuilt 标记touch prebuilt创建空文件作为「此分支是预构建产物」的标记提交与压缩策略版本号从 version.h 提取后以openpilot v$VERSION提交同样使用core.compression0注释解释「写出大对象比在设备上压缩更快」发布前最终测试RELEASE1 ./openpilot/selfdrive/test/test_onroad.py通过后以pack.window0 pack.depth0 pack.compression0的无优化 pack 强推到各目标分支。test_onroad.pyrelease 门禁的实质openpilot/selfdrive/test/test_onroad.py 是发布流程中反复出现的最后防线staging 由 Jenkins 触发、prebuilt 构建末尾直接运行。从源码看它覆盖三类约束CPU 预算MAX_TOTAL_CPU 3508 核总预算并对约 30 个进程逐一设定基线配额如controlsd16%、ui40%、pandad40%注释明确「每个进程至少 8%总占用不得超过 MAX_TOTAL_CPU」信号时序TIMINGS字典对can、carState、modelV2、controlsState等约 18 类消息给出rtolsmax/min 波动上限与rsd相对标准差两个统计阈值日志体积LOGS_SIZE规定每 segment 的qlog.zst≤ 0.5MB、rlog.zst≤ 8.1MB、摄像头 HEVC 流 ≤ 76.5MB 等预算。任何一项超预算都会让测试失败从而阻断 release 分支的推送——这正是清单中「no submodules or LFS」「stress test passes in production」等验收项的自动化对应物。辅助脚本与版本约定tools/release/ 下还有三个小型配套脚本值得单独说明identity.sh导出固定的 git 身份Vehicle Researcher userusercomma.ai形式保证 release 分支上由脚本产生的提交具有一致的作者信息便于审计区分「人写的提交」与「构建产生的提交」check-dirty.shgit status --porcelain非空即退出 1用于校验构建后工作区是否干净check-submodules.sh遍历git submodule status --recursive对每个子模块 fetch 后验证其 pin 的 commit 位于origin/master上tinygrad_repo被显式跳过否则报错退出——保证发布基于各子模块主分支的真实状态而非游离 commit。另外 pack.py 与本目录 README 的发布清单无直接关系它是一个基于zipapp的通用打包工具给定一个模块名如openpilot.system.ui.spinner与入口函数把openpilot/下按扩展名白名单.png、.py、.ttf、.capnp、.json、.fnt、.mo、.po筛选出的文件打成可独立执行的 zipapp供 CI 或单机场景运行单个入口脚本。使用方式与适用前提把上述内容收敛为可操作的命令视图均以仓库根目录为工作目录场景命令说明推送 staging 源码包BRANCHdevel-staging tools/release/build_stripped.sh生成孤立项分支并推送到devel-staging由 Jenkins 在设备端构建并运行test_onroad生成 staging 包到指定目录TARGET_DIR/tmp/staging BRANCHdevel-staging tools/release/build_stripped.shTARGET_DIR覆盖默认mktemp -d构建 prebuilt releaseRELEASE_BRANCH目标分支列表 tools/release/build_release.sh需在有 scons 构建环境、panda 证书目录/data/pandaextra/certs/release的构建机上运行构建目录固定为/data/openpilot包含大模型上述命令加INCLUDE_BIG_MODEL1把big_driving_supercombo.onnx纳入发布包prebuilt 构建会断言其 chunk manifest 存在调试版 panda 固件上述命令加PANDA_DEBUG_BUILD1使用不带 release 证书的固件构建路径适用前提与限制整套流程假设操作者拥有目标仓库含release-mici-staging等分支的写权限且设备端已接入 Jenkins 的自动构建与test_onroad链路build_release.sh硬编码了/data/openpilot构建目录与/data/pandaextra/certs/release证书路径这是 comma 构建机的约定本地无此环境时脚本无法原样运行发布产物被强制约束为「无子模块、无 LFS、单文件 100MB」大模型一律以 file_chunker.py 的 45MB 分片形式存在版本号必须与 version.h 一致并在 RELEASES.md 中补记清单中的「bump version」步骤只发生在 masterrelease 分支本身不改版本号。小结openpilot 的发布体系可以概括为三层清单README.md定义人工门禁与责任分工脚本build_stripped.sh、build_release.sh、release_files.py、file_chunker.py把「无子模块、无 LFS、大小受限」等约束固化为可执行的自动校验测试test_onroad.py 的 CPU 预算、信号时序与日志体积门禁则在 staging 与 release 两个节点各拦截一次。这种「人工 checklist 脚本硬门禁 自动化测试」的组合使得升级/降级、全新安装与实车驾驶等高风险环节都有明确的验证入口是车载软件发布流程中值得参考的工程范式。【免费下载链接】openpilotopenpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars.项目地址: https://gitcode.com/GitHub_Trending/op/openpilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表