ql-publish 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/upload/clear.js +1 -1
- package/upload/resetOss.js +1 -1
- package/upload/u.js +121 -39
package/package.json
CHANGED
package/upload/clear.js
CHANGED
|
@@ -95,7 +95,7 @@ const deleteFileByMapJson = async (sftp, currentSourceDir, mtime) => {
|
|
|
95
95
|
} else {
|
|
96
96
|
// 删除文件
|
|
97
97
|
if (mtime >= item.attrs.mtime) {
|
|
98
|
-
//
|
|
98
|
+
// logger.info(`✅ 已删除文件: ${sourcePath}`);
|
|
99
99
|
await sftp.unlink(sourcePath);
|
|
100
100
|
}
|
|
101
101
|
}
|
package/upload/resetOss.js
CHANGED
|
@@ -168,7 +168,7 @@ const getDirList = async () => {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
folderNames = [...folderNames, ...result.objects.filter(obj => obj && obj.name)
|
|
171
|
-
|
|
171
|
+
.map(obj => obj.name.split('/')[1])];
|
|
172
172
|
|
|
173
173
|
nextMarker = result.nextMarker;
|
|
174
174
|
} while (nextMarker);
|
package/upload/u.js
CHANGED
|
@@ -7,6 +7,8 @@ const { PassThrough } = require('stream');
|
|
|
7
7
|
const dayjs = require("dayjs");
|
|
8
8
|
const refreshCdn = require("../cdn/refresh");
|
|
9
9
|
const readline = require("readline");
|
|
10
|
+
const { exec } = require('child_process');
|
|
11
|
+
const fs = require('fs');
|
|
10
12
|
|
|
11
13
|
const deleteFolder = () => {
|
|
12
14
|
return new Promise(resolve => {
|
|
@@ -53,7 +55,7 @@ const deleteFolder = () => {
|
|
|
53
55
|
logger.error('❌ 连接错误:', err);
|
|
54
56
|
resolve(null);
|
|
55
57
|
});
|
|
56
|
-
conn.on('end', () => {});
|
|
58
|
+
conn.on('end', () => { });
|
|
57
59
|
})
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -323,7 +325,7 @@ const creatFileMap = async (sftp, currentSourceDir) => {
|
|
|
323
325
|
await creatFileMap(sftp, sourcePath);
|
|
324
326
|
} else {
|
|
325
327
|
fileMapData.mtime = item.attrs.mtime > fileMapData.mtime ? item.attrs.mtime : fileMapData.mtime;
|
|
326
|
-
|
|
328
|
+
|
|
327
329
|
// if (sourcePath.indexOf(`assets`) > -1) {
|
|
328
330
|
// if (sourcePath.indexOf(`assets/_plugin`) === -1) {
|
|
329
331
|
// fileMapData.deleteList.push(sourcePath)
|
|
@@ -427,8 +429,11 @@ const sshAction = async () => {
|
|
|
427
429
|
}
|
|
428
430
|
});
|
|
429
431
|
});
|
|
430
|
-
//
|
|
432
|
+
// 没有项目目录,创建项目目录后,return
|
|
431
433
|
if (!await isHasDir(sftp, config.path)) {
|
|
434
|
+
logger.warn(`项目目录 ${config.path} 不存在,正在创建...`);
|
|
435
|
+
await ensureDirectoryExists(sftp, config.path);
|
|
436
|
+
logger.info(`✅ 项目目录 ${config.path} 创建成功`);
|
|
432
437
|
return
|
|
433
438
|
}
|
|
434
439
|
if (config.backUp) {
|
|
@@ -456,46 +461,123 @@ const sshAction = async () => {
|
|
|
456
461
|
}
|
|
457
462
|
}
|
|
458
463
|
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
logger.warn('开始上传文件到服务器...');
|
|
466
|
-
|
|
467
|
-
let timer = null;
|
|
468
|
-
|
|
469
|
-
const runTimer = () => {
|
|
470
|
-
timer && clearTimeout(timer);
|
|
471
|
-
timer = setTimeout(() => {
|
|
472
|
-
if (!timer) return;
|
|
473
|
-
logger.log('✅ 拼命上传中...');
|
|
474
|
-
runTimer();
|
|
475
|
-
}, Math.random() * 5000 + 1000);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
runTimer();
|
|
479
|
-
// 上传文件
|
|
480
|
-
scpClient.scp(
|
|
481
|
-
config.localPath,
|
|
482
|
-
config,
|
|
483
|
-
async (err) => {
|
|
484
|
-
clearTimeout(timer);
|
|
485
|
-
timer = null;
|
|
464
|
+
const compressAction = (localPath, archiveName) => {
|
|
465
|
+
return new Promise((resolve, reject) => {
|
|
466
|
+
logger.warn(`正在压缩文件: ${localPath} -> ${archiveName}`);
|
|
467
|
+
// 使用 tar 压缩,-C 切换到目录,. 表示压缩当前目录下所有文件
|
|
468
|
+
// COPYFILE_DISABLE=1 和 --no-xattrs 用于防止 macOS 的扩展属性(如 com.apple.provenance)被打包
|
|
469
|
+
exec(`COPYFILE_DISABLE=1 tar --no-xattrs -czf ${archiveName} -C ${localPath} .`, (err) => {
|
|
486
470
|
if (err) {
|
|
487
|
-
logger.error(
|
|
488
|
-
|
|
489
|
-
process.exit(1);
|
|
471
|
+
logger.error('❌ 压缩失败:', err);
|
|
472
|
+
reject(err);
|
|
490
473
|
} else {
|
|
491
|
-
logger.
|
|
492
|
-
|
|
493
|
-
config.cdn && config.cdn.list && await refreshCdn(config.cdn.list);
|
|
494
|
-
logger.warn(`接下来1分钟后,记得清理旧项目版本,请手动执行 yarn clear:${process.env.NODE_ENV}`)
|
|
495
|
-
process.exit(0);
|
|
474
|
+
logger.info('✅ 压缩成功');
|
|
475
|
+
resolve();
|
|
496
476
|
}
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
const decompressRemoteAction = (config, remoteArchivePath, remoteExtractPath) => {
|
|
482
|
+
return new Promise((resolve, reject) => {
|
|
483
|
+
const conn = new Client();
|
|
484
|
+
conn.on('ready', () => {
|
|
485
|
+
logger.warn(`正在服务器解压文件: ${remoteArchivePath} -> ${remoteExtractPath}`);
|
|
486
|
+
// 确保目录存在(使用 -p 参数,如果已存在不会报错)
|
|
487
|
+
// 如果 mkdir -p 仍然报错(可能是权限问题或其他特殊情况),我们尝试直接解压
|
|
488
|
+
const command = `mkdir -p ${remoteExtractPath} 2>/dev/null; tar -xzf ${remoteArchivePath} -C ${remoteExtractPath} && rm ${remoteArchivePath}`;
|
|
489
|
+
conn.exec(command, (err, stream) => {
|
|
490
|
+
if (err) {
|
|
491
|
+
conn.end();
|
|
492
|
+
return reject(err);
|
|
493
|
+
}
|
|
494
|
+
stream.on('close', (code) => {
|
|
495
|
+
conn.end();
|
|
496
|
+
if (code === 0) {
|
|
497
|
+
logger.info('✅ 服务器解压成功');
|
|
498
|
+
resolve();
|
|
499
|
+
} else {
|
|
500
|
+
logger.error(`❌ 服务器解压失败,退出码: ${code}`);
|
|
501
|
+
reject(new Error(`Exit code ${code}`));
|
|
502
|
+
}
|
|
503
|
+
}).on('data', (data) => {
|
|
504
|
+
// console.log('STDOUT: ' + data);
|
|
505
|
+
}).stderr.on('data', (data) => {
|
|
506
|
+
logger.error('STDERR: ' + data);
|
|
507
|
+
});
|
|
508
|
+
});
|
|
509
|
+
}).on('error', (err) => {
|
|
510
|
+
logger.error('❌ 服务器连接失败:', err);
|
|
511
|
+
reject(err);
|
|
512
|
+
}).connect(config);
|
|
513
|
+
});
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const scpAction = async () => {
|
|
517
|
+
const archiveName = 'dist.tar.gz';
|
|
518
|
+
const localArchivePath = path.join(process.cwd(), archiveName);
|
|
519
|
+
const remoteArchivePath = path.posix.join(config.path, archiveName);
|
|
520
|
+
|
|
521
|
+
try {
|
|
522
|
+
// 1. 本地压缩
|
|
523
|
+
await compressAction(config.localPath, localArchivePath);
|
|
524
|
+
logger.warn('开始上传压缩包到服务器...');
|
|
525
|
+
let timer = null;
|
|
526
|
+
const runTimer = () => {
|
|
527
|
+
timer && clearTimeout(timer);
|
|
528
|
+
timer = setTimeout(() => {
|
|
529
|
+
if (!timer) return;
|
|
530
|
+
logger.log('✅ 拼命上传中...');
|
|
531
|
+
runTimer();
|
|
532
|
+
}, Math.random() * 5000 + 1000);
|
|
533
|
+
}
|
|
534
|
+
runTimer();
|
|
535
|
+
|
|
536
|
+
// 2. 上传压缩包
|
|
537
|
+
await new Promise((resolve, reject) => {
|
|
538
|
+
scpClient.scp(
|
|
539
|
+
localArchivePath,
|
|
540
|
+
{
|
|
541
|
+
...config,
|
|
542
|
+
path: config.path // 保持目标路径一致
|
|
543
|
+
},
|
|
544
|
+
(err) => {
|
|
545
|
+
clearTimeout(timer);
|
|
546
|
+
timer = null;
|
|
547
|
+
if (err) {
|
|
548
|
+
reject(err);
|
|
549
|
+
} else {
|
|
550
|
+
resolve();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
logger.success('🎉 压缩包上传成功!');
|
|
557
|
+
|
|
558
|
+
// 3. 服务器解压
|
|
559
|
+
await decompressRemoteAction(config, remoteArchivePath, config.path);
|
|
560
|
+
|
|
561
|
+
// 4. 清理本地压缩包
|
|
562
|
+
if (fs.existsSync(localArchivePath)) {
|
|
563
|
+
fs.unlinkSync(localArchivePath);
|
|
497
564
|
}
|
|
498
|
-
|
|
565
|
+
|
|
566
|
+
logger.success(`🎉 ${process.env.NODE_ENV}环境:部署成功!`);
|
|
567
|
+
|
|
568
|
+
// 刷新cdn
|
|
569
|
+
config.cdn && config.cdn.list && await refreshCdn(config.cdn.list);
|
|
570
|
+
logger.warn(`接下来1分钟后,记得清理旧项目版本,请手动执行 yarn clear:${process.env.NODE_ENV}`)
|
|
571
|
+
process.exit(0);
|
|
572
|
+
|
|
573
|
+
} catch (err) {
|
|
574
|
+
if (fs.existsSync(localArchivePath)) {
|
|
575
|
+
fs.unlinkSync(localArchivePath);
|
|
576
|
+
}
|
|
577
|
+
logger.error(`❌ ${process.env.NODE_ENV}环境:操作失败:`);
|
|
578
|
+
logger.error(err);
|
|
579
|
+
process.exit(1);
|
|
580
|
+
}
|
|
499
581
|
}
|
|
500
582
|
|
|
501
583
|
const authProjectName = () => {
|