@zmice/zc 0.2.4 → 0.2.6
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 +89 -9
- package/dist/cli/__tests__/platform.test.js +169 -2
- package/dist/cli/__tests__/platform.test.js.map +1 -1
- package/dist/cli/__tests__/surface.test.js +52 -0
- package/dist/cli/__tests__/surface.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.d.ts +2 -0
- package/dist/cli/__tests__/team.test.d.ts.map +1 -0
- package/dist/cli/__tests__/team.test.js +29 -0
- package/dist/cli/__tests__/team.test.js.map +1 -0
- package/dist/cli/__tests__/upstream.test.js +4 -0
- package/dist/cli/__tests__/upstream.test.js.map +1 -1
- package/dist/cli/platform.d.ts +11 -3
- package/dist/cli/platform.d.ts.map +1 -1
- package/dist/cli/platform.js +186 -49
- package/dist/cli/platform.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +114 -4
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/upstream.d.ts +1 -0
- package/dist/cli/upstream.d.ts.map +1 -1
- package/dist/cli/upstream.js +84 -5
- package/dist/cli/upstream.js.map +1 -1
- package/dist/node_modules/@zmice/platform-core/dist/index.d.ts +37 -3
- package/dist/node_modules/@zmice/platform-core/dist/index.d.ts.map +1 -1
- package/dist/node_modules/@zmice/platform-core/dist/index.js +68 -0
- package/dist/node_modules/@zmice/platform-core/dist/index.js.map +1 -1
- package/dist/node_modules/@zmice/platform-core/dist/index.test.js +44 -1
- package/dist/node_modules/@zmice/platform-core/dist/index.test.js.map +1 -1
- package/dist/runtime/__tests__/worktree-manager.test.js +63 -1
- package/dist/runtime/__tests__/worktree-manager.test.js.map +1 -1
- package/dist/runtime/worktree-manager.d.ts +26 -1
- package/dist/runtime/worktree-manager.d.ts.map +1 -1
- package/dist/runtime/worktree-manager.js +126 -12
- package/dist/runtime/worktree-manager.js.map +1 -1
- package/dist/team/__tests__/orchestrator.test.js +40 -0
- package/dist/team/__tests__/orchestrator.test.js.map +1 -1
- package/dist/team/__tests__/planner.test.d.ts +2 -0
- package/dist/team/__tests__/planner.test.d.ts.map +1 -0
- package/dist/team/__tests__/planner.test.js +43 -0
- package/dist/team/__tests__/planner.test.js.map +1 -0
- package/dist/team/__tests__/task-queue.test.js +18 -0
- package/dist/team/__tests__/task-queue.test.js.map +1 -1
- package/dist/team/orchestrator.d.ts +2 -1
- package/dist/team/orchestrator.d.ts.map +1 -1
- package/dist/team/orchestrator.js +29 -10
- package/dist/team/orchestrator.js.map +1 -1
- package/dist/team/planner.d.ts +27 -0
- package/dist/team/planner.d.ts.map +1 -0
- package/dist/team/planner.js +120 -0
- package/dist/team/planner.js.map +1 -0
- package/dist/team/task-queue.d.ts +3 -0
- package/dist/team/task-queue.d.ts.map +1 -1
- package/dist/team/task-queue.js +11 -2
- package/dist/team/task-queue.js.map +1 -1
- package/dist/utils/qwen-extension-cli.d.ts.map +1 -1
- package/dist/utils/qwen-extension-cli.js +23 -0
- package/dist/utils/qwen-extension-cli.js.map +1 -1
- package/dist/utils/qwen-extension-cli.test.js +40 -0
- package/dist/utils/qwen-extension-cli.test.js.map +1 -1
- package/package.json +3 -3
- package/vendor/node_modules/@zmice/platform-core/dist/index.d.ts +37 -3
- package/vendor/node_modules/@zmice/platform-core/dist/index.d.ts.map +1 -1
- package/vendor/node_modules/@zmice/platform-core/dist/index.js +68 -0
- package/vendor/node_modules/@zmice/platform-core/dist/index.js.map +1 -1
- package/vendor/node_modules/@zmice/platform-core/dist/index.test.js +44 -1
- package/vendor/node_modules/@zmice/platform-core/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-claude/dist/index.d.ts.map +1 -1
- package/vendor/packages/platform-claude/dist/index.js +12 -70
- package/vendor/packages/platform-claude/dist/index.js.map +1 -1
- package/vendor/packages/platform-codex/dist/generate.d.ts +1 -1
- package/vendor/packages/platform-codex/dist/generate.d.ts.map +1 -1
- package/vendor/packages/platform-codex/dist/generate.js +1 -1
- package/vendor/packages/platform-codex/dist/generate.js.map +1 -1
- package/vendor/packages/platform-codex/dist/index.d.ts +16 -1
- package/vendor/packages/platform-codex/dist/index.d.ts.map +1 -1
- package/vendor/packages/platform-codex/dist/index.js +268 -67
- package/vendor/packages/platform-codex/dist/index.js.map +1 -1
- package/vendor/packages/platform-codex/dist/index.test.js +102 -7
- package/vendor/packages/platform-codex/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-opencode/dist/index.d.ts.map +1 -1
- package/vendor/packages/platform-opencode/dist/index.js +15 -81
- package/vendor/packages/platform-opencode/dist/index.js.map +1 -1
- package/vendor/packages/platform-qwen/dist/index.d.ts.map +1 -1
- package/vendor/packages/platform-qwen/dist/index.js +28 -84
- package/vendor/packages/platform-qwen/dist/index.js.map +1 -1
- package/vendor/packages/toolkit/src/content/agents/architect/body.md +8 -0
- package/vendor/packages/toolkit/src/content/agents/code-reviewer/body.md +10 -0
- package/vendor/packages/toolkit/src/content/agents/product-owner/body.md +8 -0
- package/vendor/packages/toolkit/src/content/commands/plan-review/body.md +3 -1
- package/vendor/packages/toolkit/src/content/commands/start/body.md +51 -2
- package/vendor/packages/toolkit/src/content/commands/start/meta.yaml +2 -2
- package/vendor/packages/toolkit/src/content/skills/branch-finish-and-cleanup/body.md +17 -0
- package/vendor/packages/toolkit/src/content/skills/browser-qa-testing/body.md +77 -520
- package/vendor/packages/toolkit/src/content/skills/ci-cd-and-automation/body.md +56 -387
- package/vendor/packages/toolkit/src/content/skills/code-review-and-quality/body.md +10 -0
- package/vendor/packages/toolkit/src/content/skills/code-simplification/body.md +55 -301
- package/vendor/packages/toolkit/src/content/skills/context-engineering/body.md +10 -0
- package/vendor/packages/toolkit/src/content/skills/continuous-learning/body.md +66 -331
- package/vendor/packages/toolkit/src/content/skills/multi-perspective-review/body.md +30 -1
- package/vendor/packages/toolkit/src/content/skills/parallel-agent-dispatch/body.md +79 -317
- package/vendor/packages/toolkit/src/content/skills/performance-optimization/body.md +60 -330
- package/vendor/packages/toolkit/src/content/skills/planning-and-task-breakdown/body.md +35 -0
- package/vendor/packages/toolkit/src/content/skills/sdd-tdd-workflow/body.md +66 -342
- package/vendor/packages/toolkit/src/content/skills/sprint-retrospective/body.md +66 -303
- package/vendor/packages/toolkit/src/content/skills/team-orchestration/body.md +81 -327
- package/vendor/packages/toolkit/src/content/skills/test-driven-development/body.md +50 -346
- package/vendor/packages/toolkit/src/content/skills/using-agent-skills/body.md +26 -2
- package/vendor/references/upstreams.yaml +5 -0
- package/dist/cli/setup.d.ts +0 -3
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -41
- package/dist/cli/setup.js.map +0 -1
|
@@ -1,417 +1,86 @@
|
|
|
1
1
|
# CI/CD 与自动化
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 角色定位
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
**左移原则(Shift Left):** 尽早在管道中捕获问题。Lint 阶段发现的 bug 只花几分钟修;同样的 bug 到生产环境要花几小时。把检查往上游推 — 静态分析先于测试,测试先于 Staging,Staging 先于生产。
|
|
8
|
-
|
|
9
|
-
**更频繁更安全:** 更小的批次和更频繁的发布降低风险,而非增加风险。3 个变更的部署比 30 个变更的部署更容易调试。频繁发布本身会建立对发布流程的信心。
|
|
5
|
+
把质量门禁自动化,让每次变更都能被一致地构建、测试和验证。CI/CD 的目标不是堆检查,而是用最小可维护管道拦住真实风险。
|
|
10
6
|
|
|
11
7
|
## 何时使用
|
|
12
8
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
9
|
+
- 新建或修改 CI pipeline。
|
|
10
|
+
- 添加 lint、test、build、typecheck、安全扫描或发布门禁。
|
|
11
|
+
- 调试 CI 失败。
|
|
12
|
+
- 需要把本地验证提升成团队共享门禁。
|
|
13
|
+
- 部署、preview、release 或 rollback 流程需要自动化。
|
|
18
14
|
|
|
19
|
-
##
|
|
15
|
+
## 快速路径
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
1. 明确要防的风险:格式、类型、测试、构建、发布、供应链、回滚。
|
|
18
|
+
2. 先找现有 CI 文件和 package scripts,不重写整条流水线。
|
|
19
|
+
3. 设计最小门禁:install/cache -> lint/format -> typecheck -> test -> build。
|
|
20
|
+
4. 只在风险需要时增加 integration / E2E / security / bundle / deploy。
|
|
21
|
+
5. 本地先跑等价命令,再改 CI。
|
|
22
|
+
6. 对 CI 失败读取完整日志,定位失败阶段和根因。
|
|
23
|
+
7. 记录门禁语义:smoke、full verify、release check 不要混名。
|
|
25
24
|
|
|
26
25
|
## 最小可维护门禁
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
1. 依赖安装与缓存命中正常
|
|
31
|
-
2. lint / format 校验
|
|
32
|
-
3. 类型检查或等价静态分析
|
|
33
|
-
4. 单元测试
|
|
34
|
-
5. 构建产物可生成
|
|
35
|
-
|
|
36
|
-
只有当风险或业务性质要求时,再增加集成测试、E2E、安全扫描、bundle 预算、分阶段部署等更重门禁。门禁越重,越要说明它在防什么风险。
|
|
37
|
-
|
|
38
|
-
## 质量门禁管道
|
|
39
|
-
|
|
40
|
-
每个变更在合并前必须通过这些门禁:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
Pull Request 创建
|
|
44
|
-
│
|
|
45
|
-
▼
|
|
46
|
-
┌─────────────────┐
|
|
47
|
-
│ LINT 检查 │ eslint, prettier
|
|
48
|
-
│ ↓ 通过 │
|
|
49
|
-
│ 类型检查 │ tsc --noEmit
|
|
50
|
-
│ ↓ 通过 │
|
|
51
|
-
│ 单元测试 │ jest/vitest
|
|
52
|
-
│ ↓ 通过 │
|
|
53
|
-
│ 构建 │ npm run build
|
|
54
|
-
│ ↓ 通过 │
|
|
55
|
-
│ 集成测试 │ API/数据库测试
|
|
56
|
-
│ ↓ 通过 │
|
|
57
|
-
│ E2E(可选) │ Playwright/Cypress
|
|
58
|
-
│ ↓ 通过 │
|
|
59
|
-
│ 安全审计 │ npm audit
|
|
60
|
-
│ ↓ 通过 │
|
|
61
|
-
│ Bundle 体积 │ bundlesize 检查
|
|
62
|
-
└─────────────────┘
|
|
63
|
-
│
|
|
64
|
-
▼
|
|
65
|
-
可以审查
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
**任何已定义门禁都不可跳过。** Lint 失败就修 Lint,不要禁用规则;测试失败就修代码,不要跳过测试。扩门禁前先确认它是否值得长期维护。
|
|
69
|
-
|
|
70
|
-
## GitHub Actions 配置
|
|
71
|
-
|
|
72
|
-
### 基础 CI 管道
|
|
73
|
-
|
|
74
|
-
```yaml
|
|
75
|
-
# .github/workflows/ci.yml
|
|
76
|
-
name: CI
|
|
77
|
-
|
|
78
|
-
on:
|
|
79
|
-
pull_request:
|
|
80
|
-
branches: [main]
|
|
81
|
-
push:
|
|
82
|
-
branches: [main]
|
|
83
|
-
|
|
84
|
-
jobs:
|
|
85
|
-
quality:
|
|
86
|
-
runs-on: ubuntu-latest
|
|
87
|
-
steps:
|
|
88
|
-
- uses: actions/checkout@v4
|
|
89
|
-
|
|
90
|
-
- uses: actions/setup-node@v4
|
|
91
|
-
with:
|
|
92
|
-
node-version: '22'
|
|
93
|
-
cache: 'npm'
|
|
94
|
-
|
|
95
|
-
- name: 安装依赖
|
|
96
|
-
run: npm ci
|
|
97
|
-
|
|
98
|
-
- name: Lint
|
|
99
|
-
run: npm run lint
|
|
100
|
-
|
|
101
|
-
- name: 类型检查
|
|
102
|
-
run: npx tsc --noEmit
|
|
27
|
+
默认顺序:
|
|
103
28
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
- name: 构建
|
|
108
|
-
run: npm run build
|
|
109
|
-
|
|
110
|
-
- name: 安全审计
|
|
111
|
-
run: npm audit --audit-level=high
|
|
29
|
+
```text
|
|
30
|
+
install/cache -> lint/format -> typecheck -> unit test -> build
|
|
112
31
|
```
|
|
113
32
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
```yaml
|
|
117
|
-
integration:
|
|
118
|
-
runs-on: ubuntu-latest
|
|
119
|
-
services:
|
|
120
|
-
postgres:
|
|
121
|
-
image: postgres:16
|
|
122
|
-
env:
|
|
123
|
-
POSTGRES_DB: testdb
|
|
124
|
-
POSTGRES_USER: ci_user
|
|
125
|
-
POSTGRES_PASSWORD: ${{ secrets.CI_DB_PASSWORD }}
|
|
126
|
-
ports:
|
|
127
|
-
- 5432:5432
|
|
128
|
-
options: >-
|
|
129
|
-
--health-cmd pg_isready
|
|
130
|
-
--health-interval 10s
|
|
131
|
-
--health-timeout 5s
|
|
132
|
-
--health-retries 5
|
|
133
|
-
|
|
134
|
-
steps:
|
|
135
|
-
- uses: actions/checkout@v4
|
|
136
|
-
- uses: actions/setup-node@v4
|
|
137
|
-
with:
|
|
138
|
-
node-version: '22'
|
|
139
|
-
cache: 'npm'
|
|
140
|
-
- run: npm ci
|
|
141
|
-
- name: 运行迁移
|
|
142
|
-
run: npx prisma migrate deploy
|
|
143
|
-
env:
|
|
144
|
-
DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
|
|
145
|
-
- name: 集成测试
|
|
146
|
-
run: npm run test:integration
|
|
147
|
-
env:
|
|
148
|
-
DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
|
|
149
|
-
```
|
|
33
|
+
升级门禁前必须说明:
|
|
150
34
|
|
|
151
|
-
|
|
35
|
+
- 它防什么风险。
|
|
36
|
+
- 运行成本和维护成本。
|
|
37
|
+
- 失败时谁能修、怎么修。
|
|
38
|
+
- 是否需要 secrets、服务依赖或浏览器环境。
|
|
152
39
|
|
|
153
|
-
|
|
40
|
+
## CI 失败处理
|
|
154
41
|
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
cache: 'npm'
|
|
164
|
-
- run: npm ci
|
|
165
|
-
- name: 安装 Playwright
|
|
166
|
-
run: npx playwright install --with-deps chromium
|
|
167
|
-
- name: 构建
|
|
168
|
-
run: npm run build
|
|
169
|
-
- name: 运行 E2E 测试
|
|
170
|
-
run: npx playwright test
|
|
171
|
-
- uses: actions/upload-artifact@v4
|
|
172
|
-
if: failure()
|
|
173
|
-
with:
|
|
174
|
-
name: playwright-report
|
|
175
|
-
path: playwright-report/
|
|
42
|
+
```text
|
|
43
|
+
CI failure loop:
|
|
44
|
+
1. Preserve log.
|
|
45
|
+
2. Identify failing job and command.
|
|
46
|
+
3. Reproduce locally when practical.
|
|
47
|
+
4. Fix root cause.
|
|
48
|
+
5. Run local proof.
|
|
49
|
+
6. Re-run CI / explain why CI is the remaining proof.
|
|
176
50
|
```
|
|
177
51
|
|
|
178
|
-
|
|
52
|
+
不要用跳过测试、禁用规则或放宽门禁来掩盖失败。确需降级门禁时,必须写明风险和恢复计划。
|
|
179
53
|
|
|
180
|
-
|
|
54
|
+
## 部署与发布门禁
|
|
181
55
|
|
|
182
|
-
|
|
183
|
-
CI 失败
|
|
184
|
-
│
|
|
185
|
-
▼
|
|
186
|
-
复制失败输出
|
|
187
|
-
│
|
|
188
|
-
▼
|
|
189
|
-
反馈给 Agent:
|
|
190
|
-
"CI 管道失败了,错误信息如下:
|
|
191
|
-
[粘贴具体错误]
|
|
192
|
-
修复问题并在本地验证后再推送。"
|
|
193
|
-
│
|
|
194
|
-
▼
|
|
195
|
-
Agent 修复 → 推送 → CI 再次运行
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**常见模式:**
|
|
56
|
+
发布管道至少要明确:
|
|
199
57
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
```
|
|
58
|
+
- 触发条件:PR、main、tag、manual approval。
|
|
59
|
+
- 环境:preview、staging、production。
|
|
60
|
+
- secrets 来源和最小权限。
|
|
61
|
+
- rollback 或 feature flag 策略。
|
|
62
|
+
- release 前后验证命令。
|
|
206
63
|
|
|
207
|
-
|
|
64
|
+
高风险发布优先使用小批次、preview、staging、feature flag 和可回滚路径,而不是一次性大改。
|
|
208
65
|
|
|
209
|
-
##
|
|
66
|
+
## 输出契约
|
|
210
67
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
- uses: actions/checkout@v4
|
|
222
|
-
- name: 部署 Preview
|
|
223
|
-
run: npx vercel --token=${{ secrets.VERCEL_TOKEN }}
|
|
68
|
+
```text
|
|
69
|
+
CI/CD plan:
|
|
70
|
+
- Risk addressed:
|
|
71
|
+
- Existing pipeline:
|
|
72
|
+
- Proposed gate:
|
|
73
|
+
- Commands:
|
|
74
|
+
- Secrets/services:
|
|
75
|
+
- Failure handling:
|
|
76
|
+
- Rollback:
|
|
77
|
+
- Verification:
|
|
224
78
|
```
|
|
225
79
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Feature Flag 将部署与发布解耦。在 Flag 后面部署未完成或有风险的功能:
|
|
80
|
+
推荐结论:
|
|
229
81
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
- **金丝雀发布新功能。** 先对 1% 用户开放,再 10%,再 100%。
|
|
233
|
-
- **A/B 测试。** 对比有无该功能的行为差异。
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
// 简单的 Feature Flag 模式
|
|
237
|
-
if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
|
|
238
|
-
return renderNewCheckout();
|
|
239
|
-
}
|
|
240
|
-
return renderLegacyCheckout();
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**Flag 生命周期:** 创建 → 测试启用 → 金丝雀 → 全量发布 → 移除 Flag 和死代码。永久存在的 Flag 是技术债 — 创建时就定好清理日期。
|
|
244
|
-
|
|
245
|
-
### 分阶段灰度发布
|
|
246
|
-
|
|
247
|
-
```
|
|
248
|
-
PR 合并到 main
|
|
249
|
-
│
|
|
250
|
-
▼
|
|
251
|
-
Staging 部署(自动)
|
|
252
|
-
│ 手动验证
|
|
253
|
-
▼
|
|
254
|
-
生产部署(手动触发或 Staging 通过后自动)
|
|
255
|
-
│
|
|
256
|
-
▼
|
|
257
|
-
监控错误(15 分钟窗口)
|
|
258
|
-
│
|
|
259
|
-
├── 检测到错误 → 回滚
|
|
260
|
-
└── 正常 → 完成
|
|
82
|
+
```text
|
|
83
|
+
Recommendation: <add / change / defer / remove gate> because <风险、成本和被放弃替代方案>。
|
|
261
84
|
```
|
|
262
85
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
发布不是自动化的终点。对于已经上线的变更,至少补齐以下校验:
|
|
266
|
-
|
|
267
|
-
- 发布后关键命令或 smoke test 仍然通过
|
|
268
|
-
- 对外契约变化已有对应回归或监控
|
|
269
|
-
- 文档、README、运行说明、发布说明没有落后于实际行为
|
|
270
|
-
- 新增 flag、迁移、临时开关、补丁脚本有清理或追踪计划
|
|
271
|
-
|
|
272
|
-
如果做不到这些,说明发布后仍存在 uncontrolled drift,任务不能算真正闭环。
|
|
273
|
-
|
|
274
|
-
### 回滚方案
|
|
275
|
-
|
|
276
|
-
每次部署都应可逆:
|
|
277
|
-
|
|
278
|
-
```yaml
|
|
279
|
-
# 手动回滚工作流
|
|
280
|
-
name: Rollback
|
|
281
|
-
on:
|
|
282
|
-
workflow_dispatch:
|
|
283
|
-
inputs:
|
|
284
|
-
version:
|
|
285
|
-
description: '要回滚到的版本'
|
|
286
|
-
required: true
|
|
287
|
-
|
|
288
|
-
jobs:
|
|
289
|
-
rollback:
|
|
290
|
-
runs-on: ubuntu-latest
|
|
291
|
-
steps:
|
|
292
|
-
- name: 回滚部署
|
|
293
|
-
run: |
|
|
294
|
-
# 部署指定的上一个版本
|
|
295
|
-
npx vercel rollback ${{ inputs.version }}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
## 环境管理
|
|
299
|
-
|
|
300
|
-
```
|
|
301
|
-
.env.example → 已提交(开发者模板)
|
|
302
|
-
.env → 不提交(本地开发)
|
|
303
|
-
.env.test → 已提交(测试环境,无真实密钥)
|
|
304
|
-
CI secrets → 存储在 GitHub Secrets / Vault
|
|
305
|
-
Production secrets → 存储在部署平台 / Vault
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
CI 永远不应持有生产密钥。CI 测试使用独立的密钥。
|
|
309
|
-
|
|
310
|
-
## CI 之外的自动化
|
|
311
|
-
|
|
312
|
-
### Dependabot / Renovate
|
|
313
|
-
|
|
314
|
-
```yaml
|
|
315
|
-
# .github/dependabot.yml
|
|
316
|
-
version: 2
|
|
317
|
-
updates:
|
|
318
|
-
- package-ecosystem: npm
|
|
319
|
-
directory: /
|
|
320
|
-
schedule:
|
|
321
|
-
interval: weekly
|
|
322
|
-
open-pull-requests-limit: 5
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### Build Cop 角色
|
|
326
|
-
|
|
327
|
-
指定专人负责保持 CI 绿色。当构建失败时,Build Cop 负责修复或回滚 — 而非导致失败的人。这能防止在"别人会修的"的假设下,坏构建不断累积。
|
|
328
|
-
|
|
329
|
-
### PR 检查
|
|
330
|
-
|
|
331
|
-
- **必须审查:** 合并前至少 1 个 Approval
|
|
332
|
-
- **必须通过状态检查:** CI 必须通过才能合并
|
|
333
|
-
- **分支保护:** 禁止对 main 进行 force-push
|
|
334
|
-
- **自动合并:** 所有检查通过且已批准时,自动合并
|
|
335
|
-
|
|
336
|
-
## CI 优化
|
|
337
|
-
|
|
338
|
-
当管道超过 10 分钟时,按影响从大到小依次应用:
|
|
339
|
-
|
|
340
|
-
```
|
|
341
|
-
CI 管道太慢?
|
|
342
|
-
├── 缓存依赖
|
|
343
|
-
│ └── 使用 actions/cache 或 setup-node 的 cache 选项
|
|
344
|
-
├── 并行运行 Job
|
|
345
|
-
│ └── 将 lint、typecheck、test、build 拆分为独立并行 Job
|
|
346
|
-
├── 只运行变更相关的检查
|
|
347
|
-
│ └── 使用路径过滤跳过无关 Job(如纯文档 PR 跳过 E2E)
|
|
348
|
-
├── 矩阵构建
|
|
349
|
-
│ └── 将测试套件分片到多个 Runner
|
|
350
|
-
├── 优化测试套件
|
|
351
|
-
│ └── 将慢测试移出关键路径,改为定时运行
|
|
352
|
-
└── 使用更大的 Runner
|
|
353
|
-
└── GitHub 大规格 Runner 或自托管 Runner
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
**示例:缓存 + 并行**
|
|
357
|
-
```yaml
|
|
358
|
-
jobs:
|
|
359
|
-
lint:
|
|
360
|
-
runs-on: ubuntu-latest
|
|
361
|
-
steps:
|
|
362
|
-
- uses: actions/checkout@v4
|
|
363
|
-
- uses: actions/setup-node@v4
|
|
364
|
-
with: { node-version: '22', cache: 'npm' }
|
|
365
|
-
- run: npm ci
|
|
366
|
-
- run: npm run lint
|
|
367
|
-
|
|
368
|
-
typecheck:
|
|
369
|
-
runs-on: ubuntu-latest
|
|
370
|
-
steps:
|
|
371
|
-
- uses: actions/checkout@v4
|
|
372
|
-
- uses: actions/setup-node@v4
|
|
373
|
-
with: { node-version: '22', cache: 'npm' }
|
|
374
|
-
- run: npm ci
|
|
375
|
-
- run: npx tsc --noEmit
|
|
376
|
-
|
|
377
|
-
test:
|
|
378
|
-
runs-on: ubuntu-latest
|
|
379
|
-
steps:
|
|
380
|
-
- uses: actions/checkout@v4
|
|
381
|
-
- uses: actions/setup-node@v4
|
|
382
|
-
with: { node-version: '22', cache: 'npm' }
|
|
383
|
-
- run: npm ci
|
|
384
|
-
- run: npm test -- --coverage
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
## 常见借口
|
|
388
|
-
|
|
389
|
-
| 借口 | 现实 |
|
|
390
|
-
|------|------|
|
|
391
|
-
| "CI 太慢了" | 优化管道(见上方 CI 优化),不要跳过它。5 分钟的管道能省下几小时的调试。 |
|
|
392
|
-
| "这个改动很小,跳过 CI 吧" | 小改动也会搞坏构建。而且小改动 CI 本来就很快。 |
|
|
393
|
-
| "这个测试是 Flaky 的,重跑就好" | Flaky 测试掩盖真实 bug,浪费所有人的时间。修掉它。 |
|
|
394
|
-
| "以后再加 CI" | 没有 CI 的项目会累积坏状态。第一天就搭建。 |
|
|
395
|
-
| "手动测试就够了" | 手动测试无法扩展,也不可重复。能自动化的就自动化。 |
|
|
396
|
-
|
|
397
|
-
## 危险信号
|
|
398
|
-
|
|
399
|
-
- 项目没有 CI 管道
|
|
400
|
-
- CI 失败被忽略或静音
|
|
401
|
-
- 为了让管道通过而禁用测试
|
|
402
|
-
- 生产部署不经过 Staging 验证
|
|
403
|
-
- 没有回滚机制
|
|
404
|
-
- 密钥存储在代码或 CI 配置文件中(而非密钥管理器)
|
|
405
|
-
- CI 运行时间很长但无人优化
|
|
406
|
-
|
|
407
|
-
## 验证清单
|
|
408
|
-
|
|
409
|
-
搭建或修改 CI 后确认:
|
|
410
|
-
|
|
411
|
-
- [ ] 所有质量门禁就位(lint、类型、测试、构建、审计)
|
|
412
|
-
- [ ] 管道在每个 PR 和 main 推送时运行
|
|
413
|
-
- [ ] 失败阻止合并(分支保护已配置)
|
|
414
|
-
- [ ] CI 结果反馈到开发循环
|
|
415
|
-
- [ ] 密钥存储在密钥管理器中,不在代码里
|
|
416
|
-
- [ ] 部署有回滚机制
|
|
417
|
-
- [ ] 管道在 10 分钟内完成测试套件
|
|
86
|
+
如果新增门禁的维护成本高于它防住的风险,默认先不加。
|
|
@@ -35,6 +35,16 @@
|
|
|
35
35
|
- 评审没有用“看起来还行”替代事实判断
|
|
36
36
|
- 审查后的问题处理路径清楚,不把“提了意见”误当成“问题已关闭”
|
|
37
37
|
|
|
38
|
+
## 推荐结论格式
|
|
39
|
+
|
|
40
|
+
审查结论必须给出可执行推荐:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
Recommendation: <Approve / Request changes / Defer> because <evidence, risk, and trade-off>.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
如果请求修改,说明哪些问题阻塞合并;如果批准,说明剩余风险和已验证证据;如果延后,说明为什么延后比本轮修复更合适。
|
|
47
|
+
|
|
38
48
|
## 相关原则
|
|
39
49
|
|
|
40
50
|
- 先报问题,再做总结
|