|
|
@@ -0,0 +1,177 @@
|
|
|
+const { exec } = require('child_process');
|
|
|
+const path = require('path');
|
|
|
+
|
|
|
+const GLOBAL_DATA = {
|
|
|
+ gitLock: false,
|
|
|
+ buildLock: false,
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 拉取指定仓库的代码
|
|
|
+ * @param {string} repoPath 仓库路径
|
|
|
+ * @returns {Promise<string>} 拉取结果
|
|
|
+ */
|
|
|
+const gitPull = (repoPath) => {
|
|
|
+ if (GLOBAL_DATA.gitLock) {
|
|
|
+ return Promise.reject(new Error('git is locked'));
|
|
|
+ }
|
|
|
+ GLOBAL_DATA.gitLock = true;
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const cwd = path.resolve(repoPath);
|
|
|
+ exec("git pull", { cwd }, (error, stdout, stderr) => {
|
|
|
+ GLOBAL_DATA.gitLock = false;
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 拉当前项目的代码
|
|
|
+ */
|
|
|
+const gitPullCurrent = () => {
|
|
|
+ const rootPath = path.resolve(__dirname, '../../');
|
|
|
+ return gitPull(rootPath);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 启动服务
|
|
|
+ * @param {string} serviceName 服务名称
|
|
|
+ * @returns {Promise<string>} 启动结果
|
|
|
+ */
|
|
|
+const pm2Start = (serviceName) => {
|
|
|
+ // if (process.env.NODE_ENV == 'development') {
|
|
|
+ // return Promise.resolve('development mode, skip');
|
|
|
+ // }
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ exec(`pm2 start ${serviceName}`, (error, stdout, stderr) => {
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 停止服务
|
|
|
+ * @param {string} serviceName 服务名称
|
|
|
+ * @returns {Promise<string>} 停止结果
|
|
|
+ */
|
|
|
+const pm2Stop = (serviceName) => {
|
|
|
+ // if (process.env.NODE_ENV == 'development') {
|
|
|
+ // return Promise.resolve('development mode, skip');
|
|
|
+ // }
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ exec(`pm2 stop ${serviceName}`, (error, stdout, stderr) => {
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * PM2 重启服务
|
|
|
+ * @param {string} serviceName 服务名称
|
|
|
+ * @returns {Promise<string>} 重启结果
|
|
|
+ */
|
|
|
+const pm2Restart = (serviceName) => {
|
|
|
+ // if (process.env.NODE_ENV == 'development') {
|
|
|
+ // return Promise.resolve('development mode, skip');
|
|
|
+ // }
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ exec(`pm2 restart ${serviceName}`, (error, stdout, stderr) => {
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 清除缓存
|
|
|
+ */
|
|
|
+const clearCache = (cachePath) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ exec(`rm -rf ${cachePath}/*`, (error, stdout, stderr) => {
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 清除缓存并重启服务
|
|
|
+ */
|
|
|
+const pm2RestartClearCache = async (serviceName, cachePath) => {
|
|
|
+ return pm2Stop(serviceName)
|
|
|
+ .then(() => {
|
|
|
+ return clearCache(cachePath);
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ return pm2Start(serviceName);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * PM2 重启 sporttery 服务
|
|
|
+ * @param {boolean} hot 是否热重启
|
|
|
+ * @returns {Promise<string>} 重启结果
|
|
|
+ */
|
|
|
+const pm2RestartSporttery = (hot) => {
|
|
|
+ if (hot) {
|
|
|
+ return pm2Restart('sporttery');
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return pm2RestartClearCache('sporttery', path.resolve(__dirname, '../../server/data'));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * PM2 重启 pinnacle 服务
|
|
|
+ * @param {boolean} hot 是否热重启
|
|
|
+ * @returns {Promise<string>} 重启结果
|
|
|
+ */
|
|
|
+const pm2RestartPinnacle = (hot) => {
|
|
|
+ if (hot) {
|
|
|
+ return pm2Restart('pinnacle');
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return pm2RestartClearCache('pinnacle', path.resolve(__dirname, '../../pinnacle/data'));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 发布 web 服务
|
|
|
+ */
|
|
|
+const releaseWeb = () => {
|
|
|
+ if (GLOBAL_DATA.buildLock) {
|
|
|
+ return Promise.reject(new Error('build is locked'));
|
|
|
+ }
|
|
|
+ GLOBAL_DATA.buildLock = true;
|
|
|
+ const rootPath = path.resolve(__dirname, '../../web');
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ exec('npm run build', { cwd: rootPath }, (error, stdout, stderr) => {
|
|
|
+ GLOBAL_DATA.buildLock = false;
|
|
|
+ if (error) {
|
|
|
+ reject(new Error(stderr) || error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resolve(stdout || "No output");
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+module.exports = { gitPullCurrent, pm2RestartSporttery, pm2RestartPinnacle, releaseWeb };
|