pub struct GhHttp { /* private fields */ }Expand description
Native HTTP client for the GitHub API with connection pooling and proactive rate-limit avoidance.
Implementations§
Source§impl GhHttp
impl GhHttp
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Create a new client backed by the process-wide shared [TokenResolver].
Token is resolved lazily on first request:
GH_TOKEN → GITHUB_TOKEN → gh.auth.token config → gh auth token CLI
The result is cached in the shared resolver for the life of the process,
so gh auth token is only called once regardless of how many instances
are created.
Sourcepub fn is_rate_limited() -> Option<Duration>
pub fn is_rate_limited() -> Option<Duration>
Check if the REST GitHub API is currently rate-limited (backoff or approaching limit). Used by the engine to decide whether to skip a tick.
pub async fn graphql_with_vars( &self, query: &str, variables: Value, ) -> Result<Value>
pub async fn graphql_with_headers( &self, query: &str, headers: &[&str], ) -> Result<Value>
pub async fn graphql_with_headers_and_vars( &self, query: &str, headers: &[&str], variables: Value, ) -> Result<Value>
Sourcepub async fn auth_status(&self) -> Result<()>
pub async fn auth_status(&self) -> Result<()>
Verify authentication by fetching the current user.
Returns detailed error messages for common auth failures to help users diagnose configuration issues at startup.
Sourcepub async fn create_issue(
&self,
repo: &str,
title: &str,
body: &str,
labels: &[String],
) -> Result<GitHubIssue>
pub async fn create_issue( &self, repo: &str, title: &str, body: &str, labels: &[String], ) -> Result<GitHubIssue>
Create a GitHub issue.
Sourcepub async fn update_issue(
&self,
repo: &str,
number: u64,
title: &str,
body: &str,
labels: &[String],
) -> Result<GitHubIssue>
pub async fn update_issue( &self, repo: &str, number: u64, title: &str, body: &str, labels: &[String], ) -> Result<GitHubIssue>
Replace an issue’s title, body and labels.
Labels replace the full set. Callers pass labels they want to keep
Sourcepub async fn list_blocked_by(
&self,
repo: &str,
issue_number: u64,
) -> Result<BlockedByFetch>
pub async fn list_blocked_by( &self, repo: &str, issue_number: u64, ) -> Result<BlockedByFetch>
List issues that block issue_number.
GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by.
GA since 2025-08-21, no preview media type. This call sends
X-GitHub-Api-Version: 2026-03-10 and Accept: application/vnd.github+json.
404 and 403 (except rate limit) are Unavailable. Transport errors and
5xx are Failed, so the caller does not drop stored links
Sourcepub async fn add_blocked_by(
&self,
repo: &str,
issue_number: u64,
blocking_issue_id: i64,
) -> Result<()>
pub async fn add_blocked_by( &self, repo: &str, issue_number: u64, blocking_issue_id: i64, ) -> Result<()>
POST /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by
with {"issue_id": blocking_issue_id}. Same API version as list_blocked_by.
201 is success. A body that says the link already exists is also success
Sourcepub async fn remove_blocked_by(
&self,
repo: &str,
number: u64,
blocking_issue_id: u64,
) -> Result<()>
pub async fn remove_blocked_by( &self, repo: &str, number: u64, blocking_issue_id: u64, ) -> Result<()>
Remove a blocked-by link. issue_id in the path is the blocking issue’s database id
Sourcepub async fn get_issue(&self, repo: &str, number: &str) -> Result<GitHubIssue>
pub async fn get_issue(&self, repo: &str, number: &str) -> Result<GitHubIssue>
Get a single issue.
Sourcepub async fn is_pull_request(&self, repo: &str, number: &str) -> bool
pub async fn is_pull_request(&self, repo: &str, number: &str) -> bool
Check whether an issue number refers to a pull request.
Sourcepub async fn list_issues(
&self,
repo: &str,
label: &str,
) -> Result<Vec<GitHubIssue>>
pub async fn list_issues( &self, repo: &str, label: &str, ) -> Result<Vec<GitHubIssue>>
List issues filtered by a label (paginated).
Sourcepub async fn list_issues_with_state(
&self,
repo: &str,
label: &str,
state: &str,
) -> Result<Vec<GitHubIssue>>
pub async fn list_issues_with_state( &self, repo: &str, label: &str, state: &str, ) -> Result<Vec<GitHubIssue>>
List issues filtered by a label and issue state (paginated).
state is passed directly to the GitHub API: "open", "closed", or "all".
Sourcepub async fn list_issues_closed_since(
&self,
repo: &str,
label: &str,
since: &str,
) -> Result<Vec<GitHubIssue>>
pub async fn list_issues_closed_since( &self, repo: &str, label: &str, since: &str, ) -> Result<Vec<GitHubIssue>>
List closed issues updated since since (ISO 8601), filtered by label.
Used for dedup checks — prevents re-creating issues that were recently closed.
Sourcepub async fn list_closed_issues_since(
&self,
repo: &str,
since: &str,
) -> Result<Vec<GitHubIssue>>
pub async fn list_closed_issues_since( &self, repo: &str, since: &str, ) -> Result<Vec<GitHubIssue>>
List closed issues updated since since (ISO 8601), no label filter.
Sourcepub async fn list_all_open_issues(
&self,
repo: &str,
since: Option<&str>,
) -> Result<Vec<GitHubIssue>>
pub async fn list_all_open_issues( &self, repo: &str, since: Option<&str>, ) -> Result<Vec<GitHubIssue>>
List all open issues (no label filter, paginated).
When since is Some(ts), only returns issues updated after that ISO 8601 timestamp.
This is more efficient for periodic syncs — GitHub filters server-side.
Sourcepub async fn list_open_pulls(&self, repo: &str) -> Result<Vec<Value>>
pub async fn list_open_pulls(&self, repo: &str) -> Result<Vec<Value>>
List open pull requests (paginated) using the REST pulls endpoint. Returns raw JSON values for flexibility in callers.
Sourcepub async fn list_all_issues(&self, repo: &str) -> Result<Vec<GitHubIssue>>
pub async fn list_all_issues(&self, repo: &str) -> Result<Vec<GitHubIssue>>
List all issues (open and closed, no label filter, paginated).
This is more efficient than making separate calls for open and closed.
Sourcepub async fn add_labels(
&self,
repo: &str,
number: &str,
labels: &[String],
) -> Result<()>
pub async fn add_labels( &self, repo: &str, number: &str, labels: &[String], ) -> Result<()>
Add labels to an issue.
Sourcepub async fn ensure_label(
&self,
repo: &str,
name: &str,
color: &str,
description: &str,
) -> Result<()>
pub async fn ensure_label( &self, repo: &str, name: &str, color: &str, description: &str, ) -> Result<()>
Ensure a label exists on the repo, creating it if needed.
Sourcepub async fn remove_label(
&self,
repo: &str,
number: &str,
label: &str,
) -> Result<()>
pub async fn remove_label( &self, repo: &str, number: &str, label: &str, ) -> Result<()>
Remove a label from an issue.
Sourcepub async fn add_comment(
&self,
repo: &str,
number: &str,
body: &str,
) -> Result<()>
pub async fn add_comment( &self, repo: &str, number: &str, body: &str, ) -> Result<()>
Add a comment to an issue.
Sourcepub async fn post_commit_status(
&self,
repo: &str,
sha: &str,
state: &str,
context: &str,
description: &str,
) -> Result<()>
pub async fn post_commit_status( &self, repo: &str, sha: &str, state: &str, context: &str, description: &str, ) -> Result<()>
Post a commit status. state is one of pending, success, failure, error.
Sourcepub async fn add_reaction(
&self,
repo: &str,
number: &str,
content: &str,
) -> Result<()>
pub async fn add_reaction( &self, repo: &str, number: &str, content: &str, ) -> Result<()>
Add a reaction to an issue.
Supported content values: “+1”, “-1”, “laugh”, “confused”, “heart”, “hooray”, “rocket”, “eyes”
Sourcepub async fn add_comment_reaction(
&self,
repo: &str,
comment_id: &str,
content: &str,
) -> Result<()>
pub async fn add_comment_reaction( &self, repo: &str, comment_id: &str, content: &str, ) -> Result<()>
Add a reaction to an issue comment.
Supported content values: “+1”, “-1”, “laugh”, “confused”, “heart”, “hooray”, “rocket”, “eyes”
Sourcepub async fn list_comments(
&self,
repo: &str,
number: &str,
) -> Result<Vec<GitHubComment>>
pub async fn list_comments( &self, repo: &str, number: &str, ) -> Result<Vec<GitHubComment>>
List comments on an issue.
Sourcepub async fn is_pr_merged(&self, repo: &str, branch: &str) -> Result<bool>
pub async fn is_pr_merged(&self, repo: &str, branch: &str) -> Result<bool>
Check if a PR with the given branch was merged.
Sourcepub async fn get_closed_pr_state(
&self,
repo: &str,
branch: &str,
) -> Result<Option<(u64, bool, String)>>
pub async fn get_closed_pr_state( &self, repo: &str, branch: &str, ) -> Result<Option<(u64, bool, String)>>
Get the state of a closed PR for the given branch.
Returns Some((merged, state)) if a closed PR exists for the branch,
where merged indicates if it was merged and state is the PR state (“closed” or “merged”).
Returns None if no closed PR exists for the branch.
Get the state of a closed PR for a given branch.
Returns Some((pr_number, merged, state)) if a closed PR is found that
matches the expected branch. Returns None if no matching closed PR is found.
Validates that the returned PR’s head ref matches the expected branch to prevent incorrect merge decisions when multiple PRs exist for the same branch.
Sourcepub async fn batch_is_pr_merged_by_branch(
&self,
repo: &str,
branches: &[String],
) -> Result<HashMap<String, bool>>
pub async fn batch_is_pr_merged_by_branch( &self, repo: &str, branches: &[String], ) -> Result<HashMap<String, bool>>
Batch-check whether the PR for each branch was merged via a single GraphQL query.
Returns a map of branch → merged. Branches with no matching PR are omitted (callers should treat missing entries as not merged).
Sourcepub async fn get_mentions(
&self,
repo: &str,
since: &str,
) -> Result<Vec<GitHubComment>>
pub async fn get_mentions( &self, repo: &str, since: &str, ) -> Result<Vec<GitHubComment>>
Get issue/PR comments since a given timestamp (paginated).
Sourcepub async fn get_issue_comments(
&self,
repo: &str,
issue_number: u64,
) -> Result<Vec<GitHubComment>>
pub async fn get_issue_comments( &self, repo: &str, issue_number: u64, ) -> Result<Vec<GitHubComment>>
Get all comments for a specific issue number.
Sourcepub async fn get_whoami(&self) -> Result<String>
pub async fn get_whoami(&self) -> Result<String>
Get the current authenticated username (cached after first call).
Sourcepub async fn get_pr_number(
&self,
repo: &str,
branch: &str,
) -> Result<Option<u64>>
pub async fn get_pr_number( &self, repo: &str, branch: &str, ) -> Result<Option<u64>>
Get PR number by branch name.
Sourcepub async fn create_pr(
&self,
repo: &str,
title: &str,
body: &str,
head: &str,
base: &str,
) -> Result<String>
pub async fn create_pr( &self, repo: &str, title: &str, body: &str, head: &str, base: &str, ) -> Result<String>
Create a new pull request.
§Arguments
repo- Repository in “owner/repo” formattitle- PR titlebody- PR body/descriptionhead- Branch name to create PR frombase- Base branch to merge into (e.g., “main”)
Returns the created PR’s URL on success.
Sourcepub async fn get_default_branch(&self, repo: &str) -> Result<String>
pub async fn get_default_branch(&self, repo: &str) -> Result<String>
Get the repository’s default branch from the GitHub API.
Used as a fallback when local git detection yields an invalid base branch for PR creation.
Sourcepub async fn get_pr(
&self,
repo: &str,
pr_number: u64,
) -> Result<GitHubPullRequest>
pub async fn get_pr( &self, repo: &str, pr_number: u64, ) -> Result<GitHubPullRequest>
Get PR details by PR number.
Returns the full PR object including the mergeable field.
Sourcepub async fn batch_get_pr_states(
&self,
repo: &str,
pr_numbers: &[u64],
) -> Result<HashMap<u64, (bool, String)>>
pub async fn batch_get_pr_states( &self, repo: &str, pr_numbers: &[u64], ) -> Result<HashMap<u64, (bool, String)>>
Fetch the merged/state for multiple PRs in a single GraphQL query.
Returns a map of pr_number → (merged, state). PRs that fail to fetch are silently omitted from the result.
Sourcepub async fn batch_get_issue_states(
&self,
repo: &str,
issue_numbers: &[u64],
caller_context: &str,
) -> Result<HashMap<String, (String, Vec<String>)>>
pub async fn batch_get_issue_states( &self, repo: &str, issue_numbers: &[u64], caller_context: &str, ) -> Result<HashMap<String, (String, Vec<String>)>>
Batch-fetch state and labels for multiple GitHub issues in a single GraphQL request.
Returns a map of issue number (as string) → (state, labels) where state is
lowercase (“open” / “closed”) to match the REST API convention used elsewhere.
Sourcepub async fn get_required_status_check_contexts(
&self,
repo: &str,
branch: &str,
) -> Result<Vec<String>>
pub async fn get_required_status_check_contexts( &self, repo: &str, branch: &str, ) -> Result<Vec<String>>
Get the required status check contexts for a branch.
Sourcepub async fn get_commit_status_contexts(
&self,
repo: &str,
sha: &str,
) -> Result<Vec<(String, String)>>
pub async fn get_commit_status_contexts( &self, repo: &str, sha: &str, ) -> Result<Vec<(String, String)>>
Get commit status contexts for a SHA.
Sourcepub async fn has_workflows(&self, repo: &str) -> Result<bool>
pub async fn has_workflows(&self, repo: &str) -> Result<bool>
Return true when the repository has at least one GitHub Actions workflow.
This is used to distinguish repos that genuinely have no CI configured from repos where CI exists but GitHub has not surfaced any runs yet.
Sourcepub async fn get_check_runs(
&self,
repo: &str,
sha: &str,
) -> Result<Vec<GitHubCheckRun>>
pub async fn get_check_runs( &self, repo: &str, sha: &str, ) -> Result<Vec<GitHubCheckRun>>
Get check runs for a PR head SHA.
Sourcepub async fn get_check_run_annotations(
&self,
repo: &str,
check_run_id: u64,
) -> Result<Vec<GitHubAnnotation>>
pub async fn get_check_run_annotations( &self, repo: &str, check_run_id: u64, ) -> Result<Vec<GitHubAnnotation>>
Get annotations for a specific check run.
Returns the list of annotations attached to the check run, including billing failure messages (“The job was not started because recent account payments have failed …”) that GitHub surfaces as annotations rather than as a distinct CI conclusion value.
Sourcepub async fn get_pr_reviews(
&self,
repo: &str,
pr_number: u64,
) -> Result<Vec<GitHubReview>>
pub async fn get_pr_reviews( &self, repo: &str, pr_number: u64, ) -> Result<Vec<GitHubReview>>
Get reviews for a PR.
Sourcepub async fn get_commit_timestamp(
&self,
repo: &str,
sha: &str,
) -> Result<String>
pub async fn get_commit_timestamp( &self, repo: &str, sha: &str, ) -> Result<String>
Get the committer timestamp for a specific commit SHA.
Returns an ISO-8601 string, e.g. "2024-01-15T12:00:00Z".
Used to determine whether the branch has been updated since a review was submitted.
Sourcepub async fn update_pr_body(
&self,
repo: &str,
pr_number: u64,
body: &str,
) -> Result<()>
pub async fn update_pr_body( &self, repo: &str, pr_number: u64, body: &str, ) -> Result<()>
Update the body of a pull request.
Sourcepub async fn close_pr(&self, repo: &str, pr_number: u64) -> Result<()>
pub async fn close_pr(&self, repo: &str, pr_number: u64) -> Result<()>
Close a pull request without merging it.
Sourcepub async fn compare_behind_by(
&self,
repo: &str,
base: &str,
head_sha: &str,
) -> Result<u64>
pub async fn compare_behind_by( &self, repo: &str, base: &str, head_sha: &str, ) -> Result<u64>
How many commits the head is missing from base (GitHub’s behind_by).
Zero means the head already contains the current base tip, so its checks ran against the code the merge would produce.
Sourcepub async fn reopen_issue(&self, repo: &str, number: &str) -> Result<()>
pub async fn reopen_issue(&self, repo: &str, number: &str) -> Result<()>
Reopen a closed GitHub issue.
Sourcepub async fn is_collaborator(&self, repo: &str, username: &str) -> Result<bool>
pub async fn is_collaborator(&self, repo: &str, username: &str) -> Result<bool>
Check if a user is a collaborator.
Sourcepub async fn add_sub_issue(
&self,
parent_node_id: &str,
child_node_id: &str,
) -> Result<()>
pub async fn add_sub_issue( &self, parent_node_id: &str, child_node_id: &str, ) -> Result<()>
Add a sub-issue relationship via GraphQL.
Sourcepub async fn link_issue_to_branch(
&self,
repo: &str,
issue_number: u64,
branch: &str,
) -> Result<String>
pub async fn link_issue_to_branch( &self, repo: &str, issue_number: u64, branch: &str, ) -> Result<String>
Link an issue to a branch using GraphQL.
Creates a “Development” sidebar link in GitHub that connects the issue
to the branch, similar to gh issue develop.
§Arguments
repo- Repository in “owner/repo” formatissue_number- The issue number to linkbranch- The branch name to link the issue to
Returns the linked branch ID on success.
Sourcepub async fn merge_pr(
&self,
repo: &str,
pr_number: u64,
delete_branch: bool,
) -> Result<()>
pub async fn merge_pr( &self, repo: &str, pr_number: u64, delete_branch: bool, ) -> Result<()>
Merge a PR using the REST API (squash merge).
Sourcepub async fn update_pr_branch(&self, repo: &str, pr_number: u64) -> Result<()>
pub async fn update_pr_branch(&self, repo: &str, pr_number: u64) -> Result<()>
Update a PR’s branch by merging the latest base branch into it
(equivalent of the “Update branch” button on GitHub, or gh pr update-branch). Produces a new merge commit on the head branch,
which re-triggers CI — used to give a PR a chance to pick up a fix
that landed on the base branch after the PR’s last CI run failed.
Sourcepub async fn enable_auto_merge(&self, repo: &str, pr_number: u64) -> Result<()>
pub async fn enable_auto_merge(&self, repo: &str, pr_number: u64) -> Result<()>
Enable auto-merge on a PR via GraphQL.
GitHub will automatically merge the PR once all required checks pass.
Sourcepub async fn get_sub_issues(&self, repo: &str, number: &str) -> Result<Vec<u64>>
pub async fn get_sub_issues(&self, repo: &str, number: &str) -> Result<Vec<u64>>
Get sub-issues via GraphQL (paginated).
Sourcepub async fn get_combined_status(
&self,
repo: &str,
git_ref: &str,
has_workflows: bool,
mergeable_state: Option<&str>,
) -> Result<(String, u64, u64, u64, u64)>
pub async fn get_combined_status( &self, repo: &str, git_ref: &str, has_workflows: bool, mergeable_state: Option<&str>, ) -> Result<(String, u64, u64, u64, u64)>
Get combined CI check status for a git ref.
Sourcepub async fn rerun_failed_workflow(
&self,
repo: &str,
workflow_name: &str,
branch: &str,
) -> Result<()>
pub async fn rerun_failed_workflow( &self, repo: &str, workflow_name: &str, branch: &str, ) -> Result<()>
Rerun the latest failed workflow run for a given workflow name and branch.
Finds the most recent failed (or cancelled) run of workflow_name on
branch triggered by a push event, then calls the GitHub Actions
rerun endpoint so the same check run on the commit flips green.
Sourcepub async fn batch_fetch_pr_review_data(
&self,
repo: &str,
pr_numbers: &[u64],
) -> Result<HashMap<u64, PrReviewBatchData>>
pub async fn batch_fetch_pr_review_data( &self, repo: &str, pr_numbers: &[u64], ) -> Result<HashMap<u64, PrReviewBatchData>>
Fetch reviews, review comments, and issue comments for multiple PRs in a single GraphQL query instead of 4–5 REST calls per PR.
Returns a map of pr_number → PrReviewBatchData.
PRs missing from the response are omitted from the result.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for GhHttp
impl !RefUnwindSafe for GhHttp
impl !UnwindSafe for GhHttp
impl Send for GhHttp
impl Sync for GhHttp
impl Unpin for GhHttp
impl UnsafeUnpin for GhHttp
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more