Semifold 是什么?
理解 Semifold 解决的仓库问题,以及它怎样连接不同的软件包生态。
Semifold 用来管理一座仓库中来自多种软件生态的软件包版本和发布。
设想一座产品仓库:底层是 Rust 核心库,上层有 Node.js 绑定和 Python 客户端,同时还包含一个 C++ 组件。每种生态本来就有成熟的清单格式和发布工具,真正困难的是它们之间的工作:
- 一项改动完成后,判断哪些软件包应该产生新版本;
- 底层依赖升级时,一起修改其他语言软件包中的内部依赖要求;
- 为整座仓库维护一套可以读懂的变更日志;
- 按照跨语言依赖关系安排发布顺序;
- 某个软件包仓库成功、另一个失败时,判断怎样恢复。
Semifold 补上的是这层整座仓库范围的版本与发布管理。它不会替代 Cargo、npm、Python 打包工具、CMake 或软件包仓库。
一张工作区依赖图
每个受管理的软件包都会成为工作区依赖图中的一个节点。节点包含:
- 配置和变更集使用的稳定软件包 ID(
PackageId); - 对应软件生态使用的清单名称或软件包仓库名称;
- 当前版本、路径,以及是否需要发布;
- 清单依赖和可选的显式关系;
- 负责读取和修改该清单的生态适配器。
正是这张统一后的图,让 Rust 软件包的变化可以影响 Node.js 或 Python 软件包,同时不需要假装它们的清单格式完全相同。
内置与自定义软件生态
Semifold 内置 Rust、Node.js、Python 和 C++ 生态适配器。每个适配器理解实现与测试样例已经覆盖的软件包和工作区格式。
仓库内 JavaScript 生态插件实现相同的软件包发现、信息读取与修改规划边界,因此自定义软件包也能进入同一张工作区图,而不必躲在另一套发布脚本中。
使用 Semifold 时实际要做的事
1. 描述整座仓库
smif init 发现软件包并创建 .changes/config.toml。这个文件为每个软件包分配稳定 ID,并保存清单文件无法表达的发布策略。
仓库结构变化后,smif config sync 会比较当前发现结果与已保存配置。它更新自动发现的事实,但不会悄悄覆盖维护者有意制定的策略。
2. 记录一项用户可见的变化
变更集(changeset)是一份小型 Markdown 文件,其中写明受影响的软件包 ID、期望的版本提升、变更日志分类和摘要。它会与代码改动一起接受审查,并且早于真正的版本变化。
---
native-core: "minor:feat"
web-bindings: "patch:fix"
---
在 Web 绑定中开放新的解析器。3. 联动修改所有受影响的版本
smif status 展示直接变更,以及依赖规则额外影响的软件包。smif version 随后通过各清单所属的生态适配器,修改软件包版本、内部依赖要求和变更日志,并消费已经应用的变更集。
发布计划(release plan)的价值在于让这项决定可以审查;Semifold 真正提供的产品能力,是计划所描述的一致跨生态版本修改。
4. 按照各生态自己的规则发布
smif publish 根据依赖关系排列软件包,检查目标版本是否已经存在,再为每种软件生态运行已配置的发布命令。GitHub Release 和附件可以单独启用。
最终报告会区分成功、跳过、失败和尚未开始的软件包。维护者可以修复凭据或软件包仓库配置后恢复,而不必猜测哪些版本已经对外发布。
Semifold 有意不接管的工作
Semifold 不负责构建或测试软件包,不托管软件包仓库,不从提交消息猜测产品策略,也不会把凭据交给生态插件。构建和测试仍由仓库现有工具或明确的钩子负责;软件包仓库凭据仍留在执行环境中。
在需要时学习术语
开始使用前不需要背诵所有内部概念。术语表用实际区别解释了软件包 ID、生态适配器、变更集、发布通道、软件包仓库和各种计划。
下一步可以安装 Semifold,然后跟随第一次发布教程。