Files
gitlab-instance-0a899031_d2…/electron/scripts/download-chrome-for-testing.mjs
2026-03-24 17:35:28 -05:00

144 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 下载 Chrome for TestingStable / win64完整目录到 resources/chrome-cft/chrome-win64/
* 与 chrome.exe 同级的 DLL 等依赖一并保留,随安装包分发,开箱即用。
* 设置 SKIP_CHROME=1 可跳过CI 无网环境)。
*/
import fs from 'fs'
import https from 'https'
import path from 'path'
import { fileURLToPath } from 'url'
import AdmZip from 'adm-zip'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const root = path.resolve(__dirname, '..')
const resDir = path.join(root, 'resources', 'chrome-cft')
const CFT_JSON_URL =
'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json'
const PLATFORM_KEY = 'win64'
const markerName = '.chrome_cft_bundle_ok'
if (process.env.SKIP_CHROME === '1') {
console.log('[chrome-cft] SKIP_CHROME=1跳过下载')
process.exit(0)
}
function downloadBuffer(url) {
return new Promise((resolve, reject) => {
https
.get(url, (res) => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
downloadBuffer(res.headers.location).then(resolve).catch(reject)
return
}
if (res.statusCode !== 200) {
reject(new Error(`HTTP ${res.statusCode} ${url}`))
return
}
const chunks = []
res.on('data', (c) => chunks.push(c))
res.on('end', () => resolve(Buffer.concat(chunks)))
res.on('error', reject)
})
.on('error', reject)
})
}
function downloadToFile(url, dest) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(dest)
https
.get(url, (res) => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
file.close()
try {
fs.unlinkSync(dest)
} catch {
/* ignore */
}
downloadToFile(res.headers.location, dest).then(resolve).catch(reject)
return
}
if (res.statusCode !== 200) {
file.close()
reject(new Error(`HTTP ${res.statusCode}`))
return
}
res.pipe(file)
file.on('finish', () => {
file.close()
resolve()
})
})
.on('error', (e) => {
try {
file.close()
} catch {
/* ignore */
}
reject(e)
})
})
}
const chromeExe = path.join(resDir, 'chrome-win64', 'chrome.exe')
const markerPath = path.join(resDir, markerName)
fs.mkdirSync(resDir, { recursive: true })
if (fs.existsSync(chromeExe) && fs.existsSync(markerPath)) {
console.log('[chrome-cft] 已存在完整包,跳过:', chromeExe)
process.exit(0)
}
console.log('[chrome-cft] 获取元数据:', CFT_JSON_URL)
const metaBuf = await downloadBuffer(CFT_JSON_URL)
const doc = JSON.parse(metaBuf.toString('utf-8'))
const stable = doc.channels?.Stable
const list = stable?.downloads?.chrome ?? []
const hit = list.find((x) => x.platform === PLATFORM_KEY)
if (!hit?.url) {
console.error('[chrome-cft] 元数据中无', PLATFORM_KEY)
process.exit(1)
}
const zipPath = path.join(resDir, '_chrome-download.zip')
console.log('[chrome-cft] 下载(体积较大):', hit.url)
await downloadToFile(hit.url, zipPath)
console.log('[chrome-cft] 解压中…')
const zip = new AdmZip(zipPath)
const tmp = path.join(resDir, '_extract_tmp')
if (fs.existsSync(tmp)) fs.rmSync(tmp, { recursive: true })
fs.mkdirSync(tmp, { recursive: true })
zip.extractAllTo(tmp, true)
const inner = path.join(tmp, 'chrome-win64')
if (!fs.existsSync(path.join(inner, 'chrome.exe'))) {
console.error('[chrome-cft] zip 内未找到 chrome-win64/chrome.exe')
process.exit(1)
}
const destDir = path.join(resDir, 'chrome-win64')
if (fs.existsSync(destDir)) fs.rmSync(destDir, { recursive: true })
fs.cpSync(inner, destDir, { recursive: true })
fs.rmSync(tmp, { recursive: true })
try {
fs.unlinkSync(zipPath)
} catch {
/* ignore */
}
fs.writeFileSync(
path.join(resDir, 'NOTICE-ChromeForTesting.txt'),
[
'本目录包含 Chrome for TestingStable / Windows x64。',
'清单来源:' + CFT_JSON_URL,
'与 chrome.exe 同目录文件均为官方 zip 原样复制,未修改二进制。',
'',
].join('\n'),
'utf-8',
)
fs.writeFileSync(markerPath, `${stable.version}\n${new Date().toISOString()}\n`, 'utf-8')
console.log('[chrome-cft] 完成:', chromeExe)