github

Original🇺🇸 English
Translated

GitHub CLI operations via `gh` for issues, pull requests, CI/Actions, releases, repos, search, gists, and the REST/GraphQL API. Structured output with `--json` and `--jq` for parsing. Covers `gh issue create/list/view/edit/close`, `gh pr create/review/merge/checks`, `gh run list/view/rerun/watch`, `gh release create`, `gh search repos/issues/prs/code`, `gh api` for REST and GraphQL queries, and `gh gist` operations. Includes error handling for HTTP 401/403/404/422/429, scope troubleshooting, and rate limit management. Trigger phrases: "create an issue", "file a bug", "open a ticket", "submit a PR", "raise a pull request", "check pipeline", "view test results", "CI failing", "why did CI fail", "check CI status", "merge a PR", "manage releases", "query the GitHub API", "search repositories", "triage workflows", "automate GitHub operations". Also triggers when the user pastes a GitHub URL.

7installs
Added on

NPX Install

npx skill4agent add mathews-tom/praxis-skills github

Tags

Translated version includes tags in frontmatter

GitHub

All GitHub operations use the
gh
CLI. Prefer
--json
with
--jq
for structured, parseable output. Use
--repo owner/repo
when not inside a git repository with a configured remote. Use
--web
to open any resource in the browser.
Reference FilePurpose
references/graphql-queries.md
GraphQL query patterns, cost model, mutations, rate limit inspection
references/automation-workflows.md
Multi-step workflow recipes for CI triage, PR lifecycle, releases, batch ops

Prerequisites and Auth

Installation

PlatformCommand
macOS
brew install gh
Debian/Ubuntu
sudo apt install gh
Windows
winget install GitHub.cli

Authentication

Log in interactively (opens browser for OAuth):
bash
gh auth login
Check current auth status and active account:
bash
gh auth status

Required OAuth Scopes

ScopeGrants Access To
repo
Private repos, issues, PRs, commits, status
read:org
Org membership, team listing
workflow
Trigger and manage GitHub Actions workflows
gist
Create and manage gists
delete_repo
Delete repositories (not granted by default)
admin:org
Manage org settings, teams, members
project
Read/write access to ProjectV2 boards
Add missing scopes without re-authenticating from scratch:
bash
gh auth refresh --scopes repo,read:org,workflow

Issues

Create

bash
gh issue create --repo owner/repo --title "Login timeout on slow connections" --body "Users on 3G see a 504 after 8 seconds"
Create with labels, assignees, and milestone:
bash
gh issue create --repo owner/repo \
  --title "Add rate limiting to /api/upload" \
  --body "Current endpoint has no throttle. Target: 100 req/min per user." \
  --label "enhancement,backend" \
  --assignee "username1,username2" \
  --milestone "v2.1"
FlagPurpose
--title
Issue title (required unless
--fill
used)
--body
Issue body in markdown
--label
Comma-separated label names
--assignee
Comma-separated GitHub usernames
--milestone
Milestone name
--project
Project board name
--web
Open the new issue in browser after creation

List and Filter

bash
gh issue list --repo owner/repo --state open --label "bug" --assignee "@me" --limit 20
Structured output with JSON:
bash
gh issue list --repo owner/repo --json number,title,labels,assignees \
  --jq '.[] | "\(.number) [\(.labels | map(.name) | join(","))] \(.title)"'

View, Edit, Close

View issue details:
bash
gh issue view 42 --repo owner/repo
View with comments:
bash
gh issue view 42 --repo owner/repo --comments
Edit an existing issue:
bash
gh issue edit 42 --repo owner/repo --add-label "priority:high" --add-assignee "username"
Close an issue with a comment:
bash
gh issue close 42 --repo owner/repo --comment "Fixed in PR #87"

Comments

Add a comment to an issue:
bash
gh issue comment 42 --repo owner/repo --body "Reproduced on v2.0.3. Stack trace attached."

Pull Requests

Create

Standard PR from current branch:
bash
gh pr create --repo owner/repo --title "Add rate limiter middleware" --body "Implements token bucket at 100 req/min"
Draft PR with reviewers:
bash
gh pr create --repo owner/repo \
  --title "Refactor auth module" \
  --body "Splits monolithic auth into JWT and session submodules" \
  --draft \
  --reviewer "reviewer1,reviewer2" \
  --label "refactor"
Auto-fill title and body from commit messages:
bash
gh pr create --repo owner/repo --fill
Create PR targeting a specific base branch:
bash
gh pr create --repo owner/repo --base develop --head feature/rate-limiter --fill

List and Filter

bash
gh pr list --repo owner/repo --state open --author "@me" --label "needs-review"
JSON output with review status:
bash
gh pr list --repo owner/repo --json number,title,reviewDecision,statusCheckRollup \
  --jq '.[] | "\(.number) \(.reviewDecision // "PENDING") \(.title)"'

View and Review

View PR details including diff stats:
bash
gh pr view 55 --repo owner/repo
View the diff:
bash
gh pr diff 55 --repo owner/repo
Approve a PR:
bash
gh pr review 55 --repo owner/repo --approve --body "LGTM — tests pass, no security concerns"
Request changes:
bash
gh pr review 55 --repo owner/repo --request-changes --body "Missing input validation on the upload handler"
Add a review comment without approving or requesting changes:
bash
gh pr review 55 --repo owner/repo --comment --body "Consider caching the config lookup"

Merge

Merge with default strategy:
bash
gh pr merge 55 --repo owner/repo
Squash merge and delete branch:
bash
gh pr merge 55 --repo owner/repo --squash --delete-branch
Rebase merge:
bash
gh pr merge 55 --repo owner/repo --rebase
Auto-merge when CI passes:
bash
gh pr merge 55 --repo owner/repo --auto --squash

CI Status

Check CI status on a PR:
bash
gh pr checks 55 --repo owner/repo
Watch CI and block until all checks complete:
bash
gh pr checks 55 --repo owner/repo --watch

Edit, Ready, Close

Mark a draft PR as ready for review:
bash
gh pr ready 55 --repo owner/repo
Edit PR metadata:
bash
gh pr edit 55 --repo owner/repo --add-reviewer "reviewer3" --add-label "urgent"
Close a PR without merging:
bash
gh pr close 55 --repo owner/repo --comment "Superseded by #60"

CI / Actions

List Workflow Runs

bash
gh run list --repo owner/repo --limit 10
Filter by workflow name and branch:
bash
gh run list --repo owner/repo --workflow "CI" --branch main --status failure --limit 5
JSON output:
bash
gh run list --repo owner/repo --json databaseId,status,conclusion,headBranch,name \
  --jq '.[] | "\(.databaseId) \(.status) \(.conclusion // "running") \(.headBranch)"'

View Run Details

bash
gh run view 123456789 --repo owner/repo
View logs for failed steps only:
bash
gh run view 123456789 --repo owner/repo --log-failed
View full logs:
bash
gh run view 123456789 --repo owner/repo --log

Trigger and Rerun

Trigger a workflow manually:
bash
gh workflow run deploy.yml --repo owner/repo --ref main -f environment=staging
Rerun only the failed jobs in a run:
bash
gh run rerun 123456789 --repo owner/repo --failed
Rerun the entire run:
bash
gh run rerun 123456789 --repo owner/repo

Watch a Run

Stream live status updates until the run completes:
bash
gh run watch 123456789 --repo owner/repo

Enable and Disable Workflows

bash
gh workflow disable "Nightly Build" --repo owner/repo
gh workflow enable "Nightly Build" --repo owner/repo

Download Artifacts

bash
gh run download 123456789 --repo owner/repo --name "build-output"
Download all artifacts from a run:
bash
gh run download 123456789 --repo owner/repo

Repositories

Create

Create a new public repository:
bash
gh repo create owner/new-repo --public --description "Service for handling webhooks"
Create from a template:
bash
gh repo create owner/new-service --template owner/service-template --public --clone

Fork and Clone

bash
gh repo fork owner/repo --clone
gh repo clone owner/repo

View and List

bash
gh repo view owner/repo
gh repo view owner/repo --json name,description,defaultBranchRef --jq '.defaultBranchRef.name'
List repos in an org:
bash
gh repo list some-org --limit 50 --json name,isArchived \
  --jq '.[] | select(.isArchived == false) | .name'

Edit Settings

bash
gh repo edit owner/repo --description "Updated description" --enable-issues --enable-wiki=false

Archive and Delete

bash
gh repo archive owner/repo --yes
gh repo delete owner/repo --yes

Releases

Create

Create a release with auto-generated notes:
bash
gh release create v1.2.0 --repo owner/repo --generate-notes
Create with title, notes, and binary assets:
bash
gh release create v1.2.0 --repo owner/repo \
  --title "v1.2.0 — Rate Limiter" \
  --notes "Adds token bucket rate limiting to all API endpoints" \
  ./dist/app-linux-amd64 ./dist/app-darwin-arm64
Create a prerelease:
bash
gh release create v2.0.0-rc1 --repo owner/repo --prerelease --generate-notes

List and View

bash
gh release list --repo owner/repo --limit 5
gh release view v1.2.0 --repo owner/repo

Edit and Upload Assets

bash
gh release edit v1.2.0 --repo owner/repo --draft=false --prerelease=false
Upload additional assets to an existing release:
bash
gh release upload v1.2.0 --repo owner/repo ./dist/app-windows-amd64.exe

Delete

bash
gh release delete v1.0.0-beta --repo owner/repo --yes

Search

Repositories

bash
gh search repos "rate limiter language:go" --limit 10 --json fullName,description,stargazersCount \
  --jq '.[] | "\(.stargazersCount) \(.fullName): \(.description)"'

Issues

bash
gh search issues "memory leak is:open repo:owner/repo" --json number,title,url \
  --jq '.[] | "#\(.number) \(.title)"'

Pull Requests

bash
gh search prs "review:approved is:merged repo:owner/repo" --json number,title,mergedAt \
  --jq '.[] | "\(.number) \(.mergedAt) \(.title)"'

Code

bash
gh search code "func RateLimit repo:owner/repo" --json path,repository \
  --jq '.[] | "\(.repository.fullName) \(.path)"'

Commits

bash
gh search commits "fix timeout repo:owner/repo" --json sha,commit \
  --jq '.[] | "\(.sha[:8]) \(.commit.message | split("\n") | .[0])"'

API: REST and GraphQL

REST: GET

bash
gh api repos/owner/repo/pulls/55 --jq '{title: .title, state: .state, author: .user.login}'

REST: POST

bash
gh api repos/owner/repo/issues/42/comments -f body="Automated comment from CI triage"

REST: PATCH

bash
gh api repos/owner/repo/issues/42 -X PATCH -f state="closed"

Pagination

Paginate through all results automatically:
bash
gh api repos/owner/repo/issues --paginate --jq '.[].number'

Rate Limit Check

bash
gh api rate_limit --jq '{core: .resources.core, graphql: .resources.graphql}'

GraphQL Queries

Inline GraphQL query:
bash
gh api graphql -f query='
  query {
    repository(owner: "owner", name: "repo") {
      issues(first: 5, states: OPEN) {
        nodes {
          number
          title
        }
      }
    }
  }
' --jq '.data.repository.issues.nodes[] | "\(.number) \(.title)"'
See
references/graphql-queries.md
for cost model, bulk queries, mutations, and rate limit management patterns.

REST vs GraphQL Decision Table

ScenarioUseReason
Fetch a single resource (one PR, one issue)REST (
gh api
)
Simple, predictable, low overhead
Fetch nested or related data in one round-tripGraphQLAvoids N+1 requests; select only needed fields
Bulk operations across many resourcesGraphQLQuery complexity points are cheaper than REST calls
Creating or updating a resource (mutation)EitherREST:
-X POST/PATCH
; GraphQL:
mutation {}
block
Rate-limit-sensitive pipeline or scriptRESTREST has a simple 5000 req/hr counter; easier to budget
ProjectV2 board operationsGraphQLProjectV2 has no REST API; GraphQL only

Inline Workflow Examples

PR Lifecycle

bash
# 1. Create a draft PR from the current branch
gh pr create --repo owner/repo --title "Add rate limiter" --body "Token bucket at 100 req/min" --draft

# 2. Check CI status on the PR
gh pr checks 55 --repo owner/repo --watch

# 3. Mark ready once CI passes
gh pr ready 55 --repo owner/repo

# 4. Approve the PR
gh pr review 55 --repo owner/repo --approve --body "LGTM"

# 5. Squash-merge and delete branch
gh pr merge 55 --repo owner/repo --squash --delete-branch
See
references/automation-workflows.md
for the full lifecycle with label management and reviewer rotation.

CI Triage

bash
# 1. Find the latest failed run on main
gh run list --repo owner/repo --branch main --status failure --limit 1 --json databaseId --jq '.[0].databaseId'

# 2. View failed step logs (substitute run ID from step 1)
gh run view 123456789 --repo owner/repo --log-failed

# 3. Rerun only failed jobs
gh run rerun 123456789 --repo owner/repo --failed

# 4. Watch until complete
gh run watch 123456789 --repo owner/repo
See
references/automation-workflows.md
for batch triage across multiple branches and failure pattern analysis.

Error Handling

ErrorCauseResolution
HTTP 401 UnauthorizedToken expired or revokedRun
gh auth login
to re-authenticate
HTTP 403 ForbiddenInsufficient permissions or rate limitedCheck
gh auth status
for scopes; check
gh api rate_limit
HTTP 404 Not FoundRepo does not exist, is private without
repo
scope, or resource deleted
Verify repo name; run
gh auth refresh --scopes repo
HTTP 422 Unprocessable EntityInvalid payload — missing required field, validation errorCheck request body fields match API schema
HTTP 429 Too Many RequestsREST rate limit exceeded (5000 req/hr authenticated)Wait for
X-RateLimit-Reset
timestamp; reduce request frequency
GraphQL rate limit exceededUsed more than 5000 points/hrReduce query complexity or wait; see
references/graphql-queries.md
"no git remotes found"Running
gh
outside a git repo without
--repo
Add
--repo owner/repo
to the command
Insufficient OAuth scopesToken lacks required scope for the operationRun
gh auth refresh --scopes scope1,scope2
Duplicate issue/PR titleNot a real error — GitHub allows duplicates, but check before creatingSearch with
gh issue list
or
gh pr list
first
Archived repo blocks writesRepo is archived; all write operations failUnarchive with
gh repo edit owner/repo --archived=false
or use a different repo
Enable debug logging to see raw HTTP requests and responses:
bash
GH_DEBUG=api gh pr list --repo owner/repo

Gists

Create

Create a public gist from a file:
bash
gh gist create --public --desc "Rate limiter implementation" rate_limiter.py
Create from stdin:
bash
echo '{"key": "value"}' | gh gist create --filename config.json

List, View, Edit, Delete

bash
gh gist list --limit 10
gh gist view abc123def456
gh gist edit abc123def456 --add new_file.py
gh gist delete abc123def456

Organizations and Teams

List orgs for the authenticated user:
bash
gh org list
List org members with pagination:
bash
gh api orgs/some-org/members --paginate --jq '.[].login'
List teams in an org:
bash
gh api orgs/some-org/teams --paginate --jq '.[] | "\(.slug): \(.description)"'
List members of a specific team:
bash
gh api orgs/some-org/teams/backend-team/members --paginate --jq '.[].login'

Limitations

  • Network required — all
    gh
    commands require internet access; no offline mode.
  • GraphQL point budget — 5000 points/hr for authenticated users. Complex queries with high
    first
    /
    last
    values consume points faster. See
    references/graphql-queries.md
    .
  • Secrets are write-only
    gh secret set
    works, but there is no
    gh secret get
    . Secret values cannot be retrieved after creation.
  • Org admin operations — managing org settings, teams, and SAML requires the
    admin:org
    scope, which is not granted by default.
  • Artifact retention — workflow artifacts are retained for 90 days by default. Expired artifacts cannot be downloaded.

Calibration Rules

  1. Prefer
    --json
    over parsing text output.
    Text output formats are unstable across
    gh
    versions. Always use
    --json field1,field2
    to get machine-readable output.
  2. Use
    --jq
    to minimize output before processing.
    Filter at the source rather than piping large JSON blobs to external tools.
    --jq
    runs server-side and reduces data transferred.
  3. Prefer higher-level commands over raw API. Use
    gh issue create
    instead of
    gh api repos/.../issues -X POST
    . High-level commands handle auth, pagination, and error formatting automatically.
  4. Use
    --repo
    consistently when outside a git directory.
    Never rely on implicit repo detection in scripts or CI environments. Always pass
    --repo owner/repo
    explicitly.
  5. Use GraphQL only for nested or bulk data. For single-resource fetches and mutations with simple payloads, REST is faster to write, easier to debug, and predictable under rate limits.