Skip to content

refactor: simplify baseline version check, add native windows arm64 build#163

Closed
kane50613 wants to merge 4 commits intooven-sh:mainfrom
kane50613:main
Closed

refactor: simplify baseline version check, add native windows arm64 build#163
kane50613 wants to merge 4 commits intooven-sh:mainfrom
kane50613:main

Conversation

@kane50613
Copy link
Copy Markdown

@kane50613 kane50613 commented Feb 26, 2026

No description provided.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 26, 2026

Walkthrough

Adds Windows ARM64 handling: new version check/warning and fallback to x64+AVX2 disabled for unsupported Windows aarch64 tags; refactors architecture/AVX2 helpers to accept only architecture; updates download URL assembly and expands tests for Windows ARM64 behavior and utilities.

Changes

Cohort / File(s) Summary
Utils refactor & new helpers
src/utils.ts
Changed getArchitecture(arch: string) and getAvx2(arch: string, avx2?: boolean) signatures and logic (map arm64/aarch64aarch64, AVX2 true for ARM64); added exported MIN_WINDOWS_ARM64_VERSION, isWindowsArm64Supported(tag: string), and warnWindowsArm64(); added compare-versions/validation usage and updated exports.
Download URL logic
src/download-url.ts
Reworked architecture/AVX2 derivation to use the new arch-only helpers; added Windows ARM64 support check that may warn and downgrade arch to x64 and set avx2=false for unsupported tags; URL construction now uses adjusted arch/avx2 values.
Unit tests — utils
tests/utils.spec.ts
Replaced previous platform-focused tests with coverage for getArchitecture, getAvx2, isWindowsArm64Supported, and exported MIN_WINDOWS_ARM64_VERSION; removed old platform warning spies.
Unit tests — download URL
tests/download-url.spec.ts
Updated mock tags and expectations; added "Windows ARM64 Fallback" suite asserting URL outcomes and core.warning behavior for unsupported, minimum, canary, and latest tag scenarios.
🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No description was provided by the author, which is insufficient to evaluate relevance to the changeset. Add a description explaining the purpose of the Windows ARM64 support addition and the baseline version check simplification.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main changes: refactoring baseline version checks and adding native Windows ARM64 build support.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/download-url.ts`:
- Around line 67-70: The current filename construction (around getArchitecture
and getAvx2) always yields the windows-aarch64 asset for Windows ARM64; change
the download-resolution logic that builds the asset name (the function that
composes the filename using getArchitecture(...) and getAvx2(...)) so that after
composing the windows-aarch64 filename you check whether that asset actually
exists for the requested tag (e.g., with a HEAD or by checking the release
assets list), and if it does not exist, fall back to the windows-x64-baseline
filename variant before returning the URL; update any helper that computes
eavx2/getAvx2-based suffixes accordingly so the fallback uses the x64-baseline
naming.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ab8cb4e and a0c4dfc.

📒 Files selected for processing (3)
  • src/download-url.ts
  • src/utils.ts
  • tests/utils.spec.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/download-url.ts`:
- Around line 72-78: The code currently uses the URL-encoded variable eos for
platform branching which is brittle; introduce a raw osValue = os ??
getPlatform(), set eos = encodeURIComponent(osValue) for URL composition, and
change platform checks (e.g., the if that does eos === "windows" and calls
getArchitecture(archValue) and isWindowsArm64Supported(tag ?? version)) to use
osValue instead of eos; keep archValue and avx2Value logic unchanged and only
use eos when building the download URL.

In `@src/utils.ts`:
- Around line 65-71: The function isWindowsArm64Supported currently uses a
hardcoded cutoff "1.3.10"; extract that literal into a clearly named constant
(for example MIN_WINDOWS_ARM64_VERSION) at the top of the module and replace the
string in isWindowsArm64Supported with that constant so the policy boundary is
centralized and easier to update; keep the same validation and compareVersions
logic but refer to MIN_WINDOWS_ARM64_VERSION instead of the inline "1.3.10".
- Around line 76-79: The four warning strings in src/utils.ts currently read as
a global Windows ARM64 limitation; update them to be version-scoped so the log
makes clear this applies only to unsupported Bun/OS versions (e.g., change
phrasing to "On this OS/version, Bun does not provide native arm64 builds for
Windows" and similarly qualify the following lines to reference "on this
runner/version" or "on affected versions"); modify the string literals (the four
warning message entries) so they explicitly state the limitation is for the
detected/unsupported version rather than a general global statement and keep
existing contextual guidance (x64 fallback, performance caveats, suggestion to
use x64 runners). Ensure the updated messages are used wherever the original
message array/constant in src/utils.ts is referenced.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a0c4dfc and 24feafd.

⛔ Files ignored due to path filters (1)
  • dist/setup/index.js is excluded by !**/dist/**
📒 Files selected for processing (3)
  • src/download-url.ts
  • src/utils.ts
  • tests/download-url.spec.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils.ts`:
- Around line 8-10: The file contains an extra blank line after the
MIN_WINDOWS_ARM64_VERSION constant declaration; remove the redundant empty line
following the export of MIN_WINDOWS_ARM64_VERSION so the file has a single
newline at EOF and no double blank line after the constant.

In `@tests/download-url.spec.ts`:
- Around line 163-205: Add a test case exercising getDownloadUrl for version
"latest" on Windows/arm64 to assert it returns the aarch64 URL (same behavior as
canary and as dictated by isWindowsArm64Supported) and that no fallback warning
is emitted; locate the Windows ARM64 test suite (the describe block "Windows
ARM64 Fallback") and add an it block similar to the "canary" test but with
version: "latest" and expect the URL to be
"https://github.com/oven-sh/bun/releases/download/latest/bun-windows-aarch64.zip"
and do not expect core.warning to have been called.

In `@tests/utils.spec.ts`:
- Around line 29-34: Remove the unused variable declaration warningSpy from the
getArchitecture test suite: delete the line "let warningSpy: ReturnType<typeof
spyOn>;" and keep the existing afterEach block (remove any references to
warningSpy inside afterEach if present) so the suite no longer contains an
unused variable; verify getArchitecture tests still run and no other tests
reference warningSpy.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 24feafd and 0e6cdcb.

⛔ Files ignored due to path filters (1)
  • dist/setup/index.js is excluded by !**/dist/**
📒 Files selected for processing (4)
  • src/download-url.ts
  • src/utils.ts
  • tests/download-url.spec.ts
  • tests/utils.spec.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils.ts`:
- Around line 67-75: Add a unit test that verifies Windows ARM64 handling when a
semver range is passed through the download flow: specifically create a test
that calls the download URL resolution path so that isWindowsArm64Supported(tag
?? version) in download-url.ts receives a semver range (e.g., "^1.0.0") instead
of a concrete version, and assert the boolean result matches the expected
behavior; target the isWindowsArm64Supported function and the code path in
download-url.ts that computes tag/version (mock or supply the resolved version
as needed) to ensure semver ranges are correctly evaluated against
MIN_WINDOWS_ARM64_VERSION and special tags ("canary"/"latest") are still
handled.

In `@tests/download-url.spec.ts`:
- Around line 165-181: The test creates a spy via spyOn(core, "warning")
(warningSpy) but calls warningSpy.mockRestore() only at the end which can be
skipped if an assertion throws; wrap the test assertions and expectations in a
try/finally (or otherwise ensure cleanup) so that warningSpy.mockRestore() runs
in the finally block to prevent the spy from leaking into other tests; apply the
same change to the other similar test block (the one around lines 207-220) that
also uses spyOn(core, "warning") and warningSpy.mockRestore().

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0e6cdcb and aa3fc1a.

📒 Files selected for processing (3)
  • src/utils.ts
  • tests/download-url.spec.ts
  • tests/utils.spec.ts

Comment on lines +67 to +75
export function isWindowsArm64Supported(tag: string): boolean {
if (tag === "canary" || tag === "latest") return true;

const version = tag.startsWith("bun-v") ? tag.slice(5) : tag;

return (
validate(version) &&
compareVersions(version, MIN_WINDOWS_ARM64_VERSION) >= 0
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== 1) Find where Windows ARM64 support is gated ==="
rg -n -C4 '\bisWindowsArm64Supported\s*\(' src/download-url.ts

echo ""
echo "=== 2) Inspect version resolution flow around dynamic inputs ==="
rg -n -C4 '\b(latest|canary|satisfies|maxSatisfying|resolved|version)\b' src/download-url.ts

echo ""
echo "=== 3) Check current tests for Windows ARM64 + semver range coverage ==="
rg -n -C3 'Windows ARM64|\^1\.0\.0|arch:\s*"arm64"' tests/download-url.spec.ts tests/utils.spec.ts 2>/dev/null || echo "Test files or patterns not found"

echo ""
echo "=== 4) Check if validate function is available and its behavior ==="
rg -n 'validate\(' src/utils.ts | head -20

echo ""
echo "=== 5) Find all imports in utils.ts to understand dependencies ==="
head -20 src/utils.ts

Repository: oven-sh/setup-bun

Length of output: 5652


Add test coverage for Windows ARM64 with semver range inputs.

The version resolution flow (lines 30–69) should provide a concrete version to isWindowsArm64Supported(tag ?? version) at line 79 of download-url.ts. However, there is no test verifying that Windows ARM64 correctly handles semver ranges like "^1.0.0". The existing Windows ARM64 tests only use concrete versions ("1.1.0", MIN_WINDOWS_ARM64_VERSION) and special tags ("canary", "latest"). The fallback path tag ?? version is untested, and while the code flow suggests tag should be defined, an explicit test for Windows ARM64 + semver range would validate the assumption and ensure the function returns the expected value when a range is passed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils.ts` around lines 67 - 75, Add a unit test that verifies Windows
ARM64 handling when a semver range is passed through the download flow:
specifically create a test that calls the download URL resolution path so that
isWindowsArm64Supported(tag ?? version) in download-url.ts receives a semver
range (e.g., "^1.0.0") instead of a concrete version, and assert the boolean
result matches the expected behavior; target the isWindowsArm64Supported
function and the code path in download-url.ts that computes tag/version (mock or
supply the resolved version as needed) to ensure semver ranges are correctly
evaluated against MIN_WINDOWS_ARM64_VERSION and special tags ("canary"/"latest")
are still handled.

Comment on lines +165 to +181
it("should fallback to x64-baseline for versions older than MIN_WINDOWS_ARM64_VERSION and log a warning", async () => {
const warningSpy = spyOn(core, "warning");
const url = await getDownloadUrl({
version: "1.1.0",
os: "windows",
arch: "arm64",
});

expect(url).toBe(
"https://github.com/oven-sh/bun/releases/download/bun-v1.1.0/bun-windows-x64-baseline.zip",
);
expect(warningSpy).toHaveBeenCalled();
expect(warningSpy.mock.calls[0][0]).toContain(
"On this OS/version, Bun does not provide native arm64 builds for Windows",
);
warningSpy.mockRestore();
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Restore warning spies in finally to prevent cross-test leakage on failure.

If an assertion throws before mockRestore(), the spy can bleed into later tests and create noisy failures.

♻️ Suggested hardening
     it("should fallback to x64-baseline for versions older than MIN_WINDOWS_ARM64_VERSION and log a warning", async () => {
       const warningSpy = spyOn(core, "warning");
-      const url = await getDownloadUrl({
-        version: "1.1.0",
-        os: "windows",
-        arch: "arm64",
-      });
-
-      expect(url).toBe(
-        "https://github.com/oven-sh/bun/releases/download/bun-v1.1.0/bun-windows-x64-baseline.zip",
-      );
-      expect(warningSpy).toHaveBeenCalled();
-      expect(warningSpy.mock.calls[0][0]).toContain(
-        "On this OS/version, Bun does not provide native arm64 builds for Windows",
-      );
-      warningSpy.mockRestore();
+      try {
+        const url = await getDownloadUrl({
+          version: "1.1.0",
+          os: "windows",
+          arch: "arm64",
+        });
+
+        expect(url).toBe(
+          "https://github.com/oven-sh/bun/releases/download/bun-v1.1.0/bun-windows-x64-baseline.zip",
+        );
+        expect(warningSpy).toHaveBeenCalled();
+        expect(warningSpy.mock.calls[0][0]).toContain(
+          "On this OS/version, Bun does not provide native arm64 builds for Windows",
+        );
+      } finally {
+        warningSpy.mockRestore();
+      }
     });
@@
     it("should use aarch64 for latest", async () => {
       const warningSpy = spyOn(core, "warning");
-      const url = await getDownloadUrl({
-        version: "latest",
-        os: "windows",
-        arch: "arm64",
-      });
-
-      expect(url).toBe(
-        "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-windows-aarch64.zip",
-      );
-      expect(warningSpy).not.toHaveBeenCalled();
-      warningSpy.mockRestore();
+      try {
+        const url = await getDownloadUrl({
+          version: "latest",
+          os: "windows",
+          arch: "arm64",
+        });
+
+        expect(url).toBe(
+          "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-windows-aarch64.zip",
+        );
+        expect(warningSpy).not.toHaveBeenCalled();
+      } finally {
+        warningSpy.mockRestore();
+      }
     });

Also applies to: 207-220

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/download-url.spec.ts` around lines 165 - 181, The test creates a spy
via spyOn(core, "warning") (warningSpy) but calls warningSpy.mockRestore() only
at the end which can be skipped if an assertion throws; wrap the test assertions
and expectations in a try/finally (or otherwise ensure cleanup) so that
warningSpy.mockRestore() runs in the finally block to prevent the spy from
leaking into other tests; apply the same change to the other similar test block
(the one around lines 207-220) that also uses spyOn(core, "warning") and
warningSpy.mockRestore().

@xhyrom
Copy link
Copy Markdown
Collaborator

xhyrom commented Feb 26, 2026

Thank you for opening this pull request so quickly. I really appreciate the effort. :)
Although this works, i’ve also taken a look at #165, and I prefer that implementation slightly more. It feels a bit simpler and more straightforward to me.

Anyway, thank you for the effort and for taking the time to work on this.

@xhyrom xhyrom closed this Feb 26, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the version and architecture handling logic to support native Windows ARM64 builds starting from Bun version 1.3.10, while maintaining backward compatibility with older versions by falling back to x64-baseline builds.

Changes:

  • Simplified getArchitecture and getAvx2 functions by removing OS-specific parameters, moving platform-specific logic to the download URL builder
  • Added version-based Windows ARM64 support detection with fallback to x64-baseline for versions < 1.3.10
  • Updated all tests to reflect the refactored API and added comprehensive Windows ARM64 test scenarios

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

File Description
src/utils.ts Added MIN_WINDOWS_ARM64_VERSION constant, refactored getArchitecture/getAvx2 to remove OS parameter, added isWindowsArm64Supported and warnWindowsArm64 functions
src/download-url.ts Integrated Windows ARM64 version checking logic, conditionally falls back to x64-baseline for unsupported versions
tests/utils.spec.ts Added tests for isWindowsArm64Supported, updated getArchitecture/getAvx2 tests to match new simplified signatures
tests/download-url.spec.ts Added comprehensive Windows ARM64 fallback test scenarios, updated MOCK_TAGS to include version 1.3.10

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

export function isWindowsArm64Supported(tag: string): boolean {
if (tag === "canary" || tag === "latest") return true;
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for "latest" in this function appears to be unreachable in the current code flow. When version is "latest", it gets resolved to a concrete version tag (e.g., "bun-v1.3.10") in download-url.ts before being passed to this function. The function still works correctly via version comparison, but the "latest" special case check never executes. Consider documenting this or restructuring the code to make the intent clearer.

Suggested change
if (tag === "canary" || tag === "latest") return true;
// Treat "canary" as always supporting Windows arm64; all other tags are
// evaluated via semantic version comparison against MIN_WINDOWS_ARM64_VERSION.
if (tag === "canary") return true;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants