95 lines
3.6 KiB
JavaScript
95 lines
3.6 KiB
JavaScript
const { Client } = require('ssh2');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const conn = new Client();
|
|
const localH5Dir = path.join(__dirname, 'dist', 'build', 'h5');
|
|
const remoteH5Dir = '/www/huishou/dist/build/h5';
|
|
|
|
function uploadFile(sftp, localPath, remotePath, callback) {
|
|
fs.readFile(localPath, (err, content) => {
|
|
if (err) { callback(err); return; }
|
|
sftp.mkdir(path.dirname(remotePath), { recursive: true }, (mkdirErr) => {
|
|
if (mkdirErr && mkdirErr.code !== 4) { callback(mkdirErr); return; }
|
|
const writeStream = sftp.createWriteStream(remotePath);
|
|
writeStream.write(content);
|
|
writeStream.end();
|
|
writeStream.on('close', () => callback(null));
|
|
writeStream.on('error', (e) => callback(e));
|
|
});
|
|
});
|
|
}
|
|
|
|
function uploadDirectory(sftp, localDir, remoteDir, callback) {
|
|
fs.readdir(localDir, { withFileTypes: true }, (err, entries) => {
|
|
if (err) { callback(err); return; }
|
|
let completed = 0;
|
|
let hasError = false;
|
|
entries.forEach(entry => {
|
|
const localPath = path.join(localDir, entry.name);
|
|
const remotePath = path.join(remoteDir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
uploadDirectory(sftp, localPath, remotePath, (dirErr) => {
|
|
if (dirErr) { hasError = true; callback(dirErr); }
|
|
completed++;
|
|
if (completed === entries.length && !hasError) callback(null);
|
|
});
|
|
} else {
|
|
uploadFile(sftp, localPath, remotePath, (fileErr) => {
|
|
if (fileErr) { hasError = true; callback(fileErr); }
|
|
completed++;
|
|
if (completed === entries.length && !hasError) callback(null);
|
|
});
|
|
}
|
|
});
|
|
if (entries.length === 0) callback(null);
|
|
});
|
|
}
|
|
|
|
conn.on('ready', () => {
|
|
console.log('=== 删除旧的h5目录 ===');
|
|
conn.exec(`rm -rf ${remoteH5Dir}`, (err) => {
|
|
if (err) { console.log('ERR:', err); }
|
|
console.log('\n=== 上传H5目录 ===');
|
|
conn.sftp((err2, sftp) => {
|
|
if (err2) { console.log('SFTP ERR:', err2); conn.end(); return; }
|
|
uploadDirectory(sftp, localH5Dir, remoteH5Dir, (uploadErr) => {
|
|
if (uploadErr) {
|
|
console.log('上传失败:', uploadErr);
|
|
sftp.end();
|
|
conn.end();
|
|
return;
|
|
}
|
|
sftp.end();
|
|
console.log('H5目录上传成功');
|
|
console.log('\n=== 验证 ===');
|
|
conn.exec(`ls -la ${remoteH5Dir}/`, (err3, stream3) => {
|
|
if (err3) { console.log('ERR3:', err3); conn.end(); return; }
|
|
stream3.on('data', (d) => console.log(d.toString()));
|
|
stream3.on('close', () => {
|
|
console.log('\n=== 重启Nginx ===');
|
|
conn.exec('/www/server/nginx/sbin/nginx -s reload', (err4, stream4) => {
|
|
if (err4) { console.log('ERR4:', err4); }
|
|
else { stream4.on('data', (d) => console.log(d.toString())); }
|
|
stream4.on('close', () => {
|
|
setTimeout(() => {
|
|
console.log('\n=== 测试 ===');
|
|
conn.exec('curl -s -I https://hs.yifenbao.cn/assets/index-B5v3elQl.js', (err5, stream5) => {
|
|
if (err5) { console.log('ERR5:', err5); }
|
|
else { stream5.on('data', (d) => console.log(d.toString())); }
|
|
stream5.on('close', () => {
|
|
console.log('\n=== 完成 ===');
|
|
conn.end();
|
|
});
|
|
});
|
|
}, 2000);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
conn.connect({ host: 'hs.yifenbao.cn', port: 22, username: 'root', password: 'Torch1112' }); |