Skip to content

fix(vfox): scope github auth to API URLs only#9309

Merged
jdx merged 2 commits intomainfrom
fix/e2e-flakes
Apr 22, 2026
Merged

fix(vfox): scope github auth to API URLs only#9309
jdx merged 2 commits intomainfrom
fix/e2e-flakes

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 22, 2026

Summary

Two fixes for the e2e failures observed on release PR #9258 (e2e-0, e2e-3):

  • vfox auth scoping (real bug): when GITHUB_TOKEN is set and a vfox plugin (e.g. vfox-kotlin) calls http.head / http.get on a github.com/.../releases/download/... URL, GitHub redirects to objects.githubusercontent.com (not the public release-assets.githubusercontent.com). Once reqwest strips the Authorization header on the cross-origin hop, that URL 401s. The plugin's pre-install check then errors with "Current version information not detected." Mirror src/github.rs::is_github_api_url and only attach auth to api.github.com and api.*.ghe.com hosts.
  • golangci-lint pin: go:github.com/golangci/golangci-lint/cmd/golangci-lint@latest resolution flaked in CI ("no versions found"). Pin to 1.64.8 — the kratos case on the next line still exercises subpath @latest resolution.

Test plan

  • cargo test -p vfox lua_mod::http -- --nocapture (17 passed)
  • mise run test:e2e e2e/backend/test_vfox_kotlin_slow passes locally with GITHUB_TOKEN set (previously failed)
  • mise run lint
  • CI green on this PR

🤖 Generated with Claude Code


Note

Medium Risk
Changes when Authorization/x-github-api-version headers are added, which can affect private GitHub/GHE API access and plugin download flows. Also adjusts e2e tooling to avoid CI flakes by pinning golangci-lint.

Overview
Fixes vfox Lua HTTP default header injection by only attaching GitHub Authorization and x-github-api-version headers for REST API hosts (api.github.com and api.*.ghe.com), avoiding auth on github.com release download and other non-API GitHub content URLs that can break redirects.

Updates unit tests to cover the new scoping (skip release downloads/raw content, include GHE API), and pins the e2e Go install test’s golangci-lint tool from latest to 1.64.8 to reduce CI resolution flakiness.

Reviewed by Cursor Bugbot for commit 8b7f800. Bugbot is set up for automated code reviews on this repo. Configure here.

jdx and others added 2 commits April 22, 2026 14:38
Sending auth to github.com release-download URLs makes GitHub redirect
to objects.githubusercontent.com (instead of the public release-assets
host), which then 401s once reqwest strips the Authorization header on
the cross-origin redirect. The result was vfox plugins (e.g.
vfox-kotlin) failing pre-install HEAD checks whenever GITHUB_TOKEN was
set.

Mirror src/github.rs::is_github_api_url and only attach Authorization
to api.github.com and api.*.ghe.com hosts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolving golangci-lint via @latest has flaked in CI ("no versions
found for go:github.com/golangci/golangci-lint/cmd/golangci-lint").
Subpath resolution with @latest is still exercised by the kratos case
on the next line, so pinning here removes a flake without losing
coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 22, 2026

Greptile Summary

This PR fixes two CI failures: it scopes GitHub auth headers in the vfox Lua HTTP module to REST API URLs only (api.github.com / api.*.ghe.com), preventing 401s when GitHub redirects release downloads to objects.githubusercontent.com and strips the Authorization header. It also pins golangci-lint to 1.64.8 to avoid a flaky @latest resolution in the Go install e2e test.

One minor observation: the comment says the logic "mirrors src/github.rs::is_github_api_url" but the Rust implementation additionally handles GitHub Enterprise Server (GHES) self-hosted instances via an API path check (/api/v3). That third clause is absent here, but it was never handled in the old code either, and GHES in a vfox plugin context is uncommon — this is not a regression.

Confidence Score: 5/5

Safe to merge — the fix is well-targeted and tests clearly cover the new behavior.

Both changes are narrow and correct: the auth-scoping fix eliminates a real 401 bug and the updated tests prove the new semantics. The golangci-lint pin is a pure CI stability change. No P0/P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
crates/vfox/src/lua_mod/http.rs Restricts GitHub auth headers to API URLs only (api.github.com and api.*.ghe.com), fixing 401s caused by objects.githubusercontent.com rejecting forwarded tokens; tests updated to match new behavior
e2e/backend/test_go_install_slow Pins golangci-lint to 1.64.8 to stabilize CI, avoiding flaky @latest resolution

Sequence Diagram

sequenceDiagram
    participant Plugin as vfox Plugin (Lua)
    participant HTTP as http.rs add_default_headers
    participant GH as github.com/releases/download
    participant CDN as objects.githubusercontent.com
    participant API as api.github.com

    Note over HTTP: Before fix
    Plugin->>HTTP: http.get(github.com/releases/download/...)
    HTTP->>GH: GET + Authorization: Bearer token
    GH-->>CDN: 302 redirect (auth stripped by reqwest)
    CDN-->>Plugin: 401 Unauthorized

    Note over HTTP: After fix
    Plugin->>HTTP: http.get(github.com/releases/download/...)
    HTTP->>GH: GET (no Authorization header)
    GH-->>CDN: 302 redirect (public asset)
    CDN-->>Plugin: 200 OK

    Plugin->>HTTP: http.get(api.github.com/repos/.../releases)
    HTTP->>API: GET + Authorization: Bearer token + x-github-api-version
    API-->>Plugin: 200 OK
Loading

Reviews (1): Last reviewed commit: "test(go): pin golangci-lint version in i..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request modifies the logic for adding default headers to GitHub requests, specifically restricting the Authorization and x-github-api-version headers to api.github.com and api.*.ghe.com to avoid 401 errors on redirects. It also pins the golangci-lint version in an E2E test. Reviewers noted that the new API check is too restrictive for on-premise GitHub Enterprise installations and that removing raw.githubusercontent.com from the allowed list may break private repository downloads.

Comment on lines +147 to +148
let is_api =
host == "api.github.com" || (host.starts_with("api.") && host.ends_with(".ghe.com"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The is_api check is quite restrictive for GitHub Enterprise (GHE) instances. While it correctly handles the new *.ghe.com domains, it will fail to attach authentication headers for traditional GHE installations hosted on custom internal domains (e.g., github.mycompany.com/api/v3).

Consider also checking if the URL path starts with /api/v3, which is the standard API prefix for GHE Server, to improve compatibility with on-premise installations.

    let is_api =
        host == "api.github.com"
            || (host.starts_with("api.") && host.ends_with(".ghe.com"))
            || url.path().starts_with("/api/v3");

Comment on lines +147 to +148
let is_api =
host == "api.github.com" || (host.starts_with("api.") && host.ends_with(".ghe.com"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This change stops sending the Authorization header to raw.githubusercontent.com. While this avoids the redirect issue described for github.com release assets, it will break the ability for vfox plugins to download files from private repositories via raw.githubusercontent.com.

If raw.githubusercontent.com does not suffer from the same 302-to-401 redirect issue as github.com, it might be worth keeping it in the allowed list to maintain support for private repository content.

@jdx jdx enabled auto-merge (squash) April 22, 2026 19:49
@jdx jdx merged commit 4b823b2 into main Apr 22, 2026
39 checks passed
@jdx jdx deleted the fix/e2e-flakes branch April 22, 2026 19:54
@github-actions
Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.18 x -- echo 22.5 ± 0.4 21.5 23.7 1.00
mise x -- echo 23.3 ± 0.8 22.1 31.2 1.04 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.18 env 22.1 ± 0.7 20.8 31.0 1.00
mise env 22.9 ± 0.8 21.6 30.7 1.04 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.18 hook-env 22.8 ± 0.6 21.8 31.0 1.00
mise hook-env 23.6 ± 0.7 22.0 27.6 1.04 ± 0.04

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.18 ls 20.1 ± 0.6 18.8 22.6 1.00
mise ls 20.7 ± 0.6 19.7 25.7 1.03 ± 0.04

xtasks/test/perf

Command mise-2026.4.18 mise Variance
install (cached) 146ms ⚠️ 170ms -14%
ls (cached) 76ms 79ms -3%
bin-paths (cached) 81ms 84ms -3%
task-ls (cached) 833ms 813ms +2%

⚠️ Warning: install cached performance variance is -14%

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.

1 participant