ai-yuca 1.0.8 → 1.1.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/.cdn.cache.json +2 -2
- package/dist/package.json +1 -1
- package/dist/src/deploy.js +42 -24
- package/dist/src/types/deploy.d.ts +1 -1
- package/dist/src/upload.js +38 -24
- package/package.json +1 -1
- package/src/deploy.ts +50 -32
- package/src/types/deploy.ts +1 -1
- package/src/upload.ts +52 -30
package/.cdn.cache.json
CHANGED
package/dist/package.json
CHANGED
package/dist/src/deploy.js
CHANGED
|
@@ -50,15 +50,32 @@ const uploadWithConfig_1 = require("./uploadWithConfig");
|
|
|
50
50
|
const cache_1 = require("./cache");
|
|
51
51
|
const child_process_1 = require("child_process");
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* 从GCP存储读取环境配置文件
|
|
54
54
|
*/
|
|
55
|
-
const getConfigFiles = (env, config) => {
|
|
55
|
+
const getConfigFiles = (env, config, keyFile) => {
|
|
56
56
|
return new Promise(async (resolve) => {
|
|
57
57
|
try {
|
|
58
|
-
|
|
58
|
+
// 继承原来的权限文件,创建GCP存储客户端
|
|
59
|
+
const storageClient = keyFile
|
|
60
|
+
? (0, upload_1.createStorageClient)({ keyFilename: keyFile })
|
|
61
|
+
: (0, upload_1.createStorageClient)();
|
|
62
|
+
const bucket = storageClient.bucket(config.aws.Bucket);
|
|
63
|
+
const configPath = `${config.aws.prefix}/static/config/${env}.config.json`;
|
|
64
|
+
const file = bucket.file(configPath);
|
|
65
|
+
// 检查文件是否存在
|
|
66
|
+
const [exists] = await file.exists();
|
|
67
|
+
if (!exists) {
|
|
68
|
+
console.log(`配置文件不存在: ${configPath}`);
|
|
69
|
+
resolve({ data: { projects: [] } });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// 直接读取文件内容到内存,不下载到本地
|
|
73
|
+
const [contents] = await file.download();
|
|
74
|
+
const sitemap = JSON.parse(contents.toString());
|
|
59
75
|
resolve({ data: sitemap });
|
|
60
76
|
}
|
|
61
77
|
catch (e) {
|
|
78
|
+
console.log(`读取配置文件失败: ${e instanceof Error ? e.message : String(e)}`);
|
|
62
79
|
resolve({ data: { projects: [] } });
|
|
63
80
|
}
|
|
64
81
|
});
|
|
@@ -176,7 +193,7 @@ async function uploadToGcp(filePath, bucketName, destination, keyFile) {
|
|
|
176
193
|
async function updateEnvironmentConfig(env, projectName, versionInfo, config, keyFile) {
|
|
177
194
|
try {
|
|
178
195
|
// 获取当前环境配置
|
|
179
|
-
const { data: envConfig } = await getConfigFiles(env, config);
|
|
196
|
+
const { data: envConfig } = await getConfigFiles(env, config, keyFile);
|
|
180
197
|
// 查找或创建项目配置
|
|
181
198
|
let projectConfig = envConfig.projects.find((p) => p.name === projectName);
|
|
182
199
|
if (!projectConfig) {
|
|
@@ -198,11 +215,14 @@ async function updateEnvironmentConfig(env, projectName, versionInfo, config, ke
|
|
|
198
215
|
const configPath = `${config.aws.prefix}/static/config/${env}.config.json`;
|
|
199
216
|
const tempFile = path.join(process.cwd(), `temp-${env}-config.json`);
|
|
200
217
|
fs.writeFileSync(tempFile, JSON.stringify(envConfig, null, 2));
|
|
201
|
-
|
|
218
|
+
console.log("更新线上配置:", JSON.stringify(envConfig));
|
|
219
|
+
const result = await uploadToGcp(tempFile, config.aws.Bucket, configPath, keyFile);
|
|
202
220
|
fs.unlinkSync(tempFile);
|
|
221
|
+
console.log('更新环境配置状态:', JSON.stringify(result.error) || result.url);
|
|
203
222
|
return result.success;
|
|
204
223
|
}
|
|
205
|
-
catch (
|
|
224
|
+
catch (e) {
|
|
225
|
+
console.log('更新环境配置失败:', e);
|
|
206
226
|
return false;
|
|
207
227
|
}
|
|
208
228
|
}
|
|
@@ -218,23 +238,11 @@ async function deployFiles(options) {
|
|
|
218
238
|
// 2. 执行upload-config阶段
|
|
219
239
|
console.log('📤 执行upload-config上传配置文件...');
|
|
220
240
|
try {
|
|
221
|
-
|
|
241
|
+
await (0, uploadWithConfig_1.uploadFilesWithConfig)({
|
|
222
242
|
configPath: options.config,
|
|
223
243
|
storageClientOptions: options.keyFile ? { keyFilename: options.keyFile } : {},
|
|
224
244
|
enableCache: true
|
|
225
245
|
});
|
|
226
|
-
if (uploadResult.success.length > 0) {
|
|
227
|
-
console.log(chalk_1.default.green(`✅ upload-config成功: ${uploadResult.success.length}个文件`));
|
|
228
|
-
uploadResult.success.forEach(file => {
|
|
229
|
-
console.log(chalk_1.default.green(` ✅ ${file.file}: ${file.url}`));
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
if (uploadResult.failed.length > 0) {
|
|
233
|
-
console.log(chalk_1.default.red(`❌ upload-config失败: ${uploadResult.failed.length}个文件`));
|
|
234
|
-
uploadResult.failed.forEach(file => {
|
|
235
|
-
console.log(chalk_1.default.red(` ❌ ${file.file}: ${file.error}`));
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
246
|
}
|
|
239
247
|
catch (error) {
|
|
240
248
|
console.warn(`⚠️ upload-config执行失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -260,17 +268,22 @@ async function deployFiles(options) {
|
|
|
260
268
|
// 5. 文件处理与上传阶段
|
|
261
269
|
console.log('📤 上传原始HTML文件...');
|
|
262
270
|
const uploadedFiles = [];
|
|
263
|
-
|
|
271
|
+
// 使用Promise.all并行上传文件
|
|
272
|
+
const uploadPromises = files.map(file => {
|
|
264
273
|
const relativePath = path.relative(sourcePath, file);
|
|
265
274
|
const destination = `${prefix}/${cdnKey}/${relativePath}`;
|
|
266
275
|
console.log(` 上传: ${relativePath}`);
|
|
267
|
-
|
|
276
|
+
return (0, upload_1.uploadFile)({
|
|
268
277
|
bucketName: uploadConfig.bucketName,
|
|
269
278
|
filePath: file,
|
|
270
279
|
destination,
|
|
271
280
|
storageClient: (0, upload_1.createStorageClient)(options.keyFile ? { keyFilename: options.keyFile } : {}),
|
|
272
281
|
enableCompression: true
|
|
273
|
-
});
|
|
282
|
+
}).then(result => ({ result, relativePath, destination }));
|
|
283
|
+
});
|
|
284
|
+
const uploadResults = await Promise.all(uploadPromises);
|
|
285
|
+
// 同步打印上传结果
|
|
286
|
+
for (const { result, relativePath, destination } of uploadResults) {
|
|
274
287
|
if (result.success) {
|
|
275
288
|
uploadedFiles.push(relativePath);
|
|
276
289
|
console.log(chalk_1.default.green(` ✅ ${relativePath}: ${result.url || destination}`));
|
|
@@ -346,7 +359,8 @@ async function deployFiles(options) {
|
|
|
346
359
|
// 7. 环境配置同步阶段
|
|
347
360
|
console.log('🔄 同步环境配置...');
|
|
348
361
|
// 检查项目是否存在
|
|
349
|
-
const { data: envConfig } = await getConfigFiles(options.env, config);
|
|
362
|
+
const { data: envConfig } = await getConfigFiles(options.env, config, options.keyFile);
|
|
363
|
+
console.log('当前环境配置:', JSON.stringify(envConfig));
|
|
350
364
|
const existingProject = envConfig.projects.find((p) => p.name === projectInfo.name);
|
|
351
365
|
if (!existingProject) {
|
|
352
366
|
if (options.force) {
|
|
@@ -375,7 +389,11 @@ async function deployFiles(options) {
|
|
|
375
389
|
timestamp: Date.now(),
|
|
376
390
|
files: obj.links
|
|
377
391
|
};
|
|
378
|
-
await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
|
392
|
+
const projectConfigUpdate = await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
|
393
|
+
console.log('项目配置信息上传结果:', JSON.stringify(projectConfigUpdate));
|
|
394
|
+
if (!projectConfigUpdate) {
|
|
395
|
+
throw new Error('更新项目配置失败,发布失败!');
|
|
396
|
+
}
|
|
379
397
|
// 8. 发布完成阶段
|
|
380
398
|
console.log('💾 记录发布版本...');
|
|
381
399
|
(0, cache_1.writeLastDeployVersion)(cdnKey);
|
|
@@ -61,7 +61,7 @@ export interface DeployResult {
|
|
|
61
61
|
message: string;
|
|
62
62
|
}
|
|
63
63
|
export interface GetConfigFilesFunction {
|
|
64
|
-
(env: string, config: Record<string, any
|
|
64
|
+
(env: string, config: Record<string, any>, keyFile?: string): Promise<{
|
|
65
65
|
data: {
|
|
66
66
|
projects: Array<any>;
|
|
67
67
|
};
|
package/dist/src/upload.js
CHANGED
|
@@ -120,6 +120,7 @@ async function uploadFile(options) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
// 上传文件
|
|
123
|
+
// @ts-ignore
|
|
123
124
|
const [file] = await bucket.upload(fileToUpload, {
|
|
124
125
|
destination: destPath,
|
|
125
126
|
// 设置元数据
|
|
@@ -128,9 +129,6 @@ async function uploadFile(options) {
|
|
|
128
129
|
cacheControl: contentType === 'application/json' ? 'public, max-age=0' : 'public, max-age=31536000',
|
|
129
130
|
contentEncoding,
|
|
130
131
|
contentType
|
|
131
|
-
},
|
|
132
|
-
preconditionOpts: {
|
|
133
|
-
ifGenerationMatch: 0 // 0表示如果文件存在则覆盖
|
|
134
132
|
}
|
|
135
133
|
});
|
|
136
134
|
// 如果上传了压缩文件,删除临时文件
|
|
@@ -150,7 +148,7 @@ async function uploadFile(options) {
|
|
|
150
148
|
};
|
|
151
149
|
}
|
|
152
150
|
catch (error) {
|
|
153
|
-
console.log('上传文件时出错:', JSON.stringify(error));
|
|
151
|
+
console.log('上传文件时出错:', filePath, JSON.stringify(error));
|
|
154
152
|
return {
|
|
155
153
|
success: false,
|
|
156
154
|
file: filePath,
|
|
@@ -176,14 +174,15 @@ async function uploadFiles(options) {
|
|
|
176
174
|
try {
|
|
177
175
|
// 如果sourcePath是数组,批量上传多个文件
|
|
178
176
|
if (Array.isArray(sourcePath)) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
177
|
+
const uploadPromises = sourcePath.map(filePath => uploadFile({
|
|
178
|
+
bucketName,
|
|
179
|
+
filePath,
|
|
180
|
+
destination: destination ? `${destination}/${path.basename(filePath)}` : undefined,
|
|
181
|
+
storageClient,
|
|
182
|
+
enableCompression
|
|
183
|
+
}));
|
|
184
|
+
const uploadResults = await Promise.all(uploadPromises);
|
|
185
|
+
for (const result of uploadResults) {
|
|
187
186
|
if (result.success) {
|
|
188
187
|
results.success.push(result);
|
|
189
188
|
}
|
|
@@ -214,37 +213,52 @@ async function uploadFiles(options) {
|
|
|
214
213
|
else if (stats.isDirectory()) {
|
|
215
214
|
// 上传目录中的文件
|
|
216
215
|
const files = await readdir(sourcePath);
|
|
216
|
+
// 分离文件和目录
|
|
217
|
+
const filePromises = [];
|
|
218
|
+
const dirPromises = [];
|
|
217
219
|
for (const file of files) {
|
|
218
220
|
const filePath = path.join(sourcePath, file);
|
|
219
221
|
const fileStats = await stat(filePath);
|
|
220
222
|
if (fileStats.isFile()) {
|
|
221
|
-
//
|
|
223
|
+
// 准备文件上传Promise
|
|
222
224
|
const destPath = destination ? `${destination}/${file}` : file;
|
|
223
|
-
|
|
225
|
+
filePromises.push(uploadFile({
|
|
224
226
|
bucketName,
|
|
225
227
|
filePath,
|
|
226
228
|
destination: destPath,
|
|
227
229
|
storageClient,
|
|
228
230
|
enableCompression
|
|
229
|
-
});
|
|
230
|
-
if (result.success) {
|
|
231
|
-
results.success.push(result);
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
results.failed.push(result);
|
|
235
|
-
}
|
|
231
|
+
}));
|
|
236
232
|
}
|
|
237
233
|
else if (recursive && fileStats.isDirectory()) {
|
|
238
|
-
//
|
|
234
|
+
// 准备递归目录上传Promise
|
|
239
235
|
const subDestination = destination ? `${destination}/${file}` : file;
|
|
240
|
-
|
|
236
|
+
dirPromises.push(uploadFiles({
|
|
241
237
|
bucketName,
|
|
242
238
|
sourcePath: filePath,
|
|
243
239
|
destination: subDestination,
|
|
244
240
|
storageClient,
|
|
245
241
|
recursive,
|
|
246
242
|
enableCompression
|
|
247
|
-
});
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// 并行上传所有文件
|
|
247
|
+
if (filePromises.length > 0) {
|
|
248
|
+
const fileResults = await Promise.all(filePromises);
|
|
249
|
+
for (const result of fileResults) {
|
|
250
|
+
if (result.success) {
|
|
251
|
+
results.success.push(result);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
results.failed.push(result);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// 并行处理所有子目录
|
|
259
|
+
if (dirPromises.length > 0) {
|
|
260
|
+
const dirResults = await Promise.all(dirPromises);
|
|
261
|
+
for (const subResults of dirResults) {
|
|
248
262
|
results.success = results.success.concat(subResults.success);
|
|
249
263
|
results.failed = results.failed.concat(subResults.failed);
|
|
250
264
|
}
|
package/package.json
CHANGED
package/src/deploy.ts
CHANGED
|
@@ -16,23 +16,38 @@ import {
|
|
|
16
16
|
DeployConfig,
|
|
17
17
|
ProjectInfo,
|
|
18
18
|
DeployVersionInfo,
|
|
19
|
-
EnvironmentConfig,
|
|
20
|
-
ProjectConfig,
|
|
21
19
|
DeployResult,
|
|
22
20
|
GetConfigFilesFunction
|
|
23
21
|
} from './types/deploy';
|
|
24
22
|
|
|
25
23
|
/**
|
|
26
|
-
*
|
|
24
|
+
* 从GCP存储读取环境配置文件
|
|
27
25
|
*/
|
|
28
|
-
const getConfigFiles: GetConfigFilesFunction = (env, config) => {
|
|
26
|
+
const getConfigFiles: GetConfigFilesFunction = (env, config, keyFile) => {
|
|
29
27
|
return new Promise(async resolve => {
|
|
30
28
|
try {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
// 继承原来的权限文件,创建GCP存储客户端
|
|
30
|
+
const storageClient = keyFile
|
|
31
|
+
? createStorageClient({ keyFilename: keyFile })
|
|
32
|
+
: createStorageClient();
|
|
33
|
+
const bucket = storageClient.bucket(config.aws.Bucket);
|
|
34
|
+
const configPath = `${config.aws.prefix}/static/config/${env}.config.json`;
|
|
35
|
+
const file = bucket.file(configPath);
|
|
36
|
+
|
|
37
|
+
// 检查文件是否存在
|
|
38
|
+
const [exists] = await file.exists();
|
|
39
|
+
if (!exists) {
|
|
40
|
+
console.log(`配置文件不存在: ${configPath}`);
|
|
41
|
+
resolve({ data: { projects: [] } });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 直接读取文件内容到内存,不下载到本地
|
|
46
|
+
const [contents] = await file.download();
|
|
47
|
+
const sitemap = JSON.parse(contents.toString());
|
|
34
48
|
resolve({ data: sitemap });
|
|
35
49
|
} catch (e) {
|
|
50
|
+
console.log(`读取配置文件失败: ${e instanceof Error ? e.message : String(e)}`);
|
|
36
51
|
resolve({ data: { projects: [] } });
|
|
37
52
|
}
|
|
38
53
|
});
|
|
@@ -156,7 +171,7 @@ async function uploadToGcp(
|
|
|
156
171
|
storageClient: client,
|
|
157
172
|
enableCompression: true
|
|
158
173
|
});
|
|
159
|
-
|
|
174
|
+
|
|
160
175
|
if (result.success) {
|
|
161
176
|
return { success: true, url: result.url };
|
|
162
177
|
} else {
|
|
@@ -183,7 +198,7 @@ async function updateEnvironmentConfig(
|
|
|
183
198
|
): Promise<boolean> {
|
|
184
199
|
try {
|
|
185
200
|
// 获取当前环境配置
|
|
186
|
-
const { data: envConfig } = await getConfigFiles(env, config);
|
|
201
|
+
const { data: envConfig } = await getConfigFiles(env, config, keyFile);
|
|
187
202
|
|
|
188
203
|
// 查找或创建项目配置
|
|
189
204
|
let projectConfig = envConfig.projects.find((p: any) => p.name === projectName);
|
|
@@ -208,13 +223,16 @@ async function updateEnvironmentConfig(
|
|
|
208
223
|
const tempFile = path.join(process.cwd(), `temp-${env}-config.json`);
|
|
209
224
|
|
|
210
225
|
fs.writeFileSync(tempFile, JSON.stringify(envConfig, null, 2));
|
|
226
|
+
|
|
227
|
+
console.log("更新线上配置:", JSON.stringify(envConfig));
|
|
211
228
|
|
|
212
|
-
const result = await uploadToGcp(tempFile, config.
|
|
229
|
+
const result = await uploadToGcp(tempFile, config.aws.Bucket, configPath, keyFile);
|
|
213
230
|
|
|
214
231
|
fs.unlinkSync(tempFile);
|
|
215
|
-
|
|
232
|
+
console.log('更新环境配置状态:', JSON.stringify(result.error) || result.url);
|
|
216
233
|
return result.success;
|
|
217
|
-
} catch {
|
|
234
|
+
} catch(e) {
|
|
235
|
+
console.log('更新环境配置失败:', e);
|
|
218
236
|
return false;
|
|
219
237
|
}
|
|
220
238
|
}
|
|
@@ -235,23 +253,11 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
235
253
|
// 2. 执行upload-config阶段
|
|
236
254
|
console.log('📤 执行upload-config上传配置文件...');
|
|
237
255
|
try {
|
|
238
|
-
|
|
256
|
+
await uploadFilesWithConfig({
|
|
239
257
|
configPath: options.config,
|
|
240
258
|
storageClientOptions: options.keyFile ? { keyFilename: options.keyFile } : {},
|
|
241
259
|
enableCache: true
|
|
242
260
|
});
|
|
243
|
-
if (uploadResult.success.length > 0) {
|
|
244
|
-
console.log(chalk.green(`✅ upload-config成功: ${uploadResult.success.length}个文件`));
|
|
245
|
-
uploadResult.success.forEach(file => {
|
|
246
|
-
console.log(chalk.green(` ✅ ${file.file}: ${file.url}`));
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
if (uploadResult.failed.length > 0) {
|
|
250
|
-
console.log(chalk.red(`❌ upload-config失败: ${uploadResult.failed.length}个文件`));
|
|
251
|
-
uploadResult.failed.forEach(file => {
|
|
252
|
-
console.log(chalk.red(` ❌ ${file.file}: ${file.error}`));
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
261
|
} catch (error) {
|
|
256
262
|
console.warn(`⚠️ upload-config执行失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
257
263
|
}
|
|
@@ -284,19 +290,25 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
284
290
|
console.log('📤 上传原始HTML文件...');
|
|
285
291
|
const uploadedFiles: string[] = [];
|
|
286
292
|
|
|
287
|
-
|
|
293
|
+
// 使用Promise.all并行上传文件
|
|
294
|
+
const uploadPromises = files.map(file => {
|
|
288
295
|
const relativePath = path.relative(sourcePath, file);
|
|
289
296
|
const destination = `${prefix}/${cdnKey}/${relativePath}`;
|
|
290
297
|
|
|
291
298
|
console.log(` 上传: ${relativePath}`);
|
|
292
|
-
|
|
299
|
+
return uploadFile({
|
|
293
300
|
bucketName: uploadConfig.bucketName,
|
|
294
301
|
filePath: file,
|
|
295
302
|
destination,
|
|
296
303
|
storageClient: createStorageClient(options.keyFile ? { keyFilename: options.keyFile } : {}),
|
|
297
304
|
enableCompression: true
|
|
298
|
-
});
|
|
299
|
-
|
|
305
|
+
}).then(result => ({ result, relativePath, destination }));
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const uploadResults = await Promise.all(uploadPromises);
|
|
309
|
+
|
|
310
|
+
// 同步打印上传结果
|
|
311
|
+
for (const { result, relativePath, destination } of uploadResults) {
|
|
300
312
|
if (result.success) {
|
|
301
313
|
uploadedFiles.push(relativePath);
|
|
302
314
|
console.log(chalk.green(` ✅ ${relativePath}: ${result.url || destination}`));
|
|
@@ -378,7 +390,10 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
378
390
|
console.log('🔄 同步环境配置...');
|
|
379
391
|
|
|
380
392
|
// 检查项目是否存在
|
|
381
|
-
const { data: envConfig } = await getConfigFiles(options.env, config);
|
|
393
|
+
const { data: envConfig } = await getConfigFiles(options.env, config, options.keyFile);
|
|
394
|
+
|
|
395
|
+
console.log('当前环境配置:', JSON.stringify(envConfig));
|
|
396
|
+
|
|
382
397
|
const existingProject = envConfig.projects.find((p: any) => p.name === projectInfo.name);
|
|
383
398
|
|
|
384
399
|
if (!existingProject) {
|
|
@@ -410,8 +425,11 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
410
425
|
files: obj.links
|
|
411
426
|
};
|
|
412
427
|
|
|
413
|
-
await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
|
414
|
-
|
|
428
|
+
const projectConfigUpdate = await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
|
429
|
+
console.log('项目配置信息上传结果:',JSON.stringify(projectConfigUpdate));
|
|
430
|
+
if (!projectConfigUpdate) {
|
|
431
|
+
throw new Error('更新项目配置失败,发布失败!');
|
|
432
|
+
}
|
|
415
433
|
// 8. 发布完成阶段
|
|
416
434
|
console.log('💾 记录发布版本...');
|
|
417
435
|
writeLastDeployVersion(cdnKey);
|
package/src/types/deploy.ts
CHANGED
|
@@ -70,5 +70,5 @@ export interface DeployResult {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export interface GetConfigFilesFunction {
|
|
73
|
-
(env: string, config: Record<string, any
|
|
73
|
+
(env: string, config: Record<string, any>, keyFile?: string): Promise<{ data: { projects: Array<any> } }>;
|
|
74
74
|
}
|
package/src/upload.ts
CHANGED
|
@@ -52,7 +52,7 @@ function createStorageClient(options: Partial<StorageClientOptions> = {}): Stora
|
|
|
52
52
|
* @param options - 上传选项
|
|
53
53
|
* @returns 上传结果
|
|
54
54
|
*/
|
|
55
|
-
async function
|
|
55
|
+
async function uploadFile(options: UploadFileOptions): Promise<UploadResult> {
|
|
56
56
|
const { bucketName, filePath, destination, storageClient, enableCompression = true } = options;
|
|
57
57
|
|
|
58
58
|
if (!bucketName || !filePath || !storageClient) {
|
|
@@ -105,6 +105,7 @@ async function uploadFile(options: UploadFileOptions): Promise<UploadResult> {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
// 上传文件
|
|
108
|
+
// @ts-ignore
|
|
108
109
|
const [file] = await bucket.upload(fileToUpload, {
|
|
109
110
|
destination: destPath,
|
|
110
111
|
// 设置元数据
|
|
@@ -113,9 +114,6 @@ async function uploadFile(options: UploadFileOptions): Promise<UploadResult> {
|
|
|
113
114
|
cacheControl: contentType === 'application/json' ? 'public, max-age=0' : 'public, max-age=31536000',
|
|
114
115
|
contentEncoding,
|
|
115
116
|
contentType
|
|
116
|
-
},
|
|
117
|
-
preconditionOpts: {
|
|
118
|
-
ifGenerationMatch: 0 // 0表示如果文件存在则覆盖
|
|
119
117
|
}
|
|
120
118
|
});
|
|
121
119
|
|
|
@@ -137,7 +135,7 @@ async function uploadFile(options: UploadFileOptions): Promise<UploadResult> {
|
|
|
137
135
|
url: `https://storage.googleapis.com/${bucketName}/${metadata.name || path.basename(filePath)}`
|
|
138
136
|
};
|
|
139
137
|
} catch (error) {
|
|
140
|
-
console.log('上传文件时出错:', JSON.stringify(error));
|
|
138
|
+
console.log('上传文件时出错:', filePath, JSON.stringify(error));
|
|
141
139
|
return {
|
|
142
140
|
success: false,
|
|
143
141
|
file: filePath,
|
|
@@ -169,15 +167,19 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
169
167
|
try {
|
|
170
168
|
// 如果sourcePath是数组,批量上传多个文件
|
|
171
169
|
if (Array.isArray(sourcePath)) {
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
const uploadPromises = sourcePath.map(filePath =>
|
|
171
|
+
uploadFile({
|
|
174
172
|
bucketName,
|
|
175
173
|
filePath,
|
|
176
174
|
destination: destination ? `${destination}/${path.basename(filePath)}` : undefined,
|
|
177
175
|
storageClient,
|
|
178
176
|
enableCompression
|
|
179
|
-
})
|
|
180
|
-
|
|
177
|
+
})
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const uploadResults = await Promise.all(uploadPromises);
|
|
181
|
+
|
|
182
|
+
for (const result of uploadResults) {
|
|
181
183
|
if (result.success) {
|
|
182
184
|
results.success.push(result);
|
|
183
185
|
} else {
|
|
@@ -209,40 +211,60 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
209
211
|
// 上传目录中的文件
|
|
210
212
|
const files = await readdir(sourcePath);
|
|
211
213
|
|
|
214
|
+
// 分离文件和目录
|
|
215
|
+
const filePromises: Promise<any>[] = [];
|
|
216
|
+
const dirPromises: Promise<any>[] = [];
|
|
217
|
+
|
|
212
218
|
for (const file of files) {
|
|
213
219
|
const filePath = path.join(sourcePath, file);
|
|
214
220
|
const fileStats = await stat(filePath);
|
|
215
221
|
|
|
216
222
|
if (fileStats.isFile()) {
|
|
217
|
-
//
|
|
223
|
+
// 准备文件上传Promise
|
|
218
224
|
const destPath = destination ? `${destination}/${file}` : file;
|
|
219
225
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
filePromises.push(
|
|
227
|
+
uploadFile({
|
|
228
|
+
bucketName,
|
|
229
|
+
filePath,
|
|
230
|
+
destination: destPath,
|
|
231
|
+
storageClient,
|
|
232
|
+
enableCompression
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
} else if (recursive && fileStats.isDirectory()) {
|
|
236
|
+
// 准备递归目录上传Promise
|
|
237
|
+
const subDestination = destination ? `${destination}/${file}` : file;
|
|
227
238
|
|
|
239
|
+
dirPromises.push(
|
|
240
|
+
uploadFiles({
|
|
241
|
+
bucketName,
|
|
242
|
+
sourcePath: filePath,
|
|
243
|
+
destination: subDestination,
|
|
244
|
+
storageClient,
|
|
245
|
+
recursive,
|
|
246
|
+
enableCompression
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// 并行上传所有文件
|
|
253
|
+
if (filePromises.length > 0) {
|
|
254
|
+
const fileResults = await Promise.all(filePromises);
|
|
255
|
+
for (const result of fileResults) {
|
|
228
256
|
if (result.success) {
|
|
229
257
|
results.success.push(result);
|
|
230
258
|
} else {
|
|
231
259
|
results.failed.push(result);
|
|
232
260
|
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
destination: subDestination,
|
|
241
|
-
storageClient,
|
|
242
|
-
recursive,
|
|
243
|
-
enableCompression
|
|
244
|
-
});
|
|
245
|
-
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// 并行处理所有子目录
|
|
265
|
+
if (dirPromises.length > 0) {
|
|
266
|
+
const dirResults = await Promise.all(dirPromises);
|
|
267
|
+
for (const subResults of dirResults) {
|
|
246
268
|
results.success = results.success.concat(subResults.success);
|
|
247
269
|
results.failed = results.failed.concat(subResults.failed);
|
|
248
270
|
}
|