GitHub
08 / 10

GitHub CLI & REST/GraphQL API

GitHub CLI & REST/GraphQL API

gh CLI Setup & Auth

# Install (macOS)
brew install gh

# Authenticate
gh auth login
gh auth login --with-token <<< "$GITHUB_TOKEN"  # for CI

# Check status
gh auth status

# Switch account
gh auth switch --user alice

Core gh Commands

# Repos
gh repo create, clone, fork, view, list, rename, delete, archive

# PRs
gh pr create, list, view, checkout, merge, close, reopen, edit, review, diff, ready

# Issues
gh issue create, list, view, close, reopen, edit, delete, pin

# Workflows
gh workflow list
gh workflow run deploy.yml --field environment=staging
gh run list --workflow=ci.yml
gh run view 12345
gh run watch 12345   # stream logs in real time
gh run rerun 12345 --failed

# Releases
gh release create v1.2.0 dist/*.zip --generate-notes --latest
gh release list
gh release download v1.2.0

# Gists
gh gist create script.sh --public
gh gist list

REST API via gh api

# GET request
gh api repos/owner/repo
gh api repos/owner/repo/pulls?state=open
gh api user

# POST request
gh api repos/owner/repo/issues \
  --method POST \
  --field title="New bug" \
  --field body="Description" \
  --field labels[]="bug"

# Paginate through all results
gh api --paginate repos/owner/repo/issues | jq '.[].title'

# Raw output (no pretty-printing)
gh api repos/owner/repo --jq '.stargazers_count'

# Use jq to extract fields
gh api repos/owner/repo/releases | jq '.[0] | {tag: .tag_name, date: .published_at}'

GraphQL API

# GitHub GraphQL endpoint: https://api.github.com/graphql
# gh api graphql handles auth automatically

# Query PR details with reviews
gh api graphql -f query='
  query($owner: String!, $repo: String!, $number: Int!) {
    repository(owner: $owner, name: $repo) {
      pullRequest(number: $number) {
        title
        state
        additions
        deletions
        reviewDecision
        reviews(last: 5) {
          nodes {
            author { login }
            state
            body
          }
        }
      }
    }
  }
' -F owner=myorg -F repo=myrepo -F number=42

# Get all repos in org with pagination
gh api graphql --paginate -f query='
  query($endCursor: String) {
    organization(login: "myorg") {
      repositories(first: 100, after: $endCursor) {
        nodes { name stargazerCount isPrivate }
        pageInfo { hasNextPage endCursor }
      }
    }
  }
' | jq '.data.organization.repositories.nodes[] | select(.stargazerCount > 100)'

Authentication — Tokens & Apps

  • Classic PAT: broad scopes (repo, workflow, etc.), not recommended for new projects

  • Fine-grained PAT: per-repository permissions, expiry date — prefer this for automation

  • GitHub App: installs on orgs, generates short-lived tokens, better audit trail — best for CI/CD bots

  • OAuth App: user authorizes, gets token on their behalf — for third-party integrations

  • GITHUB_TOKEN: auto-generated per-workflow, scoped to the repo — use this in Actions

# In GitHub Actions — GITHUB_TOKEN is provided automatically
steps:
  - uses: actions/checkout@v4
    with:
      token: ${{ secrets.GITHUB_TOKEN }}  # default
      # OR use a PAT for cross-repo operations:
      token: ${{ secrets.MY_PAT }}

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free