feng3d-cli 0.0.2 → 0.0.4
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 +15 -0
- package/README.md +0 -2
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +9 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/oss.d.ts.map +1 -1
- package/dist/commands/oss.js +26 -1
- package/dist/commands/oss.js.map +1 -1
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +442 -24
- package/dist/commands/update.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/templates.d.ts +56 -3
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +95 -7
- package/dist/templates.js.map +1 -1
- package/dist/types/config.d.ts +111 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +50 -0
- package/dist/types/config.js.map +1 -0
- package/dist/versions.d.ts +2 -0
- package/dist/versions.d.ts.map +1 -1
- package/dist/versions.js +6 -0
- package/dist/versions.js.map +1 -1
- package/package.json +81 -64
- package/schemas/feng3d.schema.json +191 -0
- package/templates/.cursorrules +97 -17
- package/templates/.github/workflows/pages.yml +93 -0
- package/templates/.github/workflows/publish.yml +128 -0
- package/templates/.github/workflows/pull-request.yml +36 -0
- package/templates/.husky/pre-commit +2 -0
- package/templates/.vscode/settings.json +10 -0
- package/templates/LICENSE +15 -0
- package/templates/eslint.config.js +116 -65
- package/templates/feng3d.json +42 -0
- package/templates/gitignore +23 -0
- package/templates/test/_.test.ts +5 -0
- package/templates/tsconfig.json +14 -13
- package/templates/typedoc.json +2 -2
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "feng3d.schema.json",
|
|
4
|
+
"title": "feng3d 项目配置",
|
|
5
|
+
"description": "feng3d 项目配置文件,用于自定义项目规范和 CLI 行为",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"$schema": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "JSON Schema 引用"
|
|
11
|
+
},
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "项目名称"
|
|
15
|
+
},
|
|
16
|
+
"eslint": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"description": "ESLint 配置选项",
|
|
19
|
+
"properties": {
|
|
20
|
+
"enabled": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "是否启用 ESLint",
|
|
23
|
+
"default": true
|
|
24
|
+
},
|
|
25
|
+
"ignores": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"items": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
"description": "额外需要忽略的目录",
|
|
31
|
+
"default": []
|
|
32
|
+
},
|
|
33
|
+
"rules": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"description": "额外的规则覆盖",
|
|
36
|
+
"additionalProperties": true,
|
|
37
|
+
"default": {}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"additionalProperties": false
|
|
41
|
+
},
|
|
42
|
+
"vitest": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"description": "Vitest 测试配置选项",
|
|
45
|
+
"properties": {
|
|
46
|
+
"enabled": {
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"description": "是否启用 vitest",
|
|
49
|
+
"default": true
|
|
50
|
+
},
|
|
51
|
+
"testTimeout": {
|
|
52
|
+
"type": "number",
|
|
53
|
+
"description": "测试超时时间(毫秒,0 表示无限制)",
|
|
54
|
+
"default": 0,
|
|
55
|
+
"minimum": 0
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"additionalProperties": false
|
|
59
|
+
},
|
|
60
|
+
"typedoc": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"description": "TypeDoc 文档配置选项",
|
|
63
|
+
"properties": {
|
|
64
|
+
"enabled": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"description": "是否启用 typedoc",
|
|
67
|
+
"default": true
|
|
68
|
+
},
|
|
69
|
+
"outDir": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"description": "文档输出目录",
|
|
72
|
+
"default": "public/docs"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"additionalProperties": false
|
|
76
|
+
},
|
|
77
|
+
"oss": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"description": "OSS 上传配置",
|
|
80
|
+
"properties": {
|
|
81
|
+
"localDir": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "本地目录",
|
|
84
|
+
"default": "./public"
|
|
85
|
+
},
|
|
86
|
+
"ossDir": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"description": "OSS 目录(默认使用 package.json 的 name)",
|
|
89
|
+
"default": ""
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"additionalProperties": false
|
|
93
|
+
},
|
|
94
|
+
"templates": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"description": "项目模板选项",
|
|
97
|
+
"properties": {
|
|
98
|
+
"examples": {
|
|
99
|
+
"type": "boolean",
|
|
100
|
+
"description": "是否创建示例目录",
|
|
101
|
+
"default": true
|
|
102
|
+
},
|
|
103
|
+
"test": {
|
|
104
|
+
"type": "boolean",
|
|
105
|
+
"description": "是否创建测试目录",
|
|
106
|
+
"default": true
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"additionalProperties": false
|
|
110
|
+
},
|
|
111
|
+
"update": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"description": "更新配置(指定 feng3d-cli update 时默认更新哪些项目)",
|
|
114
|
+
"properties": {
|
|
115
|
+
"config": {
|
|
116
|
+
"type": "boolean",
|
|
117
|
+
"description": "是否更新 feng3d.json 配置",
|
|
118
|
+
"default": true
|
|
119
|
+
},
|
|
120
|
+
"eslint": {
|
|
121
|
+
"type": "boolean",
|
|
122
|
+
"description": "是否更新 ESLint 配置",
|
|
123
|
+
"default": true
|
|
124
|
+
},
|
|
125
|
+
"gitignore": {
|
|
126
|
+
"type": "boolean",
|
|
127
|
+
"description": "是否更新 .gitignore",
|
|
128
|
+
"default": true
|
|
129
|
+
},
|
|
130
|
+
"cursorrules": {
|
|
131
|
+
"type": "boolean",
|
|
132
|
+
"description": "是否更新 .cursorrules",
|
|
133
|
+
"default": true
|
|
134
|
+
},
|
|
135
|
+
"publish": {
|
|
136
|
+
"type": "boolean",
|
|
137
|
+
"description": "是否更新 npm publish workflow",
|
|
138
|
+
"default": true
|
|
139
|
+
},
|
|
140
|
+
"pages": {
|
|
141
|
+
"type": "boolean",
|
|
142
|
+
"description": "是否更新 GitHub Pages workflow",
|
|
143
|
+
"default": true
|
|
144
|
+
},
|
|
145
|
+
"pullRequest": {
|
|
146
|
+
"type": "boolean",
|
|
147
|
+
"description": "是否更新 Pull Request CI workflow",
|
|
148
|
+
"default": true
|
|
149
|
+
},
|
|
150
|
+
"typedoc": {
|
|
151
|
+
"type": "boolean",
|
|
152
|
+
"description": "是否更新 typedoc.json",
|
|
153
|
+
"default": true
|
|
154
|
+
},
|
|
155
|
+
"test": {
|
|
156
|
+
"type": "boolean",
|
|
157
|
+
"description": "是否更新 test/_.test.ts",
|
|
158
|
+
"default": true
|
|
159
|
+
},
|
|
160
|
+
"deps": {
|
|
161
|
+
"type": "boolean",
|
|
162
|
+
"description": "是否更新依赖版本",
|
|
163
|
+
"default": true
|
|
164
|
+
},
|
|
165
|
+
"husky": {
|
|
166
|
+
"type": "boolean",
|
|
167
|
+
"description": "是否更新 husky pre-commit hook",
|
|
168
|
+
"default": true
|
|
169
|
+
},
|
|
170
|
+
"license": {
|
|
171
|
+
"type": "boolean",
|
|
172
|
+
"description": "是否更新 LICENSE 文件",
|
|
173
|
+
"default": true
|
|
174
|
+
},
|
|
175
|
+
"vscode": {
|
|
176
|
+
"type": "boolean",
|
|
177
|
+
"description": "是否更新 .vscode/settings.json",
|
|
178
|
+
"default": true
|
|
179
|
+
},
|
|
180
|
+
"tsconfig": {
|
|
181
|
+
"type": "boolean",
|
|
182
|
+
"description": "是否更新 tsconfig.json",
|
|
183
|
+
"default": true
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"additionalProperties": false
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"additionalProperties": false
|
|
190
|
+
}
|
|
191
|
+
|
package/templates/.cursorrules
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
2. **格式**:遵循约定式提交(Conventional Commits)格式
|
|
10
10
|
```
|
|
11
11
|
<类型>(<范围>): <简短描述>
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
[可选的详细说明]
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
[可选的脚注]
|
|
16
16
|
```
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
- `feat`: 新增功能
|
|
20
20
|
- `fix`: 修复问题
|
|
21
21
|
- `refactor`: 代码重构(不改变功能)
|
|
22
|
-
- `perf`:
|
|
22
|
+
- `perf`: 性能优化(图形渲染项目重点关注)
|
|
23
23
|
- `style`: 代码格式调整(不影响代码含义)
|
|
24
24
|
- `docs`: 文档更新
|
|
25
25
|
- `test`: 测试相关
|
|
@@ -27,19 +27,37 @@
|
|
|
27
27
|
- `build`: 构建系统或外部依赖项的更改
|
|
28
28
|
- `ci`: CI 配置文件和脚本的更改
|
|
29
29
|
|
|
30
|
-
4.
|
|
30
|
+
4. **范围**(可选):可以是模块、组件或功能区域,如 `webgl`、`webgpu`、`test` 等
|
|
31
31
|
|
|
32
32
|
5. **提交信息要求**:
|
|
33
33
|
- 第一行简短描述,不超过 50 个字符
|
|
34
34
|
- 使用祈使句,如"添加"、"修复"、"优化"
|
|
35
35
|
- 描述要清晰、具体、有意义
|
|
36
|
+
- 如有必要,添加详细说明,解释"为什么"而不是"是什么"
|
|
37
|
+
- 性能优化提交应说明优化点和预期效果
|
|
38
|
+
|
|
39
|
+
6. **示例**:
|
|
40
|
+
```
|
|
41
|
+
feat(webgl): 添加深度测试功能
|
|
42
|
+
|
|
43
|
+
- 实现深度缓冲区管理
|
|
44
|
+
- 添加深度测试配置选项
|
|
45
|
+
- 更新相关文档
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
perf(webgpu): 优化纹理上传性能
|
|
50
|
+
|
|
51
|
+
- 使用批量上传减少 GPU 调用次数
|
|
52
|
+
- 预期性能提升 30%
|
|
53
|
+
```
|
|
36
54
|
|
|
37
55
|
## 代码风格
|
|
38
56
|
|
|
39
57
|
- 优先使用 TypeScript
|
|
40
58
|
- 遵循现有代码的命名约定和格式
|
|
41
59
|
- 添加必要的中文注释以提高代码可读性
|
|
42
|
-
- 使用 ESLint 保持代码格式一致
|
|
60
|
+
- 使用 ESLint 和 Prettier 保持代码格式一致
|
|
43
61
|
- 提交前必须通过 lint 检查
|
|
44
62
|
- 避免使用 `any` 类型,优先使用明确的类型定义
|
|
45
63
|
|
|
@@ -48,7 +66,7 @@
|
|
|
48
66
|
- **变量和函数**:使用驼峰命名(camelCase)
|
|
49
67
|
- **类和接口**:使用帕斯卡命名(PascalCase)
|
|
50
68
|
- **常量**:使用全大写下划线分隔(UPPER_SNAKE_CASE)
|
|
51
|
-
- **文件名**:使用小写字母和连字符(kebab-case
|
|
69
|
+
- **文件名**:使用小写字母和连字符(kebab-case)或与导出的主要类/函数同名,优先使用函数名
|
|
52
70
|
|
|
53
71
|
## 注释规范
|
|
54
72
|
|
|
@@ -57,23 +75,85 @@
|
|
|
57
75
|
- 临时解决方案或待优化代码必须添加 TODO 注释
|
|
58
76
|
- 注释应该解释"为什么"而不是"是什么"
|
|
59
77
|
|
|
60
|
-
##
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
78
|
+
## 代码组织结构
|
|
79
|
+
|
|
80
|
+
- **配置文件结构**:在配置文件中(如 `vite.config.js`、`test_vite.config.js` 等),应按照以下顺序组织代码:
|
|
81
|
+
- **文件头部**:导入语句、配置变量(可更改的设置)、主要执行逻辑(如 `export default defineConfig()`)
|
|
82
|
+
- 其次是导出函数以及类应该放在文件前面
|
|
83
|
+
- 再其次是私有函数和类应该放在文件后面
|
|
84
|
+
- **文件尾部**:函数定义(所有辅助函数和工具函数)
|
|
85
|
+
|
|
86
|
+
这样可以让配置文件的主要配置和执行逻辑一目了然,而将实现细节放在后面。
|
|
87
|
+
|
|
88
|
+
- **模块结构**:
|
|
89
|
+
- 避免使用默认导出,优先使用命名导出
|
|
90
|
+
- 避免不必要的导出
|
|
91
|
+
- 每个文件应该有一个明确的职责
|
|
92
|
+
- 每个文件应该不超过 300 行代码
|
|
93
|
+
- 相关功能应该组织在同一个目录下
|
|
94
|
+
- 使用清晰的目录结构(如 `src/utils/`、`src/types/` 等)
|
|
95
|
+
- 每个模块应该有清晰的职责边界
|
|
96
|
+
- 模块间依赖应该明确且最小化
|
|
97
|
+
- 公共 API 应该稳定,变更需要充分讨论
|
|
98
|
+
|
|
99
|
+
- **渲染相关代码**:
|
|
100
|
+
- Shader 代码应单独文件管理
|
|
101
|
+
- 渲染管线相关代码应组织在专门的目录
|
|
102
|
+
- 资源管理代码应与渲染逻辑分离
|
|
103
|
+
|
|
104
|
+
## 性能优化规范
|
|
105
|
+
|
|
106
|
+
- **内存管理**:
|
|
107
|
+
- 及时释放 GPU 资源(纹理、缓冲区等)
|
|
108
|
+
- 避免内存泄漏,特别是在渲染循环中
|
|
109
|
+
- 使用对象池复用频繁创建的对象
|
|
110
|
+
|
|
111
|
+
- **渲染优化**:
|
|
112
|
+
- 减少 draw call 数量
|
|
113
|
+
- 合理使用批处理(batching)
|
|
114
|
+
- 避免在渲染循环中进行不必要的计算
|
|
115
|
+
- 使用缓存避免重复计算
|
|
116
|
+
|
|
117
|
+
- **类型安全**:
|
|
118
|
+
- 避免使用 `any` 类型
|
|
119
|
+
- 为 GPU 资源提供明确的类型定义
|
|
120
|
+
- 使用类型守卫确保运行时类型安全
|
|
121
|
+
|
|
122
|
+
## 错误处理
|
|
123
|
+
|
|
124
|
+
- 优先使用明确的错误类型
|
|
125
|
+
- 提供有意义的错误消息
|
|
126
|
+
- 避免静默失败,除非有明确的业务需求
|
|
127
|
+
|
|
128
|
+
## 代码审查规范
|
|
129
|
+
|
|
130
|
+
- 所有代码变更必须经过代码审查
|
|
131
|
+
- 审查重点:
|
|
132
|
+
- 代码逻辑正确性
|
|
133
|
+
- 性能影响
|
|
134
|
+
- 类型安全
|
|
135
|
+
- 测试覆盖
|
|
136
|
+
- 文档完整性
|
|
137
|
+
|
|
138
|
+
## 文档规范
|
|
139
|
+
|
|
140
|
+
- 公共 API 必须包含完整的 JSDoc 注释
|
|
141
|
+
- 复杂算法或业务逻辑必须添加说明文档
|
|
142
|
+
- README 文件应该保持更新
|
|
143
|
+
- 重大变更应该更新 CHANGELOG
|
|
66
144
|
|
|
67
145
|
## 测试规范
|
|
68
146
|
|
|
69
147
|
- 新功能必须包含相应的测试
|
|
70
148
|
- 修复 bug 时必须添加回归测试
|
|
149
|
+
- 关键渲染功能必须包含测试
|
|
150
|
+
- 性能关键路径应包含性能测试
|
|
151
|
+
- 使用 WebGL/WebGPU 测试框架进行渲染测试
|
|
71
152
|
- 测试覆盖率应该保持在合理水平(建议 > 80%)
|
|
72
153
|
- 测试应该清晰、独立、可重复
|
|
73
154
|
|
|
74
|
-
##
|
|
75
|
-
|
|
76
|
-
- 没有正确修复问题时重新修复时,尽量还原上次修改的内容后再进行修复
|
|
77
|
-
- 每次完成代码修改后,必须检查并处理编译错误
|
|
78
|
-
- 确保所有测试通过后再告知用户任务完成
|
|
155
|
+
## agent 规则
|
|
79
156
|
|
|
157
|
+
- 没有正确修复问题时重新让修复时,尽量还原上次修改的内容后再进行修复
|
|
158
|
+
- 每次完成代码修改后,必须检查并处理编译错误(使用 ReadLints 工具或运行测试)
|
|
159
|
+
- 确保所有测试通过后再告知用户任务完成
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# 将文档发布到 GitHub Pages
|
|
2
|
+
# 仅在主分支版本号发生变化时触发部署
|
|
3
|
+
name: Deploy to GitHub Pages
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- master
|
|
9
|
+
- main
|
|
10
|
+
paths:
|
|
11
|
+
- 'package.json' # 仅在 package.json 变化时触发
|
|
12
|
+
workflow_dispatch: # 支持手动触发
|
|
13
|
+
|
|
14
|
+
# 设置 GITHUB_TOKEN 的权限
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pages: write
|
|
18
|
+
id-token: write
|
|
19
|
+
|
|
20
|
+
# 只允许一个并发部署
|
|
21
|
+
concurrency:
|
|
22
|
+
group: "pages"
|
|
23
|
+
cancel-in-progress: true
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
# 检查版本号是否变化
|
|
27
|
+
check-version:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
outputs:
|
|
30
|
+
version_changed: ${{ steps.check.outputs.changed }}
|
|
31
|
+
steps:
|
|
32
|
+
- name: Checkout
|
|
33
|
+
uses: actions/checkout@v4
|
|
34
|
+
with:
|
|
35
|
+
fetch-depth: 2 # 获取最近两次提交以比较版本
|
|
36
|
+
|
|
37
|
+
- name: Check if version changed
|
|
38
|
+
id: check
|
|
39
|
+
run: |
|
|
40
|
+
# 获取当前版本
|
|
41
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
42
|
+
# 获取上一次提交的版本
|
|
43
|
+
git checkout HEAD~1 -- package.json 2>/dev/null || echo "First commit"
|
|
44
|
+
PREVIOUS_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "0.0.0")
|
|
45
|
+
git checkout HEAD -- package.json
|
|
46
|
+
|
|
47
|
+
if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
|
|
48
|
+
echo "Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
|
|
49
|
+
echo "changed=true" >> $GITHUB_OUTPUT
|
|
50
|
+
else
|
|
51
|
+
echo "Version unchanged: $CURRENT_VERSION"
|
|
52
|
+
echo "changed=false" >> $GITHUB_OUTPUT
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
build:
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
needs: check-version
|
|
58
|
+
# 仅在版本号变化或手动触发时构建
|
|
59
|
+
if: needs.check-version.outputs.version_changed == 'true' || github.event_name == 'workflow_dispatch'
|
|
60
|
+
steps:
|
|
61
|
+
- name: Checkout
|
|
62
|
+
uses: actions/checkout@v4
|
|
63
|
+
|
|
64
|
+
- name: Setup Node.js
|
|
65
|
+
uses: actions/setup-node@v4
|
|
66
|
+
with:
|
|
67
|
+
node-version: '20'
|
|
68
|
+
|
|
69
|
+
- name: Install dependencies
|
|
70
|
+
run: npm install
|
|
71
|
+
|
|
72
|
+
- name: Build docs
|
|
73
|
+
run: npm run docs
|
|
74
|
+
|
|
75
|
+
- name: Setup Pages
|
|
76
|
+
uses: actions/configure-pages@v4
|
|
77
|
+
|
|
78
|
+
- name: Upload artifact
|
|
79
|
+
uses: actions/upload-pages-artifact@v3
|
|
80
|
+
with:
|
|
81
|
+
path: './public'
|
|
82
|
+
|
|
83
|
+
deploy:
|
|
84
|
+
environment:
|
|
85
|
+
name: github-pages
|
|
86
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
needs: build
|
|
89
|
+
steps:
|
|
90
|
+
- name: Deploy to GitHub Pages
|
|
91
|
+
id: deployment
|
|
92
|
+
uses: actions/deploy-pages@v4
|
|
93
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# 当 package.json 中的版本在 npm 不存在时自动发布
|
|
2
|
+
name: Publish to NPM
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
- main
|
|
9
|
+
workflow_dispatch: # 支持手动触发
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
check-version:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
outputs:
|
|
15
|
+
should_publish: ${{ steps.check.outputs.should_publish }}
|
|
16
|
+
version: ${{ steps.check.outputs.version }}
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Check if version exists on npm
|
|
22
|
+
id: check
|
|
23
|
+
run: |
|
|
24
|
+
# 获取包名和当前版本
|
|
25
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
26
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
27
|
+
echo "Package: $PACKAGE_NAME"
|
|
28
|
+
echo "Current version: $CURRENT_VERSION"
|
|
29
|
+
|
|
30
|
+
# 检查该版本是否已在 npm 上存在
|
|
31
|
+
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/$PACKAGE_NAME/$CURRENT_VERSION")
|
|
32
|
+
|
|
33
|
+
if [ "$HTTP_STATUS" = "404" ]; then
|
|
34
|
+
echo "Version $CURRENT_VERSION not found on npm, will publish"
|
|
35
|
+
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
36
|
+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
37
|
+
else
|
|
38
|
+
echo "Version $CURRENT_VERSION already exists on npm (HTTP $HTTP_STATUS)"
|
|
39
|
+
echo "should_publish=false" >> $GITHUB_OUTPUT
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
publish:
|
|
43
|
+
needs: check-version
|
|
44
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- name: Checkout
|
|
48
|
+
uses: actions/checkout@v4
|
|
49
|
+
with:
|
|
50
|
+
fetch-depth: 0 # 获取完整历史以生成更新日志
|
|
51
|
+
|
|
52
|
+
- name: Setup Node.js
|
|
53
|
+
uses: actions/setup-node@v4
|
|
54
|
+
with:
|
|
55
|
+
node-version: '20'
|
|
56
|
+
registry-url: 'https://registry.npmjs.org'
|
|
57
|
+
|
|
58
|
+
- name: Install dependencies
|
|
59
|
+
run: npm install
|
|
60
|
+
|
|
61
|
+
- name: Build
|
|
62
|
+
run: npm run build
|
|
63
|
+
|
|
64
|
+
- name: Run lint
|
|
65
|
+
run: npm run lint
|
|
66
|
+
|
|
67
|
+
- name: Run tests
|
|
68
|
+
run: npm test
|
|
69
|
+
|
|
70
|
+
- name: Publish to NPM
|
|
71
|
+
run: npm publish
|
|
72
|
+
env:
|
|
73
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
74
|
+
|
|
75
|
+
- name: Create Git Tag
|
|
76
|
+
run: |
|
|
77
|
+
VERSION=${{ needs.check-version.outputs.version }}
|
|
78
|
+
git config user.name "github-actions[bot]"
|
|
79
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
80
|
+
git tag -a "v$VERSION" -m "Release v$VERSION"
|
|
81
|
+
git push origin "v$VERSION"
|
|
82
|
+
env:
|
|
83
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
84
|
+
|
|
85
|
+
- name: Generate Release Notes
|
|
86
|
+
id: release_notes
|
|
87
|
+
run: |
|
|
88
|
+
VERSION=${{ needs.check-version.outputs.version }}
|
|
89
|
+
|
|
90
|
+
# 获取上一个版本的 tag
|
|
91
|
+
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
92
|
+
|
|
93
|
+
echo "Previous tag: $PREVIOUS_TAG"
|
|
94
|
+
|
|
95
|
+
# 生成更新日志
|
|
96
|
+
if [ -n "$PREVIOUS_TAG" ]; then
|
|
97
|
+
echo "## 更新内容" > release_notes.md
|
|
98
|
+
echo "" >> release_notes.md
|
|
99
|
+
echo "与 $PREVIOUS_TAG 相比的变更:" >> release_notes.md
|
|
100
|
+
echo "" >> release_notes.md
|
|
101
|
+
|
|
102
|
+
# 获取提交日志
|
|
103
|
+
git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..HEAD >> release_notes.md
|
|
104
|
+
else
|
|
105
|
+
echo "## 更新内容" > release_notes.md
|
|
106
|
+
echo "" >> release_notes.md
|
|
107
|
+
echo "首次发布" >> release_notes.md
|
|
108
|
+
echo "" >> release_notes.md
|
|
109
|
+
|
|
110
|
+
# 获取所有提交日志
|
|
111
|
+
git log --pretty=format:"- %s (%h)" >> release_notes.md
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
echo "" >> release_notes.md
|
|
115
|
+
|
|
116
|
+
# 输出生成的内容
|
|
117
|
+
echo "Generated release notes:"
|
|
118
|
+
cat release_notes.md
|
|
119
|
+
|
|
120
|
+
- name: Create GitHub Release
|
|
121
|
+
uses: softprops/action-gh-release@v1
|
|
122
|
+
with:
|
|
123
|
+
tag_name: v${{ needs.check-version.outputs.version }}
|
|
124
|
+
name: Release v${{ needs.check-version.outputs.version }}
|
|
125
|
+
body_path: release_notes.md
|
|
126
|
+
env:
|
|
127
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
128
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# CI - 运行单元测试
|
|
2
|
+
# 在合并到主分支或在主分支提交代码时执行
|
|
3
|
+
name: CI
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- master
|
|
9
|
+
- main
|
|
10
|
+
pull_request:
|
|
11
|
+
branches:
|
|
12
|
+
- master
|
|
13
|
+
- main
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Setup Node.js
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: '20'
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Run lint
|
|
32
|
+
run: npm run lint
|
|
33
|
+
|
|
34
|
+
- name: Run unit tests
|
|
35
|
+
run: npm test
|
|
36
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// 将设置放入此文件中以覆盖默认值和用户设置。
|
|
2
|
+
{
|
|
3
|
+
// 定义函数的左大括号是否放置在新的一行。
|
|
4
|
+
"typescript.format.placeOpenBraceOnNewLineForFunctions": true,
|
|
5
|
+
// 定义控制块的左括号是否放置在新的一行。
|
|
6
|
+
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
|
|
7
|
+
"javascript.format.placeOpenBraceOnNewLineForFunctions": true,
|
|
8
|
+
"javascript.format.placeOpenBraceOnNewLineForControlBlocks": true
|
|
9
|
+
}
|
|
10
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MIT 许可证
|
|
2
|
+
|
|
3
|
+
版权所有 (c) {{year}} feng
|
|
4
|
+
|
|
5
|
+
特此授予任何获得本软件及相关文档文件("软件")副本的人免费许可,
|
|
6
|
+
可以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、
|
|
7
|
+
发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的
|
|
8
|
+
人这样做,但须符合以下条件:
|
|
9
|
+
|
|
10
|
+
上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
|
|
11
|
+
|
|
12
|
+
本软件按"原样"提供,不提供任何明示或暗示的保证,包括但不限于对
|
|
13
|
+
适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权
|
|
14
|
+
持有人均不对因本软件或本软件的使用或其他交易而产生的任何索赔、
|
|
15
|
+
损害或其他责任负责,无论是在合同诉讼、侵权诉讼还是其他诉讼中。
|