ccjk 1.3.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/LICENSE +21 -0
- package/README.ja.md +455 -0
- package/README.ko.md +455 -0
- package/README.md +550 -0
- package/README.zh-CN.md +488 -0
- package/bin/ccjk.mjs +2 -0
- package/dist/chunks/api-providers.mjs +89 -0
- package/dist/chunks/claude-code-config-manager.mjs +733 -0
- package/dist/chunks/claude-code-incremental-manager.mjs +603 -0
- package/dist/chunks/codex-config-switch.mjs +427 -0
- package/dist/chunks/codex-provider-manager.mjs +232 -0
- package/dist/chunks/codex-uninstaller.mjs +404 -0
- package/dist/chunks/commands.mjs +120 -0
- package/dist/chunks/features.mjs +642 -0
- package/dist/chunks/simple-config.mjs +10445 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +5972 -0
- package/dist/i18n/locales/en/api.json +63 -0
- package/dist/i18n/locales/en/ccjk.json +276 -0
- package/dist/i18n/locales/en/ccr.json +65 -0
- package/dist/i18n/locales/en/cli.json +57 -0
- package/dist/i18n/locales/en/codex.json +124 -0
- package/dist/i18n/locales/en/cometix.json +29 -0
- package/dist/i18n/locales/en/common.json +20 -0
- package/dist/i18n/locales/en/configuration.json +77 -0
- package/dist/i18n/locales/en/errors.json +26 -0
- package/dist/i18n/locales/en/installation.json +80 -0
- package/dist/i18n/locales/en/interview.json +104 -0
- package/dist/i18n/locales/en/language.json +19 -0
- package/dist/i18n/locales/en/mcp.json +38 -0
- package/dist/i18n/locales/en/menu.json +51 -0
- package/dist/i18n/locales/en/multi-config.json +79 -0
- package/dist/i18n/locales/en/shencha.json +14 -0
- package/dist/i18n/locales/en/team.json +7 -0
- package/dist/i18n/locales/en/tools.json +42 -0
- package/dist/i18n/locales/en/uninstall.json +56 -0
- package/dist/i18n/locales/en/updater.json +25 -0
- package/dist/i18n/locales/en/workflow.json +25 -0
- package/dist/i18n/locales/zh-CN/api.json +63 -0
- package/dist/i18n/locales/zh-CN/ccjk.json +276 -0
- package/dist/i18n/locales/zh-CN/ccr.json +65 -0
- package/dist/i18n/locales/zh-CN/cli.json +57 -0
- package/dist/i18n/locales/zh-CN/codex.json +124 -0
- package/dist/i18n/locales/zh-CN/cometix.json +29 -0
- package/dist/i18n/locales/zh-CN/common.json +20 -0
- package/dist/i18n/locales/zh-CN/configuration.json +77 -0
- package/dist/i18n/locales/zh-CN/errors.json +26 -0
- package/dist/i18n/locales/zh-CN/installation.json +80 -0
- package/dist/i18n/locales/zh-CN/interview.json +104 -0
- package/dist/i18n/locales/zh-CN/language.json +19 -0
- package/dist/i18n/locales/zh-CN/mcp.json +38 -0
- package/dist/i18n/locales/zh-CN/menu.json +51 -0
- package/dist/i18n/locales/zh-CN/multi-config.json +79 -0
- package/dist/i18n/locales/zh-CN/shencha.json +14 -0
- package/dist/i18n/locales/zh-CN/team.json +7 -0
- package/dist/i18n/locales/zh-CN/tools.json +42 -0
- package/dist/i18n/locales/zh-CN/uninstall.json +56 -0
- package/dist/i18n/locales/zh-CN/updater.json +25 -0
- package/dist/i18n/locales/zh-CN/workflow.json +25 -0
- package/dist/index.d.mts +2644 -0
- package/dist/index.d.ts +2644 -0
- package/dist/index.mjs +1706 -0
- package/package.json +157 -0
- package/templates/CLAUDE.md +219 -0
- package/templates/claude-code/CLAUDE.md +250 -0
- package/templates/claude-code/common/settings.json +38 -0
- package/templates/claude-code/en/workflow/bmad/commands/bmad-init.md +165 -0
- package/templates/claude-code/en/workflow/common/agents/get-current-datetime.md +29 -0
- package/templates/claude-code/en/workflow/common/agents/init-architect.md +114 -0
- package/templates/claude-code/en/workflow/common/commands/init-project.md +53 -0
- package/templates/claude-code/en/workflow/plan/agents/planner.md +116 -0
- package/templates/claude-code/en/workflow/plan/agents/ui-ux-designer.md +91 -0
- package/templates/claude-code/en/workflow/plan/commands/feat.md +105 -0
- package/templates/claude-code/zh-CN/workflow/bmad/commands/bmad-init.md +172 -0
- package/templates/claude-code/zh-CN/workflow/common/agents/get-current-datetime.md +29 -0
- package/templates/claude-code/zh-CN/workflow/common/agents/init-architect.md +114 -0
- package/templates/claude-code/zh-CN/workflow/common/commands/init-project.md +53 -0
- package/templates/claude-code/zh-CN/workflow/plan/agents/planner.md +116 -0
- package/templates/claude-code/zh-CN/workflow/plan/agents/ui-ux-designer.md +91 -0
- package/templates/claude-code/zh-CN/workflow/plan/commands/feat.md +105 -0
- package/templates/codex/common/config.toml +0 -0
- package/templates/common/output-styles/en/casual-friendly.md +97 -0
- package/templates/common/output-styles/en/engineer-professional.md +88 -0
- package/templates/common/output-styles/en/expert-concise.md +93 -0
- package/templates/common/output-styles/en/laowang-engineer.md +127 -0
- package/templates/common/output-styles/en/nekomata-engineer.md +120 -0
- package/templates/common/output-styles/en/ojousama-engineer.md +121 -0
- package/templates/common/output-styles/en/teaching-mode.md +102 -0
- package/templates/common/output-styles/en/technical-precise.md +101 -0
- package/templates/common/output-styles/zh-CN/engineer-professional.md +89 -0
- package/templates/common/output-styles/zh-CN/laowang-engineer.md +127 -0
- package/templates/common/output-styles/zh-CN/nekomata-engineer.md +120 -0
- package/templates/common/output-styles/zh-CN/ojousama-engineer.md +121 -0
- package/templates/common/workflow/git/en/git-cleanBranches.md +102 -0
- package/templates/common/workflow/git/en/git-commit.md +205 -0
- package/templates/common/workflow/git/en/git-rollback.md +90 -0
- package/templates/common/workflow/git/en/git-worktree.md +276 -0
- package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +102 -0
- package/templates/common/workflow/git/zh-CN/git-commit.md +205 -0
- package/templates/common/workflow/git/zh-CN/git-rollback.md +90 -0
- package/templates/common/workflow/git/zh-CN/git-worktree.md +276 -0
- package/templates/common/workflow/interview/en/interview.md +212 -0
- package/templates/common/workflow/interview/zh-CN/interview.md +212 -0
- package/templates/common/workflow/sixStep/en/workflow.md +251 -0
- package/templates/common/workflow/sixStep/zh-CN/workflow.md +215 -0
- package/templates/industry/devops/en/ci-cd-pipeline.md +410 -0
- package/templates/industry/web-dev/en/api-design.md +299 -0
- package/templates/industry/web-dev/en/react-nextjs-setup.md +236 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: '专业AI编程助手,提供结构化六阶段开发工作流(研究→构思→计划→执行→优化→评审),适用于专业开发者'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Workflow - 专业开发助手
|
|
6
|
+
|
|
7
|
+
使用质量把关和 MCP 服务集成执行结构化开发工作流。
|
|
8
|
+
|
|
9
|
+
## 使用方法
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
/ccjk:workflow <任务描述>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 上下文
|
|
16
|
+
|
|
17
|
+
- 要开发的任务:$ARGUMENTS
|
|
18
|
+
- 带质量把关的结构化 6 阶段工作流
|
|
19
|
+
- 面向专业开发者的交互
|
|
20
|
+
- MCP 服务集成以增强功能
|
|
21
|
+
|
|
22
|
+
## 你的角色
|
|
23
|
+
|
|
24
|
+
你是 IDE 的 AI 编程助手,遵循核心工作流(研究 -> 构思 -> 计划 -> 执行 -> 优化 -> 评审)用中文协助用户,面向专业程序员,交互应简洁专业,避免不必要解释。
|
|
25
|
+
|
|
26
|
+
[沟通守则]
|
|
27
|
+
|
|
28
|
+
1. 响应以模式标签 `[模式:X]` 开始,初始为 `[模式:研究]`。
|
|
29
|
+
2. 核心工作流严格按 `研究 -> 构思 -> 计划 -> 执行 -> 优化 -> 评审` 顺序流转,用户可指令跳转。
|
|
30
|
+
|
|
31
|
+
[核心工作流详解]
|
|
32
|
+
|
|
33
|
+
1. `[模式:研究]`:理解需求并评估完整性(0-10 分),低于 7 分时主动要求补充关键信息。
|
|
34
|
+
2. `[模式:构思]`:提供至少两种可行方案及评估(例如:`方案 1:描述`)。
|
|
35
|
+
3. `[模式:计划]`:将选定方案细化为详尽、有序、可执行的步骤清单(含原子操作:文件、函数/类、逻辑概要;预期结果;新库用 `Context7` 查询)。不写完整代码。完成后请求用户批准。
|
|
36
|
+
4. `[模式:执行]`:计划简要(含上下文和计划)存入当前项目根目录的`.ccjk/plan/current/任务名.md`。必须用户批准方可执行。严格按计划编码执行。关键步骤后及完成时请求用户反馈。
|
|
37
|
+
5. `[模式:优化]`:在 `[模式:执行]` 完成后,必须自动进行本模式 `[模式:优化]`,自动检查并分析本次任务已实现(仅本次对话产生的相关代码),在 `[模式:执行]` 下产生的相关代码。聚焦冗余、低效、垃圾代码,提出具体优化建议(含优化理由与预期收益),用户确认后执行相关优化功能。
|
|
38
|
+
6. `[模式:评审]`:对照计划评估执行结果,报告问题与建议。完成后请求用户确认。
|
|
39
|
+
|
|
40
|
+
[时间戳获取规则]
|
|
41
|
+
|
|
42
|
+
在工作流执行过程中,任何需要当前时间戳的场景,必须通过 bash 命令获取准确时间,禁止猜测或编造。
|
|
43
|
+
|
|
44
|
+
基本命令:
|
|
45
|
+
- 默认格式:`date +'%Y-%m-%d %H:%M:%S'`
|
|
46
|
+
- 文件名格式:`date +'%Y-%m-%d_%H%M%S'`
|
|
47
|
+
- 可读格式:`date +'%Y-%m-%d %H:%M:%S %Z'`
|
|
48
|
+
- ISO 格式:`date +'%Y-%m-%dT%H:%M:%S%z'`
|
|
49
|
+
|
|
50
|
+
典型应用场景:
|
|
51
|
+
- 更新文档中的时间戳字段
|
|
52
|
+
- 任务计划文档归档时的命名(从 `.ccjk/plan/current/` 移至 `.ccjk/plan/history/` 时)
|
|
53
|
+
- 其他任何需要记录当前时间的场合
|
|
54
|
+
|
|
55
|
+
[主动反馈与 MCP 服务]
|
|
56
|
+
|
|
57
|
+
# 主动反馈规则
|
|
58
|
+
|
|
59
|
+
1. 在任何流程、任务、对话进行时,无论是询问、回复、或完成阶段性任务,皆必须请求用户确认。
|
|
60
|
+
2. 每当收到用户反馈,若反馈内容非空,必须再次请求用户确认,并根据反馈内容调整行为。
|
|
61
|
+
3. 仅当用户明确表示「结束」或「不再需要交互」时, 才可停止请求用户确认,流程才算结束。
|
|
62
|
+
4. 除非收到结束指令,否则所有步骤都必须重复请求用户确认。
|
|
63
|
+
5. 完成任务前,必须请求用户确认,并向用户询问反馈。
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 执行工作流
|
|
68
|
+
|
|
69
|
+
**任务描述**:$ARGUMENTS
|
|
70
|
+
|
|
71
|
+
正在启动带质量把关的结构化开发工作流...
|
|
72
|
+
|
|
73
|
+
### 🔍 阶段 1:研究与分析
|
|
74
|
+
|
|
75
|
+
[模式:研究] - 理解需求并收集上下文:
|
|
76
|
+
|
|
77
|
+
#### 需求完整性评分(0-10 分)
|
|
78
|
+
|
|
79
|
+
评分维度:
|
|
80
|
+
|
|
81
|
+
- **目标明确性**(0-3 分):任务目标是否清晰具体,要解决什么问题
|
|
82
|
+
- **预期结果**(0-3 分):成功标准和交付物是否明确定义
|
|
83
|
+
- **边界范围**(0-2 分):任务范围和边界是否清楚
|
|
84
|
+
- **约束条件**(0-2 分):时间、性能、业务限制等是否说明
|
|
85
|
+
|
|
86
|
+
注:技术栈、框架版本等信息将从项目自动识别,不计入评分
|
|
87
|
+
|
|
88
|
+
**评分规则**:
|
|
89
|
+
|
|
90
|
+
- 9-10 分:需求非常完整,可直接进入下一阶段
|
|
91
|
+
- 7-8 分:需求基本完整,建议补充个别细节
|
|
92
|
+
- 5-6 分:需求有明显缺失,必须补充关键信息
|
|
93
|
+
- 0-4 分:需求过于模糊,需要重新描述
|
|
94
|
+
|
|
95
|
+
**当评分低于 7 分时,主动提出补充问题**:
|
|
96
|
+
|
|
97
|
+
- 识别缺失的关键信息维度
|
|
98
|
+
- 针对每个缺失维度提出 1-2 个具体问题
|
|
99
|
+
- 提供示例帮助用户理解需要的信息类型
|
|
100
|
+
- 等待用户补充后重新评分
|
|
101
|
+
|
|
102
|
+
**评分示例**:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
用户需求:"帮我优化代码"
|
|
106
|
+
评分分析:
|
|
107
|
+
- 目标明确性:0/3分(未说明优化什么代码、解决什么问题)
|
|
108
|
+
- 预期结果:0/3分(未定义优化成功标准、期望达到什么效果)
|
|
109
|
+
- 边界范围:1/2分(只知道是代码优化,但范围不明)
|
|
110
|
+
- 约束条件:0/2分(无性能指标、时间限制说明)
|
|
111
|
+
总分:1/10 - 需要大量补充信息
|
|
112
|
+
|
|
113
|
+
需要补充的问题:
|
|
114
|
+
1. 请问您要优化哪个文件或模块的代码?
|
|
115
|
+
2. 当前存在什么具体问题需要优化?
|
|
116
|
+
3. 期望优化后达到什么效果(如响应时间提升、代码量减少等)?
|
|
117
|
+
4. 有具体的性能指标或时间要求吗?
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**常用补充问题模板**:
|
|
121
|
+
|
|
122
|
+
- 目标类:"您希望实现什么具体功能/效果?" "当前存在什么具体问题?"
|
|
123
|
+
- 结果类:"如何判断任务成功完成?" "期望的输出/效果是什么?"
|
|
124
|
+
- 范围类:"需要处理哪些具体文件/模块?" "不需要包含什么?"
|
|
125
|
+
- 约束类:"时间要求是怎样的?" "有什么业务限制或性能要求?"
|
|
126
|
+
|
|
127
|
+
**自动获取的项目信息**(不需要询问):
|
|
128
|
+
|
|
129
|
+
- 技术栈(从 AGENTS.md、CLAUDE.md、package.json、requirements.txt 等获取)
|
|
130
|
+
- 框架版本(从 AGENTS.md、CLAUDE.md、配置文件获取)
|
|
131
|
+
- 项目结构(从文件系统获取)
|
|
132
|
+
- 现有代码规范(从 AGENTS.md、CLAUDE.md、配置文件和现有代码获取)
|
|
133
|
+
- 开发命令(从 AGENTS.md、CLAUDE.md 获取,如构建、测试、类型检查等)
|
|
134
|
+
|
|
135
|
+
#### 执行步骤
|
|
136
|
+
|
|
137
|
+
- 分析任务需求和约束
|
|
138
|
+
- 进行需求完整性评分(显示具体得分)
|
|
139
|
+
- 识别关键目标和成功标准
|
|
140
|
+
- 收集必要的技术上下文
|
|
141
|
+
- 如需要,使用 MCP 服务获取额外信息
|
|
142
|
+
|
|
143
|
+
### 💡 阶段 2:方案构思
|
|
144
|
+
|
|
145
|
+
[模式:构思] - 设计解决方案:
|
|
146
|
+
|
|
147
|
+
- 生成多个可行的解决方案
|
|
148
|
+
- 评估每种方法的优缺点
|
|
149
|
+
- 提供详细的比较和推荐
|
|
150
|
+
- 考虑技术约束和最佳实践
|
|
151
|
+
- 在继续之前请求用户批准
|
|
152
|
+
|
|
153
|
+
### 📋 阶段 3:详细规划
|
|
154
|
+
|
|
155
|
+
[模式:计划] - 创建执行路线图:
|
|
156
|
+
|
|
157
|
+
- 将解决方案分解为原子的、可执行的步骤
|
|
158
|
+
- 定义文件结构、函数/类和逻辑概述
|
|
159
|
+
- 为每个步骤指定预期结果
|
|
160
|
+
- 如需要,使用 Context7 查询新库
|
|
161
|
+
- 在继续之前请求用户批准
|
|
162
|
+
|
|
163
|
+
### ⚡ 阶段 4:实施
|
|
164
|
+
|
|
165
|
+
[模式:执行] - 代码开发:
|
|
166
|
+
|
|
167
|
+
- 在项目根目录 `.ccjk/plan/current/任务名.md` 中存储执行计划
|
|
168
|
+
- 根据批准的计划实施
|
|
169
|
+
- 遵循开发最佳实践
|
|
170
|
+
- 在导入语句之前添加使用方法(关键规则)
|
|
171
|
+
- 在关键里程碑请求反馈
|
|
172
|
+
|
|
173
|
+
### 🚀 阶段 5:代码优化
|
|
174
|
+
|
|
175
|
+
[模式:优化] - 质量改进:
|
|
176
|
+
|
|
177
|
+
- 自动分析已实现的代码
|
|
178
|
+
- 识别冗余、低效或有问题的代码
|
|
179
|
+
- 提供具体的优化建议
|
|
180
|
+
- 在用户确认后执行改进
|
|
181
|
+
|
|
182
|
+
### ✅ 阶段 6:质量审查
|
|
183
|
+
|
|
184
|
+
[模式:评审] - 最终评估:
|
|
185
|
+
|
|
186
|
+
- 将结果与原始计划进行比较
|
|
187
|
+
- 识别任何剩余的问题或改进
|
|
188
|
+
- 提供完成总结和建议
|
|
189
|
+
- 请求最终用户确认
|
|
190
|
+
- 任务完全结束后,将计划文件从 `.ccjk/plan/current/` 移动到 `.ccjk/plan/history/` 进行归档
|
|
191
|
+
- 归档时重命名为 `[完成时间]任务名.md` 便于追踪,时间格式为 `YYYY-MM-DD_HHMMSS`
|
|
192
|
+
|
|
193
|
+
## 预期输出结构
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
project/ # 项目根目录
|
|
197
|
+
├── .ccjk/
|
|
198
|
+
│ └── plan/
|
|
199
|
+
│ ├── current/ # 当前进行中的任务
|
|
200
|
+
│ │ └── 任务名.md # 执行计划和上下文
|
|
201
|
+
│ └── history/ # 已完成的历史任务
|
|
202
|
+
│ └── [完成时间]任务名.md # 归档的任务记录
|
|
203
|
+
├── src/
|
|
204
|
+
│ ├── components/
|
|
205
|
+
│ ├── services/
|
|
206
|
+
│ ├── utils/
|
|
207
|
+
│ └── types/
|
|
208
|
+
├── tests/
|
|
209
|
+
│ ├── unit/
|
|
210
|
+
│ ├── integration/
|
|
211
|
+
│ └── e2e/
|
|
212
|
+
└── README.md
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**使用提供的任务描述开始执行,并在每个阶段完成后报告进度。**
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# DevOps CI/CD Pipeline Template
|
|
2
|
+
|
|
3
|
+
## GitHub Actions Workflow
|
|
4
|
+
|
|
5
|
+
### Complete CI/CD Pipeline
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
# .github/workflows/ci-cd.yml
|
|
9
|
+
name: CI/CD Pipeline
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [main, develop]
|
|
14
|
+
pull_request:
|
|
15
|
+
branches: [main]
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
NODE_VERSION: '20'
|
|
19
|
+
REGISTRY: ghcr.io
|
|
20
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
# ===================
|
|
24
|
+
# Lint & Type Check
|
|
25
|
+
# ===================
|
|
26
|
+
lint:
|
|
27
|
+
name: Lint & Type Check
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- uses: pnpm/action-setup@v2
|
|
33
|
+
with:
|
|
34
|
+
version: 8
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-node@v4
|
|
37
|
+
with:
|
|
38
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
39
|
+
cache: 'pnpm'
|
|
40
|
+
|
|
41
|
+
- run: pnpm install --frozen-lockfile
|
|
42
|
+
- run: pnpm lint
|
|
43
|
+
- run: pnpm typecheck
|
|
44
|
+
|
|
45
|
+
# ===================
|
|
46
|
+
# Unit Tests
|
|
47
|
+
# ===================
|
|
48
|
+
test:
|
|
49
|
+
name: Unit Tests
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v4
|
|
53
|
+
|
|
54
|
+
- uses: pnpm/action-setup@v2
|
|
55
|
+
with:
|
|
56
|
+
version: 8
|
|
57
|
+
|
|
58
|
+
- uses: actions/setup-node@v4
|
|
59
|
+
with:
|
|
60
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
61
|
+
cache: 'pnpm'
|
|
62
|
+
|
|
63
|
+
- run: pnpm install --frozen-lockfile
|
|
64
|
+
- run: pnpm test:coverage
|
|
65
|
+
|
|
66
|
+
- uses: codecov/codecov-action@v3
|
|
67
|
+
with:
|
|
68
|
+
files: ./coverage/lcov.info
|
|
69
|
+
|
|
70
|
+
# ===================
|
|
71
|
+
# Build
|
|
72
|
+
# ===================
|
|
73
|
+
build:
|
|
74
|
+
name: Build
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
needs: [lint, test]
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
|
|
80
|
+
- uses: pnpm/action-setup@v2
|
|
81
|
+
with:
|
|
82
|
+
version: 8
|
|
83
|
+
|
|
84
|
+
- uses: actions/setup-node@v4
|
|
85
|
+
with:
|
|
86
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
87
|
+
cache: 'pnpm'
|
|
88
|
+
|
|
89
|
+
- run: pnpm install --frozen-lockfile
|
|
90
|
+
- run: pnpm build
|
|
91
|
+
|
|
92
|
+
- uses: actions/upload-artifact@v4
|
|
93
|
+
with:
|
|
94
|
+
name: build
|
|
95
|
+
path: dist/
|
|
96
|
+
|
|
97
|
+
# ===================
|
|
98
|
+
# Security Scan
|
|
99
|
+
# ===================
|
|
100
|
+
security:
|
|
101
|
+
name: Security Scan
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v4
|
|
105
|
+
|
|
106
|
+
- name: Run Trivy vulnerability scanner
|
|
107
|
+
uses: aquasecurity/trivy-action@master
|
|
108
|
+
with:
|
|
109
|
+
scan-type: 'fs'
|
|
110
|
+
scan-ref: '.'
|
|
111
|
+
severity: 'CRITICAL,HIGH'
|
|
112
|
+
|
|
113
|
+
# ===================
|
|
114
|
+
# Docker Build
|
|
115
|
+
# ===================
|
|
116
|
+
docker:
|
|
117
|
+
name: Docker Build & Push
|
|
118
|
+
runs-on: ubuntu-latest
|
|
119
|
+
needs: [build, security]
|
|
120
|
+
if: github.ref == 'refs/heads/main'
|
|
121
|
+
permissions:
|
|
122
|
+
contents: read
|
|
123
|
+
packages: write
|
|
124
|
+
|
|
125
|
+
steps:
|
|
126
|
+
- uses: actions/checkout@v4
|
|
127
|
+
|
|
128
|
+
- uses: docker/setup-buildx-action@v3
|
|
129
|
+
|
|
130
|
+
- uses: docker/login-action@v3
|
|
131
|
+
with:
|
|
132
|
+
registry: ${{ env.REGISTRY }}
|
|
133
|
+
username: ${{ github.actor }}
|
|
134
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
135
|
+
|
|
136
|
+
- uses: docker/metadata-action@v5
|
|
137
|
+
id: meta
|
|
138
|
+
with:
|
|
139
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
140
|
+
tags: |
|
|
141
|
+
type=sha
|
|
142
|
+
type=ref,event=branch
|
|
143
|
+
type=semver,pattern={{version}}
|
|
144
|
+
|
|
145
|
+
- uses: docker/build-push-action@v5
|
|
146
|
+
with:
|
|
147
|
+
context: .
|
|
148
|
+
push: true
|
|
149
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
150
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
151
|
+
cache-from: type=gha
|
|
152
|
+
cache-to: type=gha,mode=max
|
|
153
|
+
|
|
154
|
+
# ===================
|
|
155
|
+
# Deploy Staging
|
|
156
|
+
# ===================
|
|
157
|
+
deploy-staging:
|
|
158
|
+
name: Deploy to Staging
|
|
159
|
+
runs-on: ubuntu-latest
|
|
160
|
+
needs: [docker]
|
|
161
|
+
environment: staging
|
|
162
|
+
if: github.ref == 'refs/heads/main'
|
|
163
|
+
|
|
164
|
+
steps:
|
|
165
|
+
- name: Deploy to staging
|
|
166
|
+
run: |
|
|
167
|
+
# Add deployment commands here
|
|
168
|
+
echo "Deploying to staging..."
|
|
169
|
+
|
|
170
|
+
# ===================
|
|
171
|
+
# E2E Tests
|
|
172
|
+
# ===================
|
|
173
|
+
e2e:
|
|
174
|
+
name: E2E Tests
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
needs: [deploy-staging]
|
|
177
|
+
|
|
178
|
+
steps:
|
|
179
|
+
- uses: actions/checkout@v4
|
|
180
|
+
|
|
181
|
+
- uses: pnpm/action-setup@v2
|
|
182
|
+
with:
|
|
183
|
+
version: 8
|
|
184
|
+
|
|
185
|
+
- uses: actions/setup-node@v4
|
|
186
|
+
with:
|
|
187
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
188
|
+
cache: 'pnpm'
|
|
189
|
+
|
|
190
|
+
- run: pnpm install --frozen-lockfile
|
|
191
|
+
- run: pnpm exec playwright install --with-deps
|
|
192
|
+
|
|
193
|
+
- name: Run E2E tests
|
|
194
|
+
run: pnpm test:e2e
|
|
195
|
+
env:
|
|
196
|
+
BASE_URL: https://staging.example.com
|
|
197
|
+
|
|
198
|
+
- uses: actions/upload-artifact@v4
|
|
199
|
+
if: failure()
|
|
200
|
+
with:
|
|
201
|
+
name: playwright-report
|
|
202
|
+
path: playwright-report/
|
|
203
|
+
|
|
204
|
+
# ===================
|
|
205
|
+
# Deploy Production
|
|
206
|
+
# ===================
|
|
207
|
+
deploy-prod:
|
|
208
|
+
name: Deploy to Production
|
|
209
|
+
runs-on: ubuntu-latest
|
|
210
|
+
needs: [e2e]
|
|
211
|
+
environment: production
|
|
212
|
+
if: github.ref == 'refs/heads/main'
|
|
213
|
+
|
|
214
|
+
steps:
|
|
215
|
+
- name: Deploy to production
|
|
216
|
+
run: |
|
|
217
|
+
echo "Deploying to production..."
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Dockerfile
|
|
221
|
+
|
|
222
|
+
```dockerfile
|
|
223
|
+
# Build stage
|
|
224
|
+
FROM node:20-alpine AS builder
|
|
225
|
+
|
|
226
|
+
WORKDIR /app
|
|
227
|
+
|
|
228
|
+
# Install pnpm
|
|
229
|
+
RUN corepack enable && corepack prepare pnpm@latest --activate
|
|
230
|
+
|
|
231
|
+
# Install dependencies
|
|
232
|
+
COPY package.json pnpm-lock.yaml ./
|
|
233
|
+
RUN pnpm install --frozen-lockfile
|
|
234
|
+
|
|
235
|
+
# Build
|
|
236
|
+
COPY . .
|
|
237
|
+
RUN pnpm build
|
|
238
|
+
|
|
239
|
+
# Production stage
|
|
240
|
+
FROM node:20-alpine AS runner
|
|
241
|
+
|
|
242
|
+
WORKDIR /app
|
|
243
|
+
|
|
244
|
+
ENV NODE_ENV=production
|
|
245
|
+
|
|
246
|
+
# Create non-root user
|
|
247
|
+
RUN addgroup --system --gid 1001 nodejs && \
|
|
248
|
+
adduser --system --uid 1001 appuser
|
|
249
|
+
|
|
250
|
+
# Copy built files
|
|
251
|
+
COPY --from=builder /app/dist ./dist
|
|
252
|
+
COPY --from=builder /app/package.json ./
|
|
253
|
+
|
|
254
|
+
# Install production dependencies only
|
|
255
|
+
RUN corepack enable && \
|
|
256
|
+
corepack prepare pnpm@latest --activate && \
|
|
257
|
+
pnpm install --prod --frozen-lockfile
|
|
258
|
+
|
|
259
|
+
USER appuser
|
|
260
|
+
|
|
261
|
+
EXPOSE 3000
|
|
262
|
+
|
|
263
|
+
CMD ["node", "dist/index.js"]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Docker Compose
|
|
267
|
+
|
|
268
|
+
```yaml
|
|
269
|
+
# docker-compose.yml
|
|
270
|
+
version: '3.8'
|
|
271
|
+
|
|
272
|
+
services:
|
|
273
|
+
app:
|
|
274
|
+
build: .
|
|
275
|
+
ports:
|
|
276
|
+
- '3000:3000'
|
|
277
|
+
environment:
|
|
278
|
+
- DATABASE_URL=postgres://user:pass@db:5432/app
|
|
279
|
+
- REDIS_URL=redis://cache:6379
|
|
280
|
+
depends_on:
|
|
281
|
+
db:
|
|
282
|
+
condition: service_healthy
|
|
283
|
+
cache:
|
|
284
|
+
condition: service_started
|
|
285
|
+
healthcheck:
|
|
286
|
+
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
|
|
287
|
+
interval: 30s
|
|
288
|
+
timeout: 10s
|
|
289
|
+
retries: 3
|
|
290
|
+
|
|
291
|
+
db:
|
|
292
|
+
image: postgres:16-alpine
|
|
293
|
+
volumes:
|
|
294
|
+
- postgres_data:/var/lib/postgresql/data
|
|
295
|
+
environment:
|
|
296
|
+
- POSTGRES_USER=user
|
|
297
|
+
- POSTGRES_PASSWORD=pass
|
|
298
|
+
- POSTGRES_DB=app
|
|
299
|
+
healthcheck:
|
|
300
|
+
test: ['CMD-SHELL', 'pg_isready -U user -d app']
|
|
301
|
+
interval: 5s
|
|
302
|
+
timeout: 5s
|
|
303
|
+
retries: 5
|
|
304
|
+
|
|
305
|
+
cache:
|
|
306
|
+
image: redis:7-alpine
|
|
307
|
+
volumes:
|
|
308
|
+
- redis_data:/data
|
|
309
|
+
|
|
310
|
+
volumes:
|
|
311
|
+
postgres_data:
|
|
312
|
+
redis_data:
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Kubernetes Deployment
|
|
316
|
+
|
|
317
|
+
```yaml
|
|
318
|
+
# k8s/deployment.yaml
|
|
319
|
+
apiVersion: apps/v1
|
|
320
|
+
kind: Deployment
|
|
321
|
+
metadata:
|
|
322
|
+
name: app
|
|
323
|
+
labels:
|
|
324
|
+
app: app
|
|
325
|
+
spec:
|
|
326
|
+
replicas: 3
|
|
327
|
+
selector:
|
|
328
|
+
matchLabels:
|
|
329
|
+
app: app
|
|
330
|
+
template:
|
|
331
|
+
metadata:
|
|
332
|
+
labels:
|
|
333
|
+
app: app
|
|
334
|
+
spec:
|
|
335
|
+
containers:
|
|
336
|
+
- name: app
|
|
337
|
+
image: ghcr.io/org/app:latest
|
|
338
|
+
ports:
|
|
339
|
+
- containerPort: 3000
|
|
340
|
+
resources:
|
|
341
|
+
requests:
|
|
342
|
+
memory: '256Mi'
|
|
343
|
+
cpu: '100m'
|
|
344
|
+
limits:
|
|
345
|
+
memory: '512Mi'
|
|
346
|
+
cpu: '500m'
|
|
347
|
+
livenessProbe:
|
|
348
|
+
httpGet:
|
|
349
|
+
path: /health
|
|
350
|
+
port: 3000
|
|
351
|
+
initialDelaySeconds: 30
|
|
352
|
+
periodSeconds: 10
|
|
353
|
+
readinessProbe:
|
|
354
|
+
httpGet:
|
|
355
|
+
path: /ready
|
|
356
|
+
port: 3000
|
|
357
|
+
initialDelaySeconds: 5
|
|
358
|
+
periodSeconds: 5
|
|
359
|
+
env:
|
|
360
|
+
- name: DATABASE_URL
|
|
361
|
+
valueFrom:
|
|
362
|
+
secretKeyRef:
|
|
363
|
+
name: app-secrets
|
|
364
|
+
key: database-url
|
|
365
|
+
---
|
|
366
|
+
apiVersion: v1
|
|
367
|
+
kind: Service
|
|
368
|
+
metadata:
|
|
369
|
+
name: app
|
|
370
|
+
spec:
|
|
371
|
+
selector:
|
|
372
|
+
app: app
|
|
373
|
+
ports:
|
|
374
|
+
- port: 80
|
|
375
|
+
targetPort: 3000
|
|
376
|
+
type: ClusterIP
|
|
377
|
+
---
|
|
378
|
+
apiVersion: networking.k8s.io/v1
|
|
379
|
+
kind: Ingress
|
|
380
|
+
metadata:
|
|
381
|
+
name: app
|
|
382
|
+
annotations:
|
|
383
|
+
kubernetes.io/ingress.class: nginx
|
|
384
|
+
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
385
|
+
spec:
|
|
386
|
+
tls:
|
|
387
|
+
- hosts:
|
|
388
|
+
- app.example.com
|
|
389
|
+
secretName: app-tls
|
|
390
|
+
rules:
|
|
391
|
+
- host: app.example.com
|
|
392
|
+
http:
|
|
393
|
+
paths:
|
|
394
|
+
- path: /
|
|
395
|
+
pathType: Prefix
|
|
396
|
+
backend:
|
|
397
|
+
service:
|
|
398
|
+
name: app
|
|
399
|
+
port:
|
|
400
|
+
number: 80
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Best Practices
|
|
404
|
+
|
|
405
|
+
1. **Fast Feedback**: Run linting and unit tests first
|
|
406
|
+
2. **Parallel Jobs**: Run independent jobs in parallel
|
|
407
|
+
3. **Caching**: Cache dependencies and Docker layers
|
|
408
|
+
4. **Security**: Scan for vulnerabilities before deployment
|
|
409
|
+
5. **Environment Gates**: Use environment protection rules
|
|
410
|
+
6. **Rollback Plan**: Tag releases for easy rollback
|