mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
ci: Add bootstrap.ps1 and automate Windows build images (#15466)
Co-authored-by: Electroid <Electroid@users.noreply.github.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
getBuildUrl,
|
||||
getEnv,
|
||||
getFileUrl,
|
||||
getLoggedInUserCount,
|
||||
getWindowsExitReason,
|
||||
isArm64,
|
||||
isBuildkite,
|
||||
@@ -59,6 +60,10 @@ const { values: options, positionals: filters } = parseArgs({
|
||||
type: "string",
|
||||
default: undefined,
|
||||
},
|
||||
["build-id"]: {
|
||||
type: "string",
|
||||
default: undefined,
|
||||
},
|
||||
["bail"]: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
@@ -99,32 +104,7 @@ const { values: options, positionals: filters } = parseArgs({
|
||||
async function runTests() {
|
||||
let execPath;
|
||||
if (options["step"]) {
|
||||
downloadLoop: for (let i = 0; i < 10; i++) {
|
||||
execPath = await getExecPathFromBuildKite(options["step"]);
|
||||
for (let j = 0; j < 10; j++) {
|
||||
const { error } = spawnSync(execPath, ["--version"], {
|
||||
encoding: "utf-8",
|
||||
timeout: spawnTimeout,
|
||||
env: {
|
||||
PATH: process.env.PATH,
|
||||
BUN_DEBUG_QUIET_LOGS: 1,
|
||||
},
|
||||
});
|
||||
if (!error) {
|
||||
break downloadLoop;
|
||||
}
|
||||
const { code } = error;
|
||||
if (code === "EBUSY") {
|
||||
console.log("Bun appears to be busy, retrying...");
|
||||
continue;
|
||||
}
|
||||
if (code === "UNKNOWN") {
|
||||
console.log("Bun appears to be corrupted, downloading again...");
|
||||
rmSync(execPath, { force: true });
|
||||
continue downloadLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
execPath = await getExecPathFromBuildKite(options["step"], options["build-id"]);
|
||||
} else {
|
||||
execPath = getExecPath(options["exec-path"]);
|
||||
}
|
||||
@@ -1080,9 +1060,10 @@ function getExecPath(bunExe) {
|
||||
|
||||
/**
|
||||
* @param {string} target
|
||||
* @param {string} [buildId]
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function getExecPathFromBuildKite(target) {
|
||||
async function getExecPathFromBuildKite(target, buildId) {
|
||||
if (existsSync(target) || target.includes("/")) {
|
||||
return getExecPath(target);
|
||||
}
|
||||
@@ -1090,23 +1071,27 @@ async function getExecPathFromBuildKite(target) {
|
||||
const releasePath = join(cwd, "release");
|
||||
mkdirSync(releasePath, { recursive: true });
|
||||
|
||||
const args = ["artifact", "download", "**", releasePath, "--step", target];
|
||||
const buildId = process.env["BUILDKITE_ARTIFACT_BUILD_ID"];
|
||||
if (buildId) {
|
||||
args.push("--build", buildId);
|
||||
}
|
||||
|
||||
await spawnSafe({
|
||||
command: "buildkite-agent",
|
||||
args,
|
||||
});
|
||||
|
||||
let zipPath;
|
||||
for (const entry of readdirSync(releasePath, { recursive: true, encoding: "utf-8" })) {
|
||||
if (/^bun.*\.zip$/i.test(entry) && !entry.includes("-profile.zip")) {
|
||||
zipPath = join(releasePath, entry);
|
||||
break;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const args = ["artifact", "download", "**", releasePath, "--step", target];
|
||||
if (buildId) {
|
||||
args.push("--build", buildId);
|
||||
}
|
||||
|
||||
await spawnSafe({
|
||||
command: "buildkite-agent",
|
||||
args,
|
||||
});
|
||||
|
||||
for (const entry of readdirSync(releasePath, { recursive: true, encoding: "utf-8" })) {
|
||||
if (/^bun.*\.zip$/i.test(entry) && !entry.includes("-profile.zip")) {
|
||||
zipPath = join(releasePath, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.warn(`Waiting for ${target}.zip to be available...`);
|
||||
await new Promise(resolve => setTimeout(resolve, i * 1000));
|
||||
}
|
||||
|
||||
if (!zipPath) {
|
||||
@@ -1115,13 +1100,15 @@ async function getExecPathFromBuildKite(target) {
|
||||
|
||||
await unzip(zipPath, releasePath);
|
||||
|
||||
for (const entry of readdirSync(releasePath, { recursive: true, encoding: "utf-8" })) {
|
||||
const releaseFiles = readdirSync(releasePath, { recursive: true, encoding: "utf-8" });
|
||||
for (const entry of releaseFiles) {
|
||||
const execPath = join(releasePath, entry);
|
||||
if (/bun(?:\.exe)?$/i.test(entry) && isExecutable(execPath)) {
|
||||
if (/bun(?:\.exe)?$/i.test(entry) && statSync(execPath).isFile()) {
|
||||
return execPath;
|
||||
}
|
||||
}
|
||||
|
||||
console.warn(`Found ${releaseFiles.length} files in ${releasePath}:`);
|
||||
throw new Error(`Could not find executable from BuildKite: ${releasePath}`);
|
||||
}
|
||||
|
||||
@@ -1466,8 +1453,39 @@ export async function main() {
|
||||
}
|
||||
|
||||
printEnvironment();
|
||||
|
||||
// FIXME: Some DNS tests hang unless we set the DNS server to 8.8.8.8
|
||||
// It also appears to hang on 1.1.1.1, which could explain this issue:
|
||||
// https://github.com/oven-sh/bun/issues/11136
|
||||
if (isWindows && isCI) {
|
||||
await spawn("pwsh", [
|
||||
"-Command",
|
||||
"Set-DnsClientServerAddress -InterfaceAlias 'Ethernet 4' -ServerAddresses ('8.8.8.8','8.8.4.4')",
|
||||
]);
|
||||
}
|
||||
|
||||
const results = await runTests();
|
||||
const ok = results.every(({ ok }) => ok);
|
||||
|
||||
let waitForUser = false;
|
||||
while (isCI) {
|
||||
const userCount = getLoggedInUserCount();
|
||||
if (!userCount) {
|
||||
if (waitForUser) {
|
||||
console.log("No users logged in, exiting runner...");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!waitForUser) {
|
||||
startGroup("Summary");
|
||||
console.warn(`Found ${userCount} users logged in, keeping the runner alive until logout...`);
|
||||
waitForUser = true;
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 60_000));
|
||||
}
|
||||
|
||||
process.exit(getExitCode(ok ? "pass" : "fail"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user