Appendix Episode 53 10-12 min

GitHub CLI Reference

Using the GitHub CLI for issues, pull requests, authentication, and automation-friendly workflows.

Listen

Transcript

Alex: Welcome back. Today we're looking at the GitHub CLI, which is the `gh` command. It lets you work with GitHub issues, pull requests, repositories, and releases from your terminal.

Jamie: So this is different from `git`, right? Because I can already clone, branch, commit, and push with Git.

Alex: Exactly. `git` handles local version control: commits, branches, history, and moving code between your computer and a remote. `gh` handles GitHub-specific work: opening an issue, viewing a pull request, checking CI, creating a release, or opening the current repo in your browser.

Jamie: That distinction helps. Git is the version control tool, and `gh` is the GitHub workflow tool that sits beside it.

Alex: Yes. A good way to learn it is local first, then GitHub. Get comfortable with the Git basics, then add `gh` when you want the GitHub page information without hunting through a web interface. And after each command, listen to or read the result before you keep going.

Jamie: I like that it encourages smaller moves. Clone, inspect, branch, edit, commit, push, then open the pull request. Nothing has to be one giant leap.

Alex: To install `gh`, the path depends on your operating system. On Windows, you can use `winget install GitHub.cli`, or download the installer from cli.github.com. On macOS, the common Homebrew command is `brew install gh`.

Jamie: And Linux has a slightly longer setup, especially on Debian or Ubuntu, because you add the official GitHub CLI package source and then install `gh` with apt.

Alex: Right. The appendix gives the full Debian and Ubuntu command block, and it is worth copying from the official reference rather than retyping it from memory. Once installed, run `gh --version` to confirm the command is available.

Jamie: Then comes signing in, which is the part people sometimes worry about.

Alex: The command is `gh auth login`. It asks where you use GitHub, usually GitHub.com unless your organization uses Enterprise. Then it asks for your preferred protocol, HTTPS or SSH, and whether to authenticate with a browser.

Jamie: And if you choose the browser option, the terminal hands you off to sign in, then you come back to the terminal when GitHub confirms it worked.

Alex: Exactly. After that, `gh auth status` checks the signed-in account. `gh auth logout` signs out. `gh auth refresh` updates credentials or adds permissions, which GitHub calls scopes.

Jamie: One thing I appreciate is that the login prompt is plain text. Arrow keys move through choices, Enter confirms, and the browser step is only one part of the flow.

Alex: On Windows, the appendix recommends setting up Windows Terminal once and reusing it. Keep a dedicated shell profile for Git work, learn mark mode with Ctrl+Shift+M for reviewing and copying output line by line, and use Ctrl+Shift+P for the command palette. Stable font size and contrast also help a lot.

Jamie: And the setup advice is not only for screen reader users. Low vision users can scale the terminal and choose contrast settings, and sighted users can watch for the greater-than marker that shows the current interactive choice.

Alex: One safety note before we leave setup: stick with options shown in `gh --help` or the official CLI manual, especially in class or production work. Undocumented flags can change or disappear.

Alex: Repository commands are where `gh` starts feeling fast. `gh repo clone owner/repo-name` clones a repository and sets up the remote for you.

Jamie: So instead of copying a URL from the website, I can use the owner and repo name directly.

Alex: Exactly. If you need a fork, `gh repo fork owner/repo-name --clone` creates the fork and clones your fork in one flow. If you only want the fork on GitHub, use `gh repo fork owner/repo-name` without `--clone`.

Jamie: What about starting something new?

Alex: Use `gh repo create my-new-project`. You can add `--public`, `--private`, and a description. Then `gh repo view` shows details for the current repository, and `gh repo view owner/repo-name` shows details for another one.

Jamie: And `gh repo view --web` opens the repo in the browser when the web page really is useful.

Alex: Yes. You can list your repositories with `gh repo list`, raise the count with `--limit 50`, or list an organization's repos with `gh repo list my-org --limit 100`. There are also admin-level commands: `gh repo archive owner/repo-name`, and `gh repo delete owner/repo-name --confirm`.

Jamie: Delete with confirm sounds like a command to slow down around.

Alex: Definitely. Read the target repository name before pressing Enter. And if you're working from a fork, `gh repo sync` or `gh repo sync --branch main` helps bring your fork up to date with its upstream repository.

Jamie: Issues feel like a natural place for the CLI, because there is so much listing, filtering, and checking.

Alex: They are a great fit. `gh issue create` starts an interactive prompt for the title, body, labels, and related fields. If you already know the details, you can provide them inline with options like `--title`, `--body`, `--label`, and `--assignee @me`.

Jamie: And for a long accessibility report, typing everything into a prompt might not be ideal.

Alex: Right. Write the report in a Markdown file first, then run `gh issue create --title "Accessibility audit findings" --body-file ./report.md`. That lets you use your editor, spell check, search, and review commands before publishing.

Jamie: Once issues exist, how do you find the right one?

Alex: `gh issue list` shows open issues in the current repo. Add filters like `--label accessibility`, `--label "good first issue"`, `--assignee @me`, `--state closed`, or `--limit 50`. You can search with `gh issue list --search "screen reader"`, and you can point at another repository with `--repo owner/repo-name`.

Jamie: Viewing is where the accessibility benefit really shows up for me.

Alex: Yes. `gh issue view 42` renders the title, metadata, and Markdown body as plain terminal text. `gh issue view 42 --comments` includes comments, and `gh issue view 42 --web` opens the browser if you want the full web page.

Jamie: Plain text means I can review line by line instead of crossing through navigation regions, sidebars, buttons, and reactions.

Alex: For updates, use `gh issue comment 42 --body "I can reproduce this on Windows 11 with NVDA."` or `--body-file ./my-comment.md`. You can edit an issue title, add or remove labels, add an assignee, close it with a comment or a reason, and reopen it later. Maintainers can also pin an issue so it appears at the top of the Issues tab, or lock it to prevent new comments when a discussion is resolved or needs to cool down.

Alex: Pull requests follow a similar pattern, but they connect your branch to a review process. After you commit and push your branch, `gh pr create` walks you through the title, body, base branch, and other details.

Jamie: And if I already know what I want, I can create it without the prompt.

Alex: Yes. You can pass a title, body, base branch, and labels inline. You can also create a draft with `--draft`, use `--body-file` to pull the description from a Markdown file, or use `gh pr create --web` to open the browser form.

Jamie: Draft is useful when the work is visible but not ready for review yet.

Alex: Exactly. To keep track of review work, `gh pr list` shows open pull requests. Filters can narrow by author, assignee, label, base branch, or state. `gh pr view` shows the title, description, review status, and checks for the current branch's pull request.

Jamie: What if I need to inspect the actual code changes?

Alex: Use `gh pr diff` for the patch, or `gh pr view --web` if a visual web diff is better for that moment. You can also run `gh pr checkout 123` to check out someone else's pull request branch locally and test it.

Jamie: The review commands are the ones I always forget.

Alex: They are direct: approve, request changes, or leave a comment-only review. For status, `gh pr checks` shows CI results, `gh pr checks --watch` refreshes while checks run, and you can check the current branch's PR too. For merging, `gh pr merge` can prompt for the merge strategy, or you can specify merge, squash, or rebase, enable auto-merge when checks pass, and delete the branch after merging.

Jamie: And if the state changes, there are commands for that as well.

Alex: Yes. You can mark a draft ready for review, move a ready PR back to draft, update the branch with the latest base branch, close without merging, reopen a closed PR, and add a comment. The CLI is especially good when you know the PR number and the action you want.

Alex: Releases are another area where the CLI keeps repeatable work tidy. You can create a release interactively, create one with all details inline, or load notes from a file.

Jamie: And there are different release states, right? Published, pre-release, and draft.

Alex: Right. A pre-release signals that the version is not final, and a draft release lets maintainers prepare everything before publishing. You can upload files to a release, list releases, view one, download release assets, and delete a release when you have permission.

Jamie: Search is broader than the current repository.

Alex: It is. `gh search issues`, `gh search prs`, `gh search repos`, and `gh search code` let you search across GitHub from the terminal. You can combine search terms and filters when you need a short, focused result set.

Jamie: Labels and milestones fit into project maintenance.

Alex: Yes. You can list labels, create a label, clone labels from another repository, or delete a label. For milestones, you can list existing milestones and create new ones. Those commands help keep issue and PR organization consistent across repositories.

Jamie: The output formatting part feels powerful, but also like the place where people might get intimidated.

Alex: A little, but the idea is simple. Many `gh` commands can return JSON with `--json`, which means structured data instead of human-formatted text. For example, you can request issue fields, PR fields, or a list of issues as JSON.

Jamie: JSON is the format with names and values, so tools can pick out just the pieces you ask for.

Alex: Exactly. Then `--jq` filters that JSON right inside the command. You can list just issue numbers and titles, get the names of labels on an issue, count open PRs, or list reviewers who approved a PR.

Jamie: That is also good for screen reader output, because less output can mean less noise.

Alex: Yes. And if you want a custom text layout, `--template` uses Go templates. That is more advanced, but it can produce exactly the line format your team wants.

Jamie: Aliases are the friendly version of that idea: make the command shorter.

Alex: Right. `gh alias set` creates a shortcut, `gh alias list` shows your aliases, and `gh alias delete` removes one. You can also create a shell alias that runs a full shell command, not only a `gh` subcommand.

Jamie: Useful examples would be issues assigned to me, my open PRs, check CI for the current branch's PR, or view the current PR.

Alex: Those are exactly the kind of shortcuts worth keeping. Extensions go one step further by adding new `gh` commands. You can browse available extensions, install one, list installed extensions, update all of them or one specific extension, and remove an extension you no longer use.

Alex: Copilot can also appear in the CLI, if your account and environment support it. After a one-time setup, you can ask for a command suggestion or ask Copilot to explain a command you do not recognize.

Jamie: That sounds helpful, but I would still want to read the command before running it.

Alex: Absolutely. Treat suggestions as drafts. Confirm the command, confirm the repository, and confirm whether it changes anything before you press Enter.

Jamie: The appendix also mentions model selection and telemetry.

Alex: Yes. Copilot can choose a model automatically by default, or you can request a specific model when that option is available. And if you need to opt out of telemetry, use the documented Copilot CLI settings rather than guessing at configuration files.

Alex: Let's spend a moment on screen reader and low vision workflow, because this is where the CLI can be genuinely comfortable. Terminal output is plain text, there are no hidden page regions, and command results are easy to copy, save, search, or open in an editor.

Jamie: But plain text can still be too much if a command prints a hundred lines.

Alex: Exactly. Pipe output to `less` for page-by-page reading. Save output to a file and open it in VS Code or your preferred editor. Limit results with flags like `--limit 20`, and combine list commands with search terms so the result set starts smaller.

Jamie: I also like asking for one field when that is all I need.

Alex: Yes. Get just the PR title, just the issue body, or CI check status as a simple list. And for writing, compose the issue body or PR body in a text file first, then create the issue or pull request from that file.

Jamie: Any platform-specific habits?

Alex: On Windows with NVDA or JAWS, Windows Terminal mark mode can help you review and copy output. On macOS with VoiceOver, keep a familiar terminal profile and use your usual text navigation commands. Across platforms, one stable terminal and one stable editor setup usually beats switching tools every time something feels tricky.

Jamie: So when is the CLI faster than the web?

Alex: When you already know the object and the action: view issue 42, comment on PR 17, check CI, list my assigned issues, create a draft PR from this branch. The browser is still useful for visual review, settings pages, and final verification, but it does not have to be your starting point for every GitHub task.

Jamie: That makes the quick reference card make sense. Authentication, repos, issues, pull requests, releases, and Copilot are all there as reminders, not as commands to memorize all at once.

Alex: Exactly. Start with `gh auth status`, `gh issue list`, `gh issue view`, `gh pr create`, and `gh pr checks`. Add more commands as your real work asks for them.

Jamie: And use the official GitHub CLI manual and the GitHub Accessibility Lab CLI guide when you need the exact syntax.

Alex: That's the habit I want learners to leave with: use the terminal for clear, repeatable GitHub actions, verify each result, and switch to the browser only when it adds something useful.

Workshop Content

Full chapter content from the Git Going with GitHub workshop guide.

Companion Podcast and Transcript

Use audio and transcript companions to review concepts in a conversational format.

GitHub CLI Reference

Companion audio: this episode reinforces key ideas and may not be a word-for-word reading of this page.

Transcript preview

Alex: Welcome back. Today we're looking at the GitHub CLI, which is the `gh` command. It lets you work with GitHub issues, pull requests, repositories, and releases from your terminal.

Jamie: So this is different from `git`, right? Because I can already clone, branch, commit, and push with Git.

Alex: Exactly. `git` handles local version control: commits, branches, history, and moving code between your computer and a remote. `gh` handles GitHub-specific work: opening an issue, viewing a pull request, checking CI, creating a release, or opening the current repo in your browser.

Jamie: That distinction helps. Git is the version control tool, and `gh` is the GitHub workflow tool that sits beside it.

Appendix I: GitHub CLI Reference

Episode coming soon: GitHub CLI Reference - a conversational audio overview of this appendix. Listen before reading to preview the concepts, or after to reinforce what you learned.

Reference companion to: Chapter 01: Choose Your Tools | Also relevant: Chapter 14

Authoritative source: GitHub CLI Manual | GitHub Accessibility Lab: CLI Guide

Your Terminal, Supercharged for GitHub

Who this is for: You want to manage GitHub — issues, pull requests, repos, releases — from your terminal without opening a browser. The GitHub CLI (gh) gives you full access to GitHub from the command line, with clean plain-text output that works beautifully with screen readers.

gh handles the GitHub side of things (issues, PRs, repos, releases). git handles the local version control side (commits, branches, history). You use both together.

Getting started principles for accessible CLI workflows

  • Follow a local-to-remote progression: learn git basics first, then layer gh workflows.
  • Treat terminal output as the source of truth. Confirm each command result before moving on.
  • Prefer short, reversible steps: clone, inspect, branch, edit, commit, push, open PR.
  • Keep one reliable terminal profile and one reliable editor setup rather than constant tool switching.
  • Use browser fallback strategically for verification, not as a replacement for command understanding.

Table of Contents

  1. Installing and Authenticating
  2. Repos — Clone, Fork, Create, View
  3. Issues — Create, List, View, Comment, Close
  4. Pull Requests — Create, Review, Merge, Check
  5. Releases — Create, List, Upload
  6. Search — Issues, PRs, Repos, Code
  7. Labels and Milestones
  8. Output Formatting — JSON, jq, Templates
  9. Aliases — Create Your Own Shortcuts
  10. Extensions — Adding New Commands
  11. Copilot in the CLI
  12. Screen Reader Tips
  13. Quick Reference Card

1. Installing and Authenticating

Installing

Windows

winget install GitHub.cli

Or download the installer from cli.github.com.

macOS

brew install gh

Linux (Debian/Ubuntu)

(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y

Verify installation

gh --version

Authenticating

gh auth login

Follow the prompts:

  • Where do you use GitHub? → GitHub.com (or Enterprise)
  • Preferred protocol? → HTTPS (or SSH)
  • Authenticate with browser? → Yes — your browser opens for OAuth sign-in

After signing in, return to the terminal. You're done.

# Check your auth status at any time
gh auth status

# Log out
gh auth logout

# Refresh credentials / add new scopes
gh auth refresh

Screen reader tip: gh auth login is an interactive prompt — navigate with Arrow keys, confirm with Enter. All prompts are plain text and read naturally. The browser step opens automatically; switch back to the terminal when the browser confirms success.

Command safety guideline: Use options documented in gh --help and the GitHub CLI manual. Avoid undocumented or experimental flags in classroom and production workflows.

Windows Terminal setup pattern

If you are on Windows, configure Windows Terminal once and reuse it:

  1. Keep a dedicated shell profile for your Git workflows.
  2. Learn mark mode (Ctrl+Shift+M) to review and copy command output line by line.
  3. Use command palette (Ctrl+Shift+P) to find terminal actions without memorizing every shortcut.
  4. Keep your font size and contrast settings stable so output remains readable across sessions.

Learning Cards: Getting Started with gh

Screen reader users
  • gh auth login uses plain-text arrow-key prompts -- every option is announced as you arrow through the list
  • After authentication, gh auth status confirms your login in a single readable line -- no browser needed
  • All gh output is plain text with no hidden elements, making it one of the most screen-reader-friendly GitHub interfaces
Low vision users
  • Increase your terminal font size before running gh commands -- all output scales with your terminal settings
  • Use a high-contrast terminal theme (light text on dark background, or vice versa) for comfortable reading of command output
  • gh output is plain text with no color-dependent meaning -- colors are supplementary labels, not the only indicator
Sighted users
  • The interactive prompts use arrow-based selection with a highlight marker -- look for the > indicator next to your current choice
  • After gh auth login, the terminal prints a success confirmation with your username -- verify it matches your GitHub account
  • Install gh via winget or brew for the fastest setup; the binary is immediately available in your current terminal session

2. Repos — Clone, Fork, Create, View

# Clone a repository (automatically sets up the remote)
gh repo clone owner/repo-name

# Fork a repo and clone your fork in one step
gh repo fork owner/repo-name --clone

# Fork without cloning (creates the fork on GitHub only)
gh repo fork owner/repo-name

# Create a brand new repository
gh repo create my-new-project
gh repo create my-new-project --public --description "My project description"
gh repo create my-new-project --private

# View a repository's details
gh repo view
gh repo view owner/repo-name

# Open the repo in your browser
gh repo view --web

# List your repositories
gh repo list
gh repo list --limit 50

# List repos for an org
gh repo list my-org --limit 100

# Archive a repository
gh repo archive owner/repo-name

# Delete a repository (careful!)
gh repo delete owner/repo-name --confirm

# Sync your fork with upstream
gh repo sync
gh repo sync --branch main

3. Issues — Create, List, View, Comment, Close

Creating issues

# Create an issue interactively (opens a prompt for title, body, labels, etc.)
gh issue create

# Create with all details inline
gh issue create \
  --title "Screen reader can't navigate the settings menu" \
  --body "When using NVDA with Firefox, the Settings menu items are not announced..." \
  --label "bug,accessibility" \
  --assignee "@me"

# Create from a Markdown file (great for detailed bug reports)
gh issue create --title "Accessibility audit findings" --body-file ./report.md

Listing and filtering issues

# List open issues (current repo)
gh issue list

# List issues with filters
gh issue list --label "accessibility"
gh issue list --label "good first issue"
gh issue list --assignee "@me"
gh issue list --state closed
gh issue list --limit 50

# Search issues by keyword
gh issue list --search "screen reader"

# List issues across all repos you watch
gh issue list --repo owner/repo-name

Viewing issues

# View an issue (renders Markdown as plain text in the terminal)
gh issue view 42

# Open the issue in your browser
gh issue view 42 --web

# View comments on an issue
gh issue view 42 --comments

Screen reader tip: gh issue view 42 outputs clean plain text — title, metadata, and body all formatted without noise. Read line by line with Arrow keys. Much faster than navigating a browser page with a screen reader.

Commenting and updating

# Add a comment to an issue
gh issue comment 42 --body "I can reproduce this on Windows 11 with NVDA 2024.1."

# Comment from a file
gh issue comment 42 --body-file ./my-comment.md

# Edit an issue (title, body, labels, assignees)
gh issue edit 42 --title "Updated title"
gh issue edit 42 --add-label "needs-reproduction"
gh issue edit 42 --remove-label "bug"
gh issue edit 42 --add-assignee username

# Close an issue
gh issue close 42
gh issue close 42 --comment "Fixed in PR #56."
gh issue close 42 --reason "not planned"

# Reopen a closed issue
gh issue reopen 42

Pinning and locking

# Pin an issue (shows at top of the Issues tab)
gh issue pin 42

# Lock an issue (prevents new comments)
gh issue lock 42 --reason "resolved"

4. Pull Requests — Create, Review, Merge, Check

Creating a PR

# Create a PR interactively (prompts for title, body, base branch, etc.)
gh pr create

# Create with all details inline
gh pr create \
  --title "Add keyboard navigation to settings menu" \
  --body "Closes #42. Adds Tab/arrow key support to the settings dropdown." \
  --base main \
  --label "accessibility,enhancement"

# Create as a draft
gh pr create --draft

# Create from a file
gh pr create --title "Accessibility improvements" --body-file ./pr-description.md

# Open the PR creation form in your browser
gh pr create --web

Listing and viewing PRs

# List open PRs
gh pr list

# List with filters
gh pr list --state closed
gh pr list --author "@me"
gh pr list --label "accessibility"
gh pr list --search "screen reader"

# View a PR (title, description, status, checks)
gh pr view 56

# View the diff of a PR
gh pr diff 56

# Open the PR in your browser
gh pr view 56 --web

# Check out a PR branch locally (to test it)
gh pr checkout 56

Reviewing PRs

# Approve a PR
gh pr review 56 --approve
gh pr review 56 --approve --body "Tested with NVDA — keyboard nav works perfectly. LGTM!"

# Request changes
gh pr review 56 --request-changes --body "The focus indicator disappears on the last menu item."

# Leave a comment review (no approval/rejection)
gh pr review 56 --comment --body "A few observations — see inline comments."

Checking CI status

# View all CI checks for a PR
gh pr checks 56

# Watch checks update in real time (refreshes every 10s)
gh pr checks 56 --watch

# View checks for the current branch
gh pr checks

Merging PRs

# Merge a PR (interactive — prompts for merge strategy)
gh pr merge 56

# Merge with a specific strategy
gh pr merge 56 --merge          # Creates a merge commit
gh pr merge 56 --squash         # Squashes all commits into one
gh pr merge 56 --rebase         # Rebases commits onto base branch

# Auto-merge when checks pass (great for PRs waiting on CI)
gh pr merge 56 --auto --squash

# Delete the branch after merging
gh pr merge 56 --squash --delete-branch

Other PR operations

# Convert a draft PR to ready for review
gh pr ready 56

# Mark a ready PR back as draft
gh pr ready 56 --undo

# Update your PR branch with the latest from base (equivalent to "Update branch" button)
gh pr update-branch 56
gh pr update-branch 56 --rebase

# Close a PR without merging
gh pr close 56
gh pr close 56 --comment "Superseded by #58."

# Reopen a closed PR
gh pr reopen 56

# Add a comment to a PR
gh pr comment 56 --body "Thanks for the thorough review! Addressing feedback now."

5. Releases — Create, List, Upload

# Create a release interactively
gh release create v1.2.0

# Create with all details
gh release create v1.2.0 \
  --title "Version 1.2.0 — Accessibility Improvements" \
  --notes "- Fixed keyboard navigation in settings\n- Added ARIA labels to all form inputs"

# Create from a notes file
gh release create v1.2.0 --notes-file ./CHANGELOG.md

# Create a pre-release
gh release create v1.2.0-beta.1 --prerelease

# Create a draft release (not published yet)
gh release create v1.2.0 --draft

# Upload files to a release
gh release upload v1.2.0 ./dist/app.zip ./dist/app.tar.gz

# List releases
gh release list

# View a release
gh release view v1.2.0

# Download release assets
gh release download v1.2.0
gh release download v1.2.0 --pattern "*.zip"

# Delete a release
gh release delete v1.2.0

See also: Appendix H: Releases, Tags, and Insights for the GitHub.com interface side of releases.


6. Search — Issues, PRs, Repos, Code

# Search issues across all of GitHub
gh search issues "screen reader navigation" --label accessibility
gh search issues "keyboard shortcut" --repo owner/repo-name
gh search issues "help wanted" --language javascript --limit 20

# Search pull requests
gh search prs "accessibility fix" --state open
gh search prs "WCAG" --author username

# Search repositories
gh search repos "accessible markdown editor" --language python --stars ">100"
gh search repos "screen reader" --topic accessibility

# Search code
gh search code "aria-label" --repo owner/repo-name
gh search code "git cherry-pick" --language markdown

7. Labels and Milestones

Labels

# List labels in the current repo
gh label list

# Create a label
gh label create "accessibility" --color "0075ca" --description "Accessibility improvements"

# Clone labels from another repo (copies all their labels to yours)
gh label clone owner/source-repo

# Delete a label
gh label delete "wontfix"

Milestones

# List milestones
gh api repos/{owner}/{repo}/milestones --jq '.[].title'

# Create a milestone
gh api repos/{owner}/{repo}/milestones \
  --method POST \
  --field title="v2.0 Launch" \
  --field description="All features for the v2.0 release" \
  --field due_on="2026-06-01T00:00:00Z"

8. Output Formatting — JSON, jq, Templates

By default gh outputs human-readable text. For scripting or custom display, you can get raw JSON and filter it.

--json flag

# Get issue data as JSON
gh issue view 42 --json title,body,labels,state

# Get PR data as JSON
gh pr view 56 --json title,number,state,mergeable,reviews

# List issues as JSON
gh issue list --json number,title,labels,assignees

--jq flag (filter JSON inline)

# List just issue numbers and titles
gh issue list --json number,title --jq '.[] | "\(.number): \(.title)"'

# Get the names of all labels on an issue
gh issue view 42 --json labels --jq '.labels[].name'

# Count open PRs
gh pr list --json number --jq 'length'

# List reviewers who approved a PR
gh pr view 56 --json reviews --jq '[.reviews[] | select(.state=="APPROVED") | .author.login] | unique'

--template flag (Go templates)

# Custom formatted output
gh issue list --template '{{range .}}#{{.number}} {{.title}} ({{.state}}){{"\n"}}{{end}}'

Screen reader tip: --json with --jq produces clean, predictable output — ideal for piping to a file or reading with a screen reader. The default human-readable output is also clean, but JSON gives you precise control over what's announced.

Learning Cards: Output Formatting

Screen reader users
  • Use --json with --jq to extract exactly the fields you need -- this eliminates table formatting noise and reads as clean key-value pairs
  • Pipe long output to a file (gh issue list --json title > issues.txt) and open it in VS Code for structured navigation with Alt+F2
  • Go templates (--template) let you define a single-line-per-item format that reads naturally with arrow keys
Low vision users
  • The default table output aligns columns with spaces -- increase terminal font size so columns stay readable
  • JSON output with --jq strips visual formatting and gives compact text that scales cleanly with any font size
  • Pipe output to VS Code (gh pr view 42 --json body --jq '.body' | code -) to read it with your preferred editor theme and zoom
Sighted users
  • Default table output is already human-readable with aligned columns -- scan the header row to orient on each column
  • Use --web on any command to open the result in your browser if you prefer the GitHub web interface for detailed views
  • Chain | head -20 (macOS/Linux) or | Select-Object -First 20 (PowerShell) to preview long output before reading the full list

9. Aliases — Create Your Own Shortcuts

Aliases let you create custom gh commands from long commands you run often.

# Create an alias
gh alias set bugs 'issue list --label bug'
gh alias set my-prs 'pr list --author @me'
gh alias set review-ready 'pr list --label "ready for review"'

# Use your alias
gh bugs
gh my-prs
gh review-ready

# List all aliases
gh alias list

# Delete an alias
gh alias delete bugs

# Create a shell alias (runs a shell command, not just gh commands)
gh alias set --shell open-pr 'gh pr view $1 --web'
gh open-pr 56   # opens PR #56 in the browser

Useful aliases to set up

# Issues assigned to you
gh alias set mine 'issue list --assignee @me'

# Your open PRs
gh alias set mypr 'pr list --author @me --state open'

# Check CI on current branch's PR
gh alias set ci 'pr checks'

# View current PR
gh alias set pr 'pr view'

10. Extensions — Adding New Commands

Extensions add new gh subcommands written by the community.

# Browse available extensions
gh extension search

# Install an extension
gh extension install owner/gh-extension-name

# List installed extensions
gh extension list

# Update all extensions
gh extension upgrade --all

# Update a specific extension
gh extension upgrade owner/gh-extension-name

# Remove an extension
gh extension remove owner/gh-extension-name

Useful extensions

Extension What it does Install
github/gh-copilot Ask Copilot questions in the terminal gh extension install github/gh-copilot
nicokosi/gh-notify Desktop notifications for GitHub events gh extension install nicokosi/gh-notify
mislav/gh-branch Better branch switching with fuzzy search gh extension install mislav/gh-branch

11. Copilot in the CLI

Install the Copilot extension once, then ask coding and git questions without leaving the terminal.

# Install (one time)
gh extension install github/gh-copilot

# Ask for a command suggestion
gh copilot suggest "squash my last 4 commits into one"
gh copilot suggest "find which commit introduced a bug in auth.js"
gh copilot suggest "create a pull request from my current branch"

# Explain a command you don't recognize
gh copilot explain "git rebase -i HEAD~3"
gh copilot explain "git bisect start"
gh copilot explain "find . -name '*.md' -mtime -7"

Copilot CLI shows the suggested command, explains what it does, and asks whether to run it - perfect for learning while doing.

Auto model selection

As of early 2026, gh copilot uses auto model selection by default - it picks the best available model for your request without you needing to specify one. You can still request a specific model using the --model flag if you prefer:

# Let Copilot choose automatically (default)
gh copilot suggest "create a pull request from my current branch"

# Request a specific model
gh copilot suggest --model gpt-5 "create a pull request from my current branch"

Telemetry opt-out

As of gh CLI 2.70 (April 2026), gh collects anonymized usage telemetry by default to improve the product. To opt out:

gh config set telemetry disabled

Or set the environment variable GH_NO_UPDATE_NOTIFIER=1 to suppress update notifications only.

See also: Appendix AA: Advanced Git Operations, Section 11 for more Copilot CLI examples with git operations.


12. Screen Reader Tips

The GitHub CLI is one of the most screen-reader-friendly ways to use GitHub. Here's why and how to get the most out of it.

Why the CLI works so well

  • Plain text output — no visual noise, no unlabelled buttons, no hidden dialogs
  • Predictable structure — every command produces consistent output you can navigate with arrow keys
  • No focus traps — you control when you read output; nothing streams unexpectedly
  • Keyboard-first by design — everything is a command you type

Tips by task

Reading issues and PRs:

# Pipe output to less for page-by-page reading
gh issue view 42 | less

# Save to a file and open in your editor
gh pr view 56 > pr-56.md
code pr-56.md

Navigating long lists:

# Limit results to a manageable number
gh issue list --limit 10

# Combine with search to narrow down
gh issue list --search "keyboard" --limit 5

Getting just what you need:

# Get just the PR title
gh pr view 56 --json title --jq '.title'

# Get just the issue body
gh issue view 42 --json body --jq '.body'

# Get CI check status as a simple list
gh pr checks 56 --json name,state --jq '.[] | "\(.state): \(.name)"'

Creating content without a browser:

# Write your issue body in a text file first (easier with a screen reader)
# Then create the issue from the file
gh issue create --title "Bug: focus lost after modal closes" --body-file ./issue.md

NVDA / JAWS (Windows)

  • Run gh commands in Windows Terminal or the VS Code integrated terminal — both work well with NVDA/JAWS
  • Use Insert+Down (NVDA) or Insert+F12 (JAWS) to read the current line of terminal output
  • For long output, use | less and navigate with Space (next page) and b (back)

VoiceOver (macOS)

  • Run gh in Terminal.app or VS Code integrated terminal
  • VO+Right moves through terminal output character by character; VO+Down line by line
  • Use Ctrl+C to stop a running command if output is too long

Learning Cards: Screen Reader CLI Workflow

Screen reader users
  • gh is keyboard-first by design -- no focus traps, no streaming, no unlabelled buttons; everything is typed and read as plain text
  • Use Insert+Down (NVDA) or Insert+F12 (JAWS) to read the current line, and arrow keys to move through multi-line output
  • Write issue and PR bodies in a text file first, then use --body-file ./issue.md to submit -- much easier than composing inline
Low vision users
  • Terminal output from gh has no icons or images -- all information is conveyed as text that scales with your terminal font
  • Use --limit 10 on list commands to keep output short enough to scan comfortably without scrolling
  • Run gh in the VS Code integrated terminal to benefit from VS Code's zoom, themes, and Accessible View (Alt+F2)
Sighted users
  • gh output uses subtle color coding (green for open, red for closed) -- these are supplementary; the text labels are always present
  • Use gh pr view --web or gh issue view --web to jump to the browser when you want the full visual GitHub interface
  • The gh pr checks command gives a quick pass/fail summary of CI checks without opening the browser

13. Quick Reference Card

Authentication

Command What it does
gh auth login Sign in to GitHub
gh auth status Check login status
gh auth logout Sign out

Repos

Command What it does
gh repo clone owner/repo Clone a repo
gh repo fork owner/repo --clone Fork and clone
gh repo create name --public Create a new repo
gh repo view View current repo info
gh repo sync Sync fork with upstream

Issues

Command What it does
gh issue list List open issues
gh issue view 42 Read issue #42
gh issue create Create a new issue
gh issue comment 42 --body "..." Add a comment
gh issue close 42 Close an issue

Pull Requests

Command What it does
gh pr list List open PRs
gh pr view 56 Read PR #56
gh pr create Create a PR
gh pr diff 56 See the diff
gh pr checks 56 See CI status
gh pr review 56 --approve Approve
gh pr merge 56 --squash Merge (squash)
gh pr checkout 56 Check out locally
gh pr update-branch Update from base

Releases

Command What it does
gh release create v1.0.0 Create a release
gh release list List releases
gh release download v1.0.0 Download assets

Copilot

Command What it does
gh copilot suggest "..." Get a command suggestion
gh copilot explain "..." Explain a command

Next: Appendix J: Codespaces
Back: Appendix H: GitHub Desktop
Teaching chapter: Chapter 01: Choose Your Tools

Authoritative Sources

Use these official references when you need the current source of truth for facts in this chapter.

Section-Level Source Map

Use this map to verify facts for each major section in this file.