Windows CI / verify (push) Successful in 3m48s
Extend the bounded Electron download retry to the installer build, then bump the release contracts to 1.0.13.
117 lines
4.0 KiB
JavaScript
117 lines
4.0 KiB
JavaScript
import { spawn } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { pathToFileURL } from 'node:url';
|
|
import { watch } from 'node:fs';
|
|
import { dirname, resolve } from 'node:path';
|
|
|
|
const scriptPath = fileURLToPath(import.meta.url);
|
|
const rootDirectory = resolve(dirname(scriptPath), '..');
|
|
const typescriptCli = resolve(rootDirectory, 'node_modules', 'typescript', 'bin', 'tsc');
|
|
const electronSourceExecutable = process.platform === 'win32'
|
|
? resolve(rootDirectory, 'node_modules', 'electron', 'dist', 'electron.exe')
|
|
: resolve(rootDirectory, 'node_modules', '.bin', 'electron');
|
|
let electronExecutable = electronSourceExecutable;
|
|
const outputDirectory = resolve(rootDirectory, 'dist');
|
|
const developmentProgramData = resolve(rootDirectory, '.dev-program-data');
|
|
const developmentUserData = resolve(rootDirectory, '.dev-user-data');
|
|
const developmentRelaunchCommand = `"${process.execPath}" "${scriptPath}" --once`;
|
|
const runOnce = process.argv.includes('--once');
|
|
|
|
let electronProcess;
|
|
let restarting = false;
|
|
let restartTimer;
|
|
let compiler;
|
|
let outputWatcher;
|
|
|
|
function run(command, args, options = {}) {
|
|
return spawn(command, args, { cwd: rootDirectory, stdio: 'inherit', ...options });
|
|
}
|
|
|
|
function waitForExit(child) {
|
|
return new Promise((resolveExit, reject) => {
|
|
child.once('error', reject);
|
|
child.once('exit', (code) => resolveExit(code ?? 1));
|
|
});
|
|
}
|
|
|
|
function startElectron() {
|
|
electronProcess = run(electronExecutable, [`--user-data-dir=${developmentUserData}`, '.'], {
|
|
env: {
|
|
...process.env,
|
|
PROGRAMDATA: developmentProgramData,
|
|
TWITCH_VOD_MANAGER_DEV: '1',
|
|
TWITCH_VOD_MANAGER_RELAUNCH_COMMAND: developmentRelaunchCommand,
|
|
},
|
|
});
|
|
electronProcess.once('exit', () => {
|
|
electronProcess = undefined;
|
|
});
|
|
return electronProcess;
|
|
}
|
|
|
|
function restartElectron() {
|
|
if (restarting) return;
|
|
restarting = true;
|
|
if (electronProcess) {
|
|
electronProcess.once('exit', () => {
|
|
restarting = false;
|
|
startElectron();
|
|
});
|
|
electronProcess.kill();
|
|
return;
|
|
}
|
|
restarting = false;
|
|
startElectron();
|
|
}
|
|
|
|
function isElectronRestartTarget(fileName) {
|
|
const baseName = fileName.replaceAll('\\', '/').split('/').at(-1) ?? '';
|
|
if (baseName === 'renderer.js') return false;
|
|
if (!baseName.startsWith('renderer') || !baseName.endsWith('.js')) return true;
|
|
const suffix = baseName.slice(8);
|
|
return suffix.length <= 4 || (suffix[0] !== '-' && suffix[0] !== '.');
|
|
}
|
|
|
|
function scheduleRestart(fileName) {
|
|
if (!fileName || !isElectronRestartTarget(fileName.toString())) return;
|
|
clearTimeout(restartTimer);
|
|
restartTimer = setTimeout(restartElectron, 200);
|
|
}
|
|
|
|
function stop(child) {
|
|
if (child && !child.killed) child.kill();
|
|
}
|
|
|
|
const initialCompile = run(process.execPath, [typescriptCli]);
|
|
const initialExitCode = await waitForExit(initialCompile);
|
|
if (initialExitCode !== 0) process.exit(initialExitCode);
|
|
|
|
if (process.platform === 'win32') {
|
|
const helperPath = pathToFileURL(resolve(outputDirectory, 'main', 'dev-executable.js')).href;
|
|
const { prepareWindowsDevExecutable } = await import(helperPath);
|
|
electronExecutable = await prepareWindowsDevExecutable({
|
|
sourcePath: electronSourceExecutable,
|
|
destinationPath: resolve(rootDirectory, 'node_modules', 'electron', 'dist', 'Twitch VOD Manager.exe'),
|
|
iconPath: resolve(rootDirectory, 'build', 'icon.ico'),
|
|
version: '1.0.13',
|
|
});
|
|
}
|
|
|
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
process.once(signal, () => {
|
|
outputWatcher?.close();
|
|
clearTimeout(restartTimer);
|
|
stop(compiler);
|
|
stop(electronProcess);
|
|
process.exit();
|
|
});
|
|
}
|
|
|
|
if (runOnce) {
|
|
process.exitCode = await waitForExit(startElectron());
|
|
} else {
|
|
compiler = run(process.execPath, [typescriptCli, '--watch', '--preserveWatchOutput']);
|
|
outputWatcher = watch(outputDirectory, { recursive: true }, (_, fileName) => scheduleRestart(fileName));
|
|
startElectron();
|
|
}
|