Files
sir1st 00ea452310 Codex/pr 1217 (#1226)
* bundle node and windows git runtimes

* split desktop runtime into release package

* fix desktop runtime packaging ci

* embed desktop runtime release tag

* show desktop runtime download progress

* fix desktop runtime release handling

* refactor desktop runtime version config

* fix desktop package license

---------

Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
Co-authored-by: ekko <fqsy1416@gmail.com>
2026-06-02 08:55:17 +08:00

86 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
// Download Git for Windows MinGit for Windows builds. Other platforms create
// an empty resource directory so electron-builder can use the same resource map.
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { arch as osArch, platform as osPlatform, tmpdir } from 'node:os'
import { spawnSync } from 'node:child_process'
const __dirname = dirname(fileURLToPath(import.meta.url))
const ROOT = resolve(__dirname, '..')
const TARGET_OS = process.env.TARGET_OS || osPlatform()
const TARGET_ARCH = process.env.TARGET_ARCH || osArch()
const OS_LABEL = TARGET_OS === 'win32' ? 'win' : TARGET_OS === 'darwin' ? 'mac' : TARGET_OS
const OUT_DIR = resolve(ROOT, 'resources', 'git', `${OS_LABEL}-${TARGET_ARCH}`)
mkdirSync(OUT_DIR, { recursive: true })
if (TARGET_OS !== 'win32') {
writeFileSync(resolve(OUT_DIR, '.placeholder'), 'Git for Windows is only bundled on Windows.\n')
console.log(`Git resource placeholder ready at ${OUT_DIR}`)
process.exit(0)
}
if (TARGET_ARCH !== 'x64') {
console.error(`Unsupported Git for Windows target: ${TARGET_OS}-${TARGET_ARCH}`)
process.exit(1)
}
if (existsSync(resolve(OUT_DIR, 'cmd', 'git.exe'))) {
console.log(`Git for Windows already present at ${OUT_DIR}, skipping`)
process.exit(0)
}
async function latestMinGitUrl() {
if (process.env.GIT_FOR_WINDOWS_URL?.trim()) return process.env.GIT_FOR_WINDOWS_URL.trim()
const headers = { 'User-Agent': 'hermes-studio-desktop-build' }
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
if (token?.trim()) headers.Authorization = `Bearer ${token.trim()}`
const response = await fetch('https://api.github.com/repos/git-for-windows/git/releases/latest', {
headers,
})
if (!response.ok) {
throw new Error(`GitHub API returned ${response.status}`)
}
const release = await response.json()
const asset = release.assets?.find(candidate =>
typeof candidate?.name === 'string'
&& /^MinGit-.*-64-bit\.zip$/.test(candidate.name)
&& typeof candidate.browser_download_url === 'string',
)
if (!asset) throw new Error('Could not find MinGit 64-bit zip in latest Git for Windows release')
return asset.browser_download_url
}
let url
try {
url = await latestMinGitUrl()
} catch (err) {
console.error(`Failed to resolve Git for Windows download URL: ${err instanceof Error ? err.message : String(err)}`)
process.exit(1)
}
const file = url.split('/').pop() || 'mingit.zip'
const archivePath = resolve(tmpdir(), file)
console.log(`Fetching ${url}`)
const curl = spawnSync('curl', ['-fL', '--retry', '3', '-o', archivePath, url], { stdio: 'inherit' })
if (curl.status !== 0) {
console.error('curl failed')
process.exit(curl.status ?? 1)
}
console.log(`Extracting into ${OUT_DIR}`)
const extract = spawnSync('tar', ['-xf', archivePath, '-C', OUT_DIR], { stdio: 'inherit' })
if (extract.status !== 0) {
console.error('extract failed')
process.exit(extract.status ?? 1)
}
rmSync(archivePath, { force: true })
console.log(`Git for Windows ready at ${OUT_DIR}`)