资讯动态

IsaacLab Changelog Fragment 体系实战:从 jdoe-fix-rotation-frame.rst 到语义化版本自动晋升

发布时间:2026/9/17 4:31:18 来源:尧图企业网站定制
IsaacLab Changelog Fragment 体系实战从 jdoe-fix-rotation-frame.rst 到语义化版本自动晋升【免费下载链接】IsaacLabUnified framework for robot learning with multi-physics/renderer support项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab导读本文以 IsaacLab 仓库 tools/changelog/test/integration/02_minor_bump/fragments/jdoe-fix-rotation-frame.rst 为切入点系统拆解 IsaacLab 的 changelog fragment变更日志片段工作流一个仅三行的 RST 片段如何定义Fixed条目、如何通过文件名后缀声明版本晋升级别并在与 minor 片段混合时如何驱动1.2.3 → 1.3.0的自动编译。读完本文你将掌握 fragment 的书写规范、bump 聚合规则、CI 门禁校验逻辑以及如何在本地用--dry-run预览一次真实的 changelog 编译。一、先认识这份文档一个小身体、大角色的测试夹具被指定的关联文档内容极简全文如下Fixed ^^^^^ * Fixed a NaN propagation in :meth:~example.Sensor.update.这份文件不是孤立存在的笔记而是 IsaacLab changelog 工具链端到端集成测试的可执行夹具。它位于02_minor_bump演示目录下与该目录的另外两个 fragment 共同构成一个小版本晋升的完整演示场景并被 test_bump_suffix.py 与 test_integration.py 直接引用作为测试输入。从 集成测试 README 可以确认其定位每个子目录存放一套worked example——输入 fragment、初始CHANGELOG.rstchangelog_before.rst以及期望的编译输出changelog_after.rst。测试套件会把编译器跑在这套夹具上并断言输出与changelog_after.rst逐字节一致日期除外从而保证编译管线任何一处漂移都会立刻暴露。换句话说这份三行文档同时是格式范本和回归测试锚点。二、Fragment 文件格式RST 章节 子弹条目jdoe-fix-rotation-frame.rst展示了 fragment 的两种关键语法要素这与 cli.py 中Fragment.parse()的实现一一对应1. 章节标题 ^下划线parse()将非空标题行 长度相等或更长的^下划线行识别为一个章节。fragment 允许一个或多个章节标题Added、Changed、Deprecated、Removed、Fixed是规范章节名编译输出时按此顺序排列见FragmentBatch._SECTION_ORDER。2. 每条条目必须以*开头Fragment.validate()强制三条内容规则文件非空且至少包含一个合法章节标题每个已声明章节内至少有一条*开头的子弹条目——否则视为作者写了标题忘了正文直接报错章节体内不允许出现顶格非子弹的孤儿段落——因为它会把 RST 子弹列表截断导致 Sphinx 构建报Unexpected indentation。子弹的续行必须以空白缩进开头。jdoe-fix-rotation-frame.rst恰好是Fixed 章节 一条*条目的最小合法样例可以直接作为新 fragment 的格式模板。条目中的:meth:~example.Sensor.update 是 Sphinx 交叉引用语法用于在文档构建时把条目链接到对应 API 文档这也是 IsaacLab 现有CHANGELOG.rst的通行风格。三、文件名后缀即版本晋升宣言fragment 的文件名是版本晋升的契约。cli.py顶部定义的FRAGMENT_RE与SKIP_RE是贡献者与门禁之间的线上格式协议FRAGMENT_RE re.compile(r^(?Pslug[^./][^./]*)(?:\.(?Pbumpminor|major))?\.rst$) SKIP_RE re.compile(r^(?Pslug[^./][^./]*)\.skip$)由此得出四类合法文件名文件名模式含义对版本的影响slug.rst补丁修复patch 晋升1.2.3 → 1.2.4slug.minor.rst新增向后兼容功能minor 晋升1.2.3 → 1.3.0slug.major.rst破坏性变更major 晋升1.2.3 → 2.0.0slug.skip无需记录无条目、无晋升其中slug是贡献者自取的短标识推荐直接用分支名把/替换为-slug 内不允许出现.点号保留给 tier 后缀使用或/路径分隔符。jdoe-fix-rotation-frame.rst的 slug 是jdoe-fix-rotation-frame无 tier 后缀因此它声明的晋升级别是patch。Fragment.bump属性正是从后缀推导级别缺省即为patch——这一点在 test_bump_suffix.py 的test_fragment_filename_regexes中被逐例验证包括.patch.rst不识别、foo.bar.rst多余点号、1234.minor缺.rst后缀等非法形态的拒绝。四、它在02_minor_bump演示中的真实角色patch 让位于 minorjdoe-fix-rotation-frame.rst所在的02_minor_bump演示目录被设计为混合 bump 级别场景其三个输入 fragment 分别是jdoe-fix-rotation-frame.rst ——Fixed章节patchasmith-add-multi-asset-spawner.minor.rst ——Added章节minorblee-add-camera-output-contract.minor.rst ——AddedChanged章节minor。test_minor_bump_demo_aggregates_to_minor断言这批片段的级别集合为[minor, minor, patch]聚合结果aggregate_bump()为minor。其背后的纯逻辑实现在FragmentBatch._aggregate按_BUMP_RANK {patch: 0, minor: 1, major: 2}取最大值即同一批次中最高声明级别胜出——只要有一个.major.rst整个包就走 major 晋升。空批次默认按patch处理。因此当这批片段以1.2.3的当前版本编译时版本取自config/extension.toml中的version字段Version.bumped(minor)生成1.3.0minor 晋升只递增第二位并清零 patch。五、端到端验证从changelog_before.rst到changelog_after.rst要理解jdoe-fix-rotation-frame.rst的终点需要对照同一目录下的两个对照文件changelog_before.rst模拟编译前的初始CHANGELOG.rst顶部是1.2.3 (2026-01-15)版本块changelog_after.rst期望编译后的产物顶部新增1.3.0 (2026-04-30)版本块。在changelog_after.rst的1.3.0块中可以看到本 fragment 条目的最终去向Fixed ^^^^^ * Fixed a NaN propagation in :meth:~example.Sensor.update.它被原样并入合并后的Fixed章节——因为本批次只有这一条 Fixed 条目所以不存在跨 fragment 合并冲突。而两个 minor 片段的内容则分别归入Added章节两条*条目被直接拼接无空行分隔与Changed章节这正是_merge_sections的行为不同 fragment 中同名章节的子弹直接串联以匹配 IsaacLab 既有CHANGELOG.rst的主流风格。test_integration.py 中的test_demo_compile_matches_changelog_after完成全链路验证在临时目录中构造一个最小包写入version 1.2.3的extension.toml、复制changelog_before.rst为docs/CHANGELOG.rst复制 fragment 后调用pkg.compile()最终断言编译产物与changelog_after.rst在剔除(YYYY-MM-DD)日期后逐字节一致且current_version()恰好等于1.3.0。六、在本地亲手复现这次编译不想动真实包的前提下可以用--dry-run对着这套测试夹具做一次完整预览。命令来自 集成测试 README./isaaclab.sh -p tools/changelog/cli.py compile --package isaaclab \ --fragments-dir tools/changelog/test/integration/02_minor_bump/fragments \ --dry-run命令拆解对应 cli.py 的cmd_compile--package isaaclab锁定单个受管包受管包需同时具备config/extension.toml与docs/CHANGELOG.rst见Package.is_managed--fragments-dir ...从指定目录读取 fragment 而非默认的source/pkg/changelog.d/相对路径会基于仓库根目录解析_resolve_fragments_dir--dry-run只打印将要写入的版本块与版本号不写文件、不删 fragment。compile刻意不提供写入但保留片段的第三模式——真实编译会删除已消费的 fragment防止下次编译重复生成版本块。值得注意的配套限制--fragments-dir与--version都要求同时指定--package--all模式下不可用因为每个受管包拥有独立的版本轨迹--version 4.7这类非法 semver 会在参数解析阶段被Version的X.Y.Z(.devN)?校验直接拦截。真实发布场景则使用cli.py compile --all每晚定时工作流执行或cli.py compile --package isaaclab --version 4.7.0显式钉版本。预览输出的核心行类似isaaclab: 3 fragment(s) → version 1.3.0 (bump: minor)七、从贡献到发布fragment 的完整生命周期把jdoe-fix-rotation-frame.rst放回大流程中IsaacLab 的 changelog 管线由两个子命令构成checkPR 门禁每次 pull request 由 CI 执行cli.py check base-branch。PRDiff.from_git通过git diff origin/base...HEAD获取变更集evaluate施加四条规则——fragment 不可变禁止修改既有 fragment、内容必须合法、slug 在同一包内唯一冲突提示重命名为slug-2、每个被触碰源码的受管包必须新增至少一个合法 fragment。jdoe-fix-rotation-frame.rst这类文件就是该门禁要求贡献者交付的入场券。compile发布/每晚读取source/pkg/changelog.d/下累积的片段按上文规则聚合 bump、生成新版本块插入锚点Changelog\n---\n\n之后见write_changelog_entry的自愈逻辑、更新extension.toml的版本号并删除已消费片段。这套设计带来的实际收益可以明确从源码与测试中读到版本晋升由文件名声明而非人工编辑驱动杜绝了改了代码忘写 changelog和手工改版本号造成不一致两类常见事故每包独立版本轨迹 单包失败不阻断整批cmd_compile的 per-package 隔离则保证了一个坏 fragment 只拖累自己所在的包。对 IsaacLab 这种包含isaaclab、isaaclab_assets、isaaclab_tasks等多个独立版本包的仓库而言fragment 体系是发布说明质量与版本一致性的基础设施。结语一份三行的 jdoe-fix-rotation-frame.rst 背后是 IsaacLab 完整的 changelog 工程化体系RST 章节语法定义内容、文件名后缀声明 bump、_aggregate决定最高者胜出、02_minor_bump夹具与 test_integration.py 守住端到端回归、check/compile双命令覆盖贡献与发布两个时点。后续贡献者完全可以照抄这份文件作为模板——写清Fixed/Added章节与*条目再按变更性质选择.rst、.minor.rst或.major.rst后缀剩下的版本计算与文档合并交给工具链自动完成。【免费下载链接】IsaacLabUnified framework for robot learning with multi-physics/renderer support项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价