@namewta/speculo 1.0.19 → 1.0.21
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 +8 -7
- package/THIRD-PARTY-NOTICES.md +33 -0
- package/dist/src/agent-files.js +2 -2
- package/dist/src/agent-files.js.map +1 -1
- package/dist/src/agent-skills.d.ts +81 -0
- package/dist/src/agent-skills.js +530 -0
- package/dist/src/agent-skills.js.map +1 -0
- package/dist/src/cli.js +11 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.js +5 -3
- package/dist/src/config.js.map +1 -1
- package/dist/src/doctor.js +7 -2
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +23 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/manifest.d.ts +9 -0
- package/dist/src/manifest.js +45 -7
- package/dist/src/manifest.js.map +1 -1
- package/dist/src/refresh.js +40 -0
- package/dist/src/refresh.js.map +1 -1
- package/dist/src/structured.js +15 -4
- package/dist/src/structured.js.map +1 -1
- package/dist/src/transaction.d.ts +24 -3
- package/dist/src/transaction.js +191 -12
- package/dist/src/transaction.js.map +1 -1
- package/package.json +7 -4
- package/scripts/validate-skills.mjs +56 -0
- package/template/AGENTS.md +1 -1
- package/template/CLAUDE.md +1 -1
- package/template/canonical/canonical-specdev-goal-plan.md +156 -28
- package/template/canonical/canonical-specdev-grill-with-docs.md +153 -31
- package/template/canonical/canonical-specdev-spec.md +153 -27
- package/template/canonical/canonical-specdev-tickets.md +153 -27
- package/template/canonical/canonical-specdev-wayfinder.md +142 -27
- package/template/commands/retro.md +11 -9
- package/template/skills/archive-and-consolidate/SKILL.md +163 -7
- package/template/skills/archive-and-consolidate/references/cleanup-rules.md +1 -1
- package/template/skills/docs-sync/references/agents/claude-redirect.md +8 -8
- package/template/skills/docs-sync/references/agents/content-contract.md +1 -1
- package/template/skills/docs-sync/references/agents/manifest-discovery.md +7 -7
- package/template/skills/docs-sync/references/agents/role-classification.md +4 -4
- package/template/skills/docs-sync/references/agents-contract.md +1 -1
- package/template/skills/engineering-standards-builder/SKILL.md +149 -9
- package/template/skills/engineering-standards-builder/agents/openai.yaml +2 -0
- package/template/skills/engineering-standards-builder/manifest.txt +2 -1
- package/template/skills/engineering-standards-builder/references/rules/09-mechanical-guardrails.md +9 -0
- package/template/skills/engineering-standards-builder/scripts/validate-builder.mjs +4 -7
- package/template/skills/git-history-squash/SKILL.md +87 -11
- package/template/skills/git-history-squash/agents/openai.yaml +2 -0
- package/template/skills/optimize-codex-config/SKILL.md +71 -11
- package/template/skills/{speculo-retro/references/entry-procedure.md → retrospective/SKILL.md} +12 -8
- package/template/skills/{speculo-retro → retrospective}/references/friction-taxonomy.md +22 -13
- package/template/skills/{speculo-retro → retrospective}/references/issue-drafting-sop.md +10 -20
- package/template/skills/source-code-zip/SKILL.md +44 -8
- package/template/skills/source-code-zip/references/{entry-procedure.md → cli-reference.md} +0 -43
- package/template/skills/upstream-fork-sync/SKILL.md +71 -8
- package/template/skills/{writing-great-skills → writing-for-agents}/GLOSSARY.md +1 -1
- package/template/skills/writing-for-agents/SKILL.md +22 -0
- package/template/skills/writing-for-agents/agents/openai.yaml +2 -0
- package/template/skills/{writing-great-skills/references/entry-procedure.md → writing-for-agents/references/authoring-principles.md} +2 -9
- package/template/workflows/ops/D-project-deploy/D-project-deploy.md +1 -1
- package/template/workflows/ops/H-host-manage/H-host-manage.md +4 -0
- package/template/workflows/ops/H-host-manage/references/host-profiles.md +4 -0
- package/template/workflows/ops/I-initialize/I-initialize.md +1 -1
- package/template/workflows/ops/INDEX.md +2 -0
- package/template/workflows/ops/README.md +7 -3
- package/template/workflows/ops/S-server-connect/S-server-connect.md +5 -5
- package/template/workflows/ops/V-inventory-view/V-inventory-view.md +2 -0
- package/template/workflows/ops/common/CAPABILITIES.md +2 -0
- package/template/workflows/ops/common/USAGE.md +5 -5
- package/template/workflows/ops/common/WORKSPACE-USAGE.md +29 -2
- package/template/workflows/ops/common/examples/README.md +1 -1
- package/template/workflows/ops/common/examples/register.example.json +7 -3
- package/template/workflows/ops/common/examples/server-connection.example.json +11 -0
- package/template/workflows/ops/common/rules/deployment-layout.md +1 -1
- package/template/workflows/ops/common/rules/host-root-and-onboarding.md +47 -0
- package/template/workflows/ops/common/rules/persistence-and-secrets.md +1 -1
- package/template/workflows/ops/common/rules/research-and-decisions.md +8 -0
- package/template/workflows/ops/common/rules/server-onboarding.md +3 -3
- package/template/workflows/ops/common/rules/workspace-and-authorization.md +2 -2
- package/template/workflows/ops/common/schemas/fleet-view.schema.json +64 -0
- package/template/workflows/ops/common/schemas/host.schema.json +19 -0
- package/template/workflows/ops/common/schemas/plan.schema.json +57 -0
- package/template/workflows/ops/common/schemas/root-confirmation.schema.json +118 -0
- package/template/workflows/ops/common/schemas/server-connection.schema.json +67 -0
- package/template/workflows/ops/common/schemas/server-discovery.schema.json +171 -0
- package/template/workflows/ops/common/schemas/spec.schema.json +19 -0
- package/template/workflows/ops/common/schemas/status.schema.json +19 -0
- package/template/workflows/ops/common/templates/FLEET.html +1 -1
- package/template/workflows/ops/common/templates/HOST-README.md +3 -1
- package/template/workflows/ops/common/tests/test_ops.mjs +8 -11
- package/template/workflows/ops/common/tests/test_ops_bootstrap.mjs +101 -16
- package/template/workflows/ops/common/tests/test_ops_onboarding.mjs +225 -0
- package/template/workflows/ops/common/tests/test_ops_workspace.mjs +17 -8
- package/template/workflows/ops/common/tools/demo-local.mjs +4 -0
- package/template/workflows/ops/common/tools/opslib/agent.mjs +26 -0
- package/template/workflows/ops/common/tools/opslib/bootstrap.mjs +52 -26
- package/template/workflows/ops/common/tools/opslib/cli.mjs +1 -0
- package/template/workflows/ops/common/tools/opslib/core.mjs +1 -1
- package/template/workflows/ops/common/tools/opslib/docs.mjs +1 -0
- package/template/workflows/ops/common/tools/opslib/execution.mjs +4 -0
- package/template/workflows/ops/common/tools/opslib/fleet.mjs +26 -4
- package/template/workflows/ops/common/tools/opslib/host_recipes.mjs +34 -0
- package/template/workflows/ops/common/tools/opslib/model.mjs +6 -0
- package/template/workflows/ops/common/tools/opslib/onboarding.mjs +215 -0
- package/template/workflows/ops/common/tools/opslib/planner.mjs +3 -0
- package/template/workflows/ops/common/tools/opslib/transport.mjs +10 -6
- package/template/workflows/ops/common/tools/opslib/workspace_cli.mjs +20 -1
- package/template/workflows/ops/common/tools/server-discover.sh +65 -0
- package/template/workflows/ops/common/tools/validate-ops.mjs +1 -1
- package/template/workflows/ops/manifest.json +12 -5
- package/template/workflows/specdev/A-archive-and-consolidate/consolidation-interview.md +3 -3
- package/template/workflows/specdev/C-code-review/C-code-review.md +1 -1
- package/template/workflows/specdev/D-diagnose-bugs/D-diagnose-bugs.md +6 -0
- package/template/workflows/specdev/G-grill-with-docs/references/interview-procedure.md +6 -6
- package/template/workflows/specdev/I-implement/references/implementation-procedure.md +1 -1
- package/template/workflows/specdev/I-implement/tdd-rules.md +4 -0
- package/template/workflows/specdev/I-init-setup/config-template.json +5 -1
- package/template/workflows/specdev/INDEX.md +2 -2
- package/template/workflows/specdev/P-goal-plan/planning-modes.md +1 -1
- package/template/workflows/specdev/P-prototype/P-prototype.md +7 -3
- package/template/workflows/specdev/P-prototype/logic-protocol.md +11 -0
- package/template/workflows/specdev/P-prototype/logic-template.md +27 -0
- package/template/workflows/specdev/P-prototype/project-preview-protocol.md +9 -0
- package/template/workflows/specdev/R-retro/R-retro.md +26 -0
- package/template/workflows/specdev/R-retro/retro-template.md +27 -0
- package/template/workflows/specdev/R-review-architecture/references/selected-design.md +1 -1
- package/template/workflows/specdev/README.md +13 -2
- package/template/workflows/specdev/S-spec/S-spec.md +4 -0
- package/template/workflows/specdev/T-tickets/T-tickets.md +4 -0
- package/template/workflows/specdev/T-triage/T-triage.md +31 -25
- package/template/workflows/specdev/T-triage/capture-protocol.md +1 -1
- package/template/workflows/specdev/T-triage/ci-security-protocol.md +11 -0
- package/template/workflows/specdev/T-triage/intake-protocol.md +10 -4
- package/template/workflows/specdev/T-triage/pr-delivery-protocol.md +13 -0
- package/template/workflows/specdev/T-triage/pr-record-template.md +39 -0
- package/template/workflows/specdev/T-triage/publish-protocol.md +1 -1
- package/template/workflows/specdev/T-triage/queue-protocol.md +7 -0
- package/template/workflows/specdev/T-triage/reconcile-protocol.md +1 -1
- package/template/workflows/specdev/T-triage/references/issue-pr-policy.md +23 -0
- package/template/workflows/specdev/T-triage/references/release-authentication.md +9 -0
- package/template/workflows/specdev/T-triage/references/release-notes-injection.md +21 -0
- package/template/workflows/specdev/T-triage/references/workflow-yaml-reference.md +37 -0
- package/template/workflows/specdev/T-triage/release-preflight.md +13 -0
- package/template/workflows/specdev/T-triage/release-protocol.md +12 -0
- package/template/workflows/specdev/T-triage/release-recovery.md +18 -0
- package/template/workflows/specdev/T-triage/remote-operations.md +25 -0
- package/template/workflows/specdev/T-triage/scripts/github-transport.mjs +208 -0
- package/template/workflows/specdev/T-triage/source-template.md +7 -0
- package/template/workflows/specdev/T-triage/triage-run-template.md +34 -0
- package/template/workflows/specdev/T-triage/triage-template.md +4 -1
- package/template/workflows/specdev/common/rules/artifact-contract.md +7 -0
- package/template/workflows/specdev/common/rules/change-completion.md +6 -0
- package/template/workflows/specdev/common/rules/workflow-routing.md +6 -0
- package/template/workflows/specdev/common/rules/workflow-state-and-lifecycle.md +1 -1
- package/template/workflows/specdev/common/schemas/config.schema.json +137 -26
- package/template/workflows/specdev/common/schemas/logic-prototype.schema.json +62 -0
- package/template/workflows/specdev/common/schemas/pull-request.schema.json +90 -0
- package/template/workflows/specdev/common/schemas/retrospective.schema.json +58 -0
- package/template/workflows/specdev/common/schemas/triage-run.schema.json +149 -0
- package/template/workflows/specdev/common/schemas/triage.schema.json +117 -15
- package/template/workflows/specdev/common/tools/delivery-artifacts.mjs +95 -0
- package/template/workflows/specdev/common/tools/validate-specdev.mjs +60 -19
- package/template/workflows/specdev/runtime-contract.json +4 -2
- package/template/skills/archive-and-consolidate/references/entry-procedure.md +0 -178
- package/template/skills/docs-sync/references/entry-procedure.md +0 -3
- package/template/skills/engineering-standards-builder/references/entry-procedure.md +0 -154
- package/template/skills/git-history-squash/references/entry-procedure.md +0 -94
- package/template/skills/github-npm-ops/SKILL.md +0 -19
- package/template/skills/github-npm-ops/references/ci-and-security-ops.md +0 -178
- package/template/skills/github-npm-ops/references/entry-procedure.md +0 -25
- package/template/skills/github-npm-ops/references/failure-recovery.md +0 -123
- package/template/skills/github-npm-ops/references/issue-pr-triage.md +0 -227
- package/template/skills/github-npm-ops/references/issue-transport.md +0 -26
- package/template/skills/github-npm-ops/references/package-json-checklist.md +0 -171
- package/template/skills/github-npm-ops/references/preflight-checklist.md +0 -39
- package/template/skills/github-npm-ops/references/publish-detection.md +0 -68
- package/template/skills/github-npm-ops/references/release-notes-injection.md +0 -238
- package/template/skills/github-npm-ops/references/release-pipeline.md +0 -108
- package/template/skills/github-npm-ops/references/setup-npm-token.md +0 -63
- package/template/skills/github-npm-ops/references/troubleshooting-playbook.md +0 -293
- package/template/skills/github-npm-ops/references/version-bump-flow.md +0 -217
- package/template/skills/github-npm-ops/references/workflow-yaml-reference.md +0 -268
- package/template/skills/github-npm-ops/scripts/issue-transport.mjs +0 -227
- package/template/skills/optimize-codex-config/references/entry-procedure.md +0 -78
- package/template/skills/speculo-retro/SKILL.md +0 -19
- package/template/skills/upstream-fork-sync/references/entry-procedure.md +0 -78
- package/template/skills/writing-great-skills/SKILL.md +0 -23
- /package/template/skills/{writing-great-skills → writing-for-agents}/references/document-contract.md +0 -0
- /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/adr-format.md +0 -0
- /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/context-format.md +0 -0
- /package/template/workflows/specdev/{I-implement → common/rules}/design-it-twice.md +0 -0
- /package/template/workflows/specdev/{G-grill-with-docs/domain-modeling-rules.md → common/rules/domain-modeling.md} +0 -0
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# GitHub Issue Transport
|
|
2
|
-
|
|
3
|
-
本合同提供 GitHub 的读取和受控写入原语,不承担 SpecDev tracker、change、Ticket、Map 或报告所有权。
|
|
4
|
-
|
|
5
|
-
## 操作
|
|
6
|
-
|
|
7
|
-
- `issue-read`:读取 title、body、state、URL、author、labels、时间与全部可见评论。
|
|
8
|
-
- `pr-read`:读取 PR 正文、评论、文件列表以及不可变 base/head SHA。
|
|
9
|
-
- `issue-search`:按 query 返回候选,用于去重。
|
|
10
|
-
- `issue-create`:默认 dry-run;调用方确认后使用 `--apply`。
|
|
11
|
-
- `issue-comment-close`:按 marker 幂等评论并关闭;默认 dry-run,只有调用方确认后使用 `--apply`。
|
|
12
|
-
|
|
13
|
-
脚本:`scripts/issue-transport.mjs`。所有参数通过 argv 传递,不使用 shell 拼接;输出为 JSON,失败退出非零。
|
|
14
|
-
|
|
15
|
-
## 写入边界
|
|
16
|
-
|
|
17
|
-
调用方必须在执行前展示 repo、Issue、标题或评论、labels/reason 和准确动作,并取得本次明确授权。脚本的 `--apply` 只表示调用方已经完成该确认,不替代授权本身。
|
|
18
|
-
|
|
19
|
-
不得把 token、Cookie、认证输出、机器绝对路径或包含秘密的正文写入长期工件。部分失败由调用方保存已完成步骤和恢复条件;不得因远程失败回滚本地事实。
|
|
20
|
-
|
|
21
|
-
## 完成标准
|
|
22
|
-
|
|
23
|
-
- 读取结果可以冻结为调用方拥有的工件;
|
|
24
|
-
- dry-run 的外部写入为零;
|
|
25
|
-
- comment-close 的 marker 使重试不会重复评论;
|
|
26
|
-
- 成功结论来自执行后的远程重读。
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# package.json 发布前字段清单
|
|
2
|
-
|
|
3
|
-
发布失败的一半原因都是 `package.json` 少字段或字段错位。按这张清单逐项确认。
|
|
4
|
-
|
|
5
|
-
## 必填字段
|
|
6
|
-
|
|
7
|
-
### name
|
|
8
|
-
|
|
9
|
-
- 普通包:全局唯一,小写 + 连字符(如 `my-cli`)
|
|
10
|
-
- Scoped 包:`@scope/name`,必须先在 npm 上拥有 scope
|
|
11
|
-
- **首次发布前用 `npm view <name>` 查询是否被占用**;返回 404 才可用
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm view my-cli # 404 = 可用;有输出 = 已占用
|
|
15
|
-
npm view @scope/my-cli # 首次发布会 404,正常
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### version
|
|
19
|
-
|
|
20
|
-
- 遵循 SemVer(MAJOR.MINOR.PATCH)
|
|
21
|
-
- 必须与要发布的 git tag 严格匹配:tag `v0.0.2` ↔ version `0.0.2`
|
|
22
|
-
- npm **不允许重复发布同一个 version**,即使之前 unpublished 也不行(24h 内)
|
|
23
|
-
|
|
24
|
-
### repository
|
|
25
|
-
|
|
26
|
-
**npm provenance 强制要求这个字段**,缺失会报 `E422`。
|
|
27
|
-
|
|
28
|
-
```json
|
|
29
|
-
{
|
|
30
|
-
"repository": {
|
|
31
|
-
"type": "git",
|
|
32
|
-
"url": "https://github.com/owner/my-cli"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
- `url` 必须指向实际托管 workflow 的 GitHub 仓库
|
|
38
|
-
- 注意大小写:GitHub 虽不区分,但 provenance 验证严格匹配
|
|
39
|
-
|
|
40
|
-
### license
|
|
41
|
-
|
|
42
|
-
SPDX 标识符(如 `MIT`、`Apache-2.0`、`ISC`)。别写 `LICENSE.md` 或随意字符串。
|
|
43
|
-
|
|
44
|
-
## CLI 包专用字段
|
|
45
|
-
|
|
46
|
-
### bin
|
|
47
|
-
|
|
48
|
-
命令入口。路径必须以 `./` 开头:
|
|
49
|
-
|
|
50
|
-
```json
|
|
51
|
-
{
|
|
52
|
-
"bin": {
|
|
53
|
-
"my-cli": "./dist/cli/index.js"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
入口文件必须:
|
|
59
|
-
|
|
60
|
-
1. 有可执行权限(`chmod +x`,或通过 `scripts/inject-shebang.mjs` 注入 shebang)
|
|
61
|
-
2. 首行是 `#!/usr/bin/env node`
|
|
62
|
-
3. 是 ESM(`"type": "module"` 时)或 CJS,与 package 一致
|
|
63
|
-
|
|
64
|
-
### files
|
|
65
|
-
|
|
66
|
-
显式允许列表,避免把源码、测试、`.env` 发到 npm:
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
{
|
|
70
|
-
"files": [
|
|
71
|
-
"dist",
|
|
72
|
-
"templates",
|
|
73
|
-
"!dist/**/*.test.js",
|
|
74
|
-
"!dist/**/__tests__",
|
|
75
|
-
"!dist/**/*.map"
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
- 不写 `files` 时,npm 走 `.gitignore` 加一堆默认规则,通常会漏发或误发
|
|
81
|
-
- 发布前用 `npm pack --dry-run` 看看 tarball 实际内容
|
|
82
|
-
|
|
83
|
-
## 推荐但可选字段
|
|
84
|
-
|
|
85
|
-
### description / keywords
|
|
86
|
-
|
|
87
|
-
影响 npm 搜索结果,写清楚。
|
|
88
|
-
|
|
89
|
-
### homepage / bugs
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"homepage": "https://github.com/owner/my-cli#readme",
|
|
94
|
-
"bugs": {
|
|
95
|
-
"url": "https://github.com/owner/my-cli/issues"
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
显示在 npm 包页面,方便用户找文档和报问题。
|
|
101
|
-
|
|
102
|
-
### engines
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"engines": {
|
|
107
|
-
"node": ">=24.14.1"
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
声明最低 Node 版本;npm 会在安装时提示(但不会阻止)。
|
|
113
|
-
|
|
114
|
-
### type / exports
|
|
115
|
-
|
|
116
|
-
ESM 包:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"type": "module",
|
|
121
|
-
"exports": {
|
|
122
|
-
".": {
|
|
123
|
-
"types": "./dist/index.d.ts",
|
|
124
|
-
"default": "./dist/index.js"
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## scripts
|
|
131
|
-
|
|
132
|
-
### prepublishOnly
|
|
133
|
-
|
|
134
|
-
发布前的质量闸门。仅在 `npm publish` 前执行(`npm install` 不触发):
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
{
|
|
138
|
-
"scripts": {
|
|
139
|
-
"prepublishOnly": "pnpm check"
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
`pnpm check` 通常是 `pnpm lint && pnpm test && pnpm build`。
|
|
145
|
-
|
|
146
|
-
### 不要用的 scripts
|
|
147
|
-
|
|
148
|
-
- `prepublish` — 已废弃,会在 `install` 时也触发,容易误伤
|
|
149
|
-
- `prepare` — 在 `install` 时也跑,写构建命令会导致普通安装变慢
|
|
150
|
-
|
|
151
|
-
## 发布前自检流程
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
# 1. 检查 name 可用(首次发布)
|
|
155
|
-
npm view @scope/my-cli
|
|
156
|
-
|
|
157
|
-
# 2. 版本一致性
|
|
158
|
-
node -e "console.log(require('./package.json').version)"
|
|
159
|
-
git tag --list 'v*' | sort -V | tail -3
|
|
160
|
-
|
|
161
|
-
# 3. tarball 内容预览
|
|
162
|
-
npm pack --dry-run
|
|
163
|
-
|
|
164
|
-
# 4. 运行质量闸门
|
|
165
|
-
pnpm check
|
|
166
|
-
|
|
167
|
-
# 5. 预演发布(不会真的推送)
|
|
168
|
-
npm publish --dry-run --access public --provenance
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
如果 5 个命令都正常,再执行真正的 `git tag && git push origin <tag>` 触发 CI 发布。
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Phase 0 — 前置检测完整清单
|
|
2
|
-
|
|
3
|
-
> 本文件是发布编排流程([release-pipeline.md](release-pipeline.md))Phase 0 的「展开形态」。编排正文只列出核心前置;这里给出 11 项完整探测、失败信号与建议修复。
|
|
4
|
-
> 全部探测都是**只读**的,不会修改任何文件。任一项不通过 → 命令终止,输出修复建议;不要尝试自动跳过。
|
|
5
|
-
|
|
6
|
-
## 探测矩阵
|
|
7
|
-
|
|
8
|
-
| # | 项 | 探测命令 | 通过判定 | 失败建议 |
|
|
9
|
-
|---|----|---------|---------|---------|
|
|
10
|
-
| 1 | 当前分支 | `git rev-parse --abbrev-ref HEAD` | 输出 = 仓库声明的发布分支(默认 `main`) | `git checkout main` 后重新触发;或显式声明本仓库的发布分支 |
|
|
11
|
-
| 2 | 工作区干净 | `git status --porcelain` | 输出为空 | 先 stash / commit;不允许 `git stash` 后立刻发版(stash 内容易丢失) |
|
|
12
|
-
| 3 | 远端可达 | `git ls-remote --exit-code origin` | 退出码 0 | 检查网络 / SSH key / `gh auth status` |
|
|
13
|
-
| 4 | gh 已登录 | `gh auth status` | 含 `Logged in to github.com` | `gh auth login` |
|
|
14
|
-
| 5 | gh 仓库权限 | `gh repo view --json viewerCanAdminister` | `viewerCanAdminister == true` 或至少 push 权限 | 联系仓库管理员;或 fork 后申请 PR 流程 |
|
|
15
|
-
| 6 | Node 版本 | `node --version` | ≥ `package.json#engines.node` | `nvm use` / `fnm use` / 升级本机 Node |
|
|
16
|
-
| 7 | 包管理器 | `pnpm --version` (或 `npm` / `yarn`) | 版本 ≥ 仓库 lockfile 隐含版本 | 安装匹配版本;不要随意切换包管理器 |
|
|
17
|
-
| 8 | release.yml 存在 | `test -f .github/workflows/release.yml` | 文件存在 | 转 `github-npm-ops` skill 的 `references/workflow-yaml-reference.md` 先落该文件 |
|
|
18
|
-
| 9 | release.yml 形态 | 见 [publish-detection.md](publish-detection.md) | 输出 `PUBLISH_TO_NPM=true` 或 `false` | 见 publish-detection 文档的判定矩阵 |
|
|
19
|
-
| 10 | docs-sync state | 对 `<Path>{roots.state}/commands/docs-sync/state.json</Path>` 执行存在性检查与 JSON 解析 | schema v4、scope 已确认,baseline 可解析 | 不存在/未确认 → 走 docs-sync command bootstrap;旧 schema 或损坏 → 停止发布并按 docs-sync state contract 修复,`speculo init` 不解析未登记的 command state |
|
|
20
|
-
| 11 | tag 名称冲突 | `git rev-parse vX.Y.Z 2>/dev/null` | 退出码非 0(tag 不存在) | 同 tag 已存在:先确认是否真的失败需要重发;若是则 `git tag -d` + `git push origin :refs/tags/vX.Y.Z`,否则 bump 到下一版本 |
|
|
21
|
-
|
|
22
|
-
## 失败处理总策略
|
|
23
|
-
|
|
24
|
-
- 探测项 1–3、6–7:本机环境问题,提示用户人工修复后重跑命令
|
|
25
|
-
- 探测项 4–5:GitHub 权限问题,给出对应的 `gh` 命令
|
|
26
|
-
- 探测项 8:基础设施缺失,明确转交 `github-npm-ops` skill 而不是在本命令里现写 release.yml
|
|
27
|
-
- 探测项 9:影响 Phase 5 的分支选择,**不阻塞**命令执行(仅决定后续是否做 npm view 校验)
|
|
28
|
-
- 探测项 10:影响 Phase 2 是否进入 docs-sync 主流程
|
|
29
|
-
- 探测项 11:直接关系到能否打 tag,必须在 Phase 0 阶段就排除
|
|
30
|
-
|
|
31
|
-
## 与后续 Phase 的边界
|
|
32
|
-
|
|
33
|
-
Phase 0 只做**只读探测**,不执行任何修复 SOP:
|
|
34
|
-
|
|
35
|
-
- 提交与版本操作在 Phase 1 / Phase 3(见 [version-bump-flow.md](version-bump-flow.md))
|
|
36
|
-
- 文档同步在 Phase 2 / Phase 6(由调用方执行 `docs-sync` command)
|
|
37
|
-
- 发布监控、验证与恢复在 Phase 4 / 5(见 [release-pipeline.md](release-pipeline.md)、[failure-recovery.md](failure-recovery.md))
|
|
38
|
-
|
|
39
|
-
如果 Phase 0 嗅探到的状态需要某个修复 SOP(如 release.yml 缺失),明确转交对应 reference,不要在前置检测阶段现场修复。
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Release.yml 是否含 npm publish 的判定脚本
|
|
2
|
-
|
|
3
|
-
> 用于决定 Phase 5 是否做 npm 端校验。命令正文只展示了核心 grep;这里给出完整模式集合、第三方 action 清单与误判排除策略。
|
|
4
|
-
|
|
5
|
-
## 判定输出
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
RELEASE_YML=".github/workflows/release.yml"
|
|
9
|
-
|
|
10
|
-
if [ ! -f "$RELEASE_YML" ]; then
|
|
11
|
-
echo "RELEASE_YML_MISSING=true"
|
|
12
|
-
exit 0
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
# 主判定:是否含 npm publish 步骤
|
|
16
|
-
if grep -Eq 'npm[[:space:]]+publish|run:[[:space:]]*pnpm[[:space:]]+publish|run:[[:space:]]*yarn[[:space:]]+publish|JS-DevTools/npm-publish|cycjimmy/semantic-release-action|changesets/action' "$RELEASE_YML"; then
|
|
17
|
-
echo "PUBLISH_TO_NPM=true"
|
|
18
|
-
else
|
|
19
|
-
echo "PUBLISH_TO_NPM=false"
|
|
20
|
-
fi
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## 模式集合
|
|
24
|
-
|
|
25
|
-
`PUBLISH_TO_NPM=true` 命中下列任一行时为真:
|
|
26
|
-
|
|
27
|
-
| 模式 | 形态 | 说明 |
|
|
28
|
-
|------|------|------|
|
|
29
|
-
| `npm publish` | `run: npm publish --provenance --access public` | 官方 npm CLI |
|
|
30
|
-
| `pnpm publish` | `run: pnpm publish --no-git-checks` | pnpm 包管理器 |
|
|
31
|
-
| `yarn publish` | `run: yarn publish --new-version $VERSION` | 旧 yarn / berry |
|
|
32
|
-
| `JS-DevTools/npm-publish@vN` | `uses: JS-DevTools/npm-publish@v3` | 第三方封装 action |
|
|
33
|
-
| `cycjimmy/semantic-release-action@vN` | `uses: cycjimmy/semantic-release-action@v4` | semantic-release 流水线 |
|
|
34
|
-
| `changesets/action@vN` | `uses: changesets/action@v1` 且配置 `publish:` 输入 | Changesets 风格的多包发布 |
|
|
35
|
-
|
|
36
|
-
## 误判排除
|
|
37
|
-
|
|
38
|
-
下列形态**不应**触发 `PUBLISH_TO_NPM=true`:
|
|
39
|
-
|
|
40
|
-
| 形态 | 是否触发 | 原因 |
|
|
41
|
-
|------|---------|------|
|
|
42
|
-
| `# npm publish` 注释行 | ❌ | grep `-E` 默认匹配整行;如需更严格可加 `^[^#]*` 锚定 |
|
|
43
|
-
| `description: 'Run npm publish ...'` | ⚠️ 可能误命中 | 收紧 grep 为 `run:[[:space:]]*npm[[:space:]]+publish` 即可避免 |
|
|
44
|
-
| `npm publish --dry-run` | ✅ 仍命中 | 视作真发布意图;如需排除,可在判定后追加 `--dry-run` 检查并手动降级 |
|
|
45
|
-
| `npm pack` | ❌ | `pack` 不是 `publish` |
|
|
46
|
-
| 仅 `softprops/action-gh-release` | ❌ | 这是 GitHub Release 创建器,不是 npm publish |
|
|
47
|
-
|
|
48
|
-
## 收紧版(推荐用于精确判定)
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
grep -E '^\s*(run:\s*(npm|pnpm|yarn)\s+publish|uses:\s*(JS-DevTools/npm-publish|cycjimmy/semantic-release-action|changesets/action))\b' "$RELEASE_YML"
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
> 如果仓库使用了非主流的发布方式(如自写 shell 脚本里调用 `npm publish`),grep 仍可能漏判。
|
|
55
|
-
> 漏判后果:Phase 5 跳过 `npm view` 校验。这是**安全侧**漏判(不会误报"未发布"),但用户应在该仓库的 README 或 SKILL 注释里明确发布方式,避免歧义。
|
|
56
|
-
|
|
57
|
-
## 多 workflow 文件的处理
|
|
58
|
-
|
|
59
|
-
若仓库有多个 release 相关 workflow(如 `release.yml` + `publish-canary.yml`),默认只看 `release.yml`。
|
|
60
|
-
如需扩展,在调用方 workflow 或项目上下文中声明 `releaseWorkflowPaths: [...]`,执行时按该列表逐个判定。
|
|
61
|
-
|
|
62
|
-
## 与 Phase 5 的衔接
|
|
63
|
-
|
|
64
|
-
| 嗅探结果 | Phase 5 行为 |
|
|
65
|
-
|---------|-------------|
|
|
66
|
-
| `PUBLISH_TO_NPM=true` | 跑 `gh release view` + `gh run` + `npm view` 三端 |
|
|
67
|
-
| `PUBLISH_TO_NPM=false` | 仅跑 `gh release view` + `gh run` 两端,并向用户输出「本仓库 release.yml 不含 npm publish 步骤」提示 |
|
|
68
|
-
| `RELEASE_YML_MISSING=true` | Phase 0 直接终止,不进入后续 phase |
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
# CHANGELOG → GitHub Release notes 注入
|
|
2
|
-
|
|
3
|
-
让每次 `git push origin vX.Y.Z` 触发的 GitHub Release **正文非空**、**与 CHANGELOG 段落严格一致**的标准方案。
|
|
4
|
-
|
|
5
|
-
## 1. 为什么 GitHub Release 默认是空的
|
|
6
|
-
|
|
7
|
-
`softprops/action-gh-release@v2` 仅设 `generate_release_notes: true` 时,GitHub 内部调用的是 **REST API `POST /repos/{owner}/{repo}/releases/generate-notes`**,该接口的输入是「上一个 tag → 当前 tag」之间的 **commit + PR + label**,优先取 PR 标题做分类。
|
|
8
|
-
|
|
9
|
-
两种典型场景下生成器会"贫瘠":
|
|
10
|
-
|
|
11
|
-
| 场景 | 生成器输出 | 原因 |
|
|
12
|
-
|------|----------|------|
|
|
13
|
-
| 直 push main(无 PR 流程) | 仅 `Full Changelog: vA...vB` 一行 | 生成器没有 PR 可分类,只能给 compare 链接 |
|
|
14
|
-
| 有 PR 但仓库没有 `.github/release.yml` | 全部 PR 都被塞进 "What's Changed" 一节 | 没有 label → 章节映射 |
|
|
15
|
-
|
|
16
|
-
而仓库通常已经维护了 `CHANGELOG.md`(Keep a Changelog 格式)。**正确做法是把 CHANGELOG 段落作为 Release 正文的事实来源**,自动生成器仅作为补充链接。
|
|
17
|
-
|
|
18
|
-
## 2. 注入方案
|
|
19
|
-
|
|
20
|
-
核心思路:在 workflow 里加一步,从 `CHANGELOG.md` 抽取当前 tag 对应的版本段落,写到 `release-notes.md`,再通过 `softprops/action-gh-release` 的 `body_path` 注入。
|
|
21
|
-
|
|
22
|
-
### 2.1 完整 workflow 步骤
|
|
23
|
-
|
|
24
|
-
加到 `Verify bin entry` 之后、`Publish to npm` 之前(也可以放 publish 之后,只要在 Create GitHub Release 之前):
|
|
25
|
-
|
|
26
|
-
```yaml
|
|
27
|
-
- name: Extract release notes from CHANGELOG.md
|
|
28
|
-
run: |
|
|
29
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
30
|
-
awk -v v="$VERSION" '
|
|
31
|
-
$0 ~ "^## \\["v"\\]" { found=1; print; next }
|
|
32
|
-
found && /^## \[/ { exit }
|
|
33
|
-
found && /^---[[:space:]]*$/ { next }
|
|
34
|
-
found { print }
|
|
35
|
-
' CHANGELOG.md > release-notes.md
|
|
36
|
-
|
|
37
|
-
if [ ! -s release-notes.md ]; then
|
|
38
|
-
echo "::warning::CHANGELOG.md 中未找到 [$VERSION] 段落,回退到自动生成。"
|
|
39
|
-
echo "See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details." > release-notes.md
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
echo "--- Release notes preview ---"
|
|
43
|
-
cat release-notes.md
|
|
44
|
-
echo "-----------------------------"
|
|
45
|
-
|
|
46
|
-
- name: Create GitHub Release
|
|
47
|
-
uses: softprops/action-gh-release@v2
|
|
48
|
-
if: success()
|
|
49
|
-
with:
|
|
50
|
-
tag_name: ${{ github.ref_name }}
|
|
51
|
-
name: Release ${{ github.ref_name }}
|
|
52
|
-
body_path: release-notes.md # ← 关键
|
|
53
|
-
generate_release_notes: true # ← 与 body_path 共存,不冲突
|
|
54
|
-
draft: false
|
|
55
|
-
prerelease: false
|
|
56
|
-
env:
|
|
57
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 2.2 awk 抽取规则解释
|
|
61
|
-
|
|
62
|
-
```awk
|
|
63
|
-
$0 ~ "^## \\["v"\\]" { found=1; print; next } # 1. 命中 "## [X.Y.Z]" 起始锚点,开关打开,打印当行
|
|
64
|
-
found && /^## \[/ { exit } # 2. 已在段落内,遇到下一个 "## [" 立刻退出
|
|
65
|
-
found && /^---[[:space:]]*$/ { next } # 3. 跳过 "---" 分隔符(GitHub Release 不需要)
|
|
66
|
-
found { print } # 4. 段落内的其他行原样输出
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
边界用例:
|
|
70
|
-
|
|
71
|
-
- **段落是 CHANGELOG 末尾**:没有下一个 `## [`,awk 跑到 EOF 自然结束
|
|
72
|
-
- **存在 `[Unreleased]` 段落**:不会被误抓,因为锚点要求精确匹配 `[X.Y.Z]` 形式
|
|
73
|
-
- **版本号含连字符(rc / beta)**:`0.0.10-rc1` 也能匹配,因为 awk 把 `v` 当字面量
|
|
74
|
-
- **CHANGELOG 缺该段**:`-s` 测试为空 → 写入兜底文案 + 输出 warning
|
|
75
|
-
|
|
76
|
-
### 2.3 `body_path` + `generate_release_notes` 共存语义
|
|
77
|
-
|
|
78
|
-
`softprops/action-gh-release@v2` 在两者同时存在时:
|
|
79
|
-
|
|
80
|
-
- **正文头部**:`body_path` 文件内容(你的 CHANGELOG 段落)
|
|
81
|
-
- **正文尾部**:GitHub 自动生成的 "What's Changed" + "Full Changelog" compare 链接
|
|
82
|
-
|
|
83
|
-
这是最优组合:**人写的精炼说明 + 机器可追溯的 PR/commit 索引**。
|
|
84
|
-
|
|
85
|
-
## 3. 事后修复历史 Release(已发布版本正文为空)
|
|
86
|
-
|
|
87
|
-
GitHub Release 的正文(body)**事后可改**(tag 不可改、npm 包不可改、但 Release body 可改)。两种方式:
|
|
88
|
-
|
|
89
|
-
### 3.1 命令行(推荐)
|
|
90
|
-
|
|
91
|
-
`notes_file` 只是一次性传给 `gh --notes-file` 的中间文件;若需要保留回填记录或 release notes,由调用方写入 `<Path>{roots.state}/commands/{command}/{date}-{scope}-{topic}[-NN].md</Path>`。
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
VERSION="0.0.10"
|
|
95
|
-
notes_file="$(mktemp -t speculo-release-notes.XXXXXX)"
|
|
96
|
-
trap 'rm -f "$notes_file"' EXIT
|
|
97
|
-
|
|
98
|
-
awk -v v="$VERSION" '
|
|
99
|
-
$0 ~ "^## \\["v"\\]" { found=1; print; next }
|
|
100
|
-
found && /^## \[/ { exit }
|
|
101
|
-
found && /^---[[:space:]]*$/ { next }
|
|
102
|
-
found { print }
|
|
103
|
-
' CHANGELOG.md > "$notes_file" && \
|
|
104
|
-
gh release edit "v$VERSION" --notes-file "$notes_file"
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### 3.2 GitHub UI
|
|
108
|
-
|
|
109
|
-
进入 `https://github.com/<owner>/<repo>/releases/tag/vX.Y.Z`,右上角铅笔图标 → 粘贴 CHANGELOG 段落 → Update release。
|
|
110
|
-
|
|
111
|
-
### 3.3 批量回填多个历史版本
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
notes_file="$(mktemp -t speculo-release-notes.XXXXXX)"
|
|
115
|
-
trap 'rm -f "$notes_file"' EXIT
|
|
116
|
-
|
|
117
|
-
for v in 0.0.7 0.0.8 0.0.9; do
|
|
118
|
-
awk -v ver="$v" '
|
|
119
|
-
$0 ~ "^## \\["ver"\\]" { found=1; print; next }
|
|
120
|
-
found && /^## \[/ { exit }
|
|
121
|
-
found && /^---[[:space:]]*$/ { next }
|
|
122
|
-
found { print }
|
|
123
|
-
' CHANGELOG.md > "$notes_file"
|
|
124
|
-
|
|
125
|
-
if [ -s "$notes_file" ]; then
|
|
126
|
-
gh release edit "v$v" --notes-file "$notes_file"
|
|
127
|
-
echo "✓ v$v"
|
|
128
|
-
else
|
|
129
|
-
echo "✗ v$v: CHANGELOG 中无对应段落,跳过"
|
|
130
|
-
fi
|
|
131
|
-
done
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## 4. 进阶:走 PR 流程的项目
|
|
135
|
-
|
|
136
|
-
若仓库以 PR 为主、合并产生 commit,推荐 **同时**保留 CHANGELOG 注入 + 配置 `.github/release.yml` 让自动生成器分类更友好。
|
|
137
|
-
|
|
138
|
-
### 4.1 `.github/release.yml`(GitHub 原生分类配置)
|
|
139
|
-
|
|
140
|
-
```yaml
|
|
141
|
-
# .github/release.yml
|
|
142
|
-
changelog:
|
|
143
|
-
exclude:
|
|
144
|
-
labels:
|
|
145
|
-
- ignore-for-release
|
|
146
|
-
- dependencies # 可选:依赖升级单独成节
|
|
147
|
-
categories:
|
|
148
|
-
- title: 🚀 Features
|
|
149
|
-
labels:
|
|
150
|
-
- feat
|
|
151
|
-
- feature
|
|
152
|
-
- enhancement
|
|
153
|
-
- title: 🐛 Bug Fixes
|
|
154
|
-
labels:
|
|
155
|
-
- fix
|
|
156
|
-
- bug
|
|
157
|
-
- title: 📚 Documentation
|
|
158
|
-
labels:
|
|
159
|
-
- docs
|
|
160
|
-
- documentation
|
|
161
|
-
- title: ♻️ Refactoring
|
|
162
|
-
labels:
|
|
163
|
-
- refactor
|
|
164
|
-
- title: 🧪 Testing
|
|
165
|
-
labels:
|
|
166
|
-
- test
|
|
167
|
-
- title: 🔧 Maintenance
|
|
168
|
-
labels:
|
|
169
|
-
- chore
|
|
170
|
-
- ci
|
|
171
|
-
- title: Other Changes
|
|
172
|
-
labels:
|
|
173
|
-
- "*"
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
效果:`generate_release_notes` 自动产出的 "What's Changed" 会被分类到上述章节中,与 CHANGELOG 段落叠加在 Release 正文内。
|
|
177
|
-
|
|
178
|
-
### 4.2 配套的 PR label 自动化
|
|
179
|
-
|
|
180
|
-
参考仓库已有 `.github/labeler.yml` + `.github/workflows/label-pr.yml`,基于改动路径自动打 label。也可让 PR 模板提示作者按 Conventional Commits 选择类型。
|
|
181
|
-
|
|
182
|
-
## 5. 多语言 CHANGELOG 处理
|
|
183
|
-
|
|
184
|
-
如果项目同时维护 `CHANGELOG.md` + `CHANGELOG-ZH.md`,Release 正文应优先取**主语言**(通常英文)。两种策略:
|
|
185
|
-
|
|
186
|
-
### A. workflow 选择主语言(简单)
|
|
187
|
-
|
|
188
|
-
```yaml
|
|
189
|
-
- name: Extract release notes
|
|
190
|
-
run: |
|
|
191
|
-
# 主语言文件名作为输入
|
|
192
|
-
awk -v v="${GITHUB_REF_NAME#v}" '...' CHANGELOG.md > release-notes.md
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### B. workflow 拼接双语(完整)
|
|
196
|
-
|
|
197
|
-
```yaml
|
|
198
|
-
- name: Extract release notes (bilingual)
|
|
199
|
-
run: |
|
|
200
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
201
|
-
EXTRACT='$0 ~ "^## \\["v"\\]" { found=1; print; next } found && /^## \[/ { exit } found && /^---[[:space:]]*$/ { next } found { print }'
|
|
202
|
-
|
|
203
|
-
{
|
|
204
|
-
awk -v v="$VERSION" "$EXTRACT" CHANGELOG.md
|
|
205
|
-
echo
|
|
206
|
-
echo "---"
|
|
207
|
-
echo
|
|
208
|
-
echo "### 中文版本说明"
|
|
209
|
-
echo
|
|
210
|
-
awk -v v="$VERSION" "$EXTRACT" CHANGELOG-ZH.md
|
|
211
|
-
} > release-notes.md
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## 6. 常见坑位
|
|
215
|
-
|
|
216
|
-
| 坑 | 现象 | 解法 |
|
|
217
|
-
|---|------|------|
|
|
218
|
-
| `body_path` 文件不存在 | action 失败 `Could not find the body_path` | 加 `if [ ! -s release-notes.md ]` 兜底写入 |
|
|
219
|
-
| awk 没匹配到 | release-notes.md 为空,Release 正文兜底文案 | 检查 CHANGELOG 段落标题与 tag 是否对应(`v0.0.10` ↔ `## [0.0.10]`) |
|
|
220
|
-
| awk 多匹配(同一版本写了两次) | Release 正文重复内容 | CHANGELOG 是 source of truth,先去重 |
|
|
221
|
-
| 全角中括号 `【】` 被当锚点 | 抽取失败 | CHANGELOG 标题统一用半角 `[` |
|
|
222
|
-
| body_path 文件含 BOM | Release 渲染异常 | 用 `sed -i '1s/^\xef\xbb\xbf//' release-notes.md` 去 BOM |
|
|
223
|
-
|
|
224
|
-
## 7. 验证
|
|
225
|
-
|
|
226
|
-
每次发布后必查:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
# Release body 必须非空且包含 CHANGELOG 关键章节
|
|
230
|
-
gh release view "v$VERSION" --json body --jq '.body' | head -20
|
|
231
|
-
|
|
232
|
-
# 三端齐绿才算发布完成
|
|
233
|
-
npm view @scope/pkg version
|
|
234
|
-
gh release view "v$VERSION" --json isDraft,isPrerelease,publishedAt
|
|
235
|
-
gh run view <run-id> --json conclusion,jobs --jq '{conclusion, steps: [.jobs[].steps[] | select(.name | contains("Extract") or contains("Release")) | {name, conclusion}]}'
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
`Extract release notes` 步骤未 success → Release 正文将走兜底文案,需排查 awk 是否抽空。
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# npm + GitHub Release 编排
|
|
2
|
-
|
|
3
|
-
把一次 npm 包发布拆成可验证的单向流水线:前置检查 -> 普通改动 commit -> docs-sync -> release commit -> tag -> workflow 监控 -> 三端验证 -> docs-sync 记录 release 节点。
|
|
4
|
-
|
|
5
|
-
## Iron Law
|
|
6
|
-
|
|
7
|
-
- 禁止提交破坏构建的代码;release 前必须运行仓库声明的 lint / test / build 或等价质量闸。
|
|
8
|
-
- docs-sync 必须由调用方按 `<Path>{roots.commands}/docs-sync.md</Path>` 执行;输入起点来自最后修改 state 文件的 commit,终点是运行前清洁后的 HEAD,并写入 `last_range`。
|
|
9
|
-
- tag 必须精确指向 release commit,即包含 `package.json` version bump 与 CHANGELOG 迁移的 commit;禁止指向后续 docs / state commit。
|
|
10
|
-
- npm 已成功上传后,同一 version 不可重发;不要通过删 tag 或 unpublish 试图覆盖。
|
|
11
|
-
|
|
12
|
-
## Phase 0 — 前置检测
|
|
13
|
-
|
|
14
|
-
读取 `preflight-checklist.md` 和 `publish-detection.md`,固定确认:
|
|
15
|
-
|
|
16
|
-
- 当前分支是发布分支,默认 `main`
|
|
17
|
-
- 工作区干净,远端可达,`gh auth status` 正常
|
|
18
|
-
- Node 与包管理器满足仓库声明
|
|
19
|
-
- `.github/workflows/release.yml` 存在
|
|
20
|
-
- 已确定 `PUBLISH_TO_NPM=true | false`
|
|
21
|
-
- `<Path>{roots.state}/commands/docs-sync/state.json</Path>` 存在且可解析;不存在时转 docs-sync command 的首次 bootstrap
|
|
22
|
-
- 目标 tag `vX.Y.Z` 不存在,除非正在执行明确的失败恢复
|
|
23
|
-
|
|
24
|
-
任一项不通过就停止,输出修复建议。
|
|
25
|
-
|
|
26
|
-
## Phase 1 — 普通改动 commit
|
|
27
|
-
|
|
28
|
-
- 运行仓库质量闸:优先 `pnpm check`,否则按项目脚本组合 lint / test / build。
|
|
29
|
-
- 审查提交粒度;不把无关修改塞进一个 commit。
|
|
30
|
-
- 暂存显式路径,避免 `git add .` 纳入噪声。
|
|
31
|
-
- 使用 Conventional Commits;body 说明做了什么和为什么。
|
|
32
|
-
|
|
33
|
-
## Phase 2 — Docs Sync
|
|
34
|
-
|
|
35
|
-
- 由调用方执行 `<Path>{roots.commands}/docs-sync.md</Path>`。
|
|
36
|
-
- 只修改全局 state 与 workflow sidecar 已确认范围中需要同步的文档或知识资产。
|
|
37
|
-
- CHANGELOG 类文档只写 `[Unreleased]`,保留该段落。
|
|
38
|
-
- 本阶段由 docs-sync 自动提交文档、报告与 state;最终 release commit 仍在 Phase 3 创建,发布后再由 Phase 6 记录为新输入终点。
|
|
39
|
-
|
|
40
|
-
## Phase 3 — 版本 bump + release commit + tag
|
|
41
|
-
|
|
42
|
-
读取 `version-bump-flow.md`。
|
|
43
|
-
|
|
44
|
-
- 将 CHANGELOG 的 `[Unreleased]` 内容迁移到 `## [X.Y.Z] - YYYY-MM-DD` 或项目既有等价格式,并重新保留空 `[Unreleased]`。
|
|
45
|
-
- 将 `package.json#version` 改为 `X.Y.Z`;tag 使用 `vX.Y.Z`。
|
|
46
|
-
- 运行质量闸;除非调用方明确记录外部预演证据,不跳过。
|
|
47
|
-
- release commit 只包含版本 bump 与 CHANGELOG 迁移,提交信息为 `chore(release): vX.Y.Z`。
|
|
48
|
-
- 记录 `RELEASE_COMMIT_SHA`。
|
|
49
|
-
- 先 push 发布分支,再 `git tag vX.Y.Z $RELEASE_COMMIT_SHA`,再 push tag。
|
|
50
|
-
|
|
51
|
-
## Phase 4 — 监控 release workflow
|
|
52
|
-
|
|
53
|
-
用 `gh run list` 找到 head SHA 等于 `RELEASE_COMMIT_SHA` 的 release run,再 `gh run watch --exit-status`。
|
|
54
|
-
|
|
55
|
-
重点检查:
|
|
56
|
-
|
|
57
|
-
- Verify tag matches package version
|
|
58
|
-
- lint / tests / build / bin entry
|
|
59
|
-
- Extract release notes from CHANGELOG
|
|
60
|
-
- Publish to npm(仅 `PUBLISH_TO_NPM=true`)
|
|
61
|
-
- Create GitHub Release
|
|
62
|
-
|
|
63
|
-
失败时进入 `failure-recovery.md` 和 `troubleshooting-playbook.md`。
|
|
64
|
-
|
|
65
|
-
## Phase 5 — 三端验证
|
|
66
|
-
|
|
67
|
-
始终验证:
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
gh release view "vX.Y.Z" --json name,tagName,isDraft,isPrerelease,body
|
|
71
|
-
gh run list --workflow release.yml --limit 1 --json conclusion,headSha
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
判定:
|
|
75
|
-
|
|
76
|
-
- Release 非 draft、非 prerelease
|
|
77
|
-
- Release body 非空,且包含 CHANGELOG 段落;仅 `Full Changelog` 一行视为残缺
|
|
78
|
-
- workflow conclusion 为 success,headSha 等于 `RELEASE_COMMIT_SHA`
|
|
79
|
-
|
|
80
|
-
仅当 `PUBLISH_TO_NPM=true` 时验证:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
npm view "<package-name>" version
|
|
84
|
-
npm view "<package-name>" dist-tags
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
判定 version 与 `dist-tags.latest` 均为 `X.Y.Z`。
|
|
88
|
-
|
|
89
|
-
## Phase 6 — 记录 release 输入节点
|
|
90
|
-
|
|
91
|
-
仅当 Phase 1-5 全绿时执行。再次调用 `<Path>{roots.commands}/docs-sync.md</Path>`,并确认运行前 `HEAD` 等于 `RELEASE_COMMIT_SHA`:
|
|
92
|
-
|
|
93
|
-
- state 的 `last_range.to_sha` 必须等于 `RELEASE_COMMIT_SHA`。
|
|
94
|
-
- `last_range.from_sha` 来自最后修改旧 state 的 commit,或迁移期 explicit baseline。
|
|
95
|
-
- docs-sync 写入 release 后报告/state commit;tag 继续精确指向 release commit,不移动。
|
|
96
|
-
|
|
97
|
-
本 skill 不直接改 state 或 workflow sidecar;原子写入、范围检查和本地 commit 均由 docs-sync command 负责。
|
|
98
|
-
|
|
99
|
-
## 完成报告
|
|
100
|
-
|
|
101
|
-
报告至少包含:
|
|
102
|
-
|
|
103
|
-
- 版本号、release commit SHA、tag SHA
|
|
104
|
-
- workflow run id 与结论
|
|
105
|
-
- GitHub Release 检查结果
|
|
106
|
-
- npm 检查结果或跳过原因
|
|
107
|
-
- docs-sync `last_range` 与 state-file baseline commit
|
|
108
|
-
- 失败恢复或后续建议
|