How do you use the GitHub CLI (gh) to automate common developer workflows, and what are its most powerful features beyond basic PR management?
Quick Answer
The GitHub CLI (gh) provides command-line access to GitHub's full API surface, enabling automation of PRs, issues, releases, Actions workflows, secrets, and custom API calls. Its most powerful features include gh api for arbitrary API calls with jq filtering, gh workflow for triggering and managing Actions runs, and gh extension for community-built plugins.
Detailed Answer
Think of the GitHub CLI like a universal remote control for your entire GitHub experience. Most people use it only to change the channel (create PRs and issues), but it can actually program the DVR (trigger workflow dispatches), manage parental controls (configure secrets and branch protection), pull up the program guide (query the API with jq filters), and install third-party streaming apps (extensions). Once you learn the advanced features, you rarely need to open the GitHub web UI for administrative tasks.
The GitHub CLI is organized into command groups that mirror GitHub's product areas: gh repo for repository operations, gh pr for pull requests, gh issue for issues, gh workflow for Actions workflows, gh secret for secrets management, gh release for releases, and gh api for raw API access. Authentication is handled through gh auth login, which supports both browser-based OAuth and personal access tokens. The CLI respects your current Git context, so running gh pr list in a cloned repository automatically targets that repository without needing to specify --repo. For scripting, most commands support --json with field selection and --jq for inline filtering, producing machine-readable output that pipes cleanly into other tools.
The gh api command is where the CLI becomes truly powerful. It provides direct access to both GitHub's REST and GraphQL APIs with automatic authentication, pagination handling, and response formatting. You can query any endpoint: gh api repos/acme-corp/checkout-service/actions/runs --jq '.workflow_runs[] | {name: .name, status: .status, conclusion: .conclusion}' lists recent workflow runs with their statuses. For mutations, you specify --method POST/PUT/DELETE and pass fields with --field. GraphQL queries are sent with gh api graphql -f query='...'. This means any GitHub operation that is possible through the web UI or API is scriptable from the terminal, enabling automation scenarios like bulk repository management, compliance auditing, and custom dashboards.
In production, teams use gh to build powerful automation scripts. An SRE team at Acme Corp might have a morning-report.sh script that uses gh api to check all failing workflow runs across their repositories, lists PRs awaiting their review, and shows open Dependabot alerts sorted by severity. A release manager might use gh release create to tag releases, generate changelogs from merged PRs using gh pr list --search 'merged:>2024-01-01', and upload build artifacts. The gh workflow run command triggers workflow dispatches, enabling ChatOps patterns where a Slack bot calls a script that triggers a deployment workflow with specific inputs. Extensions (gh extension install) add community capabilities like gh dash for a terminal-based GitHub dashboard, gh copilot for CLI-based AI assistance, and gh poi for cleaning up local branches that have been merged.
A key gotcha is that gh api paginates responses by default, returning only 30 items per request. For scripts that need all results, use --paginate to automatically follow next-page links. Without it, you silently get only the first page, which can cause scripts to miss repositories, issues, or workflow runs. Another pitfall is rate limiting: the authenticated GitHub API allows 5,000 requests per hour, and heavy scripting can exhaust this limit. Use conditional requests with --cache to reduce API calls, and monitor your rate limit with gh api rate_limit. Finally, gh auth token outputs your current token, which is dangerous in scripts that log their commands. Never pipe gh auth token into logs or echo statements.