Skip to content

Comments

perf: avoid unnecessary api calls#161

Merged
xhyrom merged 2 commits intomainfrom
perf/avoid-unnecessary-api-calls
Feb 5, 2026
Merged

perf: avoid unnecessary api calls#161
xhyrom merged 2 commits intomainfrom
perf/avoid-unnecessary-api-calls

Conversation

@xhyrom
Copy link
Collaborator

@xhyrom xhyrom commented Feb 5, 2026

closes #159

Copilot AI review requested due to automatic review settings February 5, 2026 15:00
@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Walkthrough

Modified download URL resolution to precompute tags for valid versions and defer GitHub API calls when possible, reducing unnecessary requests. Added comprehensive test suite validating optimization paths and dynamic version resolution scenarios.

Changes

Cohort / File(s) Summary
Tag Resolution Optimization
src/download-url.ts
Introduced early path for strictly valid versions that precomputes tags without API calls. Refactored tag resolution logic to defer GitHub API fetches only when tag determination is required, avoiding immediate fetches for direct version matches. Updated matchedTag resolution with improved filtering and normalization flow for bun-v prefixed tags.
Test Coverage
tests/download-url.spec.ts
Comprehensive test suite for getDownloadUrl function covering custom URL behavior, static version optimization (no API calls), dynamic version resolution (latest, semver ranges, canary), error handling for unmatched ranges, and token propagation in API requests.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'perf: avoid unnecessary api calls' clearly and concisely summarizes the main objective of the PR, which is to optimize by reducing unnecessary API calls.
Description check ✅ Passed The description references the linked issue #159 which directly relates to the PR's objective of avoiding unnecessary API calls, establishing the connection to the changeset.
Linked Issues check ✅ Passed The code changes implement early path validation for strict versions to avoid API calls when possible, add fallback tag resolution logic, and include comprehensive tests covering both optimization paths and API-driven fallback scenarios, directly addressing issue #159's requirement.
Out of Scope Changes check ✅ Passed All changes focus on optimizing the download URL resolution to avoid unnecessary API calls and include appropriate test coverage, with no unrelated modifications detected.

✏️ 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
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 optimizes the download URL generation process by avoiding unnecessary GitHub API calls when a specific version number is provided. Instead of always fetching all tags from the API, the code now directly constructs the download URL for exact version strings (e.g., "1.0.0"), only falling back to the API for dynamic versions like "latest", "canary", or semver ranges.

Changes:

  • Added validateStrict import to check if a version string is an exact semantic version
  • Modified getSemverDownloadUrl to skip API calls when an exact version is provided
  • Added comprehensive test coverage for both optimized (no API call) and dynamic (API lookup) scenarios

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/download-url.ts Implements optimization to construct download URLs directly for exact versions, avoiding API calls
tests/download-url.spec.ts Adds test suite verifying API call avoidance for exact versions and proper API usage for dynamic versions

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

@xhyrom xhyrom merged commit 196aaa2 into main Feb 5, 2026
83 checks passed
@xhyrom xhyrom deleted the perf/avoid-unnecessary-api-calls branch February 5, 2026 15:05
Copy link

@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

🤖 Fix all issues with AI agents
In `@tests/download-url.spec.ts`:
- Around line 92-104: Add a test that covers the case where version is undefined
or an empty string so the branch in getDownloadUrl that treats "latest" ||
!version is exercised; in tests/download-url.spec.ts add an it() that calls
getDownloadUrl({ version: undefined, os: "linux", arch: "x64" }) (and another
variant for "" if desired), asserts the same expected URL as the "latest" test,
and verifies requestSpy was called once to ensure the API lookup path is used.
- Around line 132-141: The test calling getDownloadUrl uses
expect(...).rejects.toThrow without awaiting the returned promise; update the
test for the "should throw error if semver range matches nothing" case to await
the rejects assertion (i.e., await
expect(getDownloadUrl({...})).rejects.toThrow(...)) so the rejection is actually
verified before asserting requestSpy call count; ensure the requestSpy assertion
(requestSpy.toHaveBeenCalledTimes(1)) remains after the awaited assertion to
avoid race conditions.

Comment on lines +92 to +104
describe("API Lookup (Dynamic Versions)", () => {
it("should call API and resolve 'latest' to the newest version", async () => {
const url = await getDownloadUrl({
version: "latest",
os: "linux",
arch: "x64",
});

expect(url).toBe(
"https://github.com/oven-sh/bun/releases/download/bun-v1.1.0/bun-linux-x64.zip",
);
expect(requestSpy).toHaveBeenCalledTimes(1);
});
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding a test for undefined/empty version.

The implementation handles version === "latest" || !version (line 50 in download-url.ts), but there's no test explicitly covering when version is undefined or an empty string.

💡 Example test case
it("should call API and resolve undefined version to latest", async () => {
  const url = await getDownloadUrl({
    version: undefined,
    os: "linux",
    arch: "x64",
  });

  expect(url).toBe(
    "https://github.com/oven-sh/bun/releases/download/bun-v1.1.0/bun-linux-x64.zip",
  );
  expect(requestSpy).toHaveBeenCalledTimes(1);
});
🤖 Prompt for AI Agents
In `@tests/download-url.spec.ts` around lines 92 - 104, Add a test that covers the
case where version is undefined or an empty string so the branch in
getDownloadUrl that treats "latest" || !version is exercised; in
tests/download-url.spec.ts add an it() that calls getDownloadUrl({ version:
undefined, os: "linux", arch: "x64" }) (and another variant for "" if desired),
asserts the same expected URL as the "latest" test, and verifies requestSpy was
called once to ensure the API lookup path is used.

Comment on lines +132 to +141
it("should throw error if semver range matches nothing", async () => {
expect(
getDownloadUrl({
version: "^2.0.0",
os: "linux",
arch: "x64",
}),
).rejects.toThrow("No Bun release found matching version '^2.0.0'");
expect(requestSpy).toHaveBeenCalledTimes(1);
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing await for rejects assertion may cause unreliable test behavior.

The rejects.toThrow() assertion returns a promise that must be awaited. Without await, the test might pass even if the promise doesn't reject, and the requestSpy assertion on line 140 could execute before the rejection is verified.

🐛 Proposed fix
     it("should throw error if semver range matches nothing", async () => {
-      expect(
+      await expect(
         getDownloadUrl({
           version: "^2.0.0",
           os: "linux",
           arch: "x64",
         }),
       ).rejects.toThrow("No Bun release found matching version '^2.0.0'");
       expect(requestSpy).toHaveBeenCalledTimes(1);
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("should throw error if semver range matches nothing", async () => {
expect(
getDownloadUrl({
version: "^2.0.0",
os: "linux",
arch: "x64",
}),
).rejects.toThrow("No Bun release found matching version '^2.0.0'");
expect(requestSpy).toHaveBeenCalledTimes(1);
});
it("should throw error if semver range matches nothing", async () => {
await expect(
getDownloadUrl({
version: "^2.0.0",
os: "linux",
arch: "x64",
}),
).rejects.toThrow("No Bun release found matching version '^2.0.0'");
expect(requestSpy).toHaveBeenCalledTimes(1);
});
🤖 Prompt for AI Agents
In `@tests/download-url.spec.ts` around lines 132 - 141, The test calling
getDownloadUrl uses expect(...).rejects.toThrow without awaiting the returned
promise; update the test for the "should throw error if semver range matches
nothing" case to await the rejects assertion (i.e., await
expect(getDownloadUrl({...})).rejects.toThrow(...)) so the rejection is actually
verified before asserting requestSpy call count; ensure the requestSpy assertion
(requestSpy.toHaveBeenCalledTimes(1)) remains after the awaited assertion to
avoid race conditions.

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.

Finding the download URL should not make API requests

1 participant