GitHub CLI Workflows Most Developers Never Use

You have GitHub CLI installed. You use it to clone repos and maybe open a pull request from the terminal. That covers about 10% of what it can do. The other 90% — the part that eliminates context switches, automates repetitive repository tasks, and lets you drive your entire GitHub workflow without touching a browser — sits undiscovered in the documentation most developers never read. This guide covers the workflows worth knowing.

Why the GitHub CLI is underused

Most developers install gh for one specific task — usually because a README told them to — and never explore further. The browser interface is familiar, the CLI has a learning curve, and the documentation is exhaustive enough to feel discouraging rather than inviting.

But the compounding cost of browser-based GitHub workflows is real: switching windows mid-focus to check a PR status, clicking through four pages to find a specific issue, waiting for a page to load to merge a branch you already reviewed locally. Each switch is small. Over a workday, they add up to a significant loss of flow.

The workflows below are not shortcuts for their own sake — each one eliminates a specific, recurring friction point.

Workflow 1: create and manage PRs entirely from the terminal

Most developers know gh pr create. Fewer know the flags that make it actually useful in a team context.

gh pr create \
  --title "feat: add rate limiting to auth endpoints" \
  --body "$(cat .github/pull_request_template.md)" \
  --reviewer username1,username2 \
  --assignee @me \
  --label "security,backend" \
  --draft

The --body "$(cat ...)" pattern is particularly useful: it pulls your PR template from the repo automatically, so you never open a blank description. The --draft flag creates the PR in draft state — visible to reviewers but clearly marked as not ready for merge. This is the correct default for work in progress.

Once the PR is open, you can check its status, view comments, and merge it without leaving the terminal:

gh pr status
gh pr view 142 --comments
gh pr merge 142 --squash --delete-branch

The --delete-branch flag on merge is worth making a habit: it cleans up the remote branch immediately, which keeps your branch list manageable without a separate cleanup pass.

Workflow 2: check out a PR locally in one command

Reviewing a PR that touches something complex often means you need to run it locally — not just read the diff. The standard process (find the branch name, fetch, checkout) is friction. This eliminates it:

gh pr checkout 142

This fetches the branch and checks it out in one step, regardless of whether the PR comes from a fork or the same repo. For fork PRs especially — where the branch lives in someone else’s remote — this is dramatically faster than the manual alternative of adding the fork as a remote and fetching the specific branch.

Workflow 3: filter issues and PRs with precision queries

The default gh issue list and gh pr list commands return open items assigned to you — useful, but limited. The search flag unlocks the full GitHub search syntax:

gh issue list --search "label:bug is:open no:assignee sort:created-asc"
gh pr list --search "review-requested:@me draft:false"
gh pr list --search "status:failure base:main"

The last example is particularly useful: it finds all open PRs targeting main where CI is currently failing. Useful for a quick morning triage before your standup — you get the list in seconds without navigating to the repository’s PR tab and filtering manually.

You can pipe these results into other commands. For example, to open every failing PR in the browser for review:

gh pr list --search "status:failure base:main" --json number \
  | jq '.[].number' \
  | xargs -I{} gh pr view {} --web

Workflow 4: run and monitor GitHub Actions from the terminal

Watching a CI run in the browser means keeping a tab open and refreshing manually. gh run brings that workflow into the terminal:

gh run list --limit 5
gh run watch
gh run view --log-failed

gh run watch streams the status of the currently running workflow in real time. gh run view --log-failed shows only the logs from failed steps — not the entire run output, which on a verbose CI pipeline can be thousands of lines. This alone saves significant time when debugging a failing workflow.

You can also trigger a workflow manually:

gh workflow run deploy.yml --ref staging

This is particularly useful for deployment workflows that are triggered manually rather than on push — no need to navigate to the Actions tab, find the workflow, and click the button.

Workflow 5: manage repository settings and secrets from the CLI

Repository secrets are one of the most browser-locked parts of GitHub. Setting or rotating a secret requires navigating to Settings → Secrets → Actions → New secret, every time. With gh secret:

gh secret set DATABASE_URL
gh secret list
gh secret delete OLD_API_KEY

gh secret set prompts for the value securely (it will not appear in shell history). You can also pipe a value from a file or another command:

gh secret set PRIVATE_KEY < ./keys/private.pem

This is especially useful during onboarding or environment rotation, where you need to set multiple secrets in sequence — the CLI approach is dramatically faster than the browser alternative.

Workflow 6: create GitHub CLI aliases for your most common commands

gh alias set lets you define shortcuts for commands you run repeatedly. This is different from shell aliases — these are first-class gh subcommands stored in your config:

gh alias set prs 'pr list --search "review-requested:@me draft:false"'
gh alias set mine 'issue list --assignee @me --state open'
gh alias set failing 'pr list --search "status:failure base:main"'

After setting these, gh prs, gh mine, and gh failing become available as first-class commands. They follow you across machines if you store your gh config in a dotfiles repo.

Workflow 7: use gh as a scripting primitive

The --json flag combined with --jq turns gh into a scriptable data source. This opens up a class of automation that would otherwise require the GitHub REST API and a dedicated script:

gh pr list --json number,title,author,createdAt \
  --jq '.[] | select(.author.login != "dependabot") | [.number, .title] | @tsv'

This returns a tab-separated list of PR numbers and titles, excluding Dependabot PRs. From here you can pipe into a Slack message, a CSV, a markdown report, or any other downstream tool. No API key management, no OAuth flow — gh handles authentication and you get structured data out.

Frequently asked questions

Does gh cli work with GitHub Enterprise?

Yes. Authenticate against your Enterprise instance with gh auth login --hostname your.enterprise.hostname. You can manage multiple authenticated hosts simultaneously — gh uses the correct credentials based on the repository remote.

How do I switch between multiple GitHub accounts?

Use gh auth switch to toggle between authenticated accounts. To see all authenticated accounts: gh auth status. For per-repo account selection, set the GH_HOST environment variable in your shell session.

Can I use gh inside CI/CD pipelines?

Yes — and this is one of the most underused patterns. Inside a GitHub Actions workflow, GITHUB_TOKEN is automatically available. Set GH_TOKEN=${{ secrets.GITHUB_TOKEN }} as an environment variable and gh commands work without any additional authentication step. Useful for auto-labeling PRs, creating issues on failure, or posting comments from within a workflow.

Final thoughts

The GitHub CLI is one of those tools where the return on investment increases steeply with depth of use. The first few commands you learn save minutes. The scripting and alias patterns save hours per week — and more importantly, they eliminate the context switches that break focus during deep work. Install it, authenticate, and spend thirty minutes reading gh help. The investment is modest; the return is not.

For more terminal-first development workflows, see our guides on terminal aliases and scripts and Hidden Software Workflows.

Leave a Reply

Your email address will not be published. Required fields are marked *