Files
bidding_watcher/src/scripts/deploy.ts
dmy a55dfd78d2 feat: 更新部署配置和API类型定义
将部署配置更改为生产环境服务器设置
将AxiosRequestConfig替换为InternalAxiosRequestConfig
2026-01-18 11:17:12 +08:00

165 lines
4.3 KiB
TypeScript

/**
* Deploy script - Upload files to remote server using SSH2
* 使用 ssh2-sftp-client 避免每次输入密钥密码
*/
import * as fs from 'fs';
import * as path from 'path';
import SftpClient from 'ssh2-sftp-client';
import * as dotenv from 'dotenv';
// 加载 .env 文件
dotenv.config();
// Configuration
// const config = {
// host: '127.0.0.1',
// port: 1122,
// username: 'cubie',
// privateKey: fs.readFileSync('d:\\163'),
// passphrase: process.env.SSH_PASSPHRASE || '',
// };
const config = {
host: '139.180.190.142',
port: 2211,
username: 'root',
privateKey: fs.readFileSync('d:\\163'),
passphrase: process.env.SSH_PASSPHRASE || '',
};
// const destinations = {
// server: '/home/cubie/down/document/bidding/publish/server',
// frontend: '/home/cubie/down/document/bidding/publish/frontend',
// src: '/home/cubie/down/document/bidding/',
// };
const destinations = {
server: '/root/bidding/publish/server',
frontend: '/root/bidding/publish/frontend',
src: '/root/bidding/',
};
async function uploadDirectory(
sftp: SftpClient,
localPath: string,
remotePath: string,
): Promise<void> {
const startTime = Date.now();
console.log(`\n[上传] ${localPath} -> ${remotePath}`);
// 检查本地目录
if (!fs.existsSync(localPath)) {
throw new Error(`本地目录不存在: ${localPath}`);
}
// 统计文件数量
const countFiles = (dir: string): number => {
let count = 0;
const items = fs.readdirSync(dir);
for (const item of items) {
const fullPath = path.join(dir, item);
if (fs.statSync(fullPath).isDirectory()) {
count += countFiles(fullPath);
} else {
count++;
}
}
return count;
};
const fileCount = countFiles(localPath);
console.log(` 文件数量: ${fileCount}`);
await sftp.uploadDir(localPath, remotePath);
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(` 完成! 耗时: ${duration}s`);
}
async function deploy(): Promise<void> {
// 检查必要目录
const requiredDirs = ['dist', 'frontend', 'src'];
for (const dir of requiredDirs) {
if (!fs.existsSync(dir)) {
console.error(`${dir} 目录不存在`);
process.exit(1);
}
}
// 检查私钥文件
if (!fs.existsSync('d:\\163')) {
console.error('私钥文件不存在: d:\\163');
process.exit(1);
}
if (!config.passphrase) {
console.error('请在 .env 文件中设置 SSH_PASSPHRASE');
process.exit(1);
}
const sftp = new SftpClient();
// 添加详细日志
sftp.on('upload', (info) => {
console.log(` 已上传: ${info.source}`);
});
try {
console.log('开始部署...');
console.log(`远程服务器: ${config.host}:${config.port}`);
console.log(`用户名: ${config.username}`);
console.log(`私钥文件: d:\\163`);
console.log('正在连接...');
await sftp.connect({
...config,
keepaliveInterval: 5000, // 每5秒发送keepalive
keepaliveCountMax: 10,
readyTimeout: 60000, // 60秒连接超时
});
console.log('连接成功!');
// 上传 dist 目录内容到 server 目录
await uploadDirectory(sftp, 'dist', destinations.server);
// 上传 frontend/dist 到 frontend 目录
await uploadDirectory(
sftp,
path.join('frontend', 'dist'),
destinations.frontend,
);
// 上传 src 目录
await uploadDirectory(sftp, 'src', destinations.src + 'src');
// 上传 package.json
console.log('\n[上传] package.json -> ' + destinations.src + 'package.json');
await sftp.put('package.json', destinations.src + 'package.json');
console.log(' 已上传: package.json');
console.log('\n========================================');
console.log('部署完成!');
console.log('========================================');
} catch (err) {
console.error('\n========================================');
console.error('部署失败!');
console.error('========================================');
console.error('错误信息:', err instanceof Error ? err.message : err);
if (err instanceof Error && err.stack) {
console.error('\n堆栈信息:');
console.error(err.stack);
}
process.exit(1);
} finally {
console.log('\n断开连接...');
await sftp.end();
console.log('连接已关闭');
}
}
deploy();