Skip to content

Commit ee165f5

Browse files
committed
fix: harden v3 data task release
1 parent 44c6489 commit ee165f5

23 files changed

Lines changed: 264 additions & 48 deletions

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ jobs:
113113
mkdir -p "${CONSUMER_DIR}"
114114
npm --prefix "${CONSUMER_DIR}" init -y
115115
npm --prefix "${CONSUMER_DIR}" install "monsqlize@${VERSION}" --ignore-scripts --no-audit --no-fund --registry=https://registry.npmjs.org/
116-
node -e "const p=require('${CONSUMER_DIR}/node_modules/monsqlize/package.json'); const M=require('${CONSUMER_DIR}/node_modules/monsqlize'); if(!M || p.version!==process.argv[1]) process.exit(1)" "${VERSION}"
117-
node --input-type=module -e "import M from '${CONSUMER_DIR}/node_modules/monsqlize/dist/esm/index.mjs'; if(!M) process.exit(1)"
116+
node -e "const p=require('${CONSUMER_DIR}/node_modules/monsqlize/package.json'); const M=require('${CONSUMER_DIR}/node_modules/monsqlize'); if(!M || p.version!==process.argv[1] || typeof M.dataTasks?.preview!=='function') process.exit(1)" "${VERSION}"
117+
node --input-type=module -e "import M,{dataTasks} from '${CONSUMER_DIR}/node_modules/monsqlize/dist/esm/index.mjs'; if(!M || typeof dataTasks?.apply!=='function') process.exit(1)"
118118
node "${CONSUMER_DIR}/node_modules/monsqlize/dist/cjs/cli/data-task.cjs" --version | grep -Fx "${VERSION}"
119119
120120
- name: Summarize release follow-up
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Release Authentication Check
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
npm-auth:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Setup Node.js
14+
uses: actions/setup-node@v4
15+
with:
16+
node-version: 22
17+
registry-url: https://registry.npmjs.org
18+
19+
- name: Verify npm publish authentication
20+
env:
21+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
22+
run: |
23+
if [ -z "${NODE_AUTH_TOKEN:-}" ]; then
24+
echo "::error::NPM_TOKEN is not available to this repository."
25+
exit 2
26+
fi
27+
npm whoami --registry=https://registry.npmjs.org/

CHANGELOG.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# CHANGELOG
22

3-
> Summary index — current v3.0.0 release-candidate details are in [changelogs/v3.0.0.md](./changelogs/v3.0.0.md); v2.0.7 was never published and remains an audit archive.
4-
> **Last updated**: 2026-07-13
3+
> Summary index — current stable v3.0.0 details are in [changelogs/v3.0.0.md](./changelogs/v3.0.0.md); v2.0.7 was never published and remains an audit archive.
4+
> **Last updated**: 2026-07-14
55
66
---
77

88
## Version Overview
99

1010
| Version | Date | Summary | Details |
1111
|---------|------|---------|---------|
12-
| [v3.0.0](./changelogs/v3.0.0.md) | 2026-07-10 | Major candidate: two-instance preview/apply/restore data tasks, write-path policy, runtime-scoped schema DSL, stricter OCC/sync/query contracts, and release recovery controls | [View](./changelogs/v3.0.0.md) |
12+
| [v3.0.0](./changelogs/v3.0.0.md) | 2026-07-14 | Major: two-instance preview/apply/restore data tasks, write-path policy, runtime-scoped schema DSL, stricter OCC/sync/query contracts, and release recovery controls | [View](./changelogs/v3.0.0.md) |
1313
| [v2.0.7](./changelogs/v2.0.7.md) | Unpublished | Withdrawn patch candidate; never published and superseded by v3.0.0 | [Archive](./changelogs/v2.0.7.md) |
1414
| [v2.0.6](./changelogs/v2.0.6.md) | 2026-06-15 | Patch: dependency alignment to `schema-dsl@2.0.11` so downstream frameworks inherit the ESM/CJS shared custom type registry fix | [View](./changelogs/v2.0.6.md) |
1515
| [v2.0.5](./changelogs/v2.0.5.md) | 2026-06-13 | Patch: Model schema adapter delegates DSL type authority to `schema-dsl@2.0.10`, removing the duplicated monSQLize allowlist while preserving legacy aliases and business literals | [View](./changelogs/v2.0.5.md) |
@@ -451,7 +451,7 @@ const result = await msq.collection('orders').insertOne(dataFromMongoose);
451451
changelogs/
452452
├── README.md # 变更文档说明
453453
├── TEMPLATE.md # 变更文档模板
454-
├── v3.0.0.md # 当前 Major 候选发布详细变更
454+
├── v3.0.0.md # 当前 Major 稳定发布详细变更
455455
├── v2.0.7.md # 从未发布的历史候选归档
456456
├── v2.0.6.md # v2.0.6 详细变更
457457
├── v2.0.5.md # v2.0.5 详细变更
@@ -510,7 +510,7 @@ changelogs/
510510

511511
## 相关文档
512512

513-
- [changelogs/v3.0.0.md](./changelogs/v3.0.0.md) - 当前 Major 候选发布详细变更文档
513+
- [changelogs/v3.0.0.md](./changelogs/v3.0.0.md) - 当前 Major 稳定发布详细变更文档
514514
- [changelogs/v2.0.7.md](./changelogs/v2.0.7.md) - 从未发布的候选归档
515515
- [changelogs/v2.0.6.md](./changelogs/v2.0.6.md) - v2.0.6 详细变更文档
516516
- [changelogs/v2.0.5.md](./changelogs/v2.0.5.md) - v2.0.5 详细变更文档

changelogs/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
changelogs/
1111
├── README.md # 本说明文档
1212
├── TEMPLATE.md # 变更文档模板
13-
├── v3.0.0.md # v3.0.0 Major 候选详细变更
13+
├── v3.0.0.md # v3.0.0 Major 稳定版详细变更
1414
├── v2.0.7.md # 从未发布的候选归档
1515
├── v2.0.6.md # v2.0.6 详细变更
1616
├── v2.0.5.md # v2.0.5 详细变更
@@ -51,9 +51,8 @@ changelogs/
5151

5252
### 按版本类型
5353

54-
- **待发布**: v3.0.0
5554
- **未发布归档**: v2.0.7
56-
- **正式发布**: v2.0.6, v2.0.5, v2.0.4, v2.0.3, v2.0.2, v2.0.1, v2.0.0, v1.0.0
55+
- **正式发布**: v3.0.0, v2.0.6, v2.0.5, v2.0.4, v2.0.3, v2.0.2, v2.0.1, v2.0.0, v1.0.0
5756
- **功能版本**: v1.x
5857
- **修复版本**: v1.x.y
5958

@@ -161,7 +160,7 @@ git push origin main --tags
161160

162161
| 版本 | 文件 | 状态 | 发布日期 |
163162
|------|------|------|---------|
164-
| v3.0.0 | v3.0.0.md | ⏳ 待发布 | - |
163+
| v3.0.0 | v3.0.0.md | ✅ 已发布 | 2026-07-14 |
165164
| v2.0.7 | v2.0.7.md | 未发布归档 | - |
166165
| v2.0.6 | v2.0.6.md | ✅ 已发布 | 2026-06-15 |
167166
| v2.0.5 | v2.0.5.md | ✅ 已发布 | 2026-06-13 |

changelogs/unreleased.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Unreleased
22

3-
> Current release candidate: [v3.0.0](./v3.0.0.md). This ledger remains the detailed development inventory until v3.0.0 is published; v2.0.7 was never published and is retained only as an archive.
3+
> No changes are currently recorded after [v3.0.0](./v3.0.0.md). The sections below retain the v3 development inventory for audit history; new work must be added above the archive heading.
4+
5+
## v3.0.0 development inventory (released 2026-07-14)
46

57
## Compatibility-impacting changes
68

@@ -19,7 +21,7 @@
1921
- Fixed Model `autoIndex=true` scheduling to preflight declared indexes with `listIndexes()`, skip matching existing indexes, create only missing indexes, and report conflicts through warning logs / `model-index-error` without destructive index changes.
2022
- Fixed Batch 1 validation findings: `getDefaults()` now returns isolated deep-frozen snapshots, aggregate `$merge` / `$out` cache tests assert explicit target invalidation instead of implicit broad invalidation, cache invalidation docs list descriptor shapes, and legacy Redis lock wording no longer implies a running Redis service is bundled.
2123
- Fixed aggregate direct `.toArray()` to honor cache/meta execution paths, extended `find()` ObjectId auto-conversion to comparison operators, forwarded CountQueue abort signals into MongoDB count options, and added a warning when sync idempotency falls back to in-memory storage.
22-
- Upgraded `schema-dsl` to `2.1.3` and moved Model schema compilation/validation onto a MonSQLize runtime-scoped `schema-dsl/runtime` engine. `schemaDsl` now supports runtime options, extension registration, external runtime injection, explicit validation disablement, and fail-closed dependency resolution diagnostics.
24+
- Upgraded `schema-dsl` to `2.1.6` and moved Model schema compilation/validation onto a MonSQLize runtime-scoped `schema-dsl/runtime` engine. `schemaDsl` now supports runtime options, extension registration, external runtime injection, explicit validation disablement, and fail-closed dependency resolution diagnostics.
2325
- Fixed `schemaDsl: { runtime, extensions }` lifecycle handling so injected runtimes register extensions once during `connect()` instead of registering the same factory during construction and reconnect setup.
2426
- Made injected `schema-dsl/runtime` extension registration idempotent across failed connect retries, close/reconnect cycles, shared external runtime instances, incremental/reordered extension sets, partial extension-registration failures, external runtime resets, and source-stable function-valued definitions. Function fingerprinting now distinguishes closure-sensitive definitions from stable local scopes, including destructuring, nested helpers, templates, class/object methods, private/member access, regex literals, reserved syntax tokens, semicolonless local declarations with and without initializers, and break/continue labels; conflicting closure definitions still surface through schema-dsl.
2527
- Hardened `schema-dsl/runtime` loading across CJS, ESM, and TypeScript-generated CJS test entry points; extended function fingerprinting for numeric literals and Unicode identifiers; and aligned full-document Model validation, docs, examples, and public type examples with the recommended `schema: (s) => s(...)` DSL callback style.

changelogs/v3.0.0.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# monSQLize v3.0.0
22

3-
> Prepared date: 2026-07-13
4-
> Release status: Prepared, not yet published
3+
> Release date: 2026-07-14
4+
> Release status: Released
55
> Type: Major
66
> Stable predecessor: v2.0.6
77
@@ -13,13 +13,14 @@ v3.0.0 consolidates the unpublished v2.0.7 work into a major release. It adds bo
1313

1414
### Bounded production data tasks
1515

16-
- Added the named `dataTasks` facade and `MonSQLize.dataTasks` static entry with `preview()`, `apply()`, `previewRestore()`, and `restore()` for two independent source/target instances.
16+
- Added the named `dataTasks` facade with `preview()`, `apply()`, `previewRestore()`, and `restore()` for two independent source/target instances. CommonJS exposes the same root facade through destructuring; it is not an instance API.
1717
- Added collection-level `indexes[]`, filtered `data`, explicit `fields` / `source-id` identity, deterministic pipeline/handler transforms, approval drift fingerprints, affected-scope BSON backup packages, verification, and reversible restore-safety packages.
1818
- Consolidated data tasks on one `DataTaskJob` contract and the named `dataTasks.preview/apply/previewRestore/restore` service; the unpublished instance runner and step configuration were removed.
1919
- Consolidated the CLI on `preview`, `apply`, `preview-restore`, and `restore`, with task files directly exporting the same Job configuration.
2020
- Production apply requires explicit `targetEnvironment`, a durable `backup.dir`, and a non-expired preview approval bound to the job, source, target, and target indexes.
2121
- Write-task environments are restricted to `development`, `test`, `staging`, `production`, `prod`, or `live`; unknown or misspelled names fail planning instead of silently bypassing production gates.
2222
- Data task locks use a renewable lease in the target database, coordinate separate processes, and stop writes after ownership is lost.
23+
- Data task planning uses a bounded stream independent of the public `findLimit`, exact write-time document CAS includes unexpected-field detection, and expired local leases fail closed before another write.
2324

2425
### Write-path policy
2526

@@ -53,6 +54,7 @@ v3.0.0 consolidates the unpublished v2.0.7 work into a major release. It adds bo
5354
- Runtime dependencies are pinned to `schema-dsl@2.1.6` and `ioredis@5.11.1`; Node 18-compatible test tooling uses `mongodb-memory-server@10.4.3`.
5455
- The release server matrix now strictly requires MongoDB 7.0.37 and 8.0.26 across standalone, replica-set, Driver 6/7, and DataTask integration paths; unavailable combinations fail release preflight instead of being recorded as a successful skip.
5556
- Release candidates must be clean, have a valid installed dependency graph, and already exist on `origin`; the same preflight also verifies the docs site and packaged `MIGRATION.md` / `SECURITY.md` consumer guidance.
57+
- A manual pre-tag authentication workflow verifies the repository's current npm publish credential with `npm whoami` without creating a tag or publishing.
5658
- Stable Pages deployment separates immutable release-tag content from current release tooling, so historical stable tags can rebuild their tagged docs with the current audited website toolchain and link gate without deploying unpublished branch content; current releases still require the complete website verification chain.
5759

5860
## Compatibility-impacting changes

docs/en/data-tasks.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ Preview calls `listIndexes()` first for every target collection and classifies e
132132
| `data.batchSize` | No | `500` | Write-ahead checkpoint batch size, from `1..10000` |
133133
| `data.maxDocuments` | No | `10000` | Maximum source documents that the collection may plan |
134134

135+
Data task source reads use a bounded internal stream and do not inherit the ordinary `findLimit` default. Planning reads at most `maxDocuments + 1` source documents so concurrent growth fails closed instead of silently truncating or loading an unbounded result.
136+
135137
Field edits run in this order: `filter -> projection -> rename -> set -> unset -> diff`. They are deliberately limited to deterministic edits of a few release fields:
136138

137139
- Paths cannot touch `_id`, identity fields, or overlap one another.

docs/en/release-preflight.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ git commit
3939
git push origin HEAD
4040
# Wait for remote CI on this commit, then run on the same clean commit:
4141
npm run release:preflight
42+
# Run the manual Release Authentication Check workflow and require npm whoami to pass.
4243
# Optional private real-environment review: npm run verify:release
4344
VERSION=$(node -p "require('./package.json').version")
4445
git tag "v${VERSION}"
4546
git push origin "v${VERSION}"
4647
```
4748

48-
`release:preflight` verifies that the current `HEAD` exists on `origin`, so it cannot run against an uncommitted or local-only candidate. Before creating the tag, manually confirm both remote CI and the preflight evidence for that exact commit. Preflight itself never creates or pushes a tag.
49+
`release:preflight` verifies that the current `HEAD` exists on `origin`, so it cannot run against an uncommitted or local-only candidate. Before creating the tag, manually confirm remote CI, preflight evidence, and a successful **Release Authentication Check** run for the current repository. The authentication probe only runs `npm whoami`; it does not create a tag or publish. Preflight itself never creates or pushes a tag.
4950

5051
The tag starts the repository preflight and publish workflows. Do not deploy Pages yet. After registry acceptance succeeds, manually run **Deploy Docs to GitHub Pages** with `release_tag=vX.Y.Z`; that workflow checks out the tag and refuses deployment unless tag, `package.json`, and npm registry versions match.
5152

docs/zh/data-tasks.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ preview 对每个目标集合先调用 `listIndexes()`,再把声明索引分
140140
| `data.batchSize` || `500` | write-ahead checkpoint 批次,范围 `1..10000` |
141141
| `data.maxDocuments` || `10000` | 本 collection 允许规划的最大来源文档数 |
142142

143+
dataTasks 的来源读取使用内部有界 stream,不继承普通查询的 `findLimit` 默认值。规划最多读取 `maxDocuments + 1` 条来源文档,因此并发增长会明确阻断,不会静默截断或无界加载。
144+
143145
字段调整顺序固定为 `filter -> projection -> rename -> set -> unset -> diff`。它只适合本次发布中少数字段的确定性调整:
144146

145147
- 路径不能是 `_id`、identity 字段,也不能互相重叠。

docs/zh/release-preflight.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ git commit
3939
git push origin HEAD
4040
# 等待当前提交的远端 CI 通过,然后在同一干净提交上执行:
4141
npm run release:preflight
42+
# 手动运行 Release Authentication Check workflow,并要求 npm whoami 通过。
4243
# 可选的私有真实环境复核:npm run verify:release
4344
VERSION=$(node -p "require('./package.json').version")
4445
git tag "v${VERSION}"
4546
git push origin "v${VERSION}"
4647
```
4748

48-
`release:preflight` 会校验当前 `HEAD` 已存在于 `origin`,因此不能在未提交或仅本地存在的候选上运行。创建 tag 前仍需人工确认当前提交的远端 CIpreflight 证据;preflight 本身不会创建或推送 tag。
49+
`release:preflight` 会校验当前 `HEAD` 已存在于 `origin`,因此不能在未提交或仅本地存在的候选上运行。创建 tag 前必须确认当前提交的远端 CIpreflight 证据,以及当前仓库的 **Release Authentication Check** 已成功。凭据探针只执行 `npm whoami`,不会创建 tag 或 publish;preflight 本身也不会创建或推送 tag。
4950

5051
tag 会启动仓库 preflight 与 publish workflow,此时不要部署 Pages。registry 验收通过后,手动运行 **Deploy Docs to GitHub Pages**,传入 `release_tag=vX.Y.Z`;该 workflow 会检出指定 tag,并在 tag、`package.json` 与 npm registry 版本不一致时拒绝部署。
5152

0 commit comments

Comments
 (0)