Skip to content

Best practices for utilizing the gh command #2

@kanywst

Description

@kanywst

Why this is open

My dotfiles ship five gh aliases and that is the entire surface I use day to day:

# kanywst/dotfiles : zsh/conf.d/50-aliases.zsh
alias ghco='gh pr checkout $(gh pr list | fzf | awk "{ print \$1 }")'
alias ghpr='gh pr create --web'
alias ghprl='gh pr list'
alias ghprv='gh pr view --web'
command -v gh &>/dev/null && alias ghd='gh dash'

Four of those wrap pr. The fifth opens a TUI. gh 2.93.0 (2026-05-27) has 30+ top-level subcommands including api, search, attestation, ruleset, cache, agent-task, and skill, and I touch none of them from muscle memory. This issue tracks the work of fixing that: figure out what is actually worth a keystroke, and what is worth knowing exists but not aliasing.

Note

Scope is gh itself, not GitHub Actions YAML, not git. The output is one TIL note under articles/TIL/meta/, then a possible deep-dive article if gh api + GraphQL turns into enough hands-on material.

The mental model I want to land

gh is not "a PR CLI". It is a GitHub REST/GraphQL client with a JSON pipeline (--json--jq / --template) and PR ergonomics layered on top. Most of the value people miss is in the pipeline, not the subcommands. The TIL should be organised around that, not around an alphabetical tour.

Angles to research

gh api as a first-class tool

Verified flags I want to write up with concrete recipes:

  • --paginate walks all pages, --slurp wraps them as a JSON array
  • --cache 1h stores the response locally (genuinely underused for write-up scripts that re-query the same endpoint while iterating)
  • --method, -f (string), -F (typed: number / boolean / @file)
  • gh api graphql -f query='...' for anything REST can't express in one round trip

Target recipes:

  • list every open PR in the org with the reviewer who has been sitting on it longest
  • diff two release tags via GraphQL compareCommits and tablerow the output
  • one-liner that finds stale gh cache entries across repos I own

--jq vs --template

gh help formatting confirms the contract: --json field1,field2 first, then either --jq or --template. Calling --json with no argument prints the available fields, which is the right way to discover schema.

When to pick which:

  • --jq if you already speak jq and want a stream of values
  • --template when you want aligned columns (tablerow + tablerender), relative time (timeago), or terminal hyperlinks (hyperlink) without piping to column

PR lifecycle without leaving the terminal

What I want to verify hands-on (none of this is in my current alias set):

  • gh pr create --fill / --fill-first / --fill-verbose: confirm the difference between "first commit only" and "all commit bodies"
  • gh pr checks --watch --fail-fast as a replacement for refresh-the-tab
  • gh pr merge --auto --squash --delete-branch for fire-and-forget
  • gh issue develop <num> --checkout --base main to create a branch linked to an issue (good test case: run it on this very issue)

Tip

gh pr co is a built-in alias for gh pr checkout. My ghco wraps it with fzf, but for one-PR-at-a-time work gh pr co <num> is shorter than the fzf dance.

GitHub Actions ops

  • gh run list --workflow publish.yml -L 5 to inspect what the dev.to publisher is doing
  • gh run watch <id> to block on the current run
  • gh run rerun <id> --failed to rerun only failed jobs with their dependencies
  • gh cache list / gh cache delete --all when CI gets wedged on a poisoned cache

Supply chain (the part that wires into this repo)

gh attestation verify requires --owner or --repo (not both), enforces https://slsa.dev/provenance/v1 by default, and accepts --predicate-type for other SLSA / in-toto predicates. The reusable-workflow caveat from --help is important: when the artifact was built via a reusable workflow, the signer is the reusable workflow, not the caller, and --signer-workflow or --cert-identity is mandatory.

This connects directly to articles/fulcio-sigstore-ca-deep-dive.md and articles/guac-supply-chain-graph.md: the "now actually verify it" step in those pieces should point at gh attestation verify as the lowest-friction client.

gh alias vs shell alias

Two mechanisms, one decision rule worth writing down:

  • gh alias set foo 'pr view' stores the alias in ~/.config/gh/config.yml, follows me across shells, and supports positional $1
  • gh alias set foo --shell '...' (or expansion prefixed with !) runs through sh, which is what you need for pipes
  • shell aliases (zsh / bash) are what you reach for when fzf, awk, or any non-gh binary is in the pipe

My ghco belongs in the second bucket. ghpr, ghprl, ghprv are all candidates to migrate to gh alias so they survive a shell switch.

Multi-account and Enterprise

gh help environment documents the precedence explicitly:

Purpose Vars (highest → lowest precedence)
github.com auth GH_TOKEN, GITHUB_TOKEN
GHES auth GH_ENTERPRISE_TOKEN, GITHUB_ENTERPRISE_TOKEN
Target host GH_HOST
Target repo GH_REPO ([HOST/]OWNER/REPO)
Editor GH_EDITOR, GIT_EDITOR, VISUAL, EDITOR

gh auth switch flips active accounts when the host has multiple users configured. GH_REPO=0-draft/dev.to gh issue list lets me work against this repo from any cwd, which the TIL should call out for users juggling repos across orgs.

Extensions actually worth installing

I verified these exist and are still maintained as of 2026-05:

  • dlvhdr/gh-dash: installed already, 11.7k stars, last push 2026-05-28
  • seachicken/gh-poi: branch cleanup after merge, 965 stars, last push 2026-05-03
  • meiji163/gh-notify: terminal notifications, 344 stars, last push 2026-04-30

Anything else needs first-hand testing before it goes in the TIL.

Preview surface (2026)

gh agent-task and gh skill both ship as preview commands in 2.93. Worth a paragraph in the TIL because they exist now and the surface will change. Pin behavior to the version that was tested.

Debugging

  • GH_DEBUG=api gh ... dumps HTTP traffic on stderr, which is how you reverse-engineer what an endpoint actually returns when --json field discovery isn't enough
  • gh status shows assigned PRs, review requests, mentions, and repo activity across subscribed repos in one screen
  • gh help exit-codes for scripting

Verify before writing

  • gh pr create --fill-first on a multi-commit branch: which commit message wins?
  • gh attestation verify against a real public artifact (e.g. a cosign release binary) end to end
  • gh issue develop 2 --checkout on this issue, observe how the linked branch shows up in the issue sidebar
  • gh api graphql --paginate --slurp cursor behavior with GH_DEBUG=api to see how the endCursor is threaded
  • -R owner/repo flag vs GH_REPO env var: which wins when both are set

Output plan

  1. TIL note at articles/TIL/meta/2026-05-31-gh-cli-best-practices.md: the 10ish patterns I'll actually reach for, with the verified flag set
  2. If gh api + GraphQL grows into enough material (paginated org-wide PR queries, attestation verification recipes), promote to articles/gh-cli-deep-dive.md and flip the label to status/article-wip

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions