Opening a PR, waiting on CI, reviewing, and merging usually bounces you across several browser tabs. The GitHub CLI (gh) handles the whole process from the terminal.
Install instructions vary by OS, so follow the official guide (brew install gh on macOS, sudo apt install gh on Ubuntu/Debian). After installing, authenticate once.
gh auth login
Browser-based OAuth is the simplest choice. Confirm it worked with the following.
$ gh auth status
github.com
✓ Logged in to github.com account in-jun (keyring)
- Active account: true
- Git operations protocol: https
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
1. Create the PR
First, branch and push your work.
git checkout -b feature/user-authentication
git add .
git commit -m "feat: implement user authentication logic"
git push -u origin feature/user-authentication
Then run gh pr create. With no options it drops into an interactive mode that prompts for title, body, and base branch. For scripts or quick work, pass the options directly.
gh pr create \
--title "feat: implement user authentication" \
--body "## Summary
- Add login/logout functionality
- Implement JWT token handling
## Test Plan
- [ ] Unit tests for auth service" \
--base main \
--assignee @me \
--reviewer teammate1,teammate2 \
--label "enhancement"
The common options are these.
| Option | Description |
|---|---|
--title / --body | Title / body |
--base | Target branch to merge into |
--draft | Create as a draft PR |
--assignee @me | Assign yourself |
--reviewer | Assign reviewers (comma-separated; org/team works too) |
--body-file | Read the body from a file |
--web | Open in the browser after creating |
If the work isn’t done, open it as a draft and flip it later with gh pr ready.
gh pr create --draft --title "WIP: refactor payment module"
gh pr ready 123 # draft -> ready for review
2. Wait for CI to pass
Once the PR is up, gh pr checks shows CI status with no browser refreshing.
$ gh pr checks 13740
CodeQL pass 3s https://github.com/.../runs/83675225118
CodeQL-Build (go) pass 3m2s https://github.com/.../job/83675078092
build (macos-latest) pass 6m32s https://github.com/.../job/83675078114
build (ubuntu-latest) pass 4m38s https://github.com/.../job/83675078251
integration-tests (ubuntu) pass 1m33s https://github.com/.../job/83675078190
--watch refreshes until every check finishes and exits non-zero if any fail, which lets a script proceed only when CI is green.
gh pr checks 13740 --watch # wait until checks finish
gh pr checks 13740 --fail-only # show only failing checks
For the status of every PR you’re involved in, use gh pr status.
$ gh pr status
Relevant pull requests in in-jun/blog
Current branch
There is no pull request associated with [main]
Created by you
You have no open pull requests
Requesting a code review from you
You have no pull requests to review
3. Review someone else’s PR
A review usually means running the code. gh pr checkout pulls the PR’s branch down locally.
gh pr checkout 123 # check out the PR branch locally
git checkout - # back to your branch when you're done
To skim the diff, read it in the terminal.
gh pr diff 123
A submitted review is one of three kinds: approve, request changes, or comment.
# Approve
gh pr review 123 --approve --body "Looks good, nicely done."
# Request changes
gh pr review 123 --request-changes --body "Error handling needs to be added."
# Comment only, no approve/reject
gh pr review 123 --comment --body "A couple of suggestions."
To add reviewers or adjust labels after the fact, use gh pr edit.
gh pr edit 123 --add-reviewer myorg/backend-team
gh pr edit 123 --add-label "priority:high" --remove-label "priority:low"
4. Merge
When the review is done, pick a merge strategy and merge.
gh pr merge 123 --squash --delete-branch
That’s the most common combination: squash the commits into one and delete the source branch afterward. Other strategies are one flag away.
gh pr merge 123 --merge # create a merge commit
gh pr merge 123 --rebase # reapply on top of the target branch
To merge the moment CI passes, use --auto. It merges automatically once all required reviews and checks pass (auto-merge must be enabled on the repo).
gh pr merge 123 --auto --squash --delete-branch
Turn common moves into aliases
Instead of typing the same option combos every time, set aliases.
gh alias set prm 'pr merge --squash --delete-branch'
gh alias set prc 'pr create --draft --assignee @me'
gh prm 123 # squash merge and delete the branch
gh prc # create a draft PR assigned to yourself
Feeding scripts with JSON output
Combine --json with --jq to feed PR data straight into a script.
# Extract just the numbers of open PRs
gh pr list --json number --jq '.[].number'
# Pick out only PRs that have an approval
gh pr list --json number,reviews \
--jq '.[] | select(.reviews | any(.state == "APPROVED")) | .number'
Inside GitHub Actions, GITHUB_TOKEN is picked up automatically, so gh works with no separate auth.
- name: Create PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr create --title "Auto PR: ${GITHUB_REF_NAME}" \
--body "Automated PR" --base main
Omit the PR number and most commands act on the PR for your current branch, so on the working branch you don’t need to type it (gh pr view, gh pr merge).