pub struct GitHub<R: ProcessRunner = JobRunner> { /* private fields */ }Expand description
The real GitHub client. Generic over the ProcessRunner so tests can inject
a fake process executor; GitHub::new uses the real job-backed runner.
Wraps a ManagedClient. By default it authenticates through gh’s own
ambient login; attach a CredentialProvider with
with_credentials to supply a token per operation
— it is injected as GH_TOKEN on every gh invocation (or, after
with_host targets a GitHub Enterprise Server host,
as GH_ENTERPRISE_TOKEN — the variable gh reads for that host).
Implementations§
Source§impl<R: ProcessRunner> GitHub<R>
impl<R: ProcessRunner> GitHub<R>
Sourcepub fn with_runner(runner: R) -> Self
pub fn with_runner(runner: R) -> Self
Create a client driving runner — inject a fake in tests.
Sourcepub fn default_timeout(self, timeout: Duration) -> Self
pub fn default_timeout(self, timeout: Duration) -> Self
Apply a default timeout to every command this client builds.
Sourcepub fn default_env(
self,
key: impl AsRef<OsStr>,
value: impl AsRef<OsStr>,
) -> Self
pub fn default_env( self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>, ) -> Self
Set an environment variable on every command this client builds.
Sourcepub fn default_env_remove(self, key: impl AsRef<OsStr>) -> Self
pub fn default_env_remove(self, key: impl AsRef<OsStr>) -> Self
Remove an inherited environment variable on every command this client builds.
Sourcepub fn default_cancel_on(self, token: CancellationToken) -> Self
pub fn default_cancel_on(self, token: CancellationToken) -> Self
Cancel every command this client builds when token fires.
Network fetch/push/clone commands additionally use the shared
[FETCH_TIMEOUT_GRACE] cancellation window when this token fires,
including the Windows-only soft-trigger opt-in where processkit can
deliver it. The process outcome remains
ErrorReason::Cancelled; the grace changes only the teardown path.
Other commands keep their existing immediate-cancellation policy.
Sourcepub fn default_output_budget(self, budget: OutputBudget) -> Self
pub fn default_output_budget(self, budget: OutputBudget) -> Self
Apply a default OutputBudget to the
potentially large content operations this client builds — the
diff/show/pr-diff verbs and the clone/fetch diagnostic capture.
Inherited by any facade built over this client. The default is
OutputBudget::unlimited
(retain everything); a single call can still override it via the
*_within method variants.
Source§impl<R: ProcessRunner> GitHub<R>
impl<R: ProcessRunner> GitHub<R>
Sourcepub fn with_credentials(self, provider: Arc<dyn CredentialProvider>) -> Self
pub fn with_credentials(self, provider: Arc<dyn CredentialProvider>) -> Self
Supply credentials per operation via a CredentialProvider — opt-in, off
by default (ambient gh auth). The resolved token is injected as GH_TOKEN
on every gh invocation, overriding the ambient login for this client.
Sourcepub fn with_token(self, token: impl Into<Secret>) -> Self
pub fn with_token(self, token: impl Into<Secret>) -> Self
Convenience for the common case: authenticate with a single static token,
injected as GH_TOKEN. Shorthand for
with_credentials(Arc::new(StaticCredential::token(token))).
Sourcepub fn with_env_token(self, var: impl Into<String>) -> Self
pub fn with_env_token(self, var: impl Into<String>) -> Self
Convenience: read the token from environment variable var at request time
(injected as GH_TOKEN); if var is unset/empty, fall back to ambient auth.
Shorthand for with_credentials(Arc::new(EnvToken::new(var))).
Sourcepub fn with_host(self, host: GitHubHost) -> Self
pub fn with_host(self, host: GitHubHost) -> Self
Bind this client to a GitHub host, so a supplied credential is injected
into the environment variable gh reads for that host, and gh’s default
host is set accordingly:
- github.com (
GitHubHost::github_com) → the token goes toGH_TOKEN(the SaaS default, unchanged) andGH_HOSTisgithub.com. - a GitHub Enterprise Server host → the token goes to
GH_ENTERPRISE_TOKEN(the variableghuses for a non-github.com host) andGH_HOSTis set to that host, so gh’s non-repo commands resolve against it. The github.comGH_TOKENis not set, so an enterprise secret never lands in the github.com token env (nor vice versa).
Compose with with_credentials /
with_token / with_env_token
in either order — the host selects the env var, the provider supplies the
secret. The bound host also travels in each operation’s CredentialRequest,
so a host-keyed provider returns the secret for this host and never a
neighbouring instance’s. For several hosts, build one client per host:
each injects only its own host’s token, so a broken or missing credential for
one host can’t leak into another. Without a host binding the client behaves
exactly as before — github.com semantics, credential injected as GH_TOKEN,
and the request carries no host (a host-keyed provider that can’t place it
defers to ambient auth).
GH_HOST only steers gh’s host inference for commands with no repository
context; a repo-scoped command still resolves its host from the working
directory’s remote, so binding a host does not override a repo you point a
method at — use a host-bound client with repositories on that host.
Source§impl<R: ProcessRunner> GitHub<R>
impl<R: ProcessRunner> GitHub<R>
Sourcepub async fn pr_diff_within(
&self,
dir: &Path,
number: u64,
budget: OutputBudget,
) -> Result<Vec<FileDiff>>
pub async fn pr_diff_within( &self, dir: &Path, number: u64, budget: OutputBudget, ) -> Result<Vec<FileDiff>>
pr_diff with an explicit per-call OutputBudget,
instead of this client’s default_output_budget.
Past the ceiling the read errors with
ErrorReason::OutputTooLarge (actual and
allowed sizes) rather than buffering an unbounded diff — the override for a
legitimately huge PR.
Source§impl<R: ProcessRunner> GitHub<R>
impl<R: ProcessRunner> GitHub<R>
Sourcepub async fn run_args(&self, args: &[&str]) -> Result<String>
pub async fn run_args(&self, args: &[&str]) -> Result<String>
Run gh <args> over string slices — gh.run_args(&["pr", "list"]) without allocating a Vec<String>. Inherent (not on the object-safe trait), so it can take &[&str]; forwards to the same path as GitHubApi::run.
Sourcepub async fn run_raw_args(&self, args: &[&str]) -> Result<ProcessResult<String>>
pub async fn run_raw_args(&self, args: &[&str]) -> Result<ProcessResult<String>>
Like run_args but never errors on a non-zero exit (mirrors GitHubApi::run_raw).
Sourcepub async fn run_in(&self, dir: &Path, args: &[String]) -> Result<String>
pub async fn run_in(&self, dir: &Path, args: &[String]) -> Result<String>
Run gh <args> in dir (the process is spawned with dir as its working directory, so gh infers the repo from dir’s remote), returning trimmed stdout — the dir-bound twin of the process-cwd run. This is what GitHubAt::run forwards to; call run on the client for the process-cwd escape hatch. Argv is forwarded verbatim (only the working directory is bound, no -R/extra flag is injected).
Sourcepub async fn run_raw_in(
&self,
dir: &Path,
args: &[String],
) -> Result<ProcessResult<String>>
pub async fn run_raw_in( &self, dir: &Path, args: &[String], ) -> Result<ProcessResult<String>>
Like run_in but never errors on a non-zero exit — the dir-bound twin of run_raw. What GitHubAt::run_raw forwards to.
Sourcepub async fn run_args_in(&self, dir: &Path, args: &[&str]) -> Result<String>
pub async fn run_args_in(&self, dir: &Path, args: &[&str]) -> Result<String>
Like run_args but bound to dir — the &[&str] twin of run_in. What GitHubAt::run_args forwards to.
Sourcepub async fn run_raw_args_in(
&self,
dir: &Path,
args: &[&str],
) -> Result<ProcessResult<String>>
pub async fn run_raw_args_in( &self, dir: &Path, args: &[&str], ) -> Result<ProcessResult<String>>
Like run_raw_args but bound to dir — the &[&str] twin of run_raw_in. What GitHubAt::run_raw_args forwards to.
Trait Implementations§
Source§impl<R: ProcessRunner> Debug for GitHub<R>
impl<R: ProcessRunner> Debug for GitHub<R>
Source§impl<R: ProcessRunner> GitHubApi for GitHub<R>
impl<R: ProcessRunner> GitHubApi for GitHub<R>
Source§fn run<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh <args> in the process’s current directory, returning trimmed
stdout (throws on a non-zero exit). A raw escape hatch — you supply the whole
argv, so pass -R owner/repo to target a specific repo. This method on the
client is the process-cwd escape hatch; the at(dir) bound view’s
run is instead bound to dir (it forwards to
GitHub::run_in, so gh.at(dir).run(…) runs in the bound repo’s cwd, like
api). Use gh.at(dir).run(…) (or GitHub::run_in) for
the bound repo (T-035).Source§fn run_raw<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<ProcessResult<String>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_raw<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<ProcessResult<String>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
GitHubApi::run but never errors on a non-zero exit — returns the
captured ProcessResult.Source§fn version<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn version<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
gh --version).Source§fn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<GitHubCapabilities>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<GitHubCapabilities>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GitHubCapabilities
(gh --version). A value type — probe once and keep it; an unrecognisable
version banner is an ErrorReason::Parse. Gate an operation on a minimum gh
with GitHubCapabilities::ensure_supported.Source§fn auth_status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn auth_status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
gh auth status exits zero). Reflects
the exit code as a bool — any non-zero exit reads as false, never an
error; only a spawn failure or timeout errors. Unscoped: it inspects
every configured host, so a broken session for one host can make it
report false even when the host you care about is fine — reach for
auth_status_for to scope it.Source§fn auth_status_for<'life0, 'life1, 'async_trait>(
&'life0 self,
host: &'life1 GitHubHost,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn auth_status_for<'life0, 'life1, 'async_trait>(
&'life0 self,
host: &'life1 GitHubHost,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
host (gh auth status --hostname <host> exits zero) — the host-scoped twin of
auth_status. Scoping to the repository’s host
(build a GitHubHost from its remote, e.g.
GitHubHost::from_remote_url) means a broken or absent session for
another host can’t turn this into a false negative for the host you
target. Like auth_status, it folds only the exit code into the bool (any
non-zero exit → false); a spawn failure or timeout still errors.
Defaulted to ErrorReason::Unsupported so external implementers of the trait
keep compiling when the crate bumps (only the GitHub concrete impl and the
regenerated MockGitHubApi override it).Source§fn repo_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<RepoView>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn repo_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<RepoView>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
dir (gh repo view --json …).Source§fn pr_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
dir (gh pr list --limit 100 --json …). Returns up to
100 open PRs; use run for more.Source§fn pr_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: PrList,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: PrList,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
spec (--state / --limit). A zero limit is
rejected before spawning. Defaulted to ErrorReason::Unsupported so
external trait implementers keep compiling when the crate bumps.Source§fn pr_list_for_branch<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
head: &'life2 str,
base: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn pr_list_for_branch<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
head: &'life2 str,
base: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
head into base, in any state — open, closed,
or merged (gh pr list --head <head> --base <base> --state all --limit 100 --json …). Each carries its title, URL, and state. Empty when none
match; returns up to 100 (use run for more).Source§fn pr_list_for_source_branch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
head: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn pr_list_for_source_branch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
head: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<PullRequest>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
head, in any state — open, closed,
or merged (gh pr list --head <head> --state all --limit 100 --json …).
Empty when none match; returns up to 100. A flag-like or empty head is
rejected before spawning so an untrusted branch cannot alter the command. Read moreSource§fn pr_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<PullRequest>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<PullRequest>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr view <n> --json …).Source§fn issue_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
dir (gh issue list --limit 100 --json …). Returns up to 100
open issues; use run for more.Source§fn issue_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: IssueList,
) -> Pin<Box<dyn Future<Output = Result<Vec<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: IssueList,
) -> Pin<Box<dyn Future<Output = Result<Vec<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
spec (--state / --limit). A zero limit is
rejected before spawning. Defaulted to ErrorReason::Unsupported so
external trait implementers keep compiling when the crate bumps.Source§fn pr_create<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: PrCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_create<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: PrCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr create) — see
PrCreate for the title/body and the optional head (source branch;
None = current branch) / base (target; None = repo default).Source§fn api<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
endpoint: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn api<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
endpoint: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh api <endpoint>), run in dir so
a relative endpoint’s {owner}/{repo} placeholder resolves against the bound
repository — not whatever repo the process’s current directory happens to be in.Source§fn pr_merge<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
merge: PrMerge,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_merge<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
merge: PrMerge,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr merge <n> --merge|--squash|--rebase [--auto] [--delete-branch]) — see PrMerge.Source§fn pr_mark_ready<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_mark_ready<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr ready <n>).Source§fn pr_close<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
spec: PrClose,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_close<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
spec: PrClose,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr close <n> [--delete-branch]); see PrClose.Source§fn pr_checkout<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_checkout<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
dir
(gh pr checkout <n>) — the head branch is fetched and switched to, so a
subsequent build/test/edit runs against the PR locally. Mutates the working
copy. Defaulted to ErrorReason::Unsupported so external implementers of the
trait keep compiling when the crate bumps (only the GitHub concrete impl
and the regenerated MockGitHubApi override it).Source§fn pr_checks<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<CheckRun>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_checks<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<CheckRun>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr checks <n> --json …). gh signals the overall
outcome through its exit code — 0 all passed, 8 still pending, 1 some
failed — and emits the same JSON either way, so all three return the
parsed list; branch on each entry’s bucket. A PR
with no checks at all yields an empty list (gh’s “no checks reported”
exit). Any other exit (no such PR, auth required, …) errors.Source§fn pr_review<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
action: ReviewAction,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_review<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
action: ReviewAction,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr review <n> --approve|--request-changes|--comment [--body <body>]) — see ReviewAction (request-changes/comment carry a
required body by construction).Source§fn pr_comment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
body: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn pr_comment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
body: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh pr comment <n> --body <body>).Source§fn pr_edit<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
edit: PrEdit,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_edit<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
edit: PrEdit,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr edit <n> [--title <title>] [--body <body>]). At least one of
title or body must be Some — the facade rejects both-None
before reaching the wrapper, so the default implementation is
unreachable in normal use. Defaulted to ErrorReason::Unsupported so
external implementers of the trait keep compiling when the crate
bumps.Source§fn pr_feedback<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<PrFeedback>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_feedback<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<PrFeedback>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh pr view <n> --json reviews,comments).Source§fn pr_diff<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<FileDiff>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pr_diff<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<FileDiff>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn workflow_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Workflow>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn workflow_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Workflow>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh workflow list --limit 50 --json …).
Disabled workflows are hidden; use workflow_list_with
with WorkflowList::all to include them. Defaulted to
ErrorReason::Unsupported so external trait implementers keep compiling.Source§fn workflow_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: WorkflowList,
) -> Pin<Box<dyn Future<Output = Result<Vec<Workflow>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn workflow_list_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: WorkflowList,
) -> Pin<Box<dyn Future<Output = Result<Vec<Workflow>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
spec (--all / --limit). A zero
limit is rejected before spawning. Defaulted to
ErrorReason::Unsupported so external trait implementers keep compiling.Source§fn workflow_view<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
selector: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Workflow>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn workflow_view<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
selector: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Workflow>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh workflow view has no --json mode,
so this resolves against the complete disabled-inclusive JSON inventory
from gh workflow list rather than scraping human-readable output.
Defaulted to ErrorReason::Unsupported so external trait implementers
keep compiling.Source§fn run_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
limit: u64,
branch: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<WorkflowRun>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
limit: u64,
branch: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<WorkflowRun>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh run list --limit <n> [--branch <b>] --json …). branch is an owned Option<String> to keep
the trait mockall-friendly.Source§fn run_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<WorkflowRun>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<WorkflowRun>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh run view <id> --json …); the id is
WorkflowRun::database_id.Source§fn run_watch<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<WorkflowRun>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_watch<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<WorkflowRun>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh run watch <id>, then a run view). Inspect
conclusion for the outcome — exit codes
can’t distinguish a failed run from a cancelled one. Read moreSource§fn workflow_dispatch<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: WorkflowDispatch,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn workflow_dispatch<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: WorkflowDispatch,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
workflow_dispatch event for a workflow, driven by a
WorkflowDispatch spec (the workflow selector plus an optional target ref
and inputs) — the whole span kept on one line so rustdoc doesn’t read the
angle-bracket placeholders as HTML:
gh workflow run <workflow> [--ref <ref>] [--raw-field key=value …].
The workflow file must declare an on: workflow_dispatch trigger. Read moreSource§fn run_rerun<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
scope: RerunScope,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_rerun<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
scope: RerunScope,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh run rerun <id> [--failed]); pass a
RerunScope to rerun every job (All) or only the
failed jobs and their dependencies (FailedOnly).
The id is WorkflowRun::database_id; being a u64, the bare positional can
never look like a flag — nothing to guard. Read moreSource§fn run_cancel<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run_cancel<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh run cancel <id>). The id is
WorkflowRun::database_id; being a u64, the bare positional can never look
like a flag — nothing to guard. Read moreSource§fn issue_create<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
title: &'life2 str,
body: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn issue_create<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
title: &'life2 str,
body: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
gh issue create --title <title> --body <body>).Source§fn issue_create_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: IssueCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_create_with<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: IssueCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
issue_create.Source§fn pr_add_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn pr_add_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh pr edit <n> --add-label <name>).Source§fn pr_remove_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn pr_remove_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh pr edit <n> --remove-label <name>).Source§fn issue_add_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn issue_add_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh issue edit <n> --add-label <name>).Source§fn issue_remove_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn issue_remove_labels<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
labels: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh issue edit <n> --remove-label <name>).Source§fn issue_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_view<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
body/url filled
(gh issue view <n> --json …).Source§fn issue_close<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_close<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh issue close <n>). number is a u64, so the bare
positional can never look like a flag — nothing to guard. Defaulted to
ErrorReason::Unsupported so external implementers of the trait keep compiling
when the crate bumps (only the GitHub concrete impl and the regenerated
MockGitHubApi override it).Source§fn issue_reopen<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn issue_reopen<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh issue reopen <n>). number is a u64, so the
bare positional can never look like a flag — nothing to guard. Defaulted
to ErrorReason::Unsupported so external implementers of the trait keep compiling
when the crate bumps (only the GitHub concrete impl and the regenerated
MockGitHubApi override it).Source§fn issue_comment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
body: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn issue_comment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
number: u64,
body: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh issue comment <n> --body <body>). The body rides in a flag-VALUE slot,
so a leading - is safe and no argv guard is needed (same as
pr_comment). Defaulted to ErrorReason::Unsupported
so external implementers of the trait keep compiling when the crate bumps
(only the GitHub concrete impl and the regenerated MockGitHubApi override
it).Source§fn release_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Release>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn release_list<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<Release>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh release list --limit 100 --json …); body/url
are not fetched here — use release_view.
Returns up to 100 releases; use run for more.Source§fn release_view<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Release>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn release_view<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Release>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
body/url filled
(gh release view <tag> --json …). gh reports is_latest only from
release_list; here it defaults to false.Source§fn release_create<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: ReleaseCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn release_create<'life0, 'life1, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
spec: ReleaseCreate,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
gh release create <tag> [--title <title>] [--notes <notes>] [--draft] [--prerelease])
— see ReleaseCreate.
gh creates the git tag from the default branch’s latest state if it doesn’t
yet exist. Asset uploads are out of scope (attach files with
run). Defaulted to ErrorReason::Unsupported so external
implementers of the trait keep compiling when the crate bumps (only the
GitHub concrete impl and the regenerated MockGitHubApi override it).Source§fn release_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn release_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
dir: &'life1 Path,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
gh release delete <tag> --yes). --yes skips gh’s
confirmation prompt so a headless caller never hangs. Deletes the release
only, not the underlying git tag (use gh release delete --cleanup-tag via
run for that). Defaulted to ErrorReason::Unsupported so
external implementers keep compiling when the crate bumps.