Kaynağa Gözat

add timeout to deployment script to kill the unresponsive process (#6324)

Madhu Dollu 2 yıl önce
ebeveyn
işleme
ad29d59214
3 değiştirilmiş dosya ile 91 ekleme ve 14 silme
  1. 7 0
      package-lock.json
  2. 1 0
      package.json
  3. 83 14
      theme-utils.mjs

+ 7 - 0
package-lock.json

@@ -28,6 +28,7 @@
 				"octokit": "^2.0.3",
 				"open": "^8.4.0",
 				"parse5-html-rewriting-stream": "^7.0.0",
+				"string-progressbar": "^1.0.4",
 				"table": "^6.8.0"
 			},
 			"engines": {
@@ -17023,6 +17024,12 @@
 				"node": ">=10"
 			}
 		},
+		"node_modules/string-progressbar": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/string-progressbar/-/string-progressbar-1.0.4.tgz",
+			"integrity": "sha512-OpkcFxlFjn7kz5jTWmPGY+FFJVN21lQ9k0fkK0XS5GVvlCgS1stgDNEoMyqnkbZEcVP3Gv6IxqgG7tnD7ChBSw==",
+			"dev": true
+		},
 		"node_modules/string-width": {
 			"version": "4.2.3",
 			"dev": true,

+ 1 - 0
package.json

@@ -46,6 +46,7 @@
 		"octokit": "^2.0.3",
 		"open": "^8.4.0",
 		"parse5-html-rewriting-stream": "^7.0.0",
+		"string-progressbar": "^1.0.4",
 		"table": "^6.8.0"
 	},
 	"stylelint": {

+ 83 - 14
theme-utils.mjs

@@ -4,6 +4,7 @@ import open from 'open';
 import inquirer from 'inquirer';
 import { RewritingStream } from 'parse5-html-rewriting-stream';
 import { table } from 'table';
+import progressbar from 'string-progressbar';
 
 const remoteSSH = 'wpcom-sandbox';
 const sandboxPublicThemesFolder = '/home/wpdev/public_html/wp-content/themes/pub';
@@ -456,12 +457,30 @@ async function buildComZip(themeSlug) {
 }
 
 async function buildComZips(themes) {
+	console.log(`Building dotcom .zip files`);
+	const progress = startProgress(themes.length);
+	const failedThemes = []
 	for (let theme of themes) {
 		try {
 			await buildComZip(theme);
 		} catch (err) {
 			console.log(`There was an error building dotcom zip for ${theme}. ${err}`);
+			failedThemes.push(theme);
 		}
+		progress.increment();
+	}
+
+	if (failedThemes.length) {
+		const tableConfig = {
+			columnDefault: {
+				width: 40,
+			},
+			header: {
+				alignment: 'center',
+				content: `There was an error building dotcom zip for following themes.`,
+			}
+		};
+		console.log(table(failedThemes.map(t => [t]), tableConfig));
 	}
 }
 
@@ -514,6 +533,8 @@ async function getChangedThemes(hash) {
 async function deployThemes(themes) {
 
 	let response;
+	const failedThemes = [];
+	const progress = startProgress(themes.length);
 
 	for (let theme of themes) {
 
@@ -527,9 +548,12 @@ async function deployThemes(themes) {
 			attempt++;
 			console.log(`\nattempt #${attempt}\n\n`);
 
-			response = await executeOnSandbox(`deploy pub ${theme};exit;`, true, true);
-
-			deploySuccess = response.includes('successfully deployed to');
+			try {
+				response = await executeOnSandbox(`deploy pub ${theme};exit;`, true, true);
+				deploySuccess = response.includes('successfully deployed to');
+			} catch (error) {
+				deploySuccess = false
+			}
 
 			if (!deploySuccess) {
 				console.log('Deploy was not successful.  Trying again in 10 seconds...');
@@ -542,15 +566,24 @@ async function deployThemes(themes) {
 		}
 
 		if (!deploySuccess) {
-
-			await inquirer.prompt([{
-				type: 'confirm',
-				message: `${theme} was not sucessfully deployed and should be deployed manually.`,
-				name: "continue",
-				default: false
-			}]);
+			console.log(`${theme} was not sucessfully deployed and should be deployed manually.`);
+			failedThemes.push(theme);
 		}
 
+		progress.increment();
+	}
+
+	if (failedThemes.length) {
+		const tableConfig = {
+			columnDefault: {
+				width: 40,
+			},
+			header: {
+				alignment: 'center',
+				content: `Following themes are not deployed.`,
+			}
+		};
+		console.log(table(failedThemes.map(t => [t]), tableConfig));
 	}
 }
 
@@ -744,10 +777,18 @@ async function versionBumpTheme(theme, addChanges) {
 	filesToUpdate = filesToUpdate.split('\n').filter(item => item != '');
 
 	for (let file of filesToUpdate) {
-		await executeCommand(`perl -pi -e 's/Version: (.*)$/"Version: '${currentVersion}'"/ge' ${file}`);
-		await executeCommand(`perl -pi -e 's/\\"version\\": (.*)$/"\\"version\\": \\"'${currentVersion}'\\","/ge' ${file}`);
+		const isPackageJson = file === `${theme}/package.json`;
+		if (isPackageJson) {
+			// update theme/package.json and package-lock.json
+			await executeCommand(`npm version ${currentVersion} --workspace=${theme} --silent`);
+		} else {
+			await executeCommand(`perl -pi -e 's/Version: (.*)$/"Version: '${currentVersion}'"/ge' ${file}`);
+		}
 		if (addChanges) {
 			await executeCommand(`git add ${file}`);
+			if (isPackageJson) {
+				await executeCommand(`git add package-lock.json`);
+			}
 		}
 	}
 }
@@ -1117,8 +1158,9 @@ EOF`, logResponse);
  Execute a command locally.
 */
 export async function executeCommand(command, logResponse) {
-	return new Promise((resolove, reject) => {
+	const timeout = 2*60*1000; // 2 min
 
+	return new Promise((resolove, reject) => {
 		let child;
 		let response = '';
 		let errResponse = '';
@@ -1127,13 +1169,23 @@ export async function executeCommand(command, logResponse) {
 			child = spawn('cmd.exe', ['/s', '/c', '"' + command + '"'], {
 				windowsVerbatimArguments: true,
 				stdio: [process.stdin, 'pipe', 'pipe'],
+				detached: true,
 			})
 		} else {
 			child = spawn(process.env.SHELL, ['-c', command], {
 				stdio: [process.stdin, 'pipe', 'pipe'],
+				detached: true,
 			});
 		}
 
+		var timer = setTimeout(() => {
+			try {
+				process.kill(-child.pid, 'SIGKILL');
+			} catch (e) {
+				console.log('Cannot kill process');
+			}
+		}, timeout);
+
 		child.stdout.on('data', (data) => {
 			response += data;
 			if (logResponse) {
@@ -1149,6 +1201,7 @@ export async function executeCommand(command, logResponse) {
 		});
 
 		child.on('exit', (code) => {
+			clearTimeout(timer)
 			if (code !== 0) {
 				reject(errResponse.trim());
 			}
@@ -1301,4 +1354,20 @@ async function escapePatterns() {
 
 		return table([patterns], tableConfig);
 	}
-}
+}
+
+function startProgress(length) {
+	let current = 0;
+	function render() {
+		const [progress, percentage] = progressbar.filledBar(length, current);
+		console.log('\nProgress:', [progress, Math.round(percentage*100)/100], `${current}/${length}\n`);
+	}
+
+	render();
+	return {
+		increment() {
+			current++;
+			render();
+		}
+	};
+}