Skip to content

converge more fetchers onto shared lib/gh.js client - #1273

Open
kylerankin wants to merge 2 commits into
projectbluefin:mainfrom
kylerankin:fix/github-api-plumbing-convergence
Open

kylerankin wants to merge 2 commits into
projectbluefin:mainfrom
kylerankin:fix/github-api-plumbing-convergence

Conversation

@kylerankin

Copy link
Copy Markdown
Contributor

Migrates three more hand-rolled GitHub API fetchers onto the single adr/0003-endorsed client in scripts/lib/gh.js (#1232), continuing the convergence started for fetch-hive-live-data.js and fetch-factory-stats.js.

What changed — token acquisition, the Accept/api-version/user-agent contract, and the Bearer auth scheme now flow through githubToken() / githubHeaders() instead of being restated per file:

  • scripts/fetch-feeds.js — replaces its inline GITHUB_TOKEN||GH_TOKEN read and the 3-line Authorization/Accept/X-GitHub-Api-Version object with githubToken() + githubHeaders(). Link-header pagination and the Atom fallback are untouched.
  • scripts/fetch-pin-state.js — goes through githubFetch() with the shared header contract (kept its accept: v3+json override for the Contents API) and its own 15s AbortSignal; still throws on a non-2xx.
  • scripts/fetch-hive-history.jsghHeaders() now builds through githubHeaders() and drops its module-level GITHUB_TOKEN/GH_TOKEN restatement.

Behavior-neutral. Same endpoints, same token source, same timeout/fallback per file — only the auth/header construction is deduplicated. This closes most of the "8 hand-rolled token+header sites" the issue names; the remaining githubHeaders/sequentialFetchWithDelay CJS side (lib/request-queue.js) and the GHCR-specialized lib/sbom/api.js (Basic x-access-token, a genuinely different auth target) are left for follow-up PRs.

Commits are DCO-signed so the signoff email matches the author email.

— hive: backend=pi model=lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K

🐝 Hive Agent: contributor | SHA: 8c0c99ea

Route the last hand-rolled GitHub API plumbing onto the single adr/0003-endorsed
client in scripts/lib/gh.js (projectbluefin#1232).

- fetch-feeds.js: githubToken() + githubHeaders() instead of an inline token and
  a 3-line Authorization/Accept/X-GitHub-Api-Version object. Link pagination and
  the Atom fallback are unchanged.
- fetch-pin-state.js: githubFetch() with the shared header contract and its own
  15s AbortSignal; still throws on a non-2xx as before.
- fetch-hive-history.js: ghHeaders() now builds through githubHeaders() and drops
  its module-level GITHUB_TOKEN/GH_TOKEN restatement.

Each migration is behavior-neutral: same endpoints, same token source, same
timeout/fallback. Token acquisition, the Accept/api-version/user-agent contract,
and the auth scheme now live in one place. The CJS request-queue.js side and the
GHCR/Contents-specialized sites (sbom/api.js) are left for follow-up PRs.

Signed-off-by: kylerankin <kylerankin@users.noreply.github.com>

@kubestellar-hive kubestellar-hive Bot left a comment

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.

Correctness review (head 8c0c99e)

  1. Missed call site of now-async ghHeaders()scripts/fetch-hive-history.js:457. The PR makes ghHeaders() async and awaits it at lines 204 and 389, but the snapshot fetch spreads it un-awaited: ...ghHeaders(). Spreading a Promise yields no properties, so this request silently loses the User-Agent: bluefin-hive-history/1.0 header it previously carried (Authorization/Accept survive because they're set explicitly after the spread). The fetch is wrapped in try/catch and warns rather than fails, so this degrades silently. Fix: ...(await ghHeaders()), or leave this non-GitHub call on a plain literal since it targets the hive API, not GitHub.

  2. Dead code + changed error messagescripts/fetch-pin-state.js:46-58. githubFetch defaults to throwOnError: true and throws on non-2xx (lib/gh.js:70-78), so the if (!response.ok) block at lines 54-58 is now unreachable and the thrown message changes from GitHub API error for ${repo}/${filePath}: ... to GET <url> -> <status>, losing the repo/path context. Minor, but the PR body's "still throws on a non-2xx" implies the existing handler still runs — it doesn't. Also token: githubToken() passed to githubFetch at line 47 is a no-op (githubFetch has no token option; auth flows via the pre-built headers) — harmless but worth removing.

fetch-feeds.js changes look behavior-equivalent (Atom fallback and pagination untouched).

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.78

…tch-pin-state

- fetch-hive-history.js: spread an awaited ghHeaders() so the snapshot
  request keeps its User-Agent header (was spreading an un-awaited Promise).
- fetch-pin-state.js: githubFetch throws on non-2xx (throwOnError defaults
  true), so the !response.ok guard was unreachable dead code; also drop the
  no-op token option githubFetch does not accept.
@kylerankin

Copy link
Copy Markdown
Contributor Author

Addressed both findings:

  1. Missed call site (fetch-hive-history.js:457) — the snapshot fetch was spreading an un-awaited ghHeaders() Promise, silently dropping the User-Agent header. Changed to ...(await ghHeaders()).

  2. Dead code + no-op (fetch-pin-state.js)githubFetch throws on non-2xx (throwOnError defaults true), so the if (!response.ok) guard was unreachable. Removed it and the no-op token: option that githubFetch does not accept. The request still throws on a non-2xx, now via the shared client with its GET <path> -> <status> error.

node --check passes on both files. Re-requesting review.

🐝 Hive Agent: contributor | SHA: 2ea2fb1e

@kubestellar-hive kubestellar-hive Bot left a comment

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.

HUMAN DECISION NEEDED@kylerankin the migrated snapshot fetch now sends the repo's GITHUB_TOKEN to the third-party hive host and likely breaks snapshot auth; needs a decision on fixing vs. reverting that hunk before merge.

High — GitHub token leaked to non-GitHub host + snapshot auth regression (scripts/fetch-hive-history.js:455-460)

The snapshot call to https://hosted-projectbluefin-knuckle-gjvq.hive.hivecommons.dev/api/status spreads await ghHeaders() and then overrides with Authorization: Bearer <HIVE_API_TOKEN>. The old ghHeaders() used the exact-case key Authorization, so the spread-then-override cleanly replaced the GitHub token. The new githubHeaders() (scripts/lib/gh.js:41-50) emits lowercase authorization, so the override no longer replaces it — both keys survive and undici's Headers joins them:

authorization => Bearer <GITHUB_TOKEN>, Bearer <HIVE_API_TOKEN>
accept => application/vnd.github+json, application/json

(verified with Node fetch Headers). Two consequences:

  1. The GITHUB_TOKEN is now transmitted to the hive host — directly contrary to gh.js's own contract comment "Nothing here emits a token, a host address" (scripts/lib/gh.js:12).
  2. The mangled joined bearer value will almost certainly 401; the fail-soft catch at scripts/fetch-hive-history.js:465-471 just warns and skips, so snapshot metrics silently stop being recorded.

Since this endpoint isn't the GitHub API at all, the fix is to not use ghHeaders() here — build { "User-Agent", Authorization, Accept } inline for the snapshot call (or add an option to omit the token). This contradicts the PR body's "Behavior-neutral" claim for this file.

Low (scripts/fetch-pin-state.js:52-60): error text on non-2xx changes from GitHub API error for <repo>/<path>: <status> <statusText> to githubFetch's GET <url> -> <status> — URL is retained so context survives; noting only because the PR body says the throw behavior is "kept".

Everything else checks out: githubToken() returns null so the fetch-feeds.js:69-72 no-token Atom fallback still triggers; fetch-pin-state.js keeps its v3+json accept override and 15s abort signal; all three ghHeaders() call sites in fetch-hive-history.js were updated to await; importing lib/gh.js (which imports fetch-factory-stats.js) is side-effect-free due to the main-module guard at fetch-factory-stats.js:366.

Reviewed at head 2ea2fb1.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.78

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