dsh-thesis 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/docs/design.md +22 -0
- package/docs/release.md +94 -85
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ node scripts/install-into-profile.ts --profile web # 没有 pnpm 时的兜
|
|
|
73
73
|
| [docs/troubleshooting.md](./docs/troubleshooting.md) | 装了没反应、没弹选择题、PDF/pptx 失败等 |
|
|
74
74
|
| [docs/design.md](./docs/design.md) | 设计文档与 ADR(架构、分层、质量策略、已知边界) |
|
|
75
75
|
| [docs/host-api.md](./docs/host-api.md) | 宿主契约:用到的 DSH 接口与实测行为 |
|
|
76
|
-
| [docs/release.md](./docs/release.md) |
|
|
76
|
+
| [docs/release.md](./docs/release.md) | 发版:`npm run release:minor` + push → GitHub Actions → npm(含 provenance)|
|
|
77
77
|
|
|
78
78
|
## 开发
|
|
79
79
|
|
|
@@ -89,8 +89,9 @@ npm run verify # build + 两个 typecheck + 全部单测 + 审
|
|
|
89
89
|
质量分层:单测/契约、真实场景端到端、真实 cordis 装配、真实 dsh 引擎装载、对外表面审计
|
|
90
90
|
(见 [docs/design.md](./docs/design.md) §9)。
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
**发版**:`npm run release:minor`(改版本号并提交)+ `git push` 即发布——workflow 发现 npm 上没有这个版本
|
|
93
|
+
就发布,发完自动补 tag 与 Release,**不需要手动打 tag**。由 GitHub Actions 跑构建、校验与
|
|
94
|
+
`npm publish --provenance`,见 [docs/release.md](./docs/release.md)。
|
|
94
95
|
|
|
95
96
|
## 许可
|
|
96
97
|
|
package/docs/design.md
CHANGED
|
@@ -351,6 +351,28 @@ DSH 的 profile 预检(`dsh-app-boot` 的 `evaluatePluginCompatibility`,在
|
|
|
351
351
|
**取舍**:内置过渡引擎只落实表格与页边距(A4、上 2.5/下 2.5/左 3.0/右 2.5 cm);
|
|
352
352
|
分节页码、目录域、页眉依赖模板级排版,交给 `build_docx.py` 或 pandoc + 学校模板。
|
|
353
353
|
|
|
354
|
+
### ADR-19 发布由「版本号」驱动,tag 是产物而不是开关
|
|
355
|
+
|
|
356
|
+
**背景**:原来发版要先打 tag 再推,tag 名还必须与 `package.json` 逐字一致——漏一步就是一次红 run,
|
|
357
|
+
而 tag 本身没有携带任何信息,只是"我现在要发版了"的暗号。
|
|
358
|
+
|
|
359
|
+
**决定**:
|
|
360
|
+
1. 触发条件改为 `push: branches: [main]`,同时保留 `tags: ['v*']` 兼容手动打 tag;
|
|
361
|
+
2. 是否发布由「`package.json` 的版本在 npm 上是否已存在」决定——**版本号没变就不发**;
|
|
362
|
+
3. 发布成功后由 workflow 自己 `git tag v<version>` 并推上去,再建 Release;
|
|
363
|
+
4. 版本号只有一个来源:`package.json`。`npm run release:minor` 同时改
|
|
364
|
+
`package.json` 与 `package-lock.json`(顶层 + `packages[""]`)并提交,提交信息从版本号派生。
|
|
365
|
+
|
|
366
|
+
**为什么不从 commit message 解析版本**:发布包里写的是 `package.json` 的 version。
|
|
367
|
+
让提交信息决定发什么版本,要么包与 tag 不一致,要么 CI 临时改包导致仓库与 npm 永久错位,
|
|
368
|
+
要么机器人提交回 main 撞保护分支。三者都比"多跑一条 `npm run release:*`"更贵。
|
|
369
|
+
|
|
370
|
+
**取舍**:每次推 main 都会多跑一个 `npm ci` + `npm view`(约 40 秒)才判定跳过;
|
|
371
|
+
换来的是"日常提交随便推、发版只需升版本号"。
|
|
372
|
+
|
|
373
|
+
**验证**:`npm run release:minor -- --dry-run` 只打印不落盘;`publish.yml` 用 PyYAML 解析校验结构与条件;
|
|
374
|
+
真正的判定(已发布则跳过)由 npm 侧 `npm view` 保证,重复触发不会覆盖已发布版本。
|
|
375
|
+
|
|
354
376
|
---
|
|
355
377
|
|
|
356
378
|
## 7. 数据与产物
|
package/docs/release.md
CHANGED
|
@@ -1,138 +1,147 @@
|
|
|
1
1
|
# 发布
|
|
2
2
|
|
|
3
3
|
发版由 GitHub Actions 完成([`.github/workflows/publish.yml`](../.github/workflows/publish.yml))。
|
|
4
|
-
**打 tag 即发布**,本地不需要 `npm login`,也不需要任何 npm token。
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
**升版本号 + push 就发版,不用打 tag。** 推上去以后 workflow 会自己看 npm 上有没有这个版本,
|
|
6
|
+
没有就发布,发完**自动补 tag 与 GitHub Release**——tag 是发布的产物,不再是发布的前提。
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
```bash
|
|
9
|
+
npm run release:minor # 2.1.0 -> 2.2.0(改 package.json 与 package-lock.json 并提交)
|
|
10
|
+
git push origin main # 推完就自动发布
|
|
11
|
+
```
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
**Select publisher: GitHub Actions**,填四个字段:
|
|
13
|
+
就这两条。`npm run release:patch` / `release:major` 同理。
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|---|---|
|
|
16
|
-
| Organization or user | `booondenz` |
|
|
17
|
-
| Repository | `dsh-thesis` |
|
|
18
|
-
| Workflow filename | `publish.yml`(只写文件名,不带路径)|
|
|
19
|
-
| Environment name | **留空**(除非 workflow 里写了 `environment:`)|
|
|
15
|
+
本地不需要 `npm login`,也不需要任何 npm token。
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
## 它怎么判断该不该发
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
| 检查 | 结果 |
|
|
20
|
+
|---|---|
|
|
21
|
+
| push 到 `main` | 进入发布流程 |
|
|
22
|
+
| push 的 tag(`v*`) | 同样进入(兼容手动打 tag 的老做法) |
|
|
23
|
+
| `package.json` 的版本 npm 上**没有** | `npm pack --dry-run` → 守卫 → `npm publish` → 自动打 tag → 建 Release |
|
|
24
|
+
| `package.json` 的版本 npm 上**已有** | 只跑检查,跳过发布(不会红,也不会覆盖)|
|
|
25
|
+
| 手动触发(`workflow_dispatch`) | 只做打包预览,不发布、不打 tag |
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
所以:**版本号没变 = 这次 push 不发版**。日常提交随便推,只有 `release:*` 那次会发。
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
3. 不需要 `NPM_TOKEN`,**之前建过的话建议在 Settings → Secrets 里删掉**,免得以后误用。
|
|
29
|
+
## 为什么版本号只认 `package.json`,不从 commit message 解析
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
发布包里真正写进去的是 `package.json` 的 `version`。如果让提交信息里的 `v2.2.0` 决定发什么版本,
|
|
32
|
+
只有三条路,都不好:
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
1. **照抄提交信息 → 包里版本不对**:提交写 `v2.2.0`、`package.json` 还是 `2.1.0`,
|
|
35
|
+
npm 上会出现两个"2.1.0"(第二次直接被拒),或者发出去的包版本与 tag 不一致;
|
|
36
|
+
2. **CI 里临时改 `package.json` 再发**:npm 上是 2.2.0,仓库里还是 2.1.0,
|
|
37
|
+
下次谁从仓库装就是旧版本,provenance 里的 commit 也对不上;
|
|
38
|
+
3. **CI 里改完再提交回 main**:机器人提交 + 可能撞保护分支 + 每次发版两个 commit。
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
存成仓库 secret `NPM_TOKEN`,然后在 workflow 的 publish 步骤加回:
|
|
40
|
+
现在的做法是:**版本号只有一处真相(`package.json`),`npm run release:*` 负责同时改两处并提交**,
|
|
41
|
+
提交信息与 tag 名都从它派生(`chore: release v2.2.0` → tag `v2.2.0`),三者不可能不一致。
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
env:
|
|
45
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
46
|
-
```
|
|
43
|
+
## 一次性设置(只做一次,已完成)
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
npm 侧认证走 **Trusted Publishing(OIDC)**:npm 只接受「这个仓库的这个 workflow」发来的包,
|
|
46
|
+
凭据每次运行临时签发,不落盘、不过期、没有 2FA 输 OTP 的问题;provenance 自动附带。
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
<https://www.npmjs.com/package/dsh-thesis/access> → **Trusted Publishers**:
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
| 字段 | 值 |
|
|
51
|
+
|---|---|
|
|
52
|
+
| Organization or user | `booondenz` |
|
|
53
|
+
| Repository | `dsh-thesis` |
|
|
54
|
+
| **Workflow filename** | **`publish.yml`**(只写文件名,不带路径)|
|
|
55
|
+
| Environment name | 留空 |
|
|
56
|
+
|
|
57
|
+
**`publish.yml` 这个文件名不能改**(也不能把发布逻辑挪进 `ci.yml`):npm 的配置绑的就是文件名,
|
|
58
|
+
改名后第一次发布会 403。改了触发条件是安全的,改文件名不是。
|
|
59
|
+
|
|
60
|
+
同一页 **Allowed actions** 里要勾 **Allow npm publish**,只勾 stage 的话每次发版还得去网页做 2FA 批准。
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
## workflow 干了什么
|
|
62
63
|
|
|
63
64
|
| 步骤 | 失败就停 |
|
|
64
65
|
|---|---|
|
|
65
|
-
| `npm ci` | 锁文件与 package.json
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| `npm
|
|
70
|
-
|
|
|
66
|
+
| `npm ci` | 锁文件与 `package.json` 不同步会红(所以别手改版本号,用 `npm run release:*`)|
|
|
67
|
+
| 读 `package.json` 版本 | — |
|
|
68
|
+
| 手动 tag 与版本一致(仅 tag 触发时)| 防止「tag 写 v2.2.0、包里是 2.1.0」|
|
|
69
|
+
| 该版本是否已发布 | 已存在则跳过发布 |
|
|
70
|
+
| `npm pack --dry-run` | 日志里能直接看到这次包里有什么 |
|
|
71
|
+
| `npm publish` | 内部跑 `prepublishOnly` 守卫:构建 + 类型 + 单测 + 审计 + 端到端;**main 红了在这里被拦下** |
|
|
72
|
+
| 自动打 tag | `git tag v<version>` + push;用 `GITHUB_TOKEN` 推的 tag 不会再触发 workflow,不会套娃 |
|
|
73
|
+
| 建 Release | 标题 `v<version>`,正文自动生成 |
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
## 手动打 tag(仍然可以,但不再是发版的必要条件)
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
```bash
|
|
78
|
+
git tag v2.2.0
|
|
79
|
+
git push origin v2.2.0
|
|
80
|
+
```
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
workflow 第一步的版本比对就会红);
|
|
80
|
-
4. 标题写 `v2.0.1`,正文可以留空——workflow 里是 `gh release view || gh release create`,
|
|
81
|
-
发现 Release 已存在会跳过;
|
|
82
|
-
5. **Publish release**。
|
|
82
|
+
行为与以前完全一致:先校验 tag 与 `package.json` 一致,再发布。适合"版本号早就提交了、只是补发"的场景。
|
|
83
|
+
|
|
84
|
+
## 备选:用 token(不推荐)
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
可信发布不可用时,在 npm 建 **Classic → Automation** token(Granular token 在开了 2FA 的账号上会报 `EOTP`),
|
|
87
|
+
存成仓库 secret `NPM_TOKEN`,然后在 publish 步骤加回:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
env:
|
|
91
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
并把 `setup-node` 的 `with:` 里加回 `registry-url: https://registry.npmjs.org`。
|
|
95
|
+
Automation token 专为 CI 设计,不受 2FA 影响。
|
|
86
96
|
|
|
87
97
|
## 确认发成功了
|
|
88
98
|
|
|
89
99
|
| 看哪 | 期望 |
|
|
90
100
|
|---|---|
|
|
91
|
-
| Actions → **publish** |
|
|
92
|
-
| `npm view dsh-thesis version` | `2.0
|
|
93
|
-
| `npm view dsh-thesis dist-tags` | `{ latest: '2.0
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
Actions 里**根本没出现 publish 这个 run**,说明 tag 没推上去(或名字不是 `v` 开头);
|
|
98
|
-
出现 run 但红在第一步,通常是 tag 与 `package.json` 版本对不上。
|
|
101
|
+
| Actions → **publish** | 绿;Summary 里有 `https://www.npmjs.com/package/dsh-thesis/v/2.2.0` |
|
|
102
|
+
| `npm view dsh-thesis version` | `2.2.0`(registry 立刻生效,网页可能慢一分钟)|
|
|
103
|
+
| `npm view dsh-thesis dist-tags` | `{ latest: '2.2.0' }` |
|
|
104
|
+
| 仓库 **Tags / Releases** | 自动多了 `v2.2.0` |
|
|
105
|
+
| <https://www.npmjs.com/package/dsh-thesis> | 版本号旁有 **Provenance** 徽章 |
|
|
99
106
|
|
|
100
107
|
## 发完之后:让 DSH 用上新版
|
|
101
108
|
|
|
102
|
-
profile 把版本钉在 `~/.dsh/profiles/<profile>/package.json`
|
|
103
|
-
所以 npm 上发了新版**不会自动生效**。到插件管理器里移除再装一次(会取 `latest`),或者把那条依赖
|
|
104
|
-
改成 `"^2.0.1"` 后重装,然后**重启 DSH**——2.0 删掉了全部斜杠命令,不是热更新能覆盖的。
|
|
109
|
+
profile 把版本钉在 `~/.dsh/profiles/<profile>/package.json` 里,npm 发了新版**不会自动生效**:
|
|
105
110
|
|
|
106
|
-
|
|
111
|
+
```bash
|
|
112
|
+
dsh plugin --profile web add dsh-thesis@2.2.0
|
|
113
|
+
dsh plugin --profile desktop add dsh-thesis@2.2.0
|
|
114
|
+
```
|
|
107
115
|
|
|
108
|
-
|
|
109
|
-
想真发版,还是打 tag。
|
|
116
|
+
然后**重启 DSH**(2.0 删掉了全部斜杠命令,不是热更新能覆盖的)。
|
|
110
117
|
|
|
111
118
|
## 失败排查
|
|
112
119
|
|
|
113
120
|
| 现象 | 原因 |
|
|
114
121
|
|---|---|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
|
|
|
122
|
+
| Actions 里**根本没有** publish run | push 的不是 `main`,也不是 `v*` tag |
|
|
123
|
+
| publish 绿但 Summary 写"已存在,未发布" | 版本号没升(`npm run release:*` 没跑)|
|
|
124
|
+
| `EOTP` / 要求一次性密码 | 用的是需要 OTP 的 token → 改用可信发布或 Automation token |
|
|
125
|
+
| 被拒、提示只能 `npm stage publish` | 可信发布里没勾 **Allow npm publish** |
|
|
126
|
+
| `403 … OIDC permission denied for this action` | 同上:认证过了,但没给「直接发布」权限 |
|
|
127
|
+
| `401 Unauthorized` | token 过期,或可信发布配置里 workflow 文件名写错 |
|
|
128
|
+
| `npm ci … not in sync` | 手改了 `package.json` 版本没同步锁文件 → 改用 `npm run release:*` |
|
|
129
|
+
| `403 … cannot publish over previously published version` | 版本号没升;workflow 里"已存在则跳过"会挡住,手动发版时要注意 |
|
|
130
|
+
| 守卫里单测红 / 端到端红 | 与 `npm run verify` 同一套;本地先复现 |
|
|
122
131
|
| 守卫警告「未找到 DSH 安装」 | CI 里正常(没有宿主);**发版前请在本地跑一次 `npm run test:host-load` 与 `npm run test:host`** |
|
|
132
|
+
| 自动打 tag 失败但 npm 已发布 | tag 只是标记,事后手动 `git tag v2.2.0 && git push origin v2.2.0` 补上即可 |
|
|
123
133
|
|
|
124
134
|
## 撤回与补救
|
|
125
135
|
|
|
126
|
-
- **已发布的版本不能改**,只能 `npm deprecate dsh-thesis@2.0
|
|
136
|
+
- **已发布的版本不能改**,只能 `npm deprecate dsh-thesis@2.2.0 "原因与替代版本"`。
|
|
127
137
|
- 72 小时内理论上可以 `npm unpublish`,但那会让依赖它的人突然装不上,**不要用**。
|
|
128
|
-
- 发错了就立刻发一个 patch:`
|
|
138
|
+
- 发错了就立刻发一个 patch:`npm run release:patch` + `git push`。
|
|
129
139
|
|
|
130
|
-
##
|
|
140
|
+
## 本地发布(应急)
|
|
131
141
|
|
|
132
142
|
```bash
|
|
133
143
|
npm login
|
|
134
144
|
npm publish --access public # 会跑同一个 prepublishOnly 守卫,会交互式要 OTP
|
|
135
145
|
```
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
CI 只是把「构建 → 校验 → 发布」串起来,判据完全一样。
|
|
147
|
+
本地发布用你登录后的凭据,不需要 token,也不需要可信发布配置。CI 只是把「构建 → 校验 → 发布」串起来,判据完全一样。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-thesis",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "论文与答辩全流程助手(DeepSeek Harness 插件):材料摄取 → 逐题追问 → 文献检索 → 逐章写作与评审 → 原创性自查与合规 → Word/答辩幻灯生产,全流程留痕,并跨会话记住学校规范与导师要求。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -60,6 +60,9 @@
|
|
|
60
60
|
"test:host": "node scripts/host-smoke.ts && node .host-smoke/app/run.ts",
|
|
61
61
|
"test:host-load": "node scripts/host-verify.ts",
|
|
62
62
|
"audit": "node scripts/audit-surface.ts",
|
|
63
|
+
"release:patch": "node scripts/release.ts patch",
|
|
64
|
+
"release:minor": "node scripts/release.ts minor",
|
|
65
|
+
"release:major": "node scripts/release.ts major",
|
|
63
66
|
"verify": "npm run build && npm run typecheck && npm run typecheck:scripts && npm run test:sandbox && npm run audit && npm run test:e2e",
|
|
64
67
|
"prepublishOnly": "node scripts/prepublish-guard.ts"
|
|
65
68
|
},
|