Files
gh-daymade-claude-code-skil…/skills/github-ops/references/api_reference.md
2025-11-29 18:18:18 +08:00

793 lines
17 KiB
Markdown

# GitHub API Reference
This reference provides comprehensive documentation for GitHub REST and GraphQL APIs, focusing on common operations accessible via `gh api`.
## Table of Contents
1. [Authentication](#authentication)
2. [Pull Requests API](#pull-requests-api)
3. [Issues API](#issues-api)
4. [Repositories API](#repositories-api)
5. [Actions/Workflows API](#actionsworkflows-api)
6. [Search API](#search-api)
7. [GraphQL API](#graphql-api)
8. [Rate Limiting](#rate-limiting)
9. [Webhooks](#webhooks)
## Authentication
All API calls via `gh api` automatically use the authenticated token from `gh auth login`.
```bash
# Check authentication status
gh auth status
# View current token (use cautiously)
gh auth status --show-token
```
**API Headers:**
- `Accept: application/vnd.github+json` (automatically set)
- `X-GitHub-Api-Version: 2022-11-28` (recommended)
## Pull Requests API
### List Pull Requests
**Endpoint:** `GET /repos/{owner}/{repo}/pulls`
```bash
# List all open PRs
gh api repos/{owner}/{repo}/pulls
# List PRs with filters
gh api repos/{owner}/{repo}/pulls -f state=closed -f base=main
# List PRs sorted by updated
gh api repos/{owner}/{repo}/pulls -f sort=updated -f direction=desc
```
**Query Parameters:**
- `state`: `open`, `closed`, `all` (default: `open`)
- `head`: Filter by branch name (format: `user:ref-name`)
- `base`: Filter by base branch
- `sort`: `created`, `updated`, `popularity`, `long-running`
- `direction`: `asc`, `desc`
- `per_page`: Results per page (max: 100)
- `page`: Page number
### Get Pull Request
**Endpoint:** `GET /repos/{owner}/{repo}/pulls/{pull_number}`
```bash
# Get PR details
gh api repos/{owner}/{repo}/pulls/123
# Get PR with specific fields
gh api repos/{owner}/{repo}/pulls/123 --jq '.title, .state, .mergeable'
```
**Response includes:**
- Basic PR info (title, body, state)
- Author and assignees
- Labels, milestone
- Merge status and conflicts
- Review status
- Head and base branch info
### Create Pull Request
**Endpoint:** `POST /repos/{owner}/{repo}/pulls`
```bash
# Create PR via API
gh api repos/{owner}/{repo}/pulls \
-f title="NOJIRA: New feature" \
-f body="Description of changes" \
-f head="feature-branch" \
-f base="main"
# Create draft PR
gh api repos/{owner}/{repo}/pulls \
-f title="WIP: Feature" \
-f body="Work in progress" \
-f head="feature-branch" \
-f base="main" \
-F draft=true
```
**Required fields:**
- `title`: PR title
- `head`: Branch containing changes
- `base`: Branch to merge into
**Optional fields:**
- `body`: PR description
- `draft`: Boolean for draft PR
- `maintainer_can_modify`: Allow maintainer edits
### Update Pull Request
**Endpoint:** `PATCH /repos/{owner}/{repo}/pulls/{pull_number}`
```bash
# Update PR title and body
gh api repos/{owner}/{repo}/pulls/123 \
-X PATCH \
-f title="Updated title" \
-f body="Updated description"
# Convert to draft
gh api repos/{owner}/{repo}/pulls/123 \
-X PATCH \
-F draft=true
# Change base branch
gh api repos/{owner}/{repo}/pulls/123 \
-X PATCH \
-f base="develop"
```
### Merge Pull Request
**Endpoint:** `PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge`
```bash
# Merge with commit message
gh api repos/{owner}/{repo}/pulls/123/merge \
-X PUT \
-f commit_title="Merge PR #123" \
-f commit_message="Additional merge message" \
-f merge_method="squash"
# Merge methods: merge, squash, rebase
```
### List PR Comments
**Endpoint:** `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments`
```bash
# Get all review comments
gh api repos/{owner}/{repo}/pulls/123/comments
# Get issue comments (conversation tab)
gh api repos/{owner}/{repo}/issues/123/comments
```
### Create PR Review
**Endpoint:** `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews`
```bash
# Approve PR
gh api repos/{owner}/{repo}/pulls/123/reviews \
-f event="APPROVE" \
-f body="Looks good!"
# Request changes
gh api repos/{owner}/{repo}/pulls/123/reviews \
-f event="REQUEST_CHANGES" \
-f body="Please address these issues"
# Comment without approval/rejection
gh api repos/{owner}/{repo}/pulls/123/reviews \
-f event="COMMENT" \
-f body="Some feedback"
```
**Review events:**
- `APPROVE`: Approve the PR
- `REQUEST_CHANGES`: Request changes
- `COMMENT`: General comment
### List PR Reviews
**Endpoint:** `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews`
```bash
# Get all reviews
gh api repos/{owner}/{repo}/pulls/123/reviews
# Parse review states
gh api repos/{owner}/{repo}/pulls/123/reviews --jq '[.[] | {user: .user.login, state: .state}]'
```
### Request Reviewers
**Endpoint:** `POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers`
```bash
# Request user reviewers
gh api repos/{owner}/{repo}/pulls/123/requested_reviewers \
-f reviewers[]="user1" \
-f reviewers[]="user2"
# Request team reviewers
gh api repos/{owner}/{repo}/pulls/123/requested_reviewers \
-f team_reviewers[]="team-slug"
```
## Issues API
### List Issues
**Endpoint:** `GET /repos/{owner}/{repo}/issues`
```bash
# List all issues
gh api repos/{owner}/{repo}/issues
# Filter by state and labels
gh api repos/{owner}/{repo}/issues -f state=open -f labels="bug,priority-high"
# Filter by assignee
gh api repos/{owner}/{repo}/issues -f assignee="username"
# Filter by milestone
gh api repos/{owner}/{repo}/issues -f milestone="v1.0"
```
**Query Parameters:**
- `state`: `open`, `closed`, `all`
- `labels`: Comma-separated label names
- `assignee`: Username or `none` or `*`
- `creator`: Username
- `mentioned`: Username
- `milestone`: Milestone number or `none` or `*`
- `sort`: `created`, `updated`, `comments`
- `direction`: `asc`, `desc`
### Create Issue
**Endpoint:** `POST /repos/{owner}/{repo}/issues`
```bash
# Create basic issue
gh api repos/{owner}/{repo}/issues \
-f title="Bug: Something broke" \
-f body="Detailed description"
# Create issue with labels and assignees
gh api repos/{owner}/{repo}/issues \
-f title="Enhancement request" \
-f body="Description" \
-f labels[]="enhancement" \
-f labels[]="good-first-issue" \
-f assignees[]="username1"
```
### Update Issue
**Endpoint:** `PATCH /repos/{owner}/{repo}/issues/{issue_number}`
```bash
# Close issue
gh api repos/{owner}/{repo}/issues/456 \
-X PATCH \
-f state="closed"
# Update labels
gh api repos/{owner}/{repo}/issues/456 \
-X PATCH \
-f labels[]="bug" \
-f labels[]="fixed"
# Assign issue
gh api repos/{owner}/{repo}/issues/456 \
-X PATCH \
-f assignees[]="username"
```
### Add Comment to Issue
**Endpoint:** `POST /repos/{owner}/{repo}/issues/{issue_number}/comments`
```bash
# Add comment
gh api repos/{owner}/{repo}/issues/456/comments \
-f body="This is a comment"
```
## Repositories API
### Get Repository
**Endpoint:** `GET /repos/{owner}/{repo}`
```bash
# Get repository details
gh api repos/{owner}/{repo}
# Get specific fields
gh api repos/{owner}/{repo} --jq '{name: .name, stars: .stargazers_count, forks: .forks_count}'
```
### List Branches
**Endpoint:** `GET /repos/{owner}/{repo}/branches`
```bash
# List all branches
gh api repos/{owner}/{repo}/branches
# Get branch names only
gh api repos/{owner}/{repo}/branches --jq '.[].name'
```
### Get Branch
**Endpoint:** `GET /repos/{owner}/{repo}/branches/{branch}`
```bash
# Get branch details
gh api repos/{owner}/{repo}/branches/main
# Check if branch is protected
gh api repos/{owner}/{repo}/branches/main --jq '.protected'
```
### Get Branch Protection
**Endpoint:** `GET /repos/{owner}/{repo}/branches/{branch}/protection`
```bash
# Get protection rules
gh api repos/{owner}/{repo}/branches/main/protection
```
### List Commits
**Endpoint:** `GET /repos/{owner}/{repo}/commits`
```bash
# List recent commits
gh api repos/{owner}/{repo}/commits
# Filter by branch
gh api repos/{owner}/{repo}/commits -f sha="feature-branch"
# Filter by author
gh api repos/{owner}/{repo}/commits -f author="username"
# Filter by date range
gh api repos/{owner}/{repo}/commits -f since="2024-01-01T00:00:00Z"
```
### Get Commit
**Endpoint:** `GET /repos/{owner}/{repo}/commits/{sha}`
```bash
# Get commit details
gh api repos/{owner}/{repo}/commits/abc123
# Get files changed in commit
gh api repos/{owner}/{repo}/commits/abc123 --jq '.files[].filename'
```
### Get Commit Status
**Endpoint:** `GET /repos/{owner}/{repo}/commits/{sha}/status`
```bash
# Get combined status for commit
gh api repos/{owner}/{repo}/commits/abc123/status
# Check if all checks passed
gh api repos/{owner}/{repo}/commits/abc123/status --jq '.state'
```
### List Collaborators
**Endpoint:** `GET /repos/{owner}/{repo}/collaborators`
```bash
# List all collaborators
gh api repos/{owner}/{repo}/collaborators
# Get collaborator permissions
gh api repos/{owner}/{repo}/collaborators --jq '[.[] | {login: .login, permissions: .permissions}]'
```
### Create Release
**Endpoint:** `POST /repos/{owner}/{repo}/releases`
```bash
# Create release
gh api repos/{owner}/{repo}/releases \
-f tag_name="v1.0.0" \
-f name="Release v1.0.0" \
-f body="Release notes here" \
-F draft=false \
-F prerelease=false
# Create draft release
gh api repos/{owner}/{repo}/releases \
-f tag_name="v1.1.0" \
-f name="Release v1.1.0" \
-f body="Release notes" \
-F draft=true
```
### List Releases
**Endpoint:** `GET /repos/{owner}/{repo}/releases`
```bash
# List all releases
gh api repos/{owner}/{repo}/releases
# Get latest release
gh api repos/{owner}/{repo}/releases/latest
```
## Actions/Workflows API
### List Workflows
**Endpoint:** `GET /repos/{owner}/{repo}/actions/workflows`
```bash
# List all workflows
gh api repos/{owner}/{repo}/actions/workflows
# Get workflow names
gh api repos/{owner}/{repo}/actions/workflows --jq '.workflows[].name'
```
### Get Workflow
**Endpoint:** `GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}`
```bash
# Get workflow by ID
gh api repos/{owner}/{repo}/actions/workflows/12345
# Get workflow by filename
gh api repos/{owner}/{repo}/actions/workflows/ci.yml
```
### List Workflow Runs
**Endpoint:** `GET /repos/{owner}/{repo}/actions/runs`
```bash
# List all runs
gh api repos/{owner}/{repo}/actions/runs
# Filter by workflow
gh api repos/{owner}/{repo}/actions/runs -f workflow_id=12345
# Filter by branch
gh api repos/{owner}/{repo}/actions/runs -f branch="main"
# Filter by status
gh api repos/{owner}/{repo}/actions/runs -f status="completed"
# Filter by conclusion
gh api repos/{owner}/{repo}/actions/runs -f conclusion="success"
```
**Status values:** `queued`, `in_progress`, `completed`
**Conclusion values:** `success`, `failure`, `cancelled`, `skipped`, `timed_out`, `action_required`
### Get Workflow Run
**Endpoint:** `GET /repos/{owner}/{repo}/actions/runs/{run_id}`
```bash
# Get run details
gh api repos/{owner}/{repo}/actions/runs/123456
# Check run status
gh api repos/{owner}/{repo}/actions/runs/123456 --jq '.status, .conclusion'
```
### Trigger Workflow
**Endpoint:** `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches`
```bash
# Trigger workflow on branch
gh api repos/{owner}/{repo}/actions/workflows/ci.yml/dispatches \
-f ref="main"
# Trigger with inputs
gh api repos/{owner}/{repo}/actions/workflows/deploy.yml/dispatches \
-f ref="main" \
-f inputs[environment]="production" \
-f inputs[version]="v1.0.0"
```
### Cancel Workflow Run
**Endpoint:** `POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel`
```bash
# Cancel run
gh api repos/{owner}/{repo}/actions/runs/123456/cancel -X POST
```
### Rerun Workflow
**Endpoint:** `POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun`
```bash
# Rerun all jobs
gh api repos/{owner}/{repo}/actions/runs/123456/rerun -X POST
# Rerun failed jobs only
gh api repos/{owner}/{repo}/actions/runs/123456/rerun-failed-jobs -X POST
```
### Download Workflow Logs
**Endpoint:** `GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs`
```bash
# Download logs (returns zip archive)
gh api repos/{owner}/{repo}/actions/runs/123456/logs > logs.zip
```
## Search API
### Search Repositories
**Endpoint:** `GET /search/repositories`
```bash
# Search repositories
gh api search/repositories -f q="topic:spring-boot language:java"
# Search with filters
gh api search/repositories -f q="stars:>1000 language:python"
```
### Search Code
**Endpoint:** `GET /search/code`
```bash
# Search code
gh api search/code -f q="addClass repo:owner/repo"
# Search in specific path
gh api search/code -f q="function path:src/ repo:owner/repo"
```
### Search Issues and PRs
**Endpoint:** `GET /search/issues`
```bash
# Search issues
gh api search/issues -f q="is:issue is:open label:bug repo:owner/repo"
# Search PRs
gh api search/issues -f q="is:pr is:merged author:username"
```
## GraphQL API
### Basic GraphQL Query
```bash
# Execute GraphQL query
gh api graphql -f query='
query {
viewer {
login
name
}
}
'
```
### Query Repository Information
```bash
gh api graphql -f query='
query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
name
description
stargazerCount
forkCount
issues(states: OPEN) {
totalCount
}
pullRequests(states: OPEN) {
totalCount
}
}
}
' -f owner="owner" -f name="repo"
```
### Query PR with Reviews
```bash
gh api graphql -f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
title
state
author {
login
}
reviews(first: 10) {
nodes {
state
author {
login
}
submittedAt
}
}
commits(last: 1) {
nodes {
commit {
statusCheckRollup {
state
}
}
}
}
}
}
}
' -f owner="owner" -f name="repo" -F number=123
```
### Query Multiple PRs with Pagination
```bash
gh api graphql -f query='
query($owner: String!, $name: String!, $cursor: String) {
repository(owner: $owner, name: $name) {
pullRequests(first: 10, states: OPEN, after: $cursor) {
pageInfo {
hasNextPage
endCursor
}
nodes {
number
title
author {
login
}
createdAt
}
}
}
}
' -f owner="owner" -f name="repo"
```
## Rate Limiting
### Check Rate Limit
**Endpoint:** `GET /rate_limit`
```bash
# Check current rate limit
gh api rate_limit
# Check core API limit
gh api rate_limit --jq '.resources.core'
# Check GraphQL limit
gh api rate_limit --jq '.resources.graphql'
```
**Rate limits:**
- Authenticated: 5,000 requests/hour
- GraphQL: 5,000 points/hour
- Search: 30 requests/minute
### Rate Limit Headers
Every API response includes rate limit headers:
- `X-RateLimit-Limit`: Total requests allowed
- `X-RateLimit-Remaining`: Requests remaining
- `X-RateLimit-Reset`: Unix timestamp when limit resets
## Webhooks
### List Webhooks
**Endpoint:** `GET /repos/{owner}/{repo}/hooks`
```bash
# List repository webhooks
gh api repos/{owner}/{repo}/hooks
```
### Create Webhook
**Endpoint:** `POST /repos/{owner}/{repo}/hooks`
```bash
# Create webhook
gh api repos/{owner}/{repo}/hooks \
-f name="web" \
-f config[url]="https://example.com/webhook" \
-f config[content_type]="json" \
-f events[]="push" \
-f events[]="pull_request"
```
### Test Webhook
**Endpoint:** `POST /repos/{owner}/{repo}/hooks/{hook_id}/tests`
```bash
# Test webhook
gh api repos/{owner}/{repo}/hooks/12345/tests -X POST
```
## Pagination
For endpoints returning lists, use pagination:
```bash
# First page (default)
gh api repos/{owner}/{repo}/issues
# Specific page
gh api repos/{owner}/{repo}/issues -f page=2 -f per_page=50
# Iterate through all pages
for page in {1..10}; do
gh api repos/{owner}/{repo}/issues -f page=$page -f per_page=100
done
```
**Link header:** Response includes `Link` header with `next`, `prev`, `first`, `last` URLs.
## Error Handling
**Common HTTP status codes:**
- `200 OK`: Success
- `201 Created`: Resource created
- `204 No Content`: Success with no response body
- `400 Bad Request`: Invalid request
- `401 Unauthorized`: Authentication required
- `403 Forbidden`: Insufficient permissions or rate limited
- `404 Not Found`: Resource doesn't exist
- `422 Unprocessable Entity`: Validation failed
**Error response format:**
```json
{
"message": "Validation Failed",
"errors": [
{
"resource": "PullRequest",
"code": "custom",
"message": "Error details"
}
]
}
```
## Best Practices
1. **Use conditional requests:** Include `If-None-Match` header with ETag to save rate limit quota
2. **Paginate efficiently:** Use `per_page=100` (maximum) to minimize requests
3. **Use GraphQL for complex queries:** Fetch multiple related resources in single request
4. **Check rate limits proactively:** Monitor `X-RateLimit-Remaining` header
5. **Handle errors gracefully:** Implement retry logic with exponential backoff for 5xx errors
6. **Cache responses:** Cache GET responses when data doesn't change frequently
7. **Use webhooks:** Subscribe to events instead of polling
## Additional Resources
- GitHub REST API documentation: https://docs.github.com/en/rest
- GitHub GraphQL API documentation: https://docs.github.com/en/graphql
- gh CLI manual: https://cli.github.com/manual/