news 2026/9/12 11:33:31

Hindsight 核心版本发布完全指南:从 release.sh 切割、Changelog 生成到博客 PR 的完整工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hindsight 核心版本发布完全指南:从 release.sh 切割、Changelog 生成到博客 PR 的完整工作流

Hindsight 核心版本发布完全指南:从 release.sh 切割、Changelog 生成到博客 PR 的完整工作流

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

Hindsight(Agent Memory That Learns)仓库中封装了一套面向 AI 助手的核心版本发布技能(位于 .claude/skills/hs-release/SKILL.md),它定义了一次core release的完整操作流程:在干净的main上执行scripts/release.sh切割版本并直推main触发 CI 发布,随后以独立 PR 补上 Changelog 与发布博客。本文以该技能文档为主体,结合仓库中 scripts/release.sh、scripts/generate-clients.sh、scripts/generate-docs-skill.sh 及 hindsight-dev/hindsight_dev/generate_changelog.py 的源码实现,还原每一步背后的脚本逻辑与工程细节,让读者不仅能照做,更能理解为什么这样做。

先厘清:什么是“核心发布”,什么不是

在进入流程前,技能文档首先划定了发布边界——核心(core)发布只针对产品本体:API(hindsight-api系列)、各语言客户端(Python / TypeScript / Go / Rust)、CLI(hindsight-cli)、控制平面(hindsight-control-plane)以及 Helm Chart。

集成(integrations)是独立版本化的。仓库中hindsight-integrations/下每一个集成(如litellmpydantic-aiclaude-codeopenai-agents等)都有自己的版本号和发布通道,必须使用 scripts/release-integration.sh 单独发布,而不是本技能。从源码看,集成发布的 tag 命名也完全不同:核心发布打v<version>(如v0.9.0),而集成发布打integrations/<integration>/v<version>(如integrations/litellm/v0.2.0),且集成脚本内置了约 50 个合法集成名的白名单校验(VALID_INTEGRATIONS数组,见 scripts/release-integration.sh),未知集成名会直接拒绝执行。

另一个必须提前建立的认知是:核心发布不可逆、且面向外部release.sh会打 tag 并直接推送main,推送动作触发ReleaseGitHub Actions 工作流,进而把包发布到 PyPI / npm / Helm。这意味着发布前必须确认两件事:

  1. 版本号正确无误;
  2. 计划包含的修复已经合并进main

Step 0 — 发布前预检(Pre-flight)

1. 决定发布基准(base)

发布永远从最新的origin/main切割,绝不允许从功能分支发布。预检命令如下:

git fetch origin --tags git log v<prev>..origin/main --oneline

第一条同步远端 tag;第二条用来确认用户口中"那几个修复"确实已经落在main上(v<prev>是上一个发布 tag)。只有确认修复已合入,才能继续。

2. 找到main所在的工作树

由于 git 的限制,main往往已经以兄弟 worktree的形式被检出(用git worktree list查看)。你不能在第二个 worktree 中再次检出main——必须在已经持有它的那个 worktree 里执行发布。

如果那个 worktree 里残留了临时杂物(比如.next-*的 tsconfig 路径、截图等),先暂存再快进:

git stash push -u git pull --ff-only origin main # 或 git merge --ff-only origin/main # ……执行发布…… git stash pop

3. 一个著名坑:不要用管道链做 checkout

技能文档明确警告:永远不要把 checkout 塞进&&链并用| tail管道,例如:

git checkout main 2>&1 | tail && git reset --hard ...

问题在于管道的退出码是tail的(恒为 0)。当 checkout 失败时,链不会被中断,随后的reset --hard会在错误的分支上执行——这是灾难性的。正确做法是:checkout 单独成命令,并且在 reset 之前用git branch --show-current确认当前分支确实是main

Step 1 — 切割发布:release.sh做了什么

在干净(clean)的mainworktree 中执行:

./scripts/release.sh <version> # 例如 ./scripts/release.sh 0.8.1(不要带前导 v)

阅读 scripts/release.sh 源码可以看到,脚本从入口就建立了四道防线:

  1. 版本格式校验VERSION必须匹配^[0-9]+\.[0-9]+\.[0-9]+$(语义化版本,见 scripts/release.sh);
  2. 分支检查git branch --show-currentmain时交互式确认(scripts/release.sh);
  3. 工作区清洁检查git status -s有输出则直接报错退出(scripts/release.sh);
  4. tag 冲突检查git rev-parse "v$VERSION"已存在则拒绝发布(scripts/release.sh)。

通过四道检查后,脚本依次完成以下动作:

(1)为所有组件统一 bump 版本。Python 包列表为hindsight-apihindsight-api-slimhindsight-all-slimhindsight-devhindsight-allhindsight-embed(scripts/release.sh),逐一改写pyproject.tomlversion字段。此外还更新三处 Python__init__.py中的__version__(含hindsight-api-slim/hindsight_api/__init__.pyhindsight-embed/hindsight_embed/__init__.pyhindsight-clients/python/hindsight_client_api/__init__.py),以及 Rust CLI 的hindsight-cli/Cargo.toml、Helm Chart 的 helm/hindsight/Chart.yaml(同时更新versionappVersion)、控制平面的hindsight-control-plane/package.json、npm 包装包hindsight-all-npm/package.json、Python 与 TypeScript 客户端清单。

(2)re-pin 元包依赖hindsight-apihindsight-allhindsight-all-slim是纯 shim 元包,必须精确锁定对应的 slim/api 版本(==$VERSION),否则pip install -U会留下旧版 slim,导致服务端上报过期的__version__。同理,hindsight-all还捆绑嵌入式 daemon,会同步把hindsight-embed锁到本版本;hindsight-dev则锁hindsight-api(scripts/release.sh)。

(3)刷新根package-lock.json。通过npm install --ignore-scripts --no-audit --no-fund让 workspace 版本与 bump 后的package.json一致。源码注释解释了原因:若不刷新,CI 里的npm ci会因 "Missing @vectorize-io/hindsight-client@ from lock file" 失败,连带 npm-publish 与 docs-deploy 两个 job 一起挂掉( scripts/release.sh)。

(4)更新文档版本。调用 scripts/update-docs-version.sh,其行为由 patch 号决定:

  • patch 发布(如 0.8.1):把hindsight-docs/docs/rsync -av --delete同步到已有的versioned_docs/version-0.8/,并用 Node 把sidebars.ts编译成versioned_sidebars/version-0.8-sidebars.json
  • minor/major 发布(如 0.9.0):执行npx docusaurus docs:version 0.9创建全新的version-0.9快照并更新versions.json

(5)重新生成 OpenAPI spec 与全部客户端 SDK。先由 scripts/generate-openapi.sh 执行uv run generate-openapi(来自hindsight-dev的命令)并npm run build构建文档站点;再由 scripts/generate-clients.sh 生成四种客户端:

  • Rust:客户端在构建时由build.rs(基于 progenitor)自动生成,脚本通过cargo build --release --locked触发再生成,--locked保证依赖解析可复现;
  • Python:用 Docker 固定版本openapitools/openapi-generator-cli:v7.10.0--platform linux/amd64保证 macOS 与 Linux CI 输出一致),并 patchrest.py把 aiohttp 初始化延迟到首次请求,规避 "no running event loop" 错误;
  • TypeScript:用@hey-api/openapi-tsnpm run generate,版本锁在package.json),再 patchclient.gen.ts以兼容 Deno(client字段在 Deno 的RequestInit中是保留字);
  • Go:同样走 Docker openapi-generator,但保留手写的hindsight_client.gogo.mod/go.sum等维护文件,并修复生成器的两个已知问题(union 类型MarshalJSON改为值接收者、api_files.go补充缺失的os导入)。

若客户端再生成失败,脚本会交互询问是否继续,选择取消则git checkout .回滚所有改动(scripts/release.sh)。

(6)提交、打 tag、推送。最后脚本git add -A,用--no-verify提交信息为Release v<version>(含组件清单与文档同步说明),创建 annotated tagv<version>,然后直接git push origin maingit push origin v<version>(scripts/release.sh)。

再次强调:这一步不是 PR,推送即触发 CI 构建发布制品。

发布后验证

推送完成后立即验证两条:

gh run list --limit 5 # 应能看到 Release v<version> 工作流正在运行 git ls-remote --tags origin v<version> # 应能返回该 tag

Step 2 — Changelog + 博客 PR(独立进行)

这一步必须在 tag 已存在之后执行,并且是独立的 PR(仓库先例:v0.8.0 = PR #2053,v0.8.1 = PR #2080)。从新main拉分支:

git checkout -b docs-changelog-<version> origin/main

只有当main被其他 worktree 占用、当前工作区又有不想打扰的改动时,才考虑单独 worktree:

git worktree add ../hindsight-changelog-<version> -b docs-changelog-<version> origin/main

分支命名:为什么必须用docs-

分支名必须采用docs-(连字符)约定,例如docs-changelog-0.8.1。原因很具体:远端已存在一个字面名为docs的分支,任何docs/...形式的分支在 push 时都会被 git 以directory file conflict拒绝。这是本仓库最容易踩的命名坑。

生成 Changelog

uv run --directory hindsight-dev generate-changelog <version>

该命令(实现见 hindsight-dev/hindsight_dev/generate_changelog.py)会:

  1. 拉取上一个 tag 到v<version>之间的全部 commit;
  2. 调用 LLM 总结,并把新条目prepend到 hindsight-docs/src/pages/changelog/index.md;
  3. 在条目末尾追加Database Migrations小节。

关于 Database Migrations 小节,有几点值得注意:

  • 由 git 确定性枚举(对hindsight_api/alembic/versions/--diff-filter=A找出新增迁移文件),不是 LLM 生成的,因此不要手工编辑;如果发现某个迁移缺失,应去检查对应 commit 是否真的在 tag 区间内新增了该文件(hindsight-dev/hindsight_dev/generate_changelog.py);
  • 源码中甚至维护了一张TABLE_VOLUME分级表,把memory_unitsmemory_linksentities等表按"高/中/低数据量"标注,用于提示迁移锁范围与耗时(hindsight-dev/hindsight_dev/generate_changelog.py),并有测试保证新建表必须被分类;
  • 运行需要OPENAI_API_KEY(仓库.env中已就绪);
  • 生成范围排除hindsight-integrations/源码,但新集成的 commit 若顺带改了文档仍会出现——这符合既有先例,保留在 changelog 中即可

手写发布博客

在 hindsight-docs/blog/ 下手写YYYY-MM-DD-version-X-Y-Z.md,可以镜像已有博客的格式(patch 发布通常很短,可参考 hindsight-docs/blog/2026-06-02-version-0-7-2.md,大版本可参考 hindsight-docs/blog/2026-08-06-hindsight-0-9-0.md)。写作规范有三条硬性要求:

  • 讲用户影响,不讲内部机制:开头就要说明用户现在能做什么、要配置什么。配置项与环境变量名可以出现(面向开发者),但代码符号与内部实现不要写;
  • 博客中不要列集成:核心博客只覆盖核心引擎 / API / 运维变化;每个集成有自己的 changelog。(集成出现在生成的changelog/index.md中没问题,只是不要进博客正文。)
  • 有运维或数据完整性修复时,明确给出升级建议

格式校验:

npx prettier --check <blog file>

同步 docs skill

./scripts/generate-docs-skill.sh

该脚本(scripts/generate-docs-skill.sh)把hindsight-docs/docssrc/pages(含 best-practices、faq、changelog)与docs-integrations转换为 AI Agent 可消费的 skills/hindsight-docs/ 技能目录:.mdx.md、内联示例代码、把<LLMProvidersTable />等 JSX 组件渲染为 Markdown 表格、并把 Docusaurus 绝对路径链接重写为相对路径、最后做链接越界校验。

运行后会刷新 skills/hindsight-docs/references/changelog/index.md,同时把 skills/hindsight-docs/references/openapi.json 的版本号 +1。背景是:release.shOpenAPI bump 之前就再生成了 skill,所以发布 commit 里 skill 的openapi.json会滞后一个版本,这一步正是为了把它同步回来——预期会有一行version的 diff,保留它

提交、推送、建 PR

git add -A git commit --no-verify -m "docs: changelog and blog post for v<version>" git push -u origin docs-changelog-<version> gh pr create --base main --title "docs: changelog and blog post for v<version>" --body "..."

PR 中应包含四类文件:

  1. changelog 新条目(hindsight-docs/src/pages/changelog/index.md);
  2. 新增的博客文件;
  3. 再生成的 skill changelog 镜像;
  4. skillopenapi.json的版本同步 diff。

收尾(Cleanup)

如果 Step 2 中创建了临时 worktree,PR 建立后应移除(分支保留在 origin 上):

git worktree remove ../hindsight-changelog-<version>

同时恢复 Step 0 中 pop 出来的 stash。

附:发布核对清单

一次完整的核心发布,按技能文档归纳为以下顺序(供 AI 助手与维护者自查):

  • git fetch origin --tags,确认目标修复已在maingit log v<prev>..origin/main --oneline
  • 定位持有main的 worktree(git worktree list),脏文件先git stash push -u
  • checkout 单独成命令,git branch --show-current确认在main
  • 执行./scripts/release.sh <version>(semver 格式,不带v
  • gh run list --limit 5看到Release v<version>在跑;git ls-remote --tags origin v<version>返回 tag
  • 从新maindocs-changelog-<version>分支(勿用docs/...命名)
  • uv run --directory hindsight-dev generate-changelog <version>(勿手改 Database Migrations 小节)
  • 手写发布博客并按npx prettier --check校验
  • ./scripts/generate-docs-skill.sh同步 skill,保留 openapi.json 的一行版本 diff
  • 提交(--no-verify)→ push →gh pr create,PR 含 changelog、博客、skill 镜像三部分
  • 清理临时 worktree、恢复 stash

这套流程的精髓在于"切割与文档分离":release.sh负责把所有机械性工作(版本 bump、SDK 再生成、tag、推送)一次性原子完成,而 changelog 与博客走独立 PR,让发布文档可以在 tag 落定后从容补写、接受 review。对任何需要维护多语言 SDK + Helm Chart + 文档站点的开源项目来说,这个"一步切割 + 一步文档"的双阶段模式都值得直接借鉴。

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 11:32:27

DeepSeek Harness本地模型服务化实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 11:29:14

OpenAI技术栈解析:从ChatGPT到GPT-5.4的模型选型指南

1. OpenAI技术栈全景解析&#xff1a;从ChatGPT到GPT-5.4的技术脉络 作为深度参与AI工具落地的技术从业者&#xff0c;我经常需要向开发团队解释OpenAI旗下各种模型的关系。2023年Q2的技术报告显示&#xff0c;超过67%的企业级AI应用都涉及OpenAI技术栈的选型决策。但面对ChatG…

作者头像 李华
网站建设 2026/9/12 11:26:11

Cursor、Claude Code等五款主流AI编程工具横评与选型建议

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 11:26:06

React富文本编辑器核心架构与组件化实现

1. 项目概述在当今Web开发领域&#xff0c;富文本编辑器已经成为内容管理系统的标配功能。不同于传统的textarea&#xff0c;富文本编辑器需要处理复杂的文档结构、样式嵌套和交互行为。React作为现代前端框架的代表&#xff0c;其组件化特性与富文本编辑器的开发需求天然契合。…

作者头像 李华
网站建设 2026/9/12 11:25:36

RAG架构解析:如何解决大模型幻觉问题

1. 为什么RAG能拯救"胡说八道"的AI程序员&#xff1f; 去年调试一个金融问答系统时&#xff0c;我亲眼见过大模型把"年化收益率"解释成"每年化妆的成本"。这种一本正经的胡说八道&#xff08;Hallucination&#xff09;在专业领域简直是灾难。直…

作者头像 李华