ly-workflow-codex 0.2.0
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/LICENSE +22 -0
- package/README.md +65 -0
- package/bin/lycx.mjs +2 -0
- package/dist/chunks/legacy-cleanup.mjs +143 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +340 -0
- package/dist/index.d.mts +223 -0
- package/dist/index.d.ts +223 -0
- package/dist/index.mjs +12 -0
- package/dist/shared/ly-workflow-codex.K-E7PMp3.mjs +2068 -0
- package/docs/codex-exec-contract.md +90 -0
- package/package.json +73 -0
- package/templates/prompts/codex/plan-reviewer.md +52 -0
- package/templates/prompts/codex/reviewer.md +58 -0
- package/templates/skills-codex/apply.md +49 -0
- package/templates/skills-codex/archive.md +22 -0
- package/templates/skills-codex/changelog.md +165 -0
- package/templates/skills-codex/clean-branches.md +121 -0
- package/templates/skills-codex/commit.md +126 -0
- package/templates/skills-codex/explore.md +19 -0
- package/templates/skills-codex/init.md +63 -0
- package/templates/skills-codex/propose.md +147 -0
- package/templates/skills-codex/publish.md +388 -0
- package/templates/skills-codex/release.md +317 -0
- package/templates/skills-codex/review-code.md +190 -0
- package/templates/skills-codex/review-plan.md +196 -0
- package/templates/skills-codex/rollback.md +120 -0
- package/templates/skills-codex/worktree.md +159 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lyx-publish
|
|
3
|
+
description: 'npm 包发布:bmc 私域 Nexus / GitHub Packages / npmjs + GitHub Release / CI 自动发布 四场景'
|
|
4
|
+
argument-hint: '<场景描述>'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Publish - npm 包发布
|
|
8
|
+
|
|
9
|
+
> 调用方式:`@lyx-publish` mention 后跟随的自然语言即参数(如 `@lyx-publish` 带需求描述/选项);无参数时直接 `@lyx-publish`。
|
|
10
|
+
|
|
11
|
+
覆盖四个发布场景:bmc 私域 Nexus、GitHub Packages、公开 npmjs.org + GitHub Release、CI 自动发布(tag push 触发)。发布前走前置检查 → 版本号自动推导 → 构建 → 发布 → 验证完整流程。
|
|
12
|
+
|
|
13
|
+
## 使用方法
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
@lyx-publish <场景描述>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**🔴 CHECKPOINT:先确认发布目标,问用户,别猜。**
|
|
20
|
+
|
|
21
|
+
- **bmc 私域**:发到公司 Nexus 私有 registry(scope 通常是 `@bmc`)
|
|
22
|
+
- **GitHub**:三种情况之一,需要用户明确
|
|
23
|
+
- A. GitHub Packages npm registry(`npm.pkg.github.com`,需要 GitHub 账号/组织权限)
|
|
24
|
+
- B. 公开发到 npmjs.org,再在 GitHub 建 Release/Tag(开源包常见做法)
|
|
25
|
+
- C. **CI 自动发布**:本地只 push commit/tag,实际 `npm publish` 由 GitHub Actions workflow 执行(团队协作/避免本地手动发布出错的常见做法)
|
|
26
|
+
|
|
27
|
+
确认后按对应场景执行。
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 前置检查(所有场景通用)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Node/pnpm 版本
|
|
35
|
+
node -v
|
|
36
|
+
pnpm -v 2>/dev/null || npm -v
|
|
37
|
+
|
|
38
|
+
# Git 工作目录是否干净
|
|
39
|
+
git status --porcelain
|
|
40
|
+
# 有未提交改动先询问用户是否继续,别自动 commit
|
|
41
|
+
|
|
42
|
+
# 当前分支
|
|
43
|
+
git branch --show-current
|
|
44
|
+
# 建议从 master/main 发布,非主分支要提醒用户
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
检查 `package.json` 必备字段:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cat package.json | grep -E '"name"|"version"|"files"|"main"|"exports"|"publishConfig"'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `files` 字段要包含实际产物目录(如 `dist`),漏了会导致发布出去的包缺文件
|
|
54
|
+
- 有 `prepublishOnly` / `build` 脚本的,发布前必须先跑一遍构建
|
|
55
|
+
|
|
56
|
+
**🔴 检测项目是否已有自定义发布脚本:**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cat package.json | grep -iE '"(publish|release)[a-z:-]*"\s*:'
|
|
60
|
+
ls scripts/*publish* scripts/*release* 2>/dev/null
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- **有** → 先读脚本内容确认它做了什么(是否已封装 registry 检查/构建/版本 bump/tag)。**🔴 CHECKPOINT:优先问用户是否直接用现有脚本**,不要绕过去重新走下面的通用流程——现有脚本往往已经绑定了正确的 registry 地址和内部约定,重新手搓一遍容易和它冲突或重复发布
|
|
64
|
+
- **没有** → 按下面场景的通用步骤走
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 版本号确定规则(SemVer + Conventional Commits 自动推导)
|
|
69
|
+
|
|
70
|
+
**不要直接问用户「patch 还是 minor」,先分析 commit 历史给出建议,再让用户确认/覆盖。**(与 `@lyx-release` 共享同一套规则)
|
|
71
|
+
|
|
72
|
+
### 自动分析步骤
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 1. 确定上一次 bump 的边界(优先 tag → package.json 历史 commit)
|
|
76
|
+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD 2>/dev/null || echo "")
|
|
77
|
+
PREV_BUMP=$(git log -2 -p --format=%H -- package.json | grep -B5 '"version"' | grep '^[0-9a-f]\{40\}$' | tail -1)
|
|
78
|
+
BASE_REF=${PREV_TAG:-${PREV_BUMP:-}}
|
|
79
|
+
|
|
80
|
+
# 2. 收集本次发版的 commit(排除 bump version 本身)
|
|
81
|
+
if [ -n "$BASE_REF" ]; then
|
|
82
|
+
COMMITS=$(git log ${BASE_REF}..HEAD --oneline --no-merges -- | grep -v "bump version")
|
|
83
|
+
else
|
|
84
|
+
COMMITS=$(git log HEAD --oneline --no-merges -- | grep -v "bump version")
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# 3. 按 Conventional Commits 分类统计
|
|
88
|
+
echo "$COMMITS" | grep -c "^[a-f0-9]* feat" || true # 新功能数量
|
|
89
|
+
echo "$COMMITS" | grep -c "^[a-f0-9]* fix" || true # 修复数量
|
|
90
|
+
echo "$COMMITS" | grep -i "BREAKING CHANGE" || true # 破坏性变更
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 推导规则
|
|
94
|
+
|
|
95
|
+
| 条件 | 建议档位 | 示例 |
|
|
96
|
+
|------|---------|------|
|
|
97
|
+
| 含 `BREAKING CHANGE` 或 `feat!:` | **major** | 1.6.1 → 2.0.0 |
|
|
98
|
+
| 无 BREAKING CHANGE,有 `feat:` | **minor** | 1.6.1 → 1.7.0 |
|
|
99
|
+
| 仅 `fix:` / `docs:` / `chore:` | **patch** | 1.6.1 → 1.6.2 |
|
|
100
|
+
| 首次发版 / 无历史 | 问用户 | — |
|
|
101
|
+
|
|
102
|
+
### 询问模板
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
分析发现本次改动:
|
|
106
|
+
- 新增功能 X 个,修复 Y 个,无破坏性变更
|
|
107
|
+
→ 建议 bump minor:1.6.1 → 1.7.0
|
|
108
|
+
|
|
109
|
+
是否使用此建议?可以改为 patch(1.6.1 → 1.6.2)或 major(1.6.1 → 2.0.0)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- **同意建议**:直接按建议执行 `npm version <patch|minor|major>`
|
|
113
|
+
- **覆盖**:按用户输入的档位执行
|
|
114
|
+
- **不存在以往的 commit**:回退到直接询问版本号
|
|
115
|
+
|
|
116
|
+
若已装 `@lyx-changelog`,version bump 后触发它更新 CHANGELOG,再补一次 commit;没装则询问用户要不要更新日志。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 场景一:发布到 bmc 私域 Nexus
|
|
121
|
+
|
|
122
|
+
**触发词:** "发私域"、"发到bmc"、"内网发布"、"发到nexus"
|
|
123
|
+
|
|
124
|
+
### 1. 确认 `.npmrc` scope 配置
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cat .npmrc 2>/dev/null | grep registry
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
应包含(scope 按实际包名调整,如 `@bmc`):
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
@bmc:registry=https://nexus-office.domob-inc.cn/repository/bfm_npm_hosted/
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
没有就先创建 `.npmrc`(询问用户具体 Nexus 地址,不要瞎填)。
|
|
137
|
+
|
|
138
|
+
### 2. 登录检查
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
REGISTRY_URL=$(grep "@bmc:registry" .npmrc | cut -d'=' -f2 | tr -d ' ')
|
|
142
|
+
npm whoami --registry="$REGISTRY_URL"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
未登录:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm login --registry="$REGISTRY_URL"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3. 构建与检查
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pnpm build # 或对应包的 build 脚本
|
|
155
|
+
pnpm type-check # 有则跑
|
|
156
|
+
pnpm lint # 有则跑,失败先询问是否继续
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 4. 版本号(🔴 SemVer 自动推导 + 用户确认,非直接问 patch/minor/major)
|
|
160
|
+
|
|
161
|
+
按上方「版本号确定规则」执行:
|
|
162
|
+
- 分析上次 bump 以来的 commit 列表
|
|
163
|
+
- 按 feat/fix/BREAKING 推导建议档位
|
|
164
|
+
- 将建议展示给用户确认/覆盖
|
|
165
|
+
- 确认后执行 `npm version <patch|minor|major>`(会自动更新 package.json + 打 git tag + commit)
|
|
166
|
+
|
|
167
|
+
若项目已装 `@lyx-changelog`,version bump 后触发它更新 CHANGELOG,再补一次 commit;没装则询问用户要不要更新日志。
|
|
168
|
+
|
|
169
|
+
### 5. 发布
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# 注意 scope 私有包默认 restricted,要标注 access
|
|
173
|
+
npm publish --registry="$REGISTRY_URL" --access restricted
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 6. 推送 tag 并验证
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
git push --follow-tags
|
|
180
|
+
|
|
181
|
+
# 验证:发布后确认新版本已出现在目标 registry
|
|
182
|
+
npm view <包名>@<新版本号> --registry="$REGISTRY_URL"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 场景二:发布到 GitHub Packages(`npm.pkg.github.com`)
|
|
188
|
+
|
|
189
|
+
**触发词:** "发到github packages"、"github registry"
|
|
190
|
+
|
|
191
|
+
### 1. `.npmrc` 配置
|
|
192
|
+
|
|
193
|
+
scope 必须对应 GitHub 用户名/组织(大小写敏感):
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
@<github用户名或组织>:registry=https://npm.pkg.github.com
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 2. 认证
|
|
200
|
+
|
|
201
|
+
需要一个具备 `write:packages`(发布)+ `read:packages` 权限的 GitHub Personal Access Token:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# 方式一:npm login 交互式
|
|
205
|
+
npm login --scope=@<github用户名或组织> --registry=https://npm.pkg.github.com
|
|
206
|
+
|
|
207
|
+
# 方式二:环境变量 + .npmrc 直接写 token(本地测试可用,别提交含 token 的 .npmrc)
|
|
208
|
+
echo "//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}" >> ~/.npmrc
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**注意:** 千万别把带 token 的 `.npmrc` commit 进仓库——检查 `.gitignore` 是否已排除本地 `.npmrc`(若项目里 `.npmrc` 本身要提交作为团队共享配置,token 必须走环境变量而非硬编码)。
|
|
212
|
+
|
|
213
|
+
### 3. package.json 需要 `publishConfig` 指向该 registry
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"publishConfig": {
|
|
218
|
+
"registry": "https://npm.pkg.github.com"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 4. 构建、版本号步骤同场景一(版本号按上方「版本号确定规则」自动推导 + 确认),发布命令:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm publish
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 场景三:公开发到 npmjs.org + GitHub Release(开源包常见流程)
|
|
232
|
+
|
|
233
|
+
**触发词:** "发到npm官方"、"发public包"、"发github release"、"开源发布"
|
|
234
|
+
|
|
235
|
+
### 1. 确认无 scope registry 覆盖
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
cat .npmrc 2>/dev/null
|
|
239
|
+
# 若有 registry 指向私有源,临时用 --registry 覆盖,别改动 .npmrc 影响其他包
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 2. 登录 npmjs.org
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npm whoami
|
|
246
|
+
# 未登录:
|
|
247
|
+
npm login
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 3. 构建、版本号步骤同场景一(版本号按上方「版本号确定规则」自动推导 + 确认)
|
|
251
|
+
|
|
252
|
+
### 4. 发布
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npm publish --access public # 首次发布 scoped 公共包必须加 --access public
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 5. GitHub Release
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# 确认 tag 已推送(npm version 已打好 tag)
|
|
262
|
+
git push --follow-tags
|
|
263
|
+
|
|
264
|
+
# 用 gh cli 建 release,标题/说明取自 CHANGELOG 对应版本段落
|
|
265
|
+
gh release create v<新版本号> --title "v<新版本号>" --notes-file <(sed -n '/## \[<新版本号>\]/,/## \[/p' CHANGELOG.md | sed '$d')
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
没装 `gh` 的话提示用户去 GitHub 网页手动创建 Release,附上对应 CHANGELOG 片段。
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 场景四:推送 GitHub 触发 CI 自动发布(GitHub Actions)
|
|
273
|
+
|
|
274
|
+
**触发词:** "用CI发布"、"github actions发包"、"推tag自动发布"、"CI自动发npm"
|
|
275
|
+
|
|
276
|
+
本地不跑 `npm publish`,只负责构建前的版本号/tag 准备,真正的发布动作在 CI 里跑。
|
|
277
|
+
|
|
278
|
+
### 1. 确认触发方式(🔴 CHECKPOINT:问用户,别猜)
|
|
279
|
+
|
|
280
|
+
- **打 tag 触发**(最常见):workflow 监听 `push: tags: ['v*']`
|
|
281
|
+
- **push 到 release 分支触发**:workflow 监听 `push: branches: [main/master]`
|
|
282
|
+
- **手动触发**:workflow 监听 `workflow_dispatch`
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
cat .github/workflows/*.yml 2>/dev/null | grep -A3 "^on:"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
没有 workflow 文件就先帮用户写一个(`.github/workflows@lyx-publish.yml`),核心结构:
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
name: Publish
|
|
292
|
+
on:
|
|
293
|
+
push:
|
|
294
|
+
tags: ['v*']
|
|
295
|
+
jobs:
|
|
296
|
+
publish:
|
|
297
|
+
runs-on: ubuntu-latest
|
|
298
|
+
steps:
|
|
299
|
+
- uses: actions/checkout@v4
|
|
300
|
+
- uses: actions/setup-node@v4
|
|
301
|
+
with:
|
|
302
|
+
node-version: 20
|
|
303
|
+
registry-url: 'https://registry.npmjs.org' # 私域改成 Nexus 地址;@scope 需在 .npmrc 里配好
|
|
304
|
+
- run: npm ci
|
|
305
|
+
- run: npm run build
|
|
306
|
+
- run: npm publish --access public # 私有包用 --access restricted
|
|
307
|
+
env:
|
|
308
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 2. 配置发布用的 Secret(GitHub 仓库设置里做,本地只提醒)
|
|
312
|
+
|
|
313
|
+
- npmjs.org / GitHub Packages:在仓库 `Settings → Secrets and variables → Actions` 添加 `NPM_TOKEN`(npm 官网生成的 Automation Token,或 GitHub PAT)
|
|
314
|
+
- bmc 私域 Nexus:CI runner 需能访问内网 Nexus 地址——若 GitHub Actions 是公网 runner,先确认 Nexus 是否对公网开放/走 self-hosted runner,不确定就提醒用户先确认网络可达性,别假设能连上
|
|
315
|
+
- **注意:** Token 只存在 Secrets 里,绝不写进 workflow 文件或 commit
|
|
316
|
+
|
|
317
|
+
### 3. 本地准备工作(触发 CI 前要做的)
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# 构建、类型检查照场景一跑一遍(确保能过,CI 里挂了排查更麻烦)
|
|
321
|
+
pnpm build
|
|
322
|
+
pnpm type-check
|
|
323
|
+
|
|
324
|
+
# 版本号 bump(按上方「版本号确定规则」自动推导 + 确认)
|
|
325
|
+
npm version <patch|minor|major>
|
|
326
|
+
|
|
327
|
+
# 若装了 @lyx-changelog,此时更新 CHANGELOG 并补 commit;没装则询问用户
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### 4. 推送触发
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
git push --follow-tags
|
|
334
|
+
# 或按 workflow 触发条件,push 到对应分支
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 5. 验证
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# 查看 workflow 运行状态
|
|
341
|
+
gh run list --limit 5
|
|
342
|
+
gh run watch # 实时看当前发布 workflow 的日志
|
|
343
|
+
|
|
344
|
+
# CI 跑完后确认包已上线
|
|
345
|
+
npm view <包名> versions --registry=<对应registry>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
没装 `gh` 就提示用户去仓库 Actions 页面看运行结果。
|
|
349
|
+
|
|
350
|
+
**🔴 CHECKPOINT:** 本地绝不要在 CI 已接管发布的项目里再手动跑一遍 `npm publish`——会导致版本号冲突或重复发布。先确认这次是走 CI 还是走本地手动,别两条路一起跑。
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 发布前自检清单(任何场景都建议过一遍)
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# 预览实际会打进包里的文件,检查是否缺文件/夹带不该发的文件
|
|
358
|
+
npm pack --dry-run
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
- `dist`/构建产物是否已生成且是最新的(避免发的是旧代码)
|
|
362
|
+
- `README.md`、`LICENSE` 是否存在且会被 `files` 字段包含
|
|
363
|
+
- `version` 是否已经存在于目标 registry(避免 409 冲突,`npm view <包名>@<版本号>` 可查)
|
|
364
|
+
- 私有包 `access` 是否为 `restricted`,公开包是否为 `public`
|
|
365
|
+
|
|
366
|
+
## `npm publish` 常见报错处理
|
|
367
|
+
|
|
368
|
+
| 报错 | 触发条件 | 处理 |
|
|
369
|
+
|---|---|---|
|
|
370
|
+
| `403 Forbidden` / `You must be logged in` | 未登录或 token 过期 | 重新 `npm login --registry=<对应地址>`;GitHub Packages/CI 场景检查 token 权限是否含 `write:packages` 或 Secret 是否过期 |
|
|
371
|
+
| `409 Conflict` / `You cannot publish over the previously published version` | 版本号已存在 | 先 `npm view <包名>@<版本号> --registry=<对应地址>` 确认;确实冲突则重新 `npm version patch/minor/major` 打一个新版本号,不要改已发布版本 |
|
|
372
|
+
| `402 Payment Required` / 需要 `--access public` | 首次发布 scoped 公共包没加 `--access public` | 补上 `--access public` 重试;私有包保持 `--access restricted` 别改 |
|
|
373
|
+
| 构建脚本报错 / `prepublishOnly` 失败 | 代码本身有问题,或依赖没装齐 | 别绕过直接强发(`npm publish` 会先跑 `prepublishOnly`,失败会自动中止,不用手动加 `--ignore-scripts` 硬闯);先定位报错原因修好代码再重试 |
|
|
374
|
+
| CI 里 `npm publish` 卡住或失败但本地能发 | CI runner 网络不通私域 Nexus,或 Secret 没配对 | 检查该 workflow 是否为 self-hosted runner、Secret 名字是否与 workflow 里 `secrets.XXX` 一致;不确定就让用户去 Actions 页面看具体报错,不要瞎猜重试 |
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 发布后验证
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
npm view <包名> versions --registry=<对应registry> # 确认新版本已出现
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
新开一个临时目录 `npm install`/`pnpm add` 装一下,跑通基本 import,确认没有漏文件。
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
**注意:** 版本号 bump(`npm version`)、tag、push 若项目已装 `@lyx-release` 和 `@lyx-changelog`,优先复用那两个命令的规则,避免重复定义流程;本命令专注 registry 认证配置 + `npm publish` 本身这一环。不引入 changesets。
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lyx-release
|
|
3
|
+
description: 'GitFlow 发版流程:feature/release/hotfix/dev-offline 四场景,SemVer 自动推导版本号'
|
|
4
|
+
argument-hint: '<场景描述>'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Release - GitFlow 发版
|
|
8
|
+
|
|
9
|
+
> 调用方式:`@lyx-release` mention 后跟随的自然语言即参数(如 `@lyx-release` 带需求描述/选项);无参数时直接 `@lyx-release`。
|
|
10
|
+
|
|
11
|
+
按场景执行 GitFlow 分支操作,版本号按 SemVer + Conventional Commits 自动推导建议,用户确认后执行。
|
|
12
|
+
|
|
13
|
+
## 使用方法
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
@lyx-release <场景描述>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
直接告诉 Codex 要做什么,例如:"开始新功能"、"准备发版"、"线上有 bug 要 hotfix"、"发到线下"。
|
|
20
|
+
|
|
21
|
+
## 重要规则
|
|
22
|
+
|
|
23
|
+
> **任何合并到 master 的改动都必须更新 `version.sh` 中的版本号,否则 CI/CD 部署会失败。**
|
|
24
|
+
>
|
|
25
|
+
> - release 流程:在 release 分支上更新版本号
|
|
26
|
+
> - hotfix 流程:**也必须**在 hotfix 分支上更新版本号,不能跳过
|
|
27
|
+
>
|
|
28
|
+
> **分支基准规则:`master` 是唯一的分支 base**——feature、release、hotfix 分支**一律从 master 拉出**;`develop` 是主开发分支,只接收合并(所有开发成果汇入 develop),**任何时候不作为创建分支的 base**。
|
|
29
|
+
>
|
|
30
|
+
> **线上合并后必须三分支同步:** 任何改动合并到 master(含 feature 方式 C 直上线、release/hotfix 的 PR merge 或本地直接合并)后,都要把 `master`、`develop`、`dev-offline` 三个分支同步一遍,**以远端 `origin/master` 为基准**——同步前先 `git fetch origin master` 保证 `origin/master` 是线上最新状态,再 `git merge origin/master`,确保本地三个分支与线上保持一致。
|
|
31
|
+
>
|
|
32
|
+
> **主分支名检测规则:主分支可能是 `master` 也可能是 `main`。** 在执行任何场景前,先检测远端主分支名:
|
|
33
|
+
>
|
|
34
|
+
> ```bash
|
|
35
|
+
> git remote show origin | grep 'HEAD branch' # 输出形如:HEAD branch: master
|
|
36
|
+
> # 远端不可用或未设置 HEAD 时的兜底:
|
|
37
|
+
> git branch -r | grep -E 'origin/(master|main)$'
|
|
38
|
+
> ```
|
|
39
|
+
>
|
|
40
|
+
> 下方所有命令示例中的 `master` 一律替换为实际检测到的主分支名(如 `main`),流程逻辑不变。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 版本号确定规则(SemVer + Conventional Commits 自动推导)
|
|
45
|
+
|
|
46
|
+
**不要直接问用户「patch 还是 minor」,先分析 commit 历史给出建议,再让用户确认/覆盖。**
|
|
47
|
+
|
|
48
|
+
### 自动分析步骤
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 1. 确定上一次 bump 的边界(优先 tag → version.sh 历史 commit)
|
|
52
|
+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD 2>/dev/null || echo "")
|
|
53
|
+
PREV_BUMP=$(git log --format=%H -- version.sh | head -2 | tail -1)
|
|
54
|
+
BASE_REF=${PREV_TAG:-${PREV_BUMP:-}}
|
|
55
|
+
|
|
56
|
+
# 2. 收集本次发版的 commit(排除 bump version 本身)
|
|
57
|
+
if [ -n "$BASE_REF" ]; then
|
|
58
|
+
COMMITS=$(git log ${BASE_REF}..HEAD --oneline --no-merges -- | grep -v "bump version")
|
|
59
|
+
else
|
|
60
|
+
COMMITS=$(git log HEAD --oneline --no-merges -- | grep -v "bump version")
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# 3. 按 Conventional Commits 分类统计
|
|
64
|
+
echo "$COMMITS" | grep -c "^[a-f0-9]* feat" || true # 新功能数量
|
|
65
|
+
echo "$COMMITS" | grep -c "^[a-f0-9]* fix" || true # 修复数量
|
|
66
|
+
echo "$COMMITS" | grep -i "BREAKING CHANGE" || true # 破坏性变更
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 推导规则
|
|
70
|
+
|
|
71
|
+
| 条件 | 建议档位 | 示例 |
|
|
72
|
+
|------|---------|------|
|
|
73
|
+
| 含 `BREAKING CHANGE` 或 `feat!:` | **major** | 1.6.1 → 2.0.0 |
|
|
74
|
+
| 无 BREAKING CHANGE,有 `feat:` | **minor** | 1.6.1 → 1.7.0 |
|
|
75
|
+
| 仅 `fix:` / `docs:` / `chore:` | **patch** | 1.6.1 → 1.6.2 |
|
|
76
|
+
| 首次发版 / 无历史 | 问用户 | — |
|
|
77
|
+
|
|
78
|
+
### 询问模板
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
分析发现本次改动:
|
|
82
|
+
- 新增功能 X 个,修复 Y 个,无破坏性变更
|
|
83
|
+
→ 建议 bump minor:1.6.1 → 1.7.0
|
|
84
|
+
|
|
85
|
+
是否使用此建议?可以改为 patch(1.6.1 → 1.6.2)或 major(1.6.1 → 2.0.0)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **同意建议**:直接按建议执行
|
|
89
|
+
- **覆盖**:按用户输入的档位执行,不改建议逻辑(记录偏好不持久化)
|
|
90
|
+
- **不存在以往的 commit**:回退到直接询问版本号
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 场景一:开始新功能(feature)
|
|
95
|
+
|
|
96
|
+
**触发词:** "开始新功能"、"新feature"、"feature分支"
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# 1. 确保 master 是最新的
|
|
100
|
+
git checkout master
|
|
101
|
+
git pull origin master
|
|
102
|
+
|
|
103
|
+
# 2. 创建 feature 分支(功能名用英文小写+连字符,如 user-login)
|
|
104
|
+
git checkout -b feature/<功能名>
|
|
105
|
+
|
|
106
|
+
# 3. 开发完成后,确认本次功能发到哪个环境,选择对应合并方式:
|
|
107
|
+
#
|
|
108
|
+
# 方式 A:合入主开发分支 develop(常规集成,后续统一走发版流程)
|
|
109
|
+
git checkout develop
|
|
110
|
+
git pull origin develop # 再次拉取;feature 基于 master 拉出,merge 前确认 develop 上没有冲突
|
|
111
|
+
git merge --no-ff feature/<功能名>
|
|
112
|
+
git push origin develop
|
|
113
|
+
#
|
|
114
|
+
# 方式 B:直接发线下测试环境 dev-offline
|
|
115
|
+
git checkout dev-offline
|
|
116
|
+
git pull origin dev-offline
|
|
117
|
+
git merge --no-ff feature/<功能名>
|
|
118
|
+
git push origin dev-offline
|
|
119
|
+
#
|
|
120
|
+
# 方式 C:直接上线 master
|
|
121
|
+
git checkout master
|
|
122
|
+
git pull origin master
|
|
123
|
+
git merge --no-ff feature/<功能名>
|
|
124
|
+
|
|
125
|
+
# 合并后必须先更新版本号(凡合入 master 都必须 bump,否则 CI/CD 部署失败)
|
|
126
|
+
# 读取当前版本:grep -oP 'VERSION=\K[^ ]+' version.sh
|
|
127
|
+
# 按上方「版本号确定规则」分析 commit 历史,给出建议档位,询问用户确认
|
|
128
|
+
# 编辑 version.sh 将 VERSION=x.x.x 改为确认的版本号,再执行:
|
|
129
|
+
git add version.sh
|
|
130
|
+
git commit -m "chore: bump version to <确认的版本号>"
|
|
131
|
+
git push origin master
|
|
132
|
+
|
|
133
|
+
# 方式 C 上线合并完成后,三分支同步(以远端 origin/master 为基准):
|
|
134
|
+
git fetch origin master # 关键:先把 origin/master 引用刷新到线上最新
|
|
135
|
+
git checkout master
|
|
136
|
+
git merge --ff-only origin/master
|
|
137
|
+
git push origin master
|
|
138
|
+
git checkout develop
|
|
139
|
+
git pull origin develop
|
|
140
|
+
git merge origin/master
|
|
141
|
+
git push origin develop
|
|
142
|
+
git checkout dev-offline
|
|
143
|
+
git pull origin dev-offline
|
|
144
|
+
git merge origin/master
|
|
145
|
+
git push origin dev-offline
|
|
146
|
+
|
|
147
|
+
# 4. 删除 feature 分支
|
|
148
|
+
git branch -d feature/<功能名>
|
|
149
|
+
git push origin --delete feature/<功能名>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**注意:** `--no-ff` 会产生一个合并提交,保留分支历史,便于后续追溯。
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 场景二:发布版本(release)
|
|
157
|
+
|
|
158
|
+
**触发词:** "发版"、"release"、"准备上线"
|
|
159
|
+
|
|
160
|
+
> **发版范围(单功能带发模式):** release 从 master 拉出,天然只包含已合入 master 的功能。
|
|
161
|
+
> 本次要发的功能需提前合入 master(feature 完成时走场景一「方式 C」直接上线,或先 merge feature 分支到 master);
|
|
162
|
+
> 若功能尚未合入 master,先按下方步骤 1 创建 release 分支后,再执行
|
|
163
|
+
> `git merge feature/<功能名>` 或 cherry-pick 对应 commit 带入本次发版。
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# 1. 从 master 创建 release 分支
|
|
167
|
+
git checkout master
|
|
168
|
+
git pull origin master
|
|
169
|
+
git checkout -b release/<版本号> # 例如 release/1.4.0
|
|
170
|
+
|
|
171
|
+
# 2. 确定版本号(SemVer 自动推导 + 用户确认)
|
|
172
|
+
# 读取当前版本:grep -oP 'VERSION=\K[^ ]+' version.sh
|
|
173
|
+
# 按上方「版本号确定规则」执行:
|
|
174
|
+
# a. 自动分析上次 bump 以来的 commit 列表
|
|
175
|
+
# b. 按 feat/fix/BREAKING 推导建议档位
|
|
176
|
+
# c. 将建议展示给用户:「建议 bump X → Y,是否确认?(可改为 Z)」
|
|
177
|
+
# d. 用户确认后,编辑 version.sh 将 VERSION=x.x.x 改为确认的版本号
|
|
178
|
+
git add version.sh
|
|
179
|
+
git commit -m "chore: bump version to <确认的版本号>"
|
|
180
|
+
|
|
181
|
+
# 3. 更新 CHANGELOG(如有)
|
|
182
|
+
# 若已安装 @lyx-changelog:直接触发它生成/更新 CHANGELOG.md 并提交
|
|
183
|
+
# 若未安装,按以下步骤手动执行:
|
|
184
|
+
#
|
|
185
|
+
# 检查项目根目录是否存在 CHANGELOG.md(或 CHANGELOG、CHANGELOG.txt):
|
|
186
|
+
# ls CHANGELOG* 2>/dev/null
|
|
187
|
+
#
|
|
188
|
+
# 【如果不存在 CHANGELOG】:询问用户是否需要创建,如果需要则按 Keep a Changelog 格式建立(见 @lyx-changelog)
|
|
189
|
+
# 【如果存在 CHANGELOG】:以本次 version.sh 的更新 commit 为节点,收集 commit 并按类型分组(Added/Fixed/Changed)写入
|
|
190
|
+
#
|
|
191
|
+
# 提交 CHANGELOG 变更:
|
|
192
|
+
git add CHANGELOG.md # 如果文件存在
|
|
193
|
+
git commit -m "docs: update CHANGELOG for v<确认的版本号>"
|
|
194
|
+
|
|
195
|
+
# 4. 上线合并到 master(二选一):
|
|
196
|
+
#
|
|
197
|
+
# 方式 A:远端 PR 合并(默认,可走 code review)
|
|
198
|
+
git push origin release/<版本号>
|
|
199
|
+
# 在 GitHub/GitLab 创建 PR:release/<版本号> → master
|
|
200
|
+
# 标题示例:Release v<版本号>
|
|
201
|
+
# 等待 code review 通过后 merge
|
|
202
|
+
#
|
|
203
|
+
# 方式 B:本地直接合并 master(跳过远端 PR,适合无需 review 的快速上线)
|
|
204
|
+
git push origin release/<版本号> # 先推送分支留档
|
|
205
|
+
git checkout master
|
|
206
|
+
git pull origin master
|
|
207
|
+
git merge --no-ff release/<版本号>
|
|
208
|
+
git push origin master
|
|
209
|
+
|
|
210
|
+
# 5. 上线合并完成后(无论方式 A 还是 B),以远端 origin/master 为基准同步 develop 和 dev-offline(带回版本号、CHANGELOG、修复)
|
|
211
|
+
git fetch origin master # 先把 origin/master 引用刷新到线上最新
|
|
212
|
+
git checkout master
|
|
213
|
+
git merge --ff-only origin/master
|
|
214
|
+
git push origin master
|
|
215
|
+
git checkout develop
|
|
216
|
+
git pull origin develop
|
|
217
|
+
git merge origin/master
|
|
218
|
+
git push origin develop
|
|
219
|
+
git checkout dev-offline
|
|
220
|
+
git pull origin dev-offline
|
|
221
|
+
git merge origin/master
|
|
222
|
+
git push origin dev-offline
|
|
223
|
+
|
|
224
|
+
# 6. 删除 release 分支
|
|
225
|
+
git branch -d release/<版本号>
|
|
226
|
+
git push origin --delete release/<版本号>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**注意:** 版本号文件在根目录 `version.sh`,格式为 `export VERSION=x.x.x`,直接修改该行即可。
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 场景三:紧急修复(hotfix)
|
|
234
|
+
|
|
235
|
+
**触发词:** "hotfix"、"紧急修复"、"线上 bug"
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# 1. 从 master 创建 hotfix 分支
|
|
239
|
+
git checkout master
|
|
240
|
+
git pull origin master
|
|
241
|
+
git checkout -b hotfix/<问题描述> # 例如 hotfix/login-crash
|
|
242
|
+
|
|
243
|
+
# 2. 修复 bug,提交
|
|
244
|
+
git add .
|
|
245
|
+
git commit -m "fix: <问题描述>"
|
|
246
|
+
|
|
247
|
+
# 3. 确定版本号并 bump(必须!否则部署会失败)
|
|
248
|
+
# 读取当前版本:grep -oP 'VERSION=\K[^ ]+' version.sh
|
|
249
|
+
# hotfix 场景下通常只包含 fix: 类型 commit,自动推导结果为 patch(如 1.6.1 → 1.6.2)
|
|
250
|
+
# 按上方「版本号确定规则」展示推导结果给用户确认,确认后:
|
|
251
|
+
# 编辑 version.sh 将 VERSION=x.x.x 改为确认的版本号
|
|
252
|
+
git add version.sh
|
|
253
|
+
git commit -m "chore: bump version to <确认的版本号>"
|
|
254
|
+
|
|
255
|
+
# 4. 上线合并到 master(二选一):
|
|
256
|
+
#
|
|
257
|
+
# 方式 A:远端 PR 合并(默认,可走 code review)
|
|
258
|
+
git push origin hotfix/<问题描述>
|
|
259
|
+
# 在 GitHub/GitLab 创建 PR:hotfix/<问题描述> → master
|
|
260
|
+
# 标题示例:Hotfix: <问题描述>
|
|
261
|
+
# 等待 code review 通过后 merge
|
|
262
|
+
#
|
|
263
|
+
# 方式 B:本地直接合并 master(跳过远端 PR,适合紧急情况快速上线)
|
|
264
|
+
git push origin hotfix/<问题描述> # 先推送分支留档
|
|
265
|
+
git checkout master
|
|
266
|
+
git pull origin master
|
|
267
|
+
git merge --no-ff hotfix/<问题描述>
|
|
268
|
+
git push origin master
|
|
269
|
+
|
|
270
|
+
# 5. 上线合并完成后(无论方式 A 还是 B),以远端 origin/master 为基准同步 develop 和 dev-offline(三个分支对齐)
|
|
271
|
+
git fetch origin master # 先把 origin/master 引用刷新到线上最新
|
|
272
|
+
git checkout master
|
|
273
|
+
git merge --ff-only origin/master
|
|
274
|
+
git push origin master
|
|
275
|
+
git checkout develop
|
|
276
|
+
git pull origin develop
|
|
277
|
+
git merge origin/master
|
|
278
|
+
git push origin develop
|
|
279
|
+
git checkout dev-offline
|
|
280
|
+
git pull origin dev-offline
|
|
281
|
+
git merge origin/master
|
|
282
|
+
git push origin dev-offline
|
|
283
|
+
|
|
284
|
+
# 6. 删除 hotfix 分支
|
|
285
|
+
git branch -d hotfix/<问题描述>
|
|
286
|
+
git push origin --delete hotfix/<问题描述>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**注意:** hotfix 上线合并后(无论 PR merge 还是本地直接合并)必须同步到 develop 和 dev-offline 两个分支,缺一不可。
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 场景四:同步到线下环境(dev-offline)
|
|
294
|
+
|
|
295
|
+
**触发词:** "同步线下"、"dev-offline"、"发到线下"
|
|
296
|
+
|
|
297
|
+
先确认同步方式:
|
|
298
|
+
|
|
299
|
+
**方式 A:全量同步 develop 到 dev-offline**
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
git checkout dev-offline
|
|
303
|
+
git pull origin dev-offline
|
|
304
|
+
git merge --no-ff develop
|
|
305
|
+
git push origin dev-offline
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**方式 B:仅同步指定 commit(cherry-pick)**
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
git checkout dev-offline
|
|
312
|
+
git pull origin dev-offline
|
|
313
|
+
git cherry-pick <commit-hash> # 多个 commit 空格分隔,如:abc1234 def5678
|
|
314
|
+
git push origin dev-offline
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**注意:** dev-offline 是线下测试环境专用分支,merge 前确认不会覆盖该分支上的线下专属配置。如有冲突,以 dev-offline 上的配置为准。
|