#!/usr/bin/env node /** * Pre-download Electron binaries for every client host so forge packaging * does not silently hang mid-package on cross-arch GitHub downloads. * * Usage: * node scripts/predownload-electron.cjs * PEARDATA_CLIENT_HOSTS=linux-x64,darwin-arm64 node scripts/predownload-electron.cjs * * Env: * ELECTRON_CACHE / electron_config_cache — cache dir (recommended in CI) * PEARDATA_ELECTRON_DOWNLOAD_TIMEOUT_MS — per-artifact timeout (default 180000) */ 'use strict' const path = require('path') const fs = require('fs') const { downloadArtifact } = require('@electron/get') const { ALL_64, parseHostList, hostToElectron } = require('./hosts.cjs') const root = path.resolve(__dirname, '..') const electronVersion = require(path.join(root, 'node_modules/electron/package.json')).version const hosts = parseHostList(process.env.PEARDATA_CLIENT_HOSTS, ALL_64) const timeoutMs = Number(process.env.PEARDATA_ELECTRON_DOWNLOAD_TIMEOUT_MS || 180000) const zipDir = path.join(root, '.cache', 'electron-zips') function withTimeout(promise, ms, label) { return new Promise((resolve, reject) => { const t = setTimeout(() => { reject(new Error(`[predownload-electron] timeout after ${ms}ms: ${label}`)) }, ms) promise.then( (v) => { clearTimeout(t) resolve(v) }, (e) => { clearTimeout(t) reject(e) } ) }) } async function main() { fs.mkdirSync(zipDir, { recursive: true }) if (process.env.ELECTRON_CACHE || process.env.electron_config_cache) { console.log( '[predownload-electron] cache:', process.env.ELECTRON_CACHE || process.env.electron_config_cache ) } console.log( `[predownload-electron] electron@${electronVersion} hosts: ${hosts.join(', ')}` ) for (const host of hosts) { const { platform, arch } = hostToElectron(host) const label = `${platform}-${arch}` const destName = `electron-v${electronVersion}-${platform}-${arch}.zip` const destPath = path.join(zipDir, destName) if (fs.existsSync(destPath) && fs.statSync(destPath).size > 1_000_000) { console.log(`[predownload-electron] skip (present): ${destName}`) continue } console.log(`[predownload-electron] downloading ${label}…`) const t0 = Date.now() const zipPath = await withTimeout( downloadArtifact({ version: electronVersion, platform, arch, artifactName: 'electron', }), timeoutMs, label ) fs.copyFileSync(zipPath, destPath) const mb = (fs.statSync(destPath).size / 1024 / 1024).toFixed(1) console.log( `[predownload-electron] ok ${label} → ${destName} (${mb} MB) in ${((Date.now() - t0) / 1000).toFixed(1)}s` ) } console.log(`[predownload-electron] zip dir: ${zipDir}`) console.log('[predownload-electron] done') } main().catch((err) => { console.error(err) process.exit(1) })