fix(github): pass repo parameter to GHClient for explicit PR resolution (#413)
The gh CLI was failing with "Could not resolve to a PullRequest" error because it inferred the repository from git remotes instead of using an explicit repository. With multiple remotes configured, the wrong repo could be queried. This fix passes the repo parameter through the call chain and adds the -R flag to all PR-related gh commands, ensuring the correct repository is always queried regardless of git remote configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -201,13 +201,15 @@ class PRContext:
|
||||
class PRContextGatherer:
|
||||
"""Gathers all context needed for PR review BEFORE the AI starts."""
|
||||
|
||||
def __init__(self, project_dir: Path, pr_number: int):
|
||||
def __init__(self, project_dir: Path, pr_number: int, repo: str | None = None):
|
||||
self.project_dir = Path(project_dir)
|
||||
self.pr_number = pr_number
|
||||
self.repo = repo
|
||||
self.gh_client = GHClient(
|
||||
project_dir=self.project_dir,
|
||||
default_timeout=30.0,
|
||||
max_retries=3,
|
||||
repo=repo,
|
||||
)
|
||||
|
||||
async def gather(self) -> PRContext:
|
||||
@@ -953,14 +955,17 @@ class FollowupContextGatherer:
|
||||
project_dir: Path,
|
||||
pr_number: int,
|
||||
previous_review: PRReviewResult, # Forward reference
|
||||
repo: str | None = None,
|
||||
):
|
||||
self.project_dir = Path(project_dir)
|
||||
self.pr_number = pr_number
|
||||
self.previous_review = previous_review
|
||||
self.repo = repo
|
||||
self.gh_client = GHClient(
|
||||
project_dir=self.project_dir,
|
||||
default_timeout=30.0,
|
||||
max_retries=3,
|
||||
repo=repo,
|
||||
)
|
||||
|
||||
async def gather(self) -> FollowupReviewContext:
|
||||
|
||||
@@ -84,6 +84,7 @@ class GHClient:
|
||||
default_timeout: float = 30.0,
|
||||
max_retries: int = 3,
|
||||
enable_rate_limiting: bool = True,
|
||||
repo: str | None = None,
|
||||
):
|
||||
"""
|
||||
Initialize GitHub CLI client.
|
||||
@@ -93,11 +94,14 @@ class GHClient:
|
||||
default_timeout: Default timeout in seconds for commands
|
||||
max_retries: Maximum number of retry attempts
|
||||
enable_rate_limiting: Whether to enforce rate limiting (default: True)
|
||||
repo: Repository in 'owner/repo' format. If provided, uses -R flag
|
||||
instead of inferring from git remotes.
|
||||
"""
|
||||
self.project_dir = Path(project_dir)
|
||||
self.default_timeout = default_timeout
|
||||
self.max_retries = max_retries
|
||||
self.enable_rate_limiting = enable_rate_limiting
|
||||
self.repo = repo
|
||||
|
||||
# Initialize rate limiter singleton
|
||||
if enable_rate_limiting:
|
||||
@@ -254,6 +258,28 @@ class GHClient:
|
||||
# Should never reach here, but for type safety
|
||||
raise GHCommandError(f"gh {args[0]} failed after {self.max_retries} attempts")
|
||||
|
||||
# =========================================================================
|
||||
# Helper methods
|
||||
# =========================================================================
|
||||
|
||||
def _add_repo_flag(self, args: list[str]) -> list[str]:
|
||||
"""
|
||||
Add -R flag to command args if repo is configured.
|
||||
|
||||
This ensures gh CLI uses the correct repository instead of
|
||||
inferring from git remotes, which can fail with multiple remotes
|
||||
or when working in worktrees.
|
||||
|
||||
Args:
|
||||
args: Command arguments list
|
||||
|
||||
Returns:
|
||||
Modified args list with -R flag if repo is set
|
||||
"""
|
||||
if self.repo:
|
||||
return args + ["-R", self.repo]
|
||||
return args
|
||||
|
||||
# =========================================================================
|
||||
# Convenience methods for common gh commands
|
||||
# =========================================================================
|
||||
@@ -295,6 +321,7 @@ class GHClient:
|
||||
"--json",
|
||||
",".join(json_fields),
|
||||
]
|
||||
args = self._add_repo_flag(args)
|
||||
|
||||
result = await self.run(args)
|
||||
return json.loads(result.stdout)
|
||||
@@ -334,6 +361,7 @@ class GHClient:
|
||||
"--json",
|
||||
",".join(json_fields),
|
||||
]
|
||||
args = self._add_repo_flag(args)
|
||||
|
||||
result = await self.run(args)
|
||||
return json.loads(result.stdout)
|
||||
@@ -352,6 +380,7 @@ class GHClient:
|
||||
PRTooLargeError: If PR exceeds GitHub's 20,000 line diff limit
|
||||
"""
|
||||
args = ["pr", "diff", str(pr_number)]
|
||||
args = self._add_repo_flag(args)
|
||||
try:
|
||||
result = await self.run(args)
|
||||
return result.stdout
|
||||
@@ -396,6 +425,7 @@ class GHClient:
|
||||
args.append("--comment")
|
||||
|
||||
args.extend(["--body", body])
|
||||
args = self._add_repo_flag(args)
|
||||
|
||||
await self.run(args)
|
||||
return 0 # gh CLI doesn't return review ID
|
||||
@@ -574,6 +604,7 @@ class GHClient:
|
||||
args.extend(["--subject", commit_title])
|
||||
if commit_message:
|
||||
args.extend(["--body", commit_message])
|
||||
args = self._add_repo_flag(args)
|
||||
|
||||
await self.run(args)
|
||||
|
||||
@@ -586,6 +617,7 @@ class GHClient:
|
||||
body: Comment body
|
||||
"""
|
||||
args = ["pr", "comment", str(pr_number), "--body", body]
|
||||
args = self._add_repo_flag(args)
|
||||
await self.run(args)
|
||||
|
||||
async def pr_get_assignees(self, pr_number: int) -> list[str]:
|
||||
|
||||
@@ -129,6 +129,7 @@ class GitHubOrchestrator:
|
||||
default_timeout=30.0,
|
||||
max_retries=3,
|
||||
enable_rate_limiting=True,
|
||||
repo=config.repo,
|
||||
)
|
||||
|
||||
# Initialize bot detector for preventing infinite loops
|
||||
@@ -300,7 +301,9 @@ class GitHubOrchestrator:
|
||||
try:
|
||||
# Gather PR context
|
||||
print("[DEBUG orchestrator] Creating context gatherer...", flush=True)
|
||||
gatherer = PRContextGatherer(self.project_dir, pr_number)
|
||||
gatherer = PRContextGatherer(
|
||||
self.project_dir, pr_number, repo=self.config.repo
|
||||
)
|
||||
|
||||
print("[DEBUG orchestrator] Gathering PR context...", flush=True)
|
||||
pr_context = await gatherer.gather()
|
||||
|
||||
@@ -56,6 +56,7 @@ class GitHubProvider:
|
||||
self._gh_client = GHClient(
|
||||
project_dir=project_dir,
|
||||
enable_rate_limiting=self.enable_rate_limiting,
|
||||
repo=self._repo,
|
||||
)
|
||||
|
||||
@property
|
||||
|
||||
Reference in New Issue
Block a user