- AI 应用
- 大模型
- AI Agent
- 交互助手
- RAG
【免费下载链接】obsidian-copilot
Run agents in Obsidian - OpenCode, Codex, Claude Code etc.
导读
本文以开源仓库 obsidian-copilot(Copilot for Obsidian 插件)的预发布 Agent 定义为主体,系统讲解如何为 Obsidian 社区插件"切一个 beta / rc / alpha 预发布版本":从预发布与稳定发布的本质区别、Pre-flight 六项安全检查,到版本号提升、预发布说明撰写、RELEASES.md 更新与 PR 创建,并辅以 version-bump.mjs 与 .github/workflows/release.yml 的源码级印证。读完本文,你将掌握一套完整、可复制、可自动化的预发布流水线,理解manifest.json/manifest-beta.json双轨制的底层原理,并能亲手创建一条触发 GitHub Release 预发布标记的 PR。
一、预发布与稳定发布的本质区别
在 Copilot for Obsidian 的发布体系中,一次"预发布"(prerelease)与稳定发布共享同一条 GitHub Actions 自动发布流水线,但存在几个关键差异:
- PR 标题是预发布 semver:形如
X.Y.Z-<tag>.<N>,例如3.2.9-beta.1、3.3.0-rc.0、4.0.0-alpha.2。这个标题本身既是版本号,也是触发发布流程的"信号"。 - 发布工作流自动识别并标记:release.yml 检测到预发布模式后,会在
gh release create时传入--prerelease标志,生成的 GitHub Release 被标记为 "prerelease"。Obsidian 的插件浏览器不会把预发布当作稳定更新推送给普通用户——这正是"预发布给测试者、稳定版给终端用户"两套通道能够共存的机制基础。 - master 上的
manifest.json永不因预发布被修改:Obsidian 社区插件商店读取 master 分支上的manifest.json来决定对外提供哪个 GitHub Release 产物,因此它必须始终指向最新稳定版本。预发布的元数据放在manifest-beta.json中。version-bump.mjs 通过环境变量npm_package_version是否包含-来判定预发布:是预发布则只写manifest-beta.json和versions.json。 package.json由 npm 自身更新为预发布版本号:它是 Agent 读取"当前版本"的唯一事实来源(对应仓库根目录的 package.json 中的version字段)。- 发布工作流仅在 runner 内部做一次 manifest 交换:上传 Release 产物前,工作流把
manifest-beta.json复制为manifest.json(仅存在于 runner 中,不会提交回 master),这样下载预发布产物的测试者拿到的是携带预发布版本的manifest.json;而 master 上提交的manifest.json依旧钉在最新稳定版上。
源码印证:release.yml 的 semver 判定
release.yml 中通过两段正则区分三种情况:
^[0-9]+\.[0-9]+\.[0-9]+$→ 稳定 semver(如3.2.3),is_prerelease=false;^[0-9]+\.[0-9]+\.[0-9]+-[0-9A-Za-z-]+\.[0-9]+$→ 预发布 semver(如3.2.9-beta.1、3.3.0-rc.0),is_prerelease=true;- 其他标题 → 非 semver,工作流静默跳过,不创建任何 Release。
工作流在pull_request.closed且merged == true时触发(release.yml),因此普通功能 PR 合并后不会误触发发布。
二、Step 0:Pre-flight 六项安全检查
在动任何版本号之前,必须先验证仓库处于可发布状态。任何一项不通过就停下并向用户报告,而不是掩盖问题继续推进——从损坏的 master 发布预发布,会误导测试者对下一个稳定版状态的判断。
1. 确认 master 工作区干净
git checkout master && git pull origin master git status --porcelain任何未提交的状态都意味着有 PR 正在进行,或上一次 Agent 运行遗留了文件。此时应停下,请用户先澄清。
2. 运行完整项目检查
npm ci npm run lint npm run build npm test对应仓库 package.json 中定义的lint(eslint)、build(tailwind + esbuild + tsc 类型检查)、test(jest)脚本。任一环节失败即代表 master 已损坏,应停下并报告具体失败步骤,与用户协商后续方案。
3. 检查构建产物 main.js 的体积
ls -lh main.js如果main.js超过5 MB,需要向用户上报该体积。预发布测试的就是稳定用户将要拿到的同一份 Release 产物,因此同样的 Sync Standard(Obsidian 同步标准)关注点同样适用。询问用户是照常发布还是先搁置。
4. 校验 manifest 完整性(两个文件)
稳定版 manifest:
node -p "JSON.stringify(require('./manifest.json'), null, 2)"确认isDesktopOnly已声明、minAppVersion与代码实际调用的 Obsidian API 匹配。当前仓库 manifest.json 中的取值为isDesktopOnly: false、minAppVersion: "1.11.4",version为4.0.11。
如果manifest-beta.json存在(说明有预发布正在流转),也要检查:
[ -f manifest-beta.json ] && node -p "JSON.stringify(require('./manifest-beta.json'), null, 2)"manifest-beta.json的minAppVersion及其他元数据必须与manifest.json一致——预发布通道不测试不同的最低版本要求。
5. 断言 master 的 manifest.json.version 与最新稳定 Release 一致
如果 master 与最新稳定发布标签发生漂移,预发布会建立在错误状态之上。务必在一切动作之前捕获漂移:
# 使用 /releases/latest:单次调用即返回最近的非预发布、非草稿 Release, # 无论自上次稳定发布以来累积了多少预发布都适用。 LATEST_STABLE=$(gh api repos/logancyang/obsidian-copilot/releases/latest -q .tag_name) MASTER_VERSION=$(node -p "require('./manifest.json').version") if [ "$LATEST_STABLE" != "$MASTER_VERSION" ]; then echo "DRIFT: master manifest.json.version='$MASTER_VERSION' but latest stable Release='$LATEST_STABLE'. Stop." >&2 exit 1 fi此检查失败就停下并告知用户,绝不能在预发布 PR 内"修复" master 的 manifest.json。release.yml 的 Verify 步骤也内置了同样的漂移守卫(release.yml):当IS_PRERELEASE=true时,工作流用gh api repos/${GITHUB_REPOSITORY}/releases/latest比对合并提交上的manifest.json与最新稳定标签,不一致则拒绝发布。
6. 确认存在已合并的 PR 可供预发布
git describe --tags --abbrev=0 git log --oneline $(git describe --tags --abbrev=0)..HEAD | head如果为空,说明没有新东西可测,停下并告诉用户。
六项检查全部通过后,才进入 Step 1。
三、Step 1:确定预发布身份
在提升版本号之前,需要向用户确认三个维度:
- Tag(
beta、rc、alpha等):用户未指定时默认beta; - 基础版本目标(
prepatch、preminor、premajor):本次预发布通往哪个稳定版本?prepatch(最常见):3.2.8→3.2.9-beta.0preminor:3.2.8→3.3.0-beta.0premajor:3.2.8→4.0.0-beta.0
- 还是对既有预发布线的迭代?如果当前版本本身已是预发布(如
3.2.9-beta.0),则用prerelease只递增预发布计数器:3.2.9-beta.0→3.2.9-beta.1。
这对应 npm semver 预发布规则:prepatch/preminor/premajor分别只提升 patch/minor/major 段并追加预发布后缀,prerelease只递增已有预发布线的序号。
四、Step 2~3:准备分支并提升版本号
准备分支
git checkout master git pull origin master创建包含预发布身份的描述性分支名:
git checkout -b prerelease/vX.Y.Z-<tag>.<N>提升版本号
使用 npm version 命令,--preid指定所选 tag,--no-git-tag-version让 npm不在本地创建 git tag(打标签交给发布工作流处理):
开启新的预发布线:
npm version <prepatch|preminor|premajor> --preid=<tag> --no-git-tag-version递增既有预发布:
npm version prerelease --preid=<tag> --no-git-tag-version示例:
3.2.8+npm version prepatch --preid=beta --no-git-tag-version→3.2.9-beta.03.2.9-beta.0+npm version prerelease --preid=beta --no-git-tag-version→3.2.9-beta.13.2.9-beta.5+npm version prerelease --preid=rc --no-git-tag-version→3.2.9-rc.0
npm version会触发package.json中的version脚本(见 package.json),即执行 version-bump.mjs。该脚本将更新manifest-beta.json(不存在时用manifest.json作种子创建)和versions.json,绝不触碰manifest.json。提升完成后,从package.json读取新版本号供后续步骤使用。
源码印证:version-bump.mjs 的双轨写盘逻辑
version-bump.mjs 的核心判断只有一行:
const isPrerelease = targetVersion.includes("-"); const manifestPath = isPrerelease ? "manifest-beta.json" : "manifest.json";- 预发布路径:
manifest-beta.json不存在时,从manifest.json种子复制(version-bump.mjs),从而继承description、fundingUrl、minAppVersion等稳定版字段,仅覆盖version; - versions.json 记录:
versions[targetVersion] = minAppVersion(version-bump.mjs),Obsidian 安装器据此为用户的 Obsidian 版本挑选合适的插件版本,预发布与稳定条目都记录于此(仓库根目录 versions.json 的结构即版本号 → 最低 Obsidian 版本); - 稳定版发布时清理:当目标版本不是预发布且
manifest-beta.json存在时,脚本将其git rm(若已被跟踪)或直接删除(若仅在工作树中),使新稳定版取代任何在途预发布(version-bump.mjs)。
五、Step 4:收集并理解合并的 PR
与稳定发布 Agent 相同:找到最近一个 tag(它本身可能就是预发布),列出其后的合并 PR,并逐条阅读 PR 描述以获取上下文。
git describe --tags --abbrev=0 gh pr list --state merged --base master --search "merged:>YYYY-MM-DD" --json number,title,author,labels --limit 500如果最近 tag 是预发布(如3.2.9-beta.0),则列出自该预发布以来合并的 PR,而不是自上次稳定版以来。预发布说明只应反映自上一个测试产物以来的新增内容——这正是迭代式预发布的增量测试理念。
六、Step 5:生成预发布说明
沿用稳定发布的 RELEASES.md 格式(仓库中已有大量历史条目可作风格参考),但做如下调整:
头部格式:
# Copilot for Obsidian - Prerelease vX.Y.Z-<tag>.<N> 🧪🧪表示测试意图。其他合适的 emoji:🚧(进行中)、🔬(研究)、🐛(bug 修复类预发布)。
开头行:说明这是面向测试者的预发布,并指出本次测试重点。
示例:This is a beta release for testing the new Vault QA caching path before it ships in 3.2.9. Please report any indexing or query issues in Discord.
项目符号列表:与稳定版相同的 emoji + 加粗 + 轻松风格,但对未经验证的内容必须诚实。若某功能存在已知的尖锐问题,请明确说明。
不要默认包含稳定版那种完整的 "Improvements / Bug Fixes" PR 汇总,除非用户明确要求。预发布说明应当简短、聚焦测试。
必须包含 "What to Test" 小节,用明确的条目告诉测试者聚焦点:
## What to Test - New behavior X: try Y workflow and confirm Z. - Changed behavior W: confirm it still does what it used to do. - Known sharp edges: list anything you suspect is unstable so testers don't waste time reporting it.必须包含 "How to Install" 小节——大多数用户不知道如何安装预发布:
## How to Install the Prerelease 1. Download `main.js`, `manifest.json`, and `styles.css` from this prerelease's GitHub release page. 2. Replace the same three files in your vault's `.obsidian/plugins/copilot/` folder. 3. Reload the plugin (Settings → Community Plugins → toggle Copilot off and back on, or restart Obsidian). 4. Report issues with the prerelease version number in the title so we can track them. To return to the stable release: reinstall the plugin from Obsidian's community-plugin browser.结尾与稳定版一样加上 Troubleshoot 页脚("If models are missing, navigate to Copilot settings -> Models tab..."),并以---分隔符收尾。
七、Step 6:更新 RELEASES.md
将预发布条目置顶插入到 RELEASES.md 中# Release Notes标题行之后,保留所有既有条目不动。
当对应的稳定版发布时,稳定版说明会追加到该预发布条目的上方(而非删除预发布条目)。预发布条目作为历史记录永久保留在文件中——这也解释了为何工作流规则明确禁止 force-push 或修改既有 Release 条目。
八、Step 7:提交并创建 PR
暂存所有变更文件。注意:预发布改动的是manifest-beta.json,而不是manifest.json:
git add package.json package-lock.json manifest-beta.json versions.json RELEASES.md如果git status显示manifest.json被修改,说明出了问题——version-bump.mjs 在预发布提升时绝不应触碰manifest.json。停下并告知用户。
提交信息:prerelease: vX.Y.Z-<tag>.<N>
推送并创建 PR:
git push -u origin prerelease/vX.Y.Z-<tag>.<N> gh pr create --title "X.Y.Z-<tag>.<N>" --body "$(cat <<'EOF' ## Prerelease vX.Y.Z-<tag>.<N> [Paste the prerelease notes content here] --- Generated by the prerelease agent. EOF )"关键点:PR 标题必须精确等于预发布 semver 字符串(如3.2.9-beta.1),不带v前缀、不加任何其他文字。这个模式正是触发发布工作流传入--prerelease的依据——对照 release.yml 的正则判定,标题不匹配则不会进入发布分支。
源码印证:合并后的发布链路
当该 PR 合并进 master 后,release.yml 依次执行:
- 版本校验:比对 PR 标题与
manifest-beta.json的version,并对 master 的manifest.json做最新稳定标签漂移守卫(release.yml); - 构建:
npm ci、npm run review:obsidian、npm run build(release.yml 内对应步骤); - Runner 内 manifest 交换:
cp manifest-beta.json manifest.json(release.yml),使上传产物的 manifest 携带预发布版本,但绝不回写 master; - 产物签名与 Release 创建:
gh release create "$VERSION" --target "$MERGE_SHA" --title "$VERSION" --notes-file /tmp/release-notes.md $PRERELEASE_FLAG main.js manifest.json styles.css(release.yml),其中IS_PRERELEASE=true时PRERELEASE_FLAG="--prerelease"。
工作流同时用actions/attest-build-provenance@v2对main.js/manifest.json/styles.css生成构建来源证明(release.yml),并在 runner 内 manifest 交换之后执行,保证被签名验证的 manifest 与上传到 Release 的文件完全一致。
九、Step 8:向用户汇报
分享 PR 链接并总结:
- 切出的预发布版本号是什么;
- 包含哪些 PR(数量与关键特性);
- main.js 体积(供关注);
- 提醒:PR 标题就是预发布 tag,合并它即发布一个预发布 GitHub Release。
十、重要规则清单
- 绝不 force-push,绝不修改 RELEASES.md 中既有的发布条目;
- 始终从最新 master 出发——分支前先 pull;
- PR 标题必须是裸预发布 semver 字符串
X.Y.Z-<tag>.<N>(如3.2.9-beta.1),无v前缀、无多余文字,这是发布工作流标记 prerelease 的依据; - 稳定发布走稳定发布 Agent,不走本流程:形如
3.2.9(无预发布后缀)的标题属于稳定发布流程(对照 .claude/agents/release.md 的规则); - 写 RELEASES.md 前先读既有条目,语气与格式保持一致;预发布条目要有视觉区分度(🧪 标题、显式 "What to Test"、"How to Install" 小节);
- 对未经验证的内容诚实:预发布存在的意义是暴露 bug,而不是过度推销稳定性。如果你不敢拿自己的声誉为某功能背书,就如实写进说明;
- 任何 Pre-flight 失败即停止:不要从 lint/build/test 失败或体积超标的 master 发布预发布,报告并询问,而不是掩盖;
- 不要在预发布 PR 中静默修改
manifest.minAppVersion或manifest.isDesktopOnly:与稳定版规则相同,这类变更应走独立 PR; - 绝不在预发布中修改 master 的
manifest.json:它必须始终反映最新稳定版本,Obsidian 插件商店依赖这一点,预发布元数据只进manifest-beta.json; - 若
npm version失败或version-bump.mjs未运行,手动更新manifest-beta.json和versions.json以匹配预发布 semver,同样不要触碰manifest.json。
十一、与稳定发布流程的对照
预发布与稳定发布共享同一套发布工作流与大部分操作步骤,差异集中在版本号语义与 manifest 处理(对照 .claude/agents/release.md):
| 维度 | 稳定发布 | 预发布 |
|---|---|---|
| PR 标题 | X.Y.Z(如3.2.4) | X.Y.Z-<tag>.<N>(如3.2.9-beta.1) |
| npm version | patch/minor/major | prepatch/preminor/premajor/prerelease |
| 写入的 manifest | manifest.json | manifest-beta.json(不存在时从manifest.json种子创建) |
manifest.json状态 | 更新为发布版本 | 保持最新稳定版不动 |
| 工作流标志 | 不带--prerelease | 带--prerelease |
| 发布通道 | Obsidian 插件浏览器稳定更新 | 仅测试者可见(插件浏览器不推送) |
对manifest-beta.json | 自动删除(新稳定版取代在途预发布) | 创建或更新 |
理解这张对照表,就能清楚"什么时候切 beta、什么时候放稳定版",并保证 Obsidian 社区插件商店始终服务于最新稳定版本,而预发布产物永远只流向愿意主动安装测试的群体。
参考资源
- 预发布 Agent 完整定义(本文核心依据)
- 稳定发布 Agent 定义(流程对照)
- version-bump.mjs(版本号写盘与双轨 manifest 逻辑)
- .github/workflows/release.yml(自动发布工作流)
- RELEASES.md(发布说明历史与格式范本)
- manifest.json 与 versions.json(版本元数据与最低版本映射)
- package.json(版本号事实来源与
version脚本)
- AI 应用
- 大模型
- AI Agent
- 交互助手
- RAG
【免费下载链接】obsidian-copilot
Run agents in Obsidian - OpenCode, Codex, Claude Code etc.
相关推荐
p5.js 发布流程实战:基于 GitHub Actions 与 semver 的自动化版本发布指南
p5.js 发布流程实战:基于 GitHub Actions 与 semver 的自动化版本发布指南 本文以 p5.js 官方发布流程文档为核心,结合仓库中实际
前端图形学3D渲染ESP32 机器狗搭建实录:99 元 + 4 路舵机,让一只会聊天的小狗落地
ESP32 机器狗搭建实录:99 元 + 4 路舵机,让一只会聊天的小狗落地 上个月我终于把这只 ESP32 机器狗搭了出来。整套方案基于 ESP HI 板:E
人工智能大模型语音交互助手嵌入式物联网智能硬件MCP 服务EmDash 插件发布实战:从本地 publish 到 GitHub Actions 自动化委托发布
EmDash 插件发布实战:从本地 publish 到 GitHub Actions 自动化委托发布 EmDash(基于 Astro 的全栈 TypeScrip
CMS后端前端插件系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考