Skip to content

Commit ad6c0e5

Browse files
committed
Fix Windows baseline Bun compile in CI
1 parent d780a93 commit ad6c0e5

1 file changed

Lines changed: 83 additions & 1 deletion

File tree

cli/scripts/build-binary.ts

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
rmSync,
1313
writeFileSync,
1414
} from 'fs'
15-
import { tmpdir } from 'os'
15+
import { homedir, tmpdir } from 'os'
1616
import { dirname, join } from 'path'
1717
import { fileURLToPath } from 'url'
1818

@@ -28,6 +28,8 @@ const OVERRIDE_PLATFORM = process.env.OVERRIDE_PLATFORM as
2828
| NodeJS.Platform
2929
| undefined
3030
const OVERRIDE_ARCH = process.env.OVERRIDE_ARCH ?? undefined
31+
const OVERRIDE_COMPILE_EXECUTABLE_PATH =
32+
process.env.BUN_COMPILE_EXECUTABLE_PATH
3133

3234
const __filename = fileURLToPath(import.meta.url)
3335
const __dirname = dirname(__filename)
@@ -111,6 +113,82 @@ function getTargetInfo(): TargetInfo {
111113
return target
112114
}
113115

116+
async function getCompileExecutablePath(
117+
targetInfo: TargetInfo,
118+
): Promise<string | undefined> {
119+
if (OVERRIDE_COMPILE_EXECUTABLE_PATH) {
120+
return OVERRIDE_COMPILE_EXECUTABLE_PATH
121+
}
122+
123+
// Bun 1.3.11 can fail to extract this target from inside `bun build` on
124+
// Windows runners. Pre-fetch the official release zip and point Bun at the
125+
// extracted runtime so release and Freebuff CI builds still produce the
126+
// baseline binary.
127+
if (
128+
process.platform !== 'win32' ||
129+
targetInfo.bunTarget !== 'bun-windows-x64-baseline'
130+
) {
131+
return undefined
132+
}
133+
134+
const cacheRoot = join(
135+
process.env.BUN_INSTALL ?? join(homedir(), '.bun'),
136+
'install',
137+
'cache',
138+
)
139+
const runtimeDir = join(
140+
cacheRoot,
141+
`${targetInfo.bunTarget}-v${Bun.version}-runtime`,
142+
)
143+
const runtimePath = join(runtimeDir, 'bun.exe')
144+
145+
if (existsSync(runtimePath)) {
146+
return runtimePath
147+
}
148+
149+
rmSync(runtimeDir, { recursive: true, force: true })
150+
mkdirSync(runtimeDir, { recursive: true })
151+
152+
const zipPath = join(runtimeDir, `${targetInfo.bunTarget}.zip`)
153+
const downloadUrl = `https://github.com/oven-sh/bun/releases/download/bun-v${Bun.version}/${targetInfo.bunTarget}.zip`
154+
155+
logAlways(`Downloading ${targetInfo.bunTarget}: ${downloadUrl}`)
156+
const response = await fetch(downloadUrl)
157+
if (!response.ok) {
158+
throw new Error(
159+
`Failed to download ${targetInfo.bunTarget}: ${response.status} ${response.statusText}`,
160+
)
161+
}
162+
writeFileSync(zipPath, new Uint8Array(await response.arrayBuffer()))
163+
164+
runCommand(
165+
'powershell.exe',
166+
[
167+
'-NoProfile',
168+
'-NonInteractive',
169+
'-ExecutionPolicy',
170+
'Bypass',
171+
'-Command',
172+
`Expand-Archive -LiteralPath '${zipPath.replaceAll("'", "''")}' -DestinationPath '${runtimeDir.replaceAll("'", "''")}' -Force`,
173+
],
174+
{ env: process.env },
175+
)
176+
177+
const extractedRuntimePath = join(
178+
runtimeDir,
179+
'bun-windows-x64-baseline',
180+
'bun.exe',
181+
)
182+
if (!existsSync(extractedRuntimePath)) {
183+
throw new Error(
184+
`Downloaded ${targetInfo.bunTarget}, but bun.exe was not found at ${extractedRuntimePath}`,
185+
)
186+
}
187+
188+
writeFileSync(runtimePath, readFileSync(extractedRuntimePath))
189+
return runtimePath
190+
}
191+
114192
async function main() {
115193
const [, , binaryNameArg, version] = process.argv
116194
const binaryName = binaryNameArg ?? 'codecane'
@@ -122,6 +200,7 @@ async function main() {
122200
log(`Building ${binaryName} @ ${version}`)
123201

124202
const targetInfo = getTargetInfo()
203+
const compileExecutablePath = await getCompileExecutablePath(targetInfo)
125204
const binDir = join(cliRoot, 'bin')
126205

127206
if (!existsSync(binDir)) {
@@ -172,6 +251,9 @@ async function main() {
172251
'--compile',
173252
'--production', // Required so compiled binaries use the production JSX runtime (avoids jsxDEV crashes).
174253
`--target=${targetInfo.bunTarget}`,
254+
...(compileExecutablePath
255+
? [`--compile-executable-path=${compileExecutablePath}`]
256+
: []),
175257
`--outfile=${outputFile}`,
176258
'--sourcemap=none',
177259
...defineFlags.flatMap(([key, value]) => ['--define', `${key}=${value}`]),

0 commit comments

Comments
 (0)