Skip to content

chore(release): 4.0.0 - #2052

Merged
os-zhuang merged 8 commits into
mainfrom
claude/issue-2049-release-3-2-0
Oct 10, 2026
Merged

os-zhuang merged 8 commits into
mainfrom
claude/issue-2049-release-3-2-0

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Part of #2049
Clause-②: no

Cuts HotCRM 4.0.0: the version PR only. The seat pushes the v4.0.0 tag and verifies staging after the merge. Landing tier: H. The diff is 3,077 changed lines (+1266 / −1811) across 88 files, over the 3,000-line human-merge line; no governed path is touched. The branch name still says 3-2-0 from the first cut.

Patch round 1: 3.2.0 → 4.0.0 (the maintainer's ruling A on #2049)

docs/RELEASE_STRATEGY.md § Compatibility Policy puts "renamed or removed objects/fields … migration-required behavior" under Major. The contact change removes five fields and needs a one-time conversion, so the maintainer ruled 4.0.0 (#2049). The re-cut:

  1. Restored the 77 consumed changesets and the pre-cut package.json / CHANGELOG.md from main.
  2. Set contact-mailing-address-one-field.md to 'hotcrm': major, keeping the round-0 first-paragraph edits.
  3. Ran pnpm changeset:version again. pnpm exec changeset status --verbose → hotcrm -> 4.0.0: 1 major, 12 minor, 36 patch, 28 empty.
  4. Re-aligned both manifests and the version-bound docs to 4.0.0.

The first re-cut credited each entry to the restore commit. The CHANGELOG was then regenerated from a clean clone (185909ce). It is byte-identical to the first re-cut except the 49 stamp lines, which now name the commit that added each changeset (all ancestors of main).

Bump reading (head 185909ce)

  • CHANGELOG.md: a new ## 4.0.0 section (Major, then Minor, then Patch). Everything from ## 3.1.0 down is byte-identical to main.
  • .changeset/: all 77 pending changesets consumed; README.md and config.json remain.
  • The marketplace release notes (scripts/publish-marketplace.mjs) send the ### Major Changes subsection when a release has one, so 4.0.0's listing carries exactly the contact-address entry. The conversion step sits at char 797 of 2,531, inside the 8,000-char cap. The full list is in CHANGELOG.md and on the What's new page.

Upgrade notes in the 4.0.0 section

Every pending changeset's first paragraph was read as the 4.0.0 section renders it (49 entries; the 28 empty changesets render none). Two were edited; only the text changed, and the one level change is the ruling's:

  • contact-mailing-address-one-field.md (now major): the one-time conversion sat in its third paragraph. The first paragraph now ends: "An existing deployment runs scripts/backfill-contact-mailing-address.ts once after upgrading, before os migrate apply --allow-destructive". The third paragraph gave the 17.6.0 route. 4.0.0 runs on 17.7.0, where no REST read returns the orphaned columns, so its command now exports them first with objectstack migrate unmapped-columns --object crm_contact --json and passes --unmapped. That is the route the script's header and the 17.7.0 entry already give.
  • 1907-sales-app-service-module.md (patch): the first paragraph now says HotCRM still installs as one app and that the one visible change is the menu order. My Cases is the last item of My Work.

Read and left alone: line-item-line-number-writer.md also carries an "existing deployments" back-fill. It is optional, because the hook numbers a line on its next edit.

Manifest alignment

  • src/sales/index.ts: the app package's version 3.1.0 → 4.0.0.
  • src/service/index.ts: the module's version 3.1.0 → 4.0.0, and dependencies['app.objectstack.hotcrm'] ^3.1.0 → ^4.0.0.
  • Built artifact: manifest = app.objectstack.hotcrm 4.0.0 / ^17.7.0; both packages[] entries at 4.0.0, and the module depends on ^4.0.0.
  • The "marketplace publish note" does not exist. The phrase refers to the per-release releaseNotes key of objectstack.manifest.json. The phrase and scripts/publish-marketplace.mjs (release_notes: mp.releaseNotes, feat: marketplace publish path (manifest + script + staging/prod workflows) #369) both landed on 2026-06-04, and no release ever declared the key. Since 3.0.0 (chore(release): 3.0.0 #1242) the script derives the notes from CHANGELOG.md when the key is absent, so there is nothing to align by hand.

Files beyond the claim's file surface, and why

test/docs-declared-versions.test.ts binds every page that states the current version to the app package's manifest. After the version cut alone it measured 4 failed / 16 passed. Seven files now follow 4.0.0, the same set the 3.1.0 version PR (#1903) moved:

  • the | Current version | rows of docs/RELEASE_STRATEGY.md and docs/ARCHITECTURE.md;
  • the README badge;
  • docs/STATUS.md: the version sentence, and the pnpm validate transcript re-read from a real run (HotCRM v4.0.0, every figure unchanged);
  • the latest-release section of content/docs/whats-new in all three locales. It now says 4.0.0 on ObjectStack 17.7.0 and drops the "ships with the next HotCRM release" paragraph, which this release makes false. It gains "What 4.0.0 adds", which says why this is a major and lists the checks to run before upgrading:
    • the contact address conversion before os migrate apply --allow-destructive;
    • integrations moving to mailing_address;
    • the My Cases menu order;
    • 404 for a write to a record the caller cannot see;
    • strict import dates.

docs-declared-versions (20/20 green) is part of pnpm verify.

The self-hosting caveat: measured, not reproduced as filed (dropped, no changeset)

The planned changeset would have said that booting the bare artifact on @objectstack/* 17.7.0 starts without sign-in because of objectstack-ai/objectstack#22288. Five bounded boots on port 4937 (timeout 70) say otherwise. Each boot had a fresh OS_HOME and the same throwaway OS_SECRET_KEY:

Boot Source Command OS_AUTH_SECRET Banner Plugins GET /api/v1/auth/get-session
A bare dist/objectstack.json, no config objectstack serve unset Server is ready — DEGRADED: missing core services: auth 35 404 ENDPOINT_NOT_FOUND
B bare, no config objectstack serve set ✓ Server is ready 40 401 Sign in first
C objectstack.config.ts objectstack serve unset Server is ready — DEGRADED: missing core services: auth 35 404
D objectstack.config.ts objectstack start unset; start creates one ✓ Server is ready 40 401
E bare, no config objectstack start unset; start creates one ✓ Server is ready 40 401
  • Bare or config makes no difference. A and C load the same 35 plugins. B, D and E load the same 40 (Auth, Security, Audit, @objectstack/account, @objectstack/setup on top).
  • The missing auth is the missing secret. In @objectstack/cli 17.7.0, production serve registers AuthPlugin only when it has a secret. start reads or creates one in its home.
  • #22288's top-level read changes nothing here. Neither path carries a top-level requires, so both read the same empty list.
  • HotCRM's documented production path (docs/DEPLOYMENT.md) is pnpm start, which is boot D. There is no release-specific self-hosting caveat to record.

Gates

On 185909ce:

  • OS_VERIFY_LOCK_SLOT=hotcrm-2049 bash …/os-verify-lock.sh -c 'pnpm verify' → VERDICT command-exit 0; Tests 3622 passed | 1 skipped (3623).
  • pnpm publish:marketplace:dry-run → ── HotCRM (app.objectstack.hotcrm) @ 4.0.0, release notes: 2531 chars. The contact entry is at char 21 and its conversion sentence at char 797.
  • CI on 185909ce: every check succeeded. Check Changeset is skipped under skip-changeset, the label the 3.1.0 version PR (chore(release): 3.1.0 #1903) also carried, because a version PR consumes the changesets rather than adding one.

维护者速读(草稿)

The seat's final 维护者速读 is posted as a comment on this PR; the round-0 draft described 3.2.0 and is superseded.


Generated by Claude Code

…first paragraphs

The 3.2.0 section opens each entry with its first paragraph, and two
upgrade-relevant notes kept their operative instruction further down:

- contact-mailing-address-one-field: the one-time conversion was in the
  third paragraph, and its command was the 17.6.0 route. 3.2.0 runs on
  17.7.0, where no REST read returns the orphaned columns, so the command
  now exports them with `objectstack migrate unmapped-columns` first and
  passes `--unmapped` (the route the script header and the 17.7.0 entry
  already give).
- 1907-sales-app-service-module: the menu-order change (My Cases moves to
  the end of My Work) was in the third paragraph.

Text only; neither bump level changes.

Part of #2049

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
`pnpm changeset:version` consumed the 77 pending changesets (13 minor,
36 patch, 28 empty) and computed 3.1.0 -> 3.2.0: it wrote `package.json`
and spliced the 3.2.0 section into `CHANGELOG.md` (+1136 lines; every
byte from `## 3.1.0` down unchanged).

Matched by hand, per docs/RELEASE_STRATEGY.md section Version Sources:
the app package's `version` in src/sales/index.ts, and the service
module's `version` and its `dependencies` range on the app in
src/service/index.ts.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
`test/docs-declared-versions.test.ts` binds these to the app package's
manifest version, and was red on the version cut alone (4 failures,
measured): the version rows in docs/RELEASE_STRATEGY.md and
docs/ARCHITECTURE.md, the README badge, the version sentence and the
`pnpm validate` transcript in docs/STATUS.md (re-run: `HotCRM v3.2.0`,
same figures), and the latest-release heading of content/docs/whats-new
in all three locales. The 3.1.0 version PR (#1903) moved the same set.

whats-new's latest-release section becomes 3.2.0 on ObjectStack 17.7.0,
drops the "ships with the next HotCRM release" paragraph that 3.2.0 makes
false, and gains "What 3.2.0 adds" with the checks to run before
upgrading (the contact address conversion, the My Cases menu order, 404
for a write to an unseen record, strict import dates).

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Oct 10, 2026 12:25pm UTC

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Dependency bumps and lockfile changes labels Oct 10, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR ships nothing to users (pure CI/docs chore) — changeset gate waived label Oct 10, 2026
The maintainer ruled this release 4.0.0 (contact-mailing-address-one-field
is a major change under docs/RELEASE_STRATEGY.md section Compatibility
Policy). The 3.2.0 cut is undone so `changeset version` can run again:
the 77 consumed changesets, `package.json`, `CHANGELOG.md`, both package
manifests and the version-bound docs return to their pre-cut state. The
tree now equals b26ecb1: main plus the first-paragraph edits to the
contact mailing-address and #1907 changesets, which are kept.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
The five `mailing_*` fields are removed and existing deployments run a
one-time conversion, which docs/RELEASE_STRATEGY.md section Compatibility
Policy files under Major (renamed or removed fields, migration-required
behavior). Maintainer ruling A on the release level. Frontmatter only;
the text is unchanged. `changeset status` now reads hotcrm -> 4.0.0.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
`pnpm changeset:version` consumed the 77 pending changesets (1 major,
12 minor, 36 patch, 28 empty) and computed 3.1.0 -> 4.0.0: it wrote
`package.json` and spliced the 4.0.0 section into `CHANGELOG.md`
(+1139 lines; every byte from `## 3.1.0` down unchanged). The contact
mailing-address entry is the one Major Change, so it opens the section.

Matched by hand, per docs/RELEASE_STRATEGY.md section Version Sources:
the app package's `version` in src/sales/index.ts, and the service
module's `version` and its `dependencies` range on the app in
src/service/index.ts.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
The set `test/docs-declared-versions.test.ts` binds to the app package's
manifest, re-aligned after the re-cut: the version rows in
docs/RELEASE_STRATEGY.md and docs/ARCHITECTURE.md, the README badge, the
version sentence and `pnpm validate` transcript in docs/STATUS.md, and the
latest-release section of content/docs/whats-new in all three locales.

whats-new reads "What 4.0.0 adds" and opens by saying why it is a major:
a contact's mailing address becomes one field, the five separate fields
are removed, and an existing deployment converts the addresses once. The
checks to run before upgrading are unchanged.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
…changeset

`changeset version` stamps each entry with the latest commit that ADDED
its changeset file (`git log --diff-filter=AC --follow --max-count=1`).
On this branch the 77 files were deleted by the 3.2.0 cut and restored by
5e50863, so the re-cut stamped all 49 entries `5e50863`: a branch
commit a squash merge leaves off main's history, in place of the 49
original commits.

The section is regenerated by the same `node scripts/changeset-version.mjs`,
run in a throwaway local clone whose history is main -> b26ecb1 -> a commit
holding c8470ff's exact tree, where the files were never deleted. Its
output differs from 35dbd3c's only in those stamps: with the 7-hex stamps
masked the two CHANGELOG.md files are byte-identical, `package.json` is
identical, and the 49 stamps are the same 49 commits the reviewed 3.2.0
cut carried, every one an ancestor of origin/main. This file is that
output, copied unchanged; nothing in it is hand-written.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot changed the title chore(release): 3.2.0 chore(release): 4.0.0 Oct 10, 2026
@objectstack-fleet objectstack-fleet Bot added the needs-user-decision Needs the maintainer's call before work proceeds label Oct 10, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿) · PR #2052 · repo:hotcrm 席位 · 2026-10-10T12:40Z · 席位已对照 head 185909ce 的 diff 校正

改了什么

把 HotCRM 定为 4.0.0 版:

  • 自 3.1.0(9 月 14 日)以来积累的 77 条变更说明编成 4.0.0 的发布记录,分为 1 条大版本变更、12 条功能、36 条修复,另有 28 条空记录。
  • 版本号改为 4.0.0,HotCRM 应用和 Service 模块两个包同步,Service 依赖改为 ^4.0.0。
  • README、维护文档和三种语言的「新特性」页改为 4.0.0。「新特性」页新增「4.0.0 新增了什么」,开头说明为什么是大版本,并列出升级前检查清单。
  • 唯一的大版本变更是联系人邮寄地址由五个字段合并为一个字段。这条记录的第一段就写明了一次性转换步骤。

代码逻辑没有改动,只改了版本号、发布记录和文档。

为什么改

  • 您要求准备版本 PR 并做 staging 验证,并在 Release HotCRM 4.0.0: the version PR (changeset version + package manifests), then the v4.0.0 tag that publishes to staging #2049 上裁定按兼容性政策定为 4.0.0(方案 A):删除字段且需要迁移的变更算大版本。
  • 定为大版本还有一个附带效果:市场列表的发布说明只取「大版本变更」小节,现在正好就是联系人地址这一条,转换步骤在第 797 个字符处,不会被截掉。
  • 4.0.0 包含:
    • REQ-0006 的销售记录与审批(立项、客户登记、采购决策圈、线索需求、赢丢单审批,默认关闭);
    • 按收件人语言发送的通知;
    • 平台从 17.4.0 升到 17.7.0;
    • 一个应用、两个包的安装形态;
    • 10 月 8–10 日的修复。

风险与代价(含回滚)

  • 已有部署升级后必须先转换联系人地址,再执行 os migrate apply --allow-destructive,否则旧地址会被删除。CHANGELOG、市场发布说明和「新特性」页都把这一步放在最前面。
  • 集成或报表如果读写 mailing_street … mailing_country,要改用 mailing_address。此外还有三处用户可见的行为变化:
    • My Cases 移到 My Work 菜单最后一项;
    • 写入看不见的记录,返回从 403 改为 404;
    • 导入时日期按严格格式解析。
  • 市场发布说明只显示联系人地址这一条,其余 48 条只在 CHANGELOG 和「新特性」页里。这是脚本的既定行为,也是选 A 的本意。
  • 原计划写入的「自托管裸启动没有登录」说明经实测不成立:缺少登录是因为生产模式下没有设置 OS_AUTH_SECRET,与 #22288 无关,所以不写入。
  • 回滚:
    • 合并前:关闭本 PR 即可。
    • 合并后、打标签前:revert 合并提交即恢复 3.1.0 状态,77 条变更说明一并恢复。
    • 打 v4.0.0 标签后:会生成公开的 GitHub Release,并发布到 staging 市场。要撤回需删除该 Release 和标签,staging 上的版本需另行处理。
    • 正式环境不受影响:production 只能由您手动触发。

席位意见

建议合并。席位自己在 git 上核过:

  • 88 个文件,只有版本号、发布记录和七份文档。
  • CHANGELOG 从 3.1.0 往下与 main 逐字节一致,49 个提交戳都指向 main 上的提交。
  • 两个包的清单都是 4.0.0,三种语言的「新特性」页内容一致。
  • CI 9 项全绿,pnpm verify 3,622 项通过。
  • 发布演练显示 @ 4.0.0,发布说明 2,531 字符,转换步骤在上限内。

体量超过 3,000 行(主要是 77 个变更说明文件删除,以及它们汇入 CHANGELOG),按规定须由您批准合并。席位不会自行转 ready、入队或开自动合并。

你要做的(一个动作)

审阅并合并本 PR。合并后,席位在合并提交上打 v4.0.0 标签,触发 Release 和 staging 发布,读日志并汇报。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 10, 2026 12:42
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 10, 2026
Merged via the queue into main with commit 6162c43 Oct 10, 2026
12 checks passed
@objectstack-fleet objectstack-fleet Bot removed the needs-user-decision Needs the maintainer's call before work proceeds label Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Dependency bumps and lockfile changes documentation Improvements or additions to documentation skip-changeset PR ships nothing to users (pure CI/docs chore) — changeset gate waived

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants