clouddreamai-cicd-setup 1.0.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/README.md +189 -0
- package/bin/cicd-setup.js +3 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +187 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/gitlab-client.d.ts +80 -0
- package/dist/core/gitlab-client.d.ts.map +1 -0
- package/dist/core/gitlab-client.js +252 -0
- package/dist/core/gitlab-client.js.map +1 -0
- package/dist/core/types.d.ts +152 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/variables.d.ts +50 -0
- package/dist/core/variables.d.ts.map +1 -0
- package/dist/core/variables.js +243 -0
- package/dist/core/variables.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/prompts.d.ts +47 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +369 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/template.d.ts +50 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +189 -0
- package/dist/utils/template.js.map +1 -0
- package/package.json +50 -0
- package/templates/gitlab-ci/nestjs.yml +167 -0
- package/templates/gitlab-ci/vue.yml +167 -0
- package/templates/scripts/deploy.sh +141 -0
- package/templates/scripts/generate-env.sh +84 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CloudDreamAI CI/CD Setup - 交互式提示工具
|
|
4
|
+
* 使用 inquirer 实现用户交互
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.PromptCollector = void 0;
|
|
44
|
+
exports.createPromptCollector = createPromptCollector;
|
|
45
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
/**
|
|
48
|
+
* 交互式收集配置信息
|
|
49
|
+
*/
|
|
50
|
+
class PromptCollector {
|
|
51
|
+
/**
|
|
52
|
+
* 收集完整的 CI/CD 配置
|
|
53
|
+
*/
|
|
54
|
+
async collectConfig() {
|
|
55
|
+
console.log('\n🚀 CloudDreamAI CI/CD 自动配置工具\n');
|
|
56
|
+
// 1. GitLab 配置
|
|
57
|
+
const gitlabConfig = await this.collectGitLabConfig();
|
|
58
|
+
// 2. 项目配置
|
|
59
|
+
const projectConfig = await this.collectProjectConfig();
|
|
60
|
+
// 3. 服务器配置
|
|
61
|
+
const serverConfig = await this.collectServerConfig();
|
|
62
|
+
// 4. Docker Hub 配置
|
|
63
|
+
const dockerHubConfig = await this.collectDockerHubConfig();
|
|
64
|
+
// 5. SSH 私钥
|
|
65
|
+
const sshPrivateKey = await this.collectSSHKey();
|
|
66
|
+
// 6. 环境变量文件
|
|
67
|
+
const envFiles = await this.collectEnvFiles();
|
|
68
|
+
return {
|
|
69
|
+
gitlab: gitlabConfig,
|
|
70
|
+
project: projectConfig,
|
|
71
|
+
server: serverConfig,
|
|
72
|
+
dockerHub: dockerHubConfig,
|
|
73
|
+
sshPrivateKey,
|
|
74
|
+
...envFiles,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 收集 GitLab 配置
|
|
79
|
+
*/
|
|
80
|
+
async collectGitLabConfig() {
|
|
81
|
+
console.log('\n📦 GitLab 配置\n');
|
|
82
|
+
const answers = await inquirer_1.default.prompt([
|
|
83
|
+
{
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'baseUrl',
|
|
86
|
+
message: 'GitLab 实例 URL:',
|
|
87
|
+
default: 'https://gitlab.clouddreamai.com',
|
|
88
|
+
validate: (input) => {
|
|
89
|
+
if (!input)
|
|
90
|
+
return '请输入 GitLab URL';
|
|
91
|
+
if (!input.startsWith('http')) {
|
|
92
|
+
return 'URL 必须以 http:// 或 https:// 开头';
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
type: 'password',
|
|
99
|
+
name: 'token',
|
|
100
|
+
message: 'GitLab Personal Access Token:',
|
|
101
|
+
validate: (input) => (input ? true : '请输入 Access Token'),
|
|
102
|
+
},
|
|
103
|
+
]);
|
|
104
|
+
return answers;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 收集项目配置
|
|
108
|
+
*/
|
|
109
|
+
async collectProjectConfig() {
|
|
110
|
+
console.log('\n🔧 项目配置\n');
|
|
111
|
+
const answers = await inquirer_1.default.prompt([
|
|
112
|
+
{
|
|
113
|
+
type: 'input',
|
|
114
|
+
name: 'name',
|
|
115
|
+
message: '项目名称 (用于容器名称):',
|
|
116
|
+
validate: (input) => {
|
|
117
|
+
if (!input)
|
|
118
|
+
return '请输入项目名称';
|
|
119
|
+
if (!/^[a-z0-9-]+$/.test(input)) {
|
|
120
|
+
return '项目名称只能包含小写字母、数字和连字符';
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'list',
|
|
127
|
+
name: 'type',
|
|
128
|
+
message: '项目类型:',
|
|
129
|
+
choices: [
|
|
130
|
+
{ name: 'NestJS 后端', value: 'nestjs' },
|
|
131
|
+
{ name: 'Vue 前端', value: 'vue' },
|
|
132
|
+
{ name: 'React 前端', value: 'react' },
|
|
133
|
+
{ name: 'Node.js 通用', value: 'node' },
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'input',
|
|
138
|
+
name: 'dockerImage',
|
|
139
|
+
message: 'Docker Hub 镜像名称 (格式: username/image):',
|
|
140
|
+
validate: (input) => {
|
|
141
|
+
if (!input)
|
|
142
|
+
return '请输入镜像名称';
|
|
143
|
+
if (!input.includes('/')) {
|
|
144
|
+
return '格式错误,应为 username/image-name';
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'input',
|
|
151
|
+
name: 'deployDir',
|
|
152
|
+
message: '部署目录 (服务器上的绝对路径):',
|
|
153
|
+
default: (answers) => `/www/wwwroot/${answers.name}`,
|
|
154
|
+
validate: (input) => {
|
|
155
|
+
if (!input)
|
|
156
|
+
return '请输入部署目录';
|
|
157
|
+
if (!input.startsWith('/'))
|
|
158
|
+
return '必须是绝对路径';
|
|
159
|
+
return true;
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'number',
|
|
164
|
+
name: 'devPort',
|
|
165
|
+
message: '开发环境端口:',
|
|
166
|
+
default: 3000,
|
|
167
|
+
validate: (input) => {
|
|
168
|
+
const port = Number(input);
|
|
169
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
170
|
+
return '端口必须在 1-65535 之间';
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: 'number',
|
|
177
|
+
name: 'prodPort',
|
|
178
|
+
message: '生产环境端口:',
|
|
179
|
+
default: 3001,
|
|
180
|
+
validate: (input) => {
|
|
181
|
+
const port = Number(input);
|
|
182
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
183
|
+
return '端口必须在 1-65535 之间';
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'input',
|
|
190
|
+
name: 'devUrl',
|
|
191
|
+
message: '开发环境 URL (可选,回车跳过):',
|
|
192
|
+
default: '',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: 'input',
|
|
196
|
+
name: 'prodUrl',
|
|
197
|
+
message: '生产环境 URL (可选,回车跳过):',
|
|
198
|
+
default: '',
|
|
199
|
+
},
|
|
200
|
+
]);
|
|
201
|
+
return answers;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* 收集服务器配置
|
|
205
|
+
*/
|
|
206
|
+
async collectServerConfig() {
|
|
207
|
+
console.log('\n🖥️ 服务器配置\n');
|
|
208
|
+
const answers = await inquirer_1.default.prompt([
|
|
209
|
+
{
|
|
210
|
+
type: 'confirm',
|
|
211
|
+
name: 'singleServer',
|
|
212
|
+
message: '是否使用单服务器多环境模式?',
|
|
213
|
+
default: true,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
type: 'input',
|
|
217
|
+
name: 'testServerHost',
|
|
218
|
+
message: '测试/开发服务器地址 (IP 或域名):',
|
|
219
|
+
validate: (input) => (input ? true : '请输入服务器地址'),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
type: 'input',
|
|
223
|
+
name: 'prodServerHost',
|
|
224
|
+
message: '生产服务器地址 (单服务器模式请输入相同地址):',
|
|
225
|
+
default: (answers) => answers.singleServer ? answers.testServerHost : '',
|
|
226
|
+
validate: (input) => (input ? true : '请输入服务器地址'),
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
return answers;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 收集 Docker Hub 配置
|
|
233
|
+
*/
|
|
234
|
+
async collectDockerHubConfig() {
|
|
235
|
+
console.log('\n🐳 Docker Hub 配置\n');
|
|
236
|
+
const answers = await inquirer_1.default.prompt([
|
|
237
|
+
{
|
|
238
|
+
type: 'input',
|
|
239
|
+
name: 'username',
|
|
240
|
+
message: 'Docker Hub 用户名:',
|
|
241
|
+
validate: (input) => (input ? true : '请输入用户名'),
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
type: 'password',
|
|
245
|
+
name: 'password',
|
|
246
|
+
message: 'Docker Hub 密码或 Access Token:',
|
|
247
|
+
validate: (input) => (input ? true : '请输入密码'),
|
|
248
|
+
},
|
|
249
|
+
]);
|
|
250
|
+
return answers;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 收集 SSH 私钥
|
|
254
|
+
*/
|
|
255
|
+
async collectSSHKey() {
|
|
256
|
+
console.log('\n🔑 SSH 私钥配置\n');
|
|
257
|
+
const { method } = await inquirer_1.default.prompt([
|
|
258
|
+
{
|
|
259
|
+
type: 'list',
|
|
260
|
+
name: 'method',
|
|
261
|
+
message: '如何提供 SSH 私钥?',
|
|
262
|
+
choices: [
|
|
263
|
+
{ name: '从文件读取', value: 'file' },
|
|
264
|
+
{ name: '手动粘贴', value: 'paste' },
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
]);
|
|
268
|
+
if (method === 'file') {
|
|
269
|
+
const { filePath } = await inquirer_1.default.prompt([
|
|
270
|
+
{
|
|
271
|
+
type: 'input',
|
|
272
|
+
name: 'filePath',
|
|
273
|
+
message: 'SSH 私钥文件路径:',
|
|
274
|
+
default: '~/.ssh/id_rsa',
|
|
275
|
+
validate: (input) => {
|
|
276
|
+
const expandedPath = input.replace(/^~/, process.env.HOME || '~');
|
|
277
|
+
if (!fs.existsSync(expandedPath)) {
|
|
278
|
+
return '文件不存在';
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
]);
|
|
284
|
+
const expandedPath = filePath.replace(/^~/, process.env.HOME || '~');
|
|
285
|
+
return fs.readFileSync(expandedPath, 'utf-8');
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
const { key } = await inquirer_1.default.prompt([
|
|
289
|
+
{
|
|
290
|
+
type: 'editor',
|
|
291
|
+
name: 'key',
|
|
292
|
+
message: '请在编辑器中粘贴 SSH 私钥内容 (保存并关闭编辑器):',
|
|
293
|
+
validate: (input) => {
|
|
294
|
+
if (!input)
|
|
295
|
+
return '请提供 SSH 私钥';
|
|
296
|
+
if (!input.includes('PRIVATE KEY')) {
|
|
297
|
+
return 'SSH 私钥格式不正确';
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
]);
|
|
303
|
+
return key;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* 收集环境变量文件
|
|
308
|
+
*/
|
|
309
|
+
async collectEnvFiles() {
|
|
310
|
+
console.log('\n📄 环境变量文件配置\n');
|
|
311
|
+
const { includeEnvFiles } = await inquirer_1.default.prompt([
|
|
312
|
+
{
|
|
313
|
+
type: 'confirm',
|
|
314
|
+
name: 'includeEnvFiles',
|
|
315
|
+
message: '是否需要配置 .env 文件 (开发和生产环境)?',
|
|
316
|
+
default: true,
|
|
317
|
+
},
|
|
318
|
+
]);
|
|
319
|
+
if (!includeEnvFiles) {
|
|
320
|
+
return {};
|
|
321
|
+
}
|
|
322
|
+
const { method } = await inquirer_1.default.prompt([
|
|
323
|
+
{
|
|
324
|
+
type: 'list',
|
|
325
|
+
name: 'method',
|
|
326
|
+
message: '如何提供 .env 文件?',
|
|
327
|
+
choices: [
|
|
328
|
+
{ name: '从本地文件读取', value: 'file' },
|
|
329
|
+
{ name: '稍后手动配置', value: 'skip' },
|
|
330
|
+
],
|
|
331
|
+
},
|
|
332
|
+
]);
|
|
333
|
+
if (method === 'skip') {
|
|
334
|
+
console.log('\n⚠️ 跳过 .env 文件配置,请稍后在 GitLab CI/CD 变量中手动添加');
|
|
335
|
+
return {};
|
|
336
|
+
}
|
|
337
|
+
const devEnvFile = await this.readEnvFile('开发环境', '.env.dev');
|
|
338
|
+
const prodEnvFile = await this.readEnvFile('生产环境', '.env.prod');
|
|
339
|
+
return { devEnvFile, prodEnvFile };
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* 读取环境变量文件
|
|
343
|
+
*/
|
|
344
|
+
async readEnvFile(envName, defaultPath) {
|
|
345
|
+
const { filePath } = await inquirer_1.default.prompt([
|
|
346
|
+
{
|
|
347
|
+
type: 'input',
|
|
348
|
+
name: 'filePath',
|
|
349
|
+
message: `${envName} .env 文件路径 (回车跳过):`,
|
|
350
|
+
default: defaultPath,
|
|
351
|
+
},
|
|
352
|
+
]);
|
|
353
|
+
if (!filePath)
|
|
354
|
+
return undefined;
|
|
355
|
+
if (!fs.existsSync(filePath)) {
|
|
356
|
+
console.log(`⚠️ 文件 ${filePath} 不存在,跳过`);
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
exports.PromptCollector = PromptCollector;
|
|
363
|
+
/**
|
|
364
|
+
* 创建提示收集器实例
|
|
365
|
+
*/
|
|
366
|
+
function createPromptCollector() {
|
|
367
|
+
return new PromptCollector();
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudDreamAI CI/CD Setup - 模板生成器
|
|
3
|
+
* 负责读取模板文件并替换占位符生成最终文件
|
|
4
|
+
*/
|
|
5
|
+
import { ProjectConfig, ProjectType } from '../core/types';
|
|
6
|
+
/**
|
|
7
|
+
* 模板生成器
|
|
8
|
+
*/
|
|
9
|
+
export declare class TemplateGenerator {
|
|
10
|
+
private templatesDir;
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* 生成 .gitlab-ci.yml 文件内容
|
|
14
|
+
*/
|
|
15
|
+
generateGitLabCI(projectType: ProjectType, config: ProjectConfig, gitlabHost: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* 生成 deploy.sh 脚本内容
|
|
18
|
+
*/
|
|
19
|
+
generateDeployScript(config: ProjectConfig): string;
|
|
20
|
+
/**
|
|
21
|
+
* 生成 generate-env.sh 脚本内容
|
|
22
|
+
*/
|
|
23
|
+
generateEnvScript(config: ProjectConfig): string;
|
|
24
|
+
/**
|
|
25
|
+
* 生成所有文件到指定目录
|
|
26
|
+
*/
|
|
27
|
+
generateAll(outputDir: string, projectType: ProjectType, config: ProjectConfig, gitlabHost: string): {
|
|
28
|
+
success: boolean;
|
|
29
|
+
files: string[];
|
|
30
|
+
error?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 替换模板中的占位符
|
|
34
|
+
* 占位符格式:{{VARIABLE_NAME}}
|
|
35
|
+
*/
|
|
36
|
+
private replacePlaceholders;
|
|
37
|
+
/**
|
|
38
|
+
* 根据项目类型获取模板名称
|
|
39
|
+
*/
|
|
40
|
+
private getTemplateNameByType;
|
|
41
|
+
/**
|
|
42
|
+
* 根据项目类型获取 lint 命令
|
|
43
|
+
*/
|
|
44
|
+
private getLintCommand;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 创建模板生成器实例
|
|
48
|
+
*/
|
|
49
|
+
export declare function createTemplateGenerator(): TemplateGenerator;
|
|
50
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAqB,MAAM,eAAe,CAAC;AAE9E;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,YAAY,CAAS;;IAO7B;;OAEG;IACH,gBAAgB,CACd,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,GACjB,MAAM;IA6BT;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAcnD;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAehD;;OAEG;IACH,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,GACjB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAmDxD;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,OAAO,CAAC,cAAc;CAUvB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAE3D"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CloudDreamAI CI/CD Setup - 模板生成器
|
|
4
|
+
* 负责读取模板文件并替换占位符生成最终文件
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.TemplateGenerator = void 0;
|
|
41
|
+
exports.createTemplateGenerator = createTemplateGenerator;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
/**
|
|
45
|
+
* 模板生成器
|
|
46
|
+
*/
|
|
47
|
+
class TemplateGenerator {
|
|
48
|
+
constructor() {
|
|
49
|
+
// 模板文件目录(编译后在 dist/utils/,所以需要 ../../templates 到达项目根)
|
|
50
|
+
this.templatesDir = path.join(__dirname, '../../templates');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 生成 .gitlab-ci.yml 文件内容
|
|
54
|
+
*/
|
|
55
|
+
generateGitLabCI(projectType, config, gitlabHost) {
|
|
56
|
+
// 根据项目类型选择模板
|
|
57
|
+
const templateName = this.getTemplateNameByType(projectType);
|
|
58
|
+
const templatePath = path.join(this.templatesDir, 'gitlab-ci', `${templateName}.yml`);
|
|
59
|
+
// 读取模板
|
|
60
|
+
const template = fs.readFileSync(templatePath, 'utf-8');
|
|
61
|
+
// 准备替换变量
|
|
62
|
+
const variables = {
|
|
63
|
+
APP_NAME: config.name,
|
|
64
|
+
DOCKER_IMAGE: config.dockerImage,
|
|
65
|
+
DEPLOY_DIR: config.deployDir,
|
|
66
|
+
DEV_PORT: config.devPort.toString(),
|
|
67
|
+
PROD_PORT: config.prodPort.toString(),
|
|
68
|
+
DEV_URL: config.devUrl || `http://localhost:${config.devPort}`,
|
|
69
|
+
PROD_URL: config.prodUrl || `http://localhost:${config.prodPort}`,
|
|
70
|
+
GITLAB_HOST: gitlabHost.replace(/^https?:\/\//, ''),
|
|
71
|
+
LINT_COMMAND: this.getLintCommand(projectType),
|
|
72
|
+
};
|
|
73
|
+
// 替换占位符
|
|
74
|
+
return this.replacePlaceholders(template, variables);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 生成 deploy.sh 脚本内容
|
|
78
|
+
*/
|
|
79
|
+
generateDeployScript(config) {
|
|
80
|
+
const templatePath = path.join(this.templatesDir, 'scripts', 'deploy.sh');
|
|
81
|
+
const template = fs.readFileSync(templatePath, 'utf-8');
|
|
82
|
+
const variables = {
|
|
83
|
+
APP_NAME: config.name,
|
|
84
|
+
DEPLOY_DIR: config.deployDir,
|
|
85
|
+
DEV_PORT: config.devPort.toString(),
|
|
86
|
+
PROD_PORT: config.prodPort.toString(),
|
|
87
|
+
};
|
|
88
|
+
return this.replacePlaceholders(template, variables);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 生成 generate-env.sh 脚本内容
|
|
92
|
+
*/
|
|
93
|
+
generateEnvScript(config) {
|
|
94
|
+
const templatePath = path.join(this.templatesDir, 'scripts', 'generate-env.sh');
|
|
95
|
+
const template = fs.readFileSync(templatePath, 'utf-8');
|
|
96
|
+
const variables = {
|
|
97
|
+
APP_PORT: config.prodPort.toString(), // 默认使用生产端口
|
|
98
|
+
};
|
|
99
|
+
return this.replacePlaceholders(template, variables);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 生成所有文件到指定目录
|
|
103
|
+
*/
|
|
104
|
+
generateAll(outputDir, projectType, config, gitlabHost) {
|
|
105
|
+
try {
|
|
106
|
+
const files = [];
|
|
107
|
+
// 确保输出目录存在
|
|
108
|
+
if (!fs.existsSync(outputDir)) {
|
|
109
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
// 创建 ci 子目录
|
|
112
|
+
const ciDir = path.join(outputDir, 'ci');
|
|
113
|
+
if (!fs.existsSync(ciDir)) {
|
|
114
|
+
fs.mkdirSync(ciDir, { recursive: true });
|
|
115
|
+
}
|
|
116
|
+
// 生成 .gitlab-ci.yml
|
|
117
|
+
const gitlabCIContent = this.generateGitLabCI(projectType, config, gitlabHost);
|
|
118
|
+
const gitlabCIPath = path.join(outputDir, '.gitlab-ci.yml');
|
|
119
|
+
fs.writeFileSync(gitlabCIPath, gitlabCIContent, 'utf-8');
|
|
120
|
+
files.push(gitlabCIPath);
|
|
121
|
+
// 生成 ci/deploy.sh
|
|
122
|
+
const deployScriptContent = this.generateDeployScript(config);
|
|
123
|
+
const deployScriptPath = path.join(ciDir, 'deploy.sh');
|
|
124
|
+
fs.writeFileSync(deployScriptContent, deployScriptPath, 'utf-8');
|
|
125
|
+
// 添加执行权限
|
|
126
|
+
fs.chmodSync(deployScriptPath, '755');
|
|
127
|
+
files.push(deployScriptPath);
|
|
128
|
+
// 生成 ci/generate-env.sh
|
|
129
|
+
const envScriptContent = this.generateEnvScript(config);
|
|
130
|
+
const envScriptPath = path.join(ciDir, 'generate-env.sh');
|
|
131
|
+
fs.writeFileSync(envScriptContent, envScriptPath, 'utf-8');
|
|
132
|
+
// 添加执行权限
|
|
133
|
+
fs.chmodSync(envScriptPath, '755');
|
|
134
|
+
files.push(envScriptPath);
|
|
135
|
+
return { success: true, files };
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
files: [],
|
|
141
|
+
error: `生成文件失败: ${String(error)}`,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 替换模板中的占位符
|
|
147
|
+
* 占位符格式:{{VARIABLE_NAME}}
|
|
148
|
+
*/
|
|
149
|
+
replacePlaceholders(template, variables) {
|
|
150
|
+
let result = template;
|
|
151
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
152
|
+
const placeholder = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
|
|
153
|
+
result = result.replace(placeholder, value);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 根据项目类型获取模板名称
|
|
159
|
+
*/
|
|
160
|
+
getTemplateNameByType(projectType) {
|
|
161
|
+
const mapping = {
|
|
162
|
+
nestjs: 'nestjs',
|
|
163
|
+
vue: 'vue',
|
|
164
|
+
react: 'vue', // React 使用和 Vue 相同的模板
|
|
165
|
+
node: 'nestjs', // 通用 Node.js 项目使用 NestJS 模板
|
|
166
|
+
};
|
|
167
|
+
return mapping[projectType] || 'nestjs';
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 根据项目类型获取 lint 命令
|
|
171
|
+
*/
|
|
172
|
+
getLintCommand(projectType) {
|
|
173
|
+
const commands = {
|
|
174
|
+
nestjs: 'npm run lint:check',
|
|
175
|
+
vue: 'npm run type-check',
|
|
176
|
+
react: 'npm run type-check',
|
|
177
|
+
node: 'npm run lint',
|
|
178
|
+
};
|
|
179
|
+
return commands[projectType] || 'npm run lint';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
exports.TemplateGenerator = TemplateGenerator;
|
|
183
|
+
/**
|
|
184
|
+
* 创建模板生成器实例
|
|
185
|
+
*/
|
|
186
|
+
function createTemplateGenerator() {
|
|
187
|
+
return new TemplateGenerator();
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"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"}
|