213 lines
9.3 KiB
JavaScript
213 lines
9.3 KiB
JavaScript
process.env.DEBUG = 'electron-windows-installer:main';
|
|
const path = require('path');
|
|
const pkg = require(path.join(__dirname, 'package.json'));
|
|
const fs = require('fs');
|
|
const child_process = require('child_process');
|
|
const _ = require('lodash');
|
|
const axios = require('axios');
|
|
|
|
const distDir = path.join(__dirname, 'dist');
|
|
const isBeta = pkg.version.indexOf('beta') !== -1;
|
|
const modules = path.join(__dirname, 'app', 'node_modules');
|
|
|
|
// const spellcheckerPath = 'spellchecker/build/Release/spellchecker.node',
|
|
// keytarPath = 'keytar/build/Release/keytar.node',
|
|
// integerPath = 'integer/build/Release/integer.node',
|
|
// betterSqlite3 = 'better-sqlite3/build/Release/better_sqlite3.node';
|
|
//
|
|
// mkdir(path.dirname(path.join(modules, spellcheckerPath)));
|
|
// mkdir(path.dirname(path.join(modules, keytarPath)));
|
|
// fs.copyFileSync(require.resolve(spellcheckerPath), path.join(modules, spellcheckerPath));
|
|
// fs.copyFileSync(require.resolve(keytarPath), path.join(modules, keytarPath));
|
|
|
|
const includedPaths = [
|
|
// 'spellchecker/build/Release/spellchecker.node',
|
|
// 'keytar/build/Release/keytar.node',
|
|
'throat',
|
|
'node-fetch',
|
|
'jquery'
|
|
];
|
|
|
|
_.each(
|
|
includedPaths,
|
|
(p) => {
|
|
let from = p;
|
|
let to = p;
|
|
|
|
if (_.isArray(p)) {
|
|
from = p[0];
|
|
to = p[1];
|
|
}
|
|
|
|
fs.mkdirSync(path.dirname(path.join(modules, to)), {recursive: true});
|
|
fs.copyFileSync(require.resolve(from), path.join(modules, to));
|
|
}
|
|
);
|
|
|
|
|
|
|
|
require('electron-packager')({
|
|
dir: path.join(__dirname, 'app'),
|
|
out: distDir,
|
|
overwrite: true,
|
|
name: 'F-Chat',
|
|
icon: path.join(__dirname, 'build', 'icon'),
|
|
ignore: ['\.map$'],
|
|
osxSign: process.argv.length > 2 ? {identity: process.argv[2]} : false,
|
|
prune: false,
|
|
arch: process.platform === 'darwin' ? ['x64', 'arm64'] : ['x64', 'arm64'],
|
|
}).then(async (appPaths) => {
|
|
if (process.env.SKIP_INSTALLER) {
|
|
return;
|
|
}
|
|
|
|
if(process.platform === 'win32') {
|
|
console.log('Creating Windows installer');
|
|
const icon = path.join(__dirname, 'build', 'icon.ico');
|
|
|
|
for (const appPath of appPaths) {
|
|
console.log('WinAppPath', appPath);
|
|
const appArch = appPath.match(/F-Chat-win32-([a-zA-Z0-9]+)$/)[1];
|
|
const appArchLong = appArch === 'x64' ? 'x86_64' : 'aarch64';
|
|
const setupName = `F-Chat-Rising-Setup-win-${appArch}.exe`;
|
|
const distFinal = path.join(distDir, appArch);
|
|
|
|
console.log('DistFinal', distFinal);
|
|
|
|
fs.mkdirSync(distFinal, {recursive: true});
|
|
|
|
if(fs.existsSync(path.join(distFinal, setupName))) {
|
|
fs.unlinkSync(path.join(distFinal, setupName));
|
|
}
|
|
|
|
const nupkgName = path.join(distFinal, `fchat-${pkg.version}-full.nupkg`);
|
|
const deltaName = path.join(distFinal, `fchat-${pkg.version}-delta.nupkg`);
|
|
|
|
if(fs.existsSync(nupkgName)) fs.unlinkSync(nupkgName);
|
|
if(fs.existsSync(deltaName)) fs.unlinkSync(deltaName);
|
|
|
|
if(process.argv.length <= 3) console.warn('Warning: Creating unsigned installer');
|
|
|
|
try {
|
|
await require('electron-winstaller').createWindowsInstaller({
|
|
appDirectory: appPath,
|
|
outputDirectory: distFinal,
|
|
iconUrl: 'file:///%localappdata%\\fchat\\app.ico',
|
|
setupIcon: icon,
|
|
noMsi: true,
|
|
exe: 'F-Chat.exe',
|
|
title: 'F-Chat Rising',
|
|
setupExe: setupName,
|
|
name: 'fchat'
|
|
// remoteReleases: 'https://client.f-list.net/win32/' + (isBeta ? '?channel=beta' : ''),
|
|
// signWithParams: process.argv.length > 3 ? `/a /f ${process.argv[2]} /p ${process.argv[3]} /fd sha256 /tr http://timestamp.digicert.com /td sha256` : undefined
|
|
});
|
|
} catch (e) {
|
|
console.error(`Error while creating installer: ${e.message}`);
|
|
throw e;
|
|
}
|
|
}
|
|
} else if(process.platform === 'darwin') {
|
|
console.log('Creating Mac DMG');
|
|
|
|
_.each([{ name: 'Intel', path: appPaths[0] }, { name: 'M1', path: appPaths[1] }], (arch) => {
|
|
console.log(arch.name, arch.path);
|
|
|
|
const target = path.join(distDir, `F-Chat Rising ${arch.name}.dmg`);
|
|
if(fs.existsSync(target)) fs.unlinkSync(target);
|
|
const appPath = path.join(arch.path, 'F-Chat.app');
|
|
if(process.argv.length <= 2) console.warn('Warning: Creating unsigned DMG');
|
|
require('appdmg')({
|
|
basepath: arch.path,
|
|
target,
|
|
specification: {
|
|
title: 'F-Chat Rising',
|
|
icon: path.join(__dirname, 'build', 'icon.png'),
|
|
background: path.join(__dirname, 'build', 'dmg.png'),
|
|
contents: [{x: 555, y: 345, type: 'link', path: '/Applications'}, {x: 555, y: 105, type: 'file', path: appPath}],
|
|
'code-sign': process.argv.length > 2 ? {
|
|
'signing-identity': process.argv[2]
|
|
} : undefined
|
|
}
|
|
}).on('error', console.error);
|
|
const zipName = `F-Chat_Rising_${arch.name}_${pkg.version}.zip`;
|
|
const zipPath = path.join(distDir, zipName);
|
|
if(fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
|
|
const child = child_process.spawn('zip', ['-r', '-y', '-9', zipPath, 'F-Chat.app'], {cwd: arch.path});
|
|
child.stdout.on('data', () => {});
|
|
child.stderr.on('data', (data) => console.error(data.toString()));
|
|
fs.writeFileSync(path.join(distDir, 'updates.json'), JSON.stringify({
|
|
releases: [{version: pkg.version, updateTo: {url: 'https://client.f-list.net/darwin/' + zipName}}],
|
|
currentRelease: pkg.version
|
|
}));
|
|
});
|
|
} else {
|
|
console.log('Creating Linux AppImage');
|
|
|
|
async function downloadAppImageTool(appImageBase) {
|
|
const localArch = process.arch === 'x64' ? 'x86_64' : 'aarch64';
|
|
const url = `https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${localArch}.AppImage`;
|
|
const res = await axios.get(url, { responseType: 'arraybuffer' });
|
|
const appImagePath = path.join(appImageBase, 'appimagetool.AppImage');
|
|
|
|
console.log('Downloading', url, appImageBase, typeof res.data);
|
|
|
|
|
|
|
|
fs.writeFileSync(appImagePath, res.data);
|
|
fs.chmodSync(appImagePath, 0o755);
|
|
|
|
const result = child_process.spawnSync(appImagePath, ['--appimage-extract'], {cwd: appImageBase});
|
|
|
|
if (result.status !== 0) {
|
|
console.log('Run failed', 'APPIMAGE EXTRACT', {status: result.status, call: result.error?.syscall, args: result.error?.spawnargs, path: result.error?.path, code: result.error?.code, stdout: String(result.stdout), stderr: String(result.stderr) });
|
|
}
|
|
|
|
return appImagePath;
|
|
}
|
|
|
|
const appImageBase = path.join(distDir, 'downloaded');
|
|
fs.mkdirSync(appImageBase, {recursive: true});
|
|
|
|
const appImagePath = await downloadAppImageTool(appImageBase);
|
|
|
|
for (const appPath of appPaths) {
|
|
const appArch = appPath.match(/F-Chat-linux-([a-zA-Z0-9]+)$/)[1];
|
|
const appArchLong = appArch === 'x64' ? 'x86_64' : 'aarch64';
|
|
const buildPath = path.join(__dirname, 'build');
|
|
|
|
fs.renameSync(path.join(appPath, 'F-Chat'), path.join(appPath, 'AppRun'));
|
|
fs.copyFileSync(path.join(buildPath, 'icon.png'), path.join(appPath, 'icon.png'));
|
|
|
|
const libDir = path.join(appPath, 'usr', 'lib'), libSource = path.join(buildPath, 'linux-libs', appArchLong);
|
|
|
|
fs.mkdirSync(libDir, {recursive: true});
|
|
|
|
for(const file of fs.readdirSync(libSource)) {
|
|
fs.copyFileSync(path.join(libSource, file), path.join(libDir, file));
|
|
}
|
|
|
|
fs.symlinkSync(path.join(appPath, 'icon.png'), path.join(appPath, '.DirIcon'));
|
|
fs.writeFileSync(path.join(appPath, 'fchat.desktop'), '[Desktop Entry]\nName=F-Chat\nExec=AppRun\nIcon=icon\nType=Application\nCategories=GTK;GNOME;Utility;');
|
|
|
|
const args = [appPath, `fchat.${appArch}.AppImage`, '-u', `gh-releases-zsync|hearmeneigh|fchat-rising|latest|F-Chat-Rising-linux-${appArch}.AppImage.zsync`];
|
|
|
|
if(process.argv.length > 2) {
|
|
args.push('-s', '--sign-key', process.argv[2]);
|
|
} else {
|
|
console.warn('Warning: Creating unsigned AppImage');
|
|
}
|
|
|
|
if(process.argv.length > 3) {
|
|
args.push('--sign-args', `--no-tty --pinentry-mode loopback --yes --passphrase=${process.argv[3]}`);
|
|
}
|
|
|
|
const appRunResult = child_process.spawnSync(path.join(appImageBase, 'squashfs-root', 'AppRun'), args, {cwd: appImageBase, env: {ARCH: appArchLong }});
|
|
|
|
if (appRunResult.status !== 0) {
|
|
console.log('Run failed', 'APPRUN', appArch, {status: appRunResult.status, call: appRunResult.error?.syscall, args: appRunResult.error?.spawnargs, path: appRunResult.error?.path, code: appRunResult.error?.code, stdout: String(appRunResult.stdout), stderr: String(appRunResult.stderr) });
|
|
}
|
|
}
|
|
}
|
|
}, (e) => console.log(`Error while packaging: ${e.message}`));
|