refactor(github): resolve token once at pipeline boundary; pad no-token envelope

Greptile review (PR #438) flagged two issues:

1. search_github and enrich_with_comments both call _resolve_token,
   so when GITHUB_TOKEN is absent from config and env the gh-CLI
   subprocess (with its 5s timeout) fires twice per query.

2. The no-token early-return envelope `{"items": [], "error": "no token"}`
   was missing the `context` key that every other failure path includes,
   making the envelope shape inconsistent between the no-token and
   fetch-failure cases.

Fix 1: add public github.resolve_token(token) wrapping the existing
_resolve_token. Pipeline calls it once before search and enrich, so
both downstream calls receive an already-resolved (or already-None)
token and skip the fallback chain.

Fix 2: thread core/from_date/to_date/count through the no-token
envelope's `context` key, matching the fetch-failure envelope shape.
parse_github_response was already tolerant of the missing key, but
diagnostics callers that read response["context"]["..."] now get a
consistent dict in both error paths.

Reviewer's suggested code patch for issue 1 was a no-op (it kept the
same _resolve_token(token) call inside enrich_with_comments); the
underlying intent — resolve at the boundary — is what this commit
implements.
This commit is contained in:
Ilia Alshanetsky
2026-05-19 12:35:40 -04:00
parent 269dda9f6c
commit c5c0239dc9
3 changed files with 42 additions and 5 deletions
+15
View File
@@ -80,6 +80,21 @@ class TestSearchGithub(unittest.TestCase):
result = github.search_github("react", "2026-03-01", "2026-03-31", token=None)
self.assertEqual(result.get("items", []), [])
self.assertIn("error", result)
# Envelope shape must match the fetch-failure path: context is
# always present so callers (and parse_github_response) can read
# diagnostic fields without branching on which failure mode hit.
self.assertIn("context", result)
self.assertEqual(result["context"]["from_date"], "2026-03-01")
self.assertEqual(result["context"]["to_date"], "2026-03-31")
def test_resolve_token_public_alias(self):
"""resolve_token is the public entry point pipeline uses; _resolve_token stays
private. Both should return the same value for the same input."""
self.assertEqual(
github.resolve_token("explicit-token"),
github._resolve_token("explicit-token"),
)
self.assertEqual(github.resolve_token("explicit-token"), "explicit-token")
@patch.object(github, "_fetch_json")
@patch.object(github, "_resolve_token", return_value="test-token")