GitHub Commands
Overview
The netapi github commands provide CLI access to GitHub’s REST API. All commands support -f json for jq piping.
Prerequisites
# Set GitHub token (personal access token)
export GITHUB_TOKEN="ghp_..."
# Or use gh CLI token
export GH_TOKEN="ghp_..."
Create token at: github.com/settings/tokens
Commands (26 total)
| Command | Description |
|---|---|
|
Get user info |
|
Check API rate limit |
|
List user repositories |
|
Get repository details |
|
Search repositories |
|
List branches |
|
List commits |
|
List releases |
|
List tags |
|
Get language breakdown |
|
List contributors |
|
List issues |
|
Get issue details |
|
List pull requests |
|
Get PR details |
|
List PR files |
|
List organizations |
|
Get org details |
|
List org repos |
|
List org members |
|
List workflows |
|
List workflow runs |
|
List gists |
|
Get gist details |
|
List starred repos |
|
Raw API request |
JSON Output
All commands support -f json for machine-readable output:
netapi github repos -f json
netapi github repo owner/repo -f json
netapi github prs owner/repo -f json
jq Patterns
Exploring Structure
# See all keys in first object
netapi github repos -f json | jq '.[0] | keys'
# Keys with types
netapi github repos -f json | jq '.[0] | to_entries | .[] | "\(.key): \(.value | type)"'
# Full first object (all keys + values)
netapi github repos -f json | jq '.[0]'
Repository Operations
# List all repo names
netapi github repos -f json | jq -r '.[].full_name'
# Filter by language
netapi github repos -f json | jq -r '.[] | select(.language == "Python") | .full_name'
# Get specific fields
netapi github repos -f json | jq '.[] | {name: .full_name, stars: .stargazers_count, language}'
# Sort by stars
netapi github repos -f json | jq 'sort_by(-.stargazers_count) | .[] | "\(.full_name): \(.stargazers_count) stars"'
# Private repos only
netapi github repos -f json | jq '.[] | select(.private) | .full_name'
# Repos updated in last 7 days
netapi github repos -f json | jq --arg d "$(date -d '7 days ago' -Iseconds)" \
'.[] | select(.updated_at > $d) | .full_name'
Single Repository
# Full repo details
netapi github repo EvanusModestus/netapi -f json | jq '.'
# Summary object
netapi github repo EvanusModestus/netapi -f json | jq '{
name: .full_name,
stars: .stargazers_count,
forks: .forks_count,
issues: .open_issues_count,
language: .language,
default_branch: .default_branch,
created: .created_at[0:10],
updated: .updated_at[0:10]
}'
# Clone URL
netapi github repo EvanusModestus/netapi -f json | jq -r '.ssh_url'
Language Breakdown
# All languages with bytes
netapi github languages EvanusModestus/netapi -f json | jq '.'
# Sorted by size
netapi github languages EvanusModestus/netapi -f json | jq 'to_entries | sort_by(-.value) | .[] | "\(.key): \(.value)"'
# As percentage
netapi github languages EvanusModestus/netapi -f json | jq '
to_entries |
(map(.value) | add) as $total |
map({key, pct: (.value / $total * 100 | floor)}) |
sort_by(-.pct) |
.[] | "\(.key): \(.pct)%"
'
Commits
# Recent commits - short format
netapi github commits EvanusModestus/netapi -l 10 -f json | jq -r '.[] | "\(.sha[0:8]) \(.commit.author.name): \(.commit.message | split("\n")[0])"'
# Commits by author
netapi github commits EvanusModestus/netapi -f json | jq -r '.[] | .commit.author.name' | sort | uniq -c | sort -rn
# Commits with date
netapi github commits EvanusModestus/netapi -f json | jq '.[] | {
sha: .sha[0:8],
author: .commit.author.name,
date: .commit.author.date[0:10],
message: (.commit.message | split("\n")[0])
}'
Pull Requests
# Open PRs - titles only
netapi github prs EvanusModestus/netapi -f json | jq -r '.[] | "#\(.number): \(.title)"'
# PRs with stats
netapi github prs EvanusModestus/netapi -f json | jq '.[] | {
number,
title,
author: .user.login,
branch: .head.ref,
base: .base.ref,
created: .created_at[0:10]
}'
# Get specific PR
netapi github pr EvanusModestus/netapi 42 -f json | jq '{
title,
state,
author: .user.login,
commits,
additions,
deletions,
changed_files
}'
# PR files with diff stats
netapi github pr-files EvanusModestus/netapi 42 -f json | jq -r '.[] | "\(.filename): +\(.additions) -\(.deletions)"'
# Only modified files (not added/removed)
netapi github pr-files EvanusModestus/netapi 42 -f json | jq -r '.[] | select(.status == "modified") | .filename'
Issues
# Open issues - titles
netapi github issues EvanusModestus/netapi -f json | jq -r '.[] | "#\(.number): \(.title)"'
# Issues with labels
netapi github issues EvanusModestus/netapi -f json | jq '.[] | {
number,
title,
author: .user.login,
labels: [.labels[].name]
}'
# Filter by label
netapi github issues EvanusModestus/netapi -f json | jq '.[] | select(.labels | map(.name) | index("bug"))'
# Issue details
netapi github issue EvanusModestus/netapi 123 -f json | jq '{
title,
state,
author: .user.login,
body,
comments,
labels: [.labels[].name]
}'
Workflows & Actions
# List workflows
netapi github workflows EvanusModestus/netapi -f json | jq '.workflows[] | {name, state, path}'
# Recent runs with status
netapi github runs EvanusModestus/netapi -f json | jq '.workflow_runs[] | {
id,
name,
status,
conclusion,
branch: .head_branch,
created: .created_at[0:10]
}'
# Failed runs only
netapi github runs EvanusModestus/netapi -f json | jq '.workflow_runs[] | select(.conclusion == "failure") | {name, branch: .head_branch}'
Organizations
# List orgs
netapi github orgs -f json | jq -r '.[].login'
# Org repos sorted by stars
netapi github org-repos anthropics -f json | jq 'sort_by(-.stargazers_count) | .[] | "\(.name): \(.stargazers_count) stars"'
# Org members
netapi github org-members anthropics -f json | jq -r '.[].login'
Search
# Search repos
netapi github search "network automation" -f json | jq '.items[] | {name: .full_name, stars: .stargazers_count, language}'
# Search with language filter
netapi github search "network automation language:python" -f json | jq '.items[] | .full_name'
# Top results by stars
netapi github search "ansible network" -f json | jq '.items | sort_by(-.stargazers_count)[0:5] | .[] | "\(.full_name): \(.stargazers_count)"'
Rate Limits
# Check rate limit
netapi github rate-limit -f json | jq '.resources.core | "Remaining: \(.remaining)/\(.limit)"'
# All rate limits
netapi github rate-limit -f json | jq '.resources | to_entries | .[] | "\(.key): \(.value.remaining)/\(.value.limit)"'
Raw API Access
# Any GET endpoint
netapi github api /users/torvalds | jq '.'
# Repository topics
netapi github api /repos/EvanusModestus/netapi/topics | jq '.names'
# Repo README
netapi github api /repos/EvanusModestus/netapi/readme | jq -r '.content' | base64 -d
Environment Variables
| Variable | Description |
|---|---|
|
Personal access token (required) |
|
Alternative token variable (gh CLI compatible) |
Useful jq Recipes
Export to CSV
netapi github repos -f json | jq -r '.[] | [.full_name, .language, .stargazers_count] | @csv'
Create Markdown Table
netapi github repos -f json | jq -r '["Name", "Language", "Stars"], (.[] | [.full_name, .language, .stargazers_count]) | @tsv' | column -t -s$'\t'