conflicts

This commit is contained in:
Jozef Steinhübl 2026-01-05 12:39:31 +01:00
commit ff52cf1833
No known key found for this signature in database
GPG Key ID: 8D9A5E4549AA84FD
5 changed files with 368 additions and 165 deletions

View File

@ -50,6 +50,7 @@ jobs:
- ubuntu-latest - ubuntu-latest
- macos-latest - macos-latest
- windows-latest - windows-latest
- windows-11-arm
bun-version: bun-version:
- latest - latest
- canary - canary
@ -98,6 +99,7 @@ jobs:
- ubuntu-latest - ubuntu-latest
- macos-latest - macos-latest
- windows-latest - windows-latest
- windows-11-arm
file: file:
- name: package.json (packageManager bun@1.1.0) - name: package.json (packageManager bun@1.1.0)

289
dist/setup/index.js generated vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
import { compareVersions, satisfies, validate } from "compare-versions"; import { compareVersions, satisfies, validate } from "compare-versions";
import { Input } from "./action"; import { Input } from "./action";
import { getArchitecture, getPlatform, request } from "./utils"; import { getArchitecture, getAvx2, getPlatform, request } from "./utils";
export async function getDownloadUrl(options: Input): Promise<string> { export async function getDownloadUrl(options: Input): Promise<string> {
const { customUrl } = options; const { customUrl } = options;
@ -50,8 +50,14 @@ async function getSemverDownloadUrl(options: Input): Promise<string> {
const eversion = encodeURIComponent(tag ?? version); const eversion = encodeURIComponent(tag ?? version);
const eos = encodeURIComponent(os ?? getPlatform()); const eos = encodeURIComponent(os ?? getPlatform());
const earch = encodeURIComponent(arch ?? getArchitecture()); const earch = encodeURIComponent(
const eavx2 = encodeURIComponent(avx2 === false ? "-baseline" : ""); getArchitecture(os ?? getPlatform(), arch ?? process.arch),
);
const eavx2 = encodeURIComponent(
getAvx2(os ?? getPlatform(), arch ?? process.arch, avx2) === false
? "-baseline"
: "",
);
const eprofile = encodeURIComponent(profile === true ? "-profile" : ""); const eprofile = encodeURIComponent(profile === true ? "-profile" : "");
const { href } = new URL( const { href } = new URL(

View File

@ -42,13 +42,33 @@ export function getPlatform(): string {
return platform; return platform;
} }
export function getArchitecture(): string { export function getArchitecture(os: string, arch: string): string {
const arch = process.arch; if (os === "windows" && (arch === "aarch64" || arch === "arm64")) {
if (arch === "arm64") return "aarch64"; warning(
[
"⚠️ Bun does not provide native arm64 builds for Windows.",
"Using x64 baseline build which will run through Microsoft's x64 emulation layer.",
"This may result in reduced performance and potential compatibility issues.",
"💡 For best performance, consider using x64 Windows runners or other platforms with native support.",
].join("\n"),
);
return "x64";
}
if (arch === "arm64") return "aarch64";
return arch; return arch;
} }
export function getAvx2(os: string, arch: string, avx2?: boolean): boolean {
// Temporary workaround for absence of arm64 builds on Windows (#130)
if (os === "windows" && (arch === "aarch64" || arch === "arm64")) {
return false;
}
return avx2 ?? true;
}
const FILE_VERSION_READERS = { const FILE_VERSION_READERS = {
"package.json": (content: string) => { "package.json": (content: string) => {
const pkg = JSON.parse(content); const pkg = JSON.parse(content);

View File

@ -1,114 +1,124 @@
import { describe, expect, it, beforeEach, afterEach } from "bun:test"; import { afterEach, describe, expect, it, spyOn } from "bun:test";
import { existsSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; import { getArchitecture, getAvx2 } from "../src/utils";
import { readVersionFromFile } from "../src/utils"; import * as core from "@actions/core";
import { resolve } from "node:path";
import { tmpdir } from "node:os";
describe("readVersionFromFile", () => { describe("getArchitecture", () => {
const testDir = resolve(tmpdir(), "setup-bun-tests"); let warningSpy: ReturnType<typeof spyOn>;
const originalWorkspace = process.env.GITHUB_WORKSPACE;
beforeEach(() => {
// Set up test directory
if (!existsSync(testDir)) {
mkdirSync(testDir, { recursive: true });
}
process.env.GITHUB_WORKSPACE = testDir;
});
afterEach(() => { afterEach(() => {
// Clean up test directory warningSpy?.mockRestore();
try {
if (existsSync(testDir)) {
rmSync(testDir, { recursive: true, force: true });
}
} catch (error) {
console.error("Error cleaning up test files:", error);
}
process.env.GITHUB_WORKSPACE = originalWorkspace;
}); });
describe("package.json with packageManager field", () => { it("should return x64 for Windows with arm64 architecture", () => {
it("should read version from packageManager field", () => { warningSpy = spyOn(core, "warning");
const packageJson = { const result = getArchitecture("windows", "arm64");
name: "test",
packageManager: "bun@1.0.25", expect(result).toBe("x64");
}; expect(warningSpy).toHaveBeenCalledTimes(1);
writeFileSync( expect(warningSpy).toHaveBeenCalledWith(
resolve(testDir, "package.json"), expect.stringContaining(
JSON.stringify(packageJson, null, 2) "⚠️ Bun does not provide native arm64 builds for Windows."
)
); );
const version = readVersionFromFile("package.json");
expect(version).toBe("1.0.25");
}); });
it("should fallback to engines.bun when packageManager doesn't exist", () => { it("should return x64 for Windows with aarch64 architecture", () => {
const packageJson = { warningSpy = spyOn(core, "warning");
name: "test", const result = getArchitecture("windows", "aarch64");
engines: {
bun: ">=1.0.0", expect(result).toBe("x64");
}, expect(warningSpy).toHaveBeenCalledTimes(1);
}; expect(warningSpy).toHaveBeenCalledWith(
writeFileSync( expect.stringContaining(
resolve(testDir, "package.json"), "⚠️ Bun does not provide native arm64 builds for Windows."
JSON.stringify(packageJson, null, 2) )
); );
const version = readVersionFromFile("package.json");
expect(version).toBe(">=1.0.0");
}); });
it("should return undefined when neither packageManager nor engines.bun exist (with warning)", () => { it("should return aarch64 for non-Windows platforms with arm64", () => {
const packageJson = { warningSpy = spyOn(core, "warning");
name: "test", const result = getArchitecture("linux", "arm64");
};
writeFileSync(
resolve(testDir, "package.json"),
JSON.stringify(packageJson, null, 2)
);
const version = readVersionFromFile("package.json"); expect(result).toBe("aarch64");
expect(version).toBeUndefined(); expect(warningSpy).not.toHaveBeenCalled();
});
it("should return aarch64 for macOS with arm64", () => {
warningSpy = spyOn(core, "warning");
const result = getArchitecture("darwin", "arm64");
expect(result).toBe("aarch64");
expect(warningSpy).not.toHaveBeenCalled();
});
it("should return original arch value for x64", () => {
warningSpy = spyOn(core, "warning");
const result = getArchitecture("windows", "x64");
expect(result).toBe("x64");
expect(warningSpy).not.toHaveBeenCalled();
});
it("should return original arch value for x86", () => {
warningSpy = spyOn(core, "warning");
const result = getArchitecture("linux", "x86");
expect(result).toBe("x86");
expect(warningSpy).not.toHaveBeenCalled();
});
it("should return original arch value for aarch64 on Linux", () => {
warningSpy = spyOn(core, "warning");
const result = getArchitecture("linux", "aarch64");
expect(result).toBe("aarch64");
expect(warningSpy).not.toHaveBeenCalled();
}); });
}); });
describe("silent mode", () => { describe("getAvx2", () => {
it("should not warn when file doesn't exist and silent is true", () => { it("should return false when called with os: 'windows' and arch: 'arm64'", () => {
// This should not produce a warning const result = getAvx2("windows", "arm64");
const version = readVersionFromFile("package.json", true); expect(result).toBe(false);
expect(version).toBeUndefined();
}); });
it("should not warn when version cannot be read and silent is true", () => { it("should return false when called with os: 'windows' and arch: 'aarch64'", () => {
const packageJson = { const result = getAvx2("windows", "aarch64");
name: "test", expect(result).toBe(false);
};
writeFileSync(
resolve(testDir, "package.json"),
JSON.stringify(packageJson, null, 2)
);
const version = readVersionFromFile("package.json", true);
expect(version).toBeUndefined();
});
}); });
describe(".bun-version file", () => { it("should return false when called with os: 'windows', arch: 'arm64', and avx2: true", () => {
it("should read version from .bun-version file", () => { const result = getAvx2("windows", "arm64", true);
writeFileSync(resolve(testDir, ".bun-version"), "1.0.20"); expect(result).toBe(false);
const version = readVersionFromFile(".bun-version");
expect(version).toBe("1.0.20");
});
}); });
describe(".tool-versions file", () => { it("should return false when called with os: 'windows', arch: 'aarch64', and avx2: false", () => {
it("should read bun version from .tool-versions file", () => { const result = getAvx2("windows", "aarch64", false);
writeFileSync(resolve(testDir, ".tool-versions"), "nodejs 18.0.0\nbun 1.0.15\npython 3.9.0"); expect(result).toBe(false);
});
const version = readVersionFromFile(".tool-versions"); it("should return the provided avx2 value (true) when specified and not on Windows ARM64", () => {
expect(version).toBe("1.0.15"); expect(getAvx2("linux", "x64", true)).toBe(true);
}); expect(getAvx2("darwin", "x64", true)).toBe(true);
expect(getAvx2("windows", "x64", true)).toBe(true);
});
it("should return the provided avx2 value (false) when specified and not on Windows ARM64", () => {
expect(getAvx2("linux", "x64", false)).toBe(false);
expect(getAvx2("darwin", "x64", false)).toBe(false);
expect(getAvx2("windows", "x64", false)).toBe(false);
});
it("should return true by default when avx2 is not specified and not on Windows ARM64", () => {
// x64 architecture on various platforms
expect(getAvx2("linux", "x64")).toBe(true);
expect(getAvx2("darwin", "x64")).toBe(true);
expect(getAvx2("windows", "x64")).toBe(true);
// ARM architecture on non-Windows platforms
expect(getAvx2("linux", "arm64")).toBe(true);
expect(getAvx2("linux", "aarch64")).toBe(true);
expect(getAvx2("darwin", "arm64")).toBe(true);
expect(getAvx2("darwin", "aarch64")).toBe(true);
}); });
}); });