Initial commit
This commit is contained in:
793
skills/github-ops/references/api_reference.md
Normal file
793
skills/github-ops/references/api_reference.md
Normal file
@@ -0,0 +1,793 @@
|
||||
# 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/
|
||||
446
skills/github-ops/references/best_practices.md
Normal file
446
skills/github-ops/references/best_practices.md
Normal file
@@ -0,0 +1,446 @@
|
||||
# GitHub CLI Best Practices
|
||||
|
||||
Shell scripting patterns, bulk operations, and automation strategies for gh CLI.
|
||||
|
||||
## Output Formats and Processing
|
||||
|
||||
### JSON Output for Programmatic Parsing
|
||||
|
||||
```bash
|
||||
# Default: Human-readable text
|
||||
gh pr list
|
||||
|
||||
# JSON output for programmatic parsing
|
||||
gh pr list --json number,title,state,author
|
||||
|
||||
# JSON with jq processing
|
||||
gh pr list --json number,title | jq '.[] | select(.title | contains("bug"))'
|
||||
|
||||
# Template output for custom formatting
|
||||
gh pr list --template '{{range .}}{{.number}}: {{.title}}{{"\n"}}{{end}}'
|
||||
```
|
||||
|
||||
### Field Selection
|
||||
|
||||
```bash
|
||||
# Select specific fields
|
||||
gh pr view 123 --json number,title,state,reviews
|
||||
|
||||
# All available fields
|
||||
gh pr view 123 --json
|
||||
|
||||
# Nested field extraction
|
||||
gh pr list --json number,author | jq '.[].author.login'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pagination Strategies
|
||||
|
||||
### Controlling Result Limits
|
||||
|
||||
```bash
|
||||
# Limit results (default is usually 30)
|
||||
gh pr list --limit 50
|
||||
|
||||
# Show all results (use carefully)
|
||||
gh pr list --limit 999
|
||||
|
||||
# Paginate manually
|
||||
gh pr list --limit 100 --page 1
|
||||
gh pr list --limit 100 --page 2
|
||||
```
|
||||
|
||||
### Processing Large Result Sets
|
||||
|
||||
```bash
|
||||
# Get all PRs in batches
|
||||
for page in {1..10}; do
|
||||
gh pr list --limit 100 --page $page --json number,title
|
||||
done
|
||||
|
||||
# Stop when no more results
|
||||
page=1
|
||||
while true; do
|
||||
results=$(gh pr list --limit 100 --page $page --json number)
|
||||
if [ "$results" == "[]" ]; then break; fi
|
||||
echo "$results"
|
||||
((page++))
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling and Reliability
|
||||
|
||||
### Exit Code Checking
|
||||
|
||||
```bash
|
||||
# Check exit codes
|
||||
gh pr merge 123 && echo "Success" || echo "Failed"
|
||||
|
||||
# Capture exit code
|
||||
gh pr create --title "Title" --body "Body"
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo "PR created successfully"
|
||||
else
|
||||
echo "PR creation failed with code $exit_code"
|
||||
fi
|
||||
```
|
||||
|
||||
### Error Output Handling
|
||||
|
||||
```bash
|
||||
# Separate stdout and stderr
|
||||
gh pr list > success.log 2> error.log
|
||||
|
||||
# Redirect errors to stdout
|
||||
gh pr list 2>&1 | tee combined.log
|
||||
|
||||
# Suppress errors
|
||||
gh pr view 999 2>/dev/null || echo "PR not found"
|
||||
```
|
||||
|
||||
### Retry Logic
|
||||
|
||||
```bash
|
||||
# Simple retry
|
||||
for i in {1..3}; do
|
||||
gh api repos/{owner}/{repo}/pulls && break
|
||||
echo "Retry $i failed, waiting..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Exponential backoff
|
||||
attempt=1
|
||||
max_attempts=5
|
||||
delay=1
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
if gh pr create --title "Title" --body "Body"; then
|
||||
break
|
||||
fi
|
||||
echo "Attempt $attempt failed, retrying in ${delay}s..."
|
||||
sleep $delay
|
||||
delay=$((delay * 2))
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
### Operating on Multiple Items
|
||||
|
||||
```bash
|
||||
# Close all PRs with specific label
|
||||
gh pr list --label "wip" --json number -q '.[].number' | \
|
||||
xargs -I {} gh pr close {}
|
||||
|
||||
# Add label to multiple issues
|
||||
gh issue list --state open --json number -q '.[].number' | \
|
||||
xargs -I {} gh issue edit {} --add-label "needs-triage"
|
||||
|
||||
# Approve multiple PRs
|
||||
gh pr list --author username --json number -q '.[].number' | \
|
||||
xargs -I {} gh pr review {} --approve
|
||||
```
|
||||
|
||||
### Parallel Execution
|
||||
|
||||
```bash
|
||||
# Process items in parallel (GNU parallel)
|
||||
gh pr list --json number -q '.[].number' | \
|
||||
parallel -j 4 gh pr view {}
|
||||
|
||||
# Xargs parallel execution
|
||||
gh pr list --json number -q '.[].number' | \
|
||||
xargs -P 4 -I {} gh pr checks {}
|
||||
```
|
||||
|
||||
### Batch Processing with Confirmation
|
||||
|
||||
```bash
|
||||
# Confirm before bulk operation
|
||||
gh pr list --label "old" --json number,title | \
|
||||
jq -r '.[] | "\(.number): \(.title)"' | \
|
||||
while read -r line; do
|
||||
echo "Close PR $line? (y/n)"
|
||||
read -r answer
|
||||
if [ "$answer" == "y" ]; then
|
||||
pr_num=$(echo "$line" | cut -d: -f1)
|
||||
gh pr close "$pr_num"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Enterprise GitHub Patterns
|
||||
|
||||
### Working with GitHub Enterprise
|
||||
|
||||
```bash
|
||||
# Authenticate with enterprise hostname
|
||||
gh auth login --hostname github.enterprise.com
|
||||
|
||||
# Set environment variable for enterprise
|
||||
export GH_HOST=github.enterprise.com
|
||||
gh pr list
|
||||
|
||||
# Use with specific host
|
||||
gh pr list --hostname github.enterprise.com
|
||||
|
||||
# Check current authentication
|
||||
gh auth status
|
||||
```
|
||||
|
||||
### Switching Between Instances
|
||||
|
||||
```bash
|
||||
# Switch between GitHub.com and Enterprise
|
||||
gh auth switch
|
||||
|
||||
# Use specific auth token
|
||||
GH_TOKEN=ghp_enterprise_token gh pr list --hostname github.enterprise.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Automation and Scripting
|
||||
|
||||
### Capturing Output
|
||||
|
||||
```bash
|
||||
# Capture PR number
|
||||
PR_NUMBER=$(gh pr create --title "Title" --body "Body" | grep -oP '\d+$')
|
||||
echo "Created PR #$PR_NUMBER"
|
||||
|
||||
# Capture JSON and parse
|
||||
pr_data=$(gh pr view 123 --json number,title,state)
|
||||
pr_state=$(echo "$pr_data" | jq -r '.state')
|
||||
|
||||
# Capture and validate
|
||||
if output=$(gh pr merge 123 2>&1); then
|
||||
echo "Merged successfully"
|
||||
else
|
||||
echo "Merge failed: $output"
|
||||
fi
|
||||
```
|
||||
|
||||
### Conditional Operations
|
||||
|
||||
```bash
|
||||
# Check PR status before merging
|
||||
pr_state=$(gh pr view 123 --json state -q '.state')
|
||||
if [ "$pr_state" == "OPEN" ]; then
|
||||
gh pr merge 123 --squash
|
||||
fi
|
||||
|
||||
# Check CI status
|
||||
checks=$(gh pr checks 123 --json state -q '.[].state')
|
||||
if echo "$checks" | grep -q "FAILURE"; then
|
||||
echo "CI checks failed, cannot merge"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Workflow Automation
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Automated PR workflow
|
||||
|
||||
# Create feature branch
|
||||
git checkout -b feature/new-feature
|
||||
|
||||
# Make changes and commit
|
||||
# ...
|
||||
|
||||
# Push and create PR
|
||||
git push -u origin feature/new-feature
|
||||
PR_NUM=$(gh pr create \
|
||||
--title "feat: New feature" \
|
||||
--body "Description of feature" \
|
||||
--label "enhancement" \
|
||||
| grep -oP '\d+$')
|
||||
|
||||
# Wait for CI
|
||||
echo "Waiting for CI checks..."
|
||||
while true; do
|
||||
status=$(gh pr checks "$PR_NUM" --json state -q '.[].state' | grep -v "SUCCESS")
|
||||
if [ -z "$status" ]; then
|
||||
echo "All checks passed!"
|
||||
break
|
||||
fi
|
||||
sleep 30
|
||||
done
|
||||
|
||||
# Auto-merge if checks pass
|
||||
gh pr merge "$PR_NUM" --squash --auto
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration and Customization
|
||||
|
||||
### Setting Defaults
|
||||
|
||||
```bash
|
||||
# Set default repository
|
||||
gh repo set-default owner/repo
|
||||
|
||||
# Configure editor
|
||||
gh config set editor vim
|
||||
|
||||
# Configure browser
|
||||
gh config set browser firefox
|
||||
|
||||
# Set Git protocol preference
|
||||
gh config set git_protocol ssh # or https
|
||||
|
||||
# View current configuration
|
||||
gh config list
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# GitHub token
|
||||
export GH_TOKEN=ghp_your_token
|
||||
|
||||
# GitHub host
|
||||
export GH_HOST=github.enterprise.com
|
||||
|
||||
# Default repository
|
||||
export GH_REPO=owner/repo
|
||||
|
||||
# Pager
|
||||
export GH_PAGER=less
|
||||
|
||||
# No prompts (for automation)
|
||||
export GH_NO_UPDATE_NOTIFIER=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Reducing API Calls
|
||||
|
||||
```bash
|
||||
# Cache frequently used data
|
||||
pr_list=$(gh pr list --json number,title,state)
|
||||
echo "$pr_list" | jq '.[] | select(.state == "OPEN")'
|
||||
echo "$pr_list" | jq '.[] | select(.state == "MERGED")'
|
||||
|
||||
# Use single API call for multiple fields
|
||||
gh pr view 123 --json number,title,state,reviews,comments
|
||||
```
|
||||
|
||||
### Selective Field Loading
|
||||
|
||||
```bash
|
||||
# Only fetch needed fields
|
||||
gh pr list --json number,title # Fast
|
||||
|
||||
# vs. fetching all fields
|
||||
gh pr list --json # Slower
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debugging and Troubleshooting
|
||||
|
||||
### Verbose Output
|
||||
|
||||
```bash
|
||||
# Enable debug logging
|
||||
GH_DEBUG=1 gh pr list
|
||||
|
||||
# API logging
|
||||
GH_DEBUG=api gh pr create --title "Test"
|
||||
|
||||
# Full HTTP trace
|
||||
GH_DEBUG=api,http gh api repos/{owner}/{repo}
|
||||
```
|
||||
|
||||
### Testing API Calls
|
||||
|
||||
```bash
|
||||
# Test API endpoint
|
||||
gh api repos/{owner}/{repo}/pulls
|
||||
|
||||
# Test with custom headers
|
||||
gh api repos/{owner}/{repo}/pulls \
|
||||
-H "Accept: application/vnd.github.v3+json"
|
||||
|
||||
# Test pagination
|
||||
gh api repos/{owner}/{repo}/pulls --paginate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices Summary
|
||||
|
||||
### Do's
|
||||
|
||||
✅ **Use JSON output** for programmatic parsing
|
||||
✅ **Handle errors** with proper exit code checking
|
||||
✅ **Implement retries** for network operations
|
||||
✅ **Cache results** when making multiple queries
|
||||
✅ **Use bulk operations** for efficiency
|
||||
✅ **Set appropriate limits** to avoid rate limiting
|
||||
✅ **Validate input** before operations
|
||||
✅ **Log operations** for audit trail
|
||||
|
||||
### Don'ts
|
||||
|
||||
❌ **Don't hardcode credentials** - Use environment variables or gh auth
|
||||
❌ **Don't ignore errors** - Always check exit codes
|
||||
❌ **Don't fetch all fields** - Select only what you need
|
||||
❌ **Don't skip rate limit checks** - Monitor API usage
|
||||
❌ **Don't run destructive operations without confirmation**
|
||||
❌ **Don't assume unlimited results** - Always paginate
|
||||
❌ **Don't mix automation with interactive** - Use GH_NO_UPDATE_NOTIFIER=1
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Create, Wait, Merge Pattern
|
||||
|
||||
```bash
|
||||
# Create PR
|
||||
PR_NUM=$(gh pr create --title "Feature" --body "Description" | grep -oP '\d+$')
|
||||
|
||||
# Wait for checks
|
||||
gh pr checks "$PR_NUM" --watch
|
||||
|
||||
# Merge when ready
|
||||
gh pr merge "$PR_NUM" --squash
|
||||
```
|
||||
|
||||
### Search and Process Pattern
|
||||
|
||||
```bash
|
||||
# Find and process matching items
|
||||
gh pr list --json number,title | \
|
||||
jq -r '.[] | select(.title | contains("bug")) | .number' | \
|
||||
while read -r pr; do
|
||||
gh pr edit "$pr" --add-label "bug"
|
||||
done
|
||||
```
|
||||
|
||||
### Batch Approval Pattern
|
||||
|
||||
```bash
|
||||
# Review and approve multiple PRs
|
||||
gh pr list --author trusted-user --json number -q '.[].number' | \
|
||||
while read -r pr; do
|
||||
gh pr diff "$pr"
|
||||
gh pr review "$pr" --approve --body "LGTM"
|
||||
done
|
||||
```
|
||||
283
skills/github-ops/references/issue_operations.md
Normal file
283
skills/github-ops/references/issue_operations.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# Issue Operations Reference
|
||||
|
||||
Comprehensive examples for GitHub issue management using gh CLI.
|
||||
|
||||
## Creating Issues
|
||||
|
||||
### Basic Issue Creation
|
||||
|
||||
```bash
|
||||
# Create simple issue
|
||||
gh issue create --title "Bug: Issue title" --body "Issue description"
|
||||
|
||||
# Create issue with labels and assignees
|
||||
gh issue create --title "Bug: Title" --body "Description" \
|
||||
--label bug,priority-high --assignee username
|
||||
|
||||
# Create issue from template
|
||||
gh issue create --template bug_report.md
|
||||
|
||||
# Create issue with body from file
|
||||
gh issue create --title "Feature Request" --body-file feature.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Listing Issues
|
||||
|
||||
### Basic Listing
|
||||
|
||||
```bash
|
||||
# List all issues
|
||||
gh issue list
|
||||
|
||||
# List issues with filters
|
||||
gh issue list --state open --label bug
|
||||
gh issue list --assignee username
|
||||
gh issue list --milestone "v2.0"
|
||||
|
||||
# List with pagination
|
||||
gh issue list --limit 50
|
||||
```
|
||||
|
||||
### Advanced Filtering
|
||||
|
||||
```bash
|
||||
# List issues by multiple labels
|
||||
gh issue list --label "bug,priority-high"
|
||||
|
||||
# List issues NOT assigned to anyone
|
||||
gh issue list --assignee ""
|
||||
|
||||
# List issues mentioned in PR
|
||||
gh issue list --mention username
|
||||
|
||||
# List recently updated issues
|
||||
gh issue list --state all --limit 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viewing Issues
|
||||
|
||||
### Viewing Details
|
||||
|
||||
```bash
|
||||
# View specific issue
|
||||
gh issue view 456
|
||||
|
||||
# View issue in browser
|
||||
gh issue view 456 --web
|
||||
|
||||
# View issue with comments
|
||||
gh issue view 456 --comments
|
||||
|
||||
# Get issue as JSON
|
||||
gh issue view 456 --json number,title,body,state,labels,assignees
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Editing Issues
|
||||
|
||||
### Update Issue Metadata
|
||||
|
||||
```bash
|
||||
# Edit issue title
|
||||
gh issue edit 456 --title "New title"
|
||||
|
||||
# Edit issue body
|
||||
gh issue edit 456 --body "Updated description"
|
||||
|
||||
# Add labels
|
||||
gh issue edit 456 --add-label enhancement,documentation
|
||||
|
||||
# Remove labels
|
||||
gh issue edit 456 --remove-label wip
|
||||
|
||||
# Add assignees
|
||||
gh issue edit 456 --add-assignee user1,user2
|
||||
|
||||
# Remove assignees
|
||||
gh issue edit 456 --remove-assignee user1
|
||||
|
||||
# Set milestone
|
||||
gh issue edit 456 --milestone "v2.0"
|
||||
|
||||
# Remove milestone
|
||||
gh issue edit 456 --milestone ""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Issue Lifecycle
|
||||
|
||||
### State Management
|
||||
|
||||
```bash
|
||||
# Close issue
|
||||
gh issue close 456
|
||||
|
||||
# Close issue with comment
|
||||
gh issue close 456 --comment "Fixed in PR #789"
|
||||
|
||||
# Reopen issue
|
||||
gh issue reopen 456
|
||||
|
||||
# Reopen with comment
|
||||
gh issue reopen 456 --comment "Issue persists in v2.0"
|
||||
```
|
||||
|
||||
### Issue Linking
|
||||
|
||||
```bash
|
||||
# Link to PR in issue (manual)
|
||||
gh issue comment 456 --body "Fixed by #789"
|
||||
|
||||
# Close issue when PR merges (in PR description)
|
||||
# Use keywords: closes, fixes, resolves
|
||||
gh pr create --title "Fix bug" --body "Closes #456"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commenting on Issues
|
||||
|
||||
### Adding Comments
|
||||
|
||||
```bash
|
||||
# Add comment to issue
|
||||
gh issue comment 456 --body "Comment text"
|
||||
|
||||
# Add comment from file
|
||||
gh issue comment 456 --body-file comment.txt
|
||||
|
||||
# Add comment with emoji reactions
|
||||
gh issue comment 456 --body "Great idea! :+1:"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Issue Pinning and Priority
|
||||
|
||||
### Pinning Issues
|
||||
|
||||
```bash
|
||||
# Pin issue to repository
|
||||
gh issue pin 456
|
||||
|
||||
# Unpin issue
|
||||
gh issue unpin 456
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Issue Transfers
|
||||
|
||||
### Transfer to Another Repository
|
||||
|
||||
```bash
|
||||
# Transfer issue to another repo
|
||||
gh issue transfer 456 owner/other-repo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
### Operating on Multiple Issues
|
||||
|
||||
```bash
|
||||
# Close all bug issues
|
||||
gh issue list --label bug --json number -q '.[].number' | \
|
||||
xargs -I {} gh issue close {}
|
||||
|
||||
# Add label to all open issues
|
||||
gh issue list --state open --json number -q '.[].number' | \
|
||||
xargs -I {} gh issue edit {} --add-label "needs-triage"
|
||||
|
||||
# Assign milestone to multiple issues
|
||||
gh issue list --label "v2.0" --json number -q '.[].number' | \
|
||||
xargs -I {} gh issue edit {} --milestone "Release 2.0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output Formatting
|
||||
|
||||
### JSON Output
|
||||
|
||||
```bash
|
||||
# Get issue data as JSON
|
||||
gh issue view 456 --json number,title,body,state,labels,assignees,milestone
|
||||
|
||||
# List issues with custom fields
|
||||
gh issue list --json number,title,state,createdAt,updatedAt
|
||||
|
||||
# Process with jq
|
||||
gh issue list --json number,title,labels | \
|
||||
jq '.[] | select(.labels | any(.name == "bug"))'
|
||||
```
|
||||
|
||||
### Template Output
|
||||
|
||||
```bash
|
||||
# Custom format with Go templates
|
||||
gh issue list --template '{{range .}}#{{.number}}: {{.title}} [{{.state}}]{{"\n"}}{{end}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Search Operations
|
||||
|
||||
### Using GitHub Search Syntax
|
||||
|
||||
```bash
|
||||
# Search issues with text
|
||||
gh issue list --search "error in logs"
|
||||
|
||||
# Search issues by author
|
||||
gh issue list --search "author:username"
|
||||
|
||||
# Search issues by label
|
||||
gh issue list --search "label:bug"
|
||||
|
||||
# Complex search queries
|
||||
gh issue list --search "is:open label:bug created:>2024-01-01"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Creating Effective Issues
|
||||
|
||||
1. **Use descriptive titles** - Be specific about the problem
|
||||
2. **Provide context** - Include steps to reproduce
|
||||
3. **Add labels** - Help with categorization and filtering
|
||||
4. **Assign appropriately** - Tag people who can help
|
||||
5. **Link related items** - Connect to PRs, other issues
|
||||
|
||||
### Issue Management
|
||||
|
||||
1. **Triage regularly** - Review and label new issues
|
||||
2. **Update status** - Keep issues current with comments
|
||||
3. **Close resolved issues** - Link to fixing PR
|
||||
4. **Use milestones** - Group related work
|
||||
5. **Pin important issues** - Highlight key items
|
||||
|
||||
### Labels Strategy
|
||||
|
||||
Common label categories:
|
||||
- **Type**: bug, feature, enhancement, documentation
|
||||
- **Priority**: priority-high, priority-medium, priority-low
|
||||
- **Status**: wip, needs-review, blocked
|
||||
- **Area**: frontend, backend, database, infrastructure
|
||||
|
||||
### Automation Tips
|
||||
|
||||
1. **Issue templates** - Create templates for bugs, features
|
||||
2. **Auto-labeling** - Use GitHub Actions to auto-label
|
||||
3. **Stale bot** - Auto-close inactive issues
|
||||
4. **Project boards** - Track issue progress
|
||||
5. **Webhooks** - Integrate with external tools
|
||||
250
skills/github-ops/references/pr_operations.md
Normal file
250
skills/github-ops/references/pr_operations.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# Pull Request Operations Reference
|
||||
|
||||
Comprehensive examples for GitHub pull request operations using gh CLI.
|
||||
|
||||
## Creating Pull Requests
|
||||
|
||||
### Basic PR Creation
|
||||
|
||||
```bash
|
||||
# Create PR with NOJIRA prefix (bypasses JIRA enforcement checks)
|
||||
gh pr create --title "NOJIRA: Your PR title" --body "PR description"
|
||||
|
||||
# Create PR with JIRA ticket reference
|
||||
gh pr create --title "GR-1234: Your PR title" --body "PR description"
|
||||
|
||||
# Create PR targeting specific branch
|
||||
gh pr create --title "NOJIRA: Feature" --body "Description" --base main --head feature-branch
|
||||
|
||||
# Create PR with body from file
|
||||
gh pr create --title "NOJIRA: Feature" --body-file pr-description.md
|
||||
```
|
||||
|
||||
### PR Title Convention
|
||||
|
||||
- **With JIRA ticket**: `GR-1234: Descriptive title`
|
||||
- **Without JIRA ticket**: `NOJIRA: Descriptive title` (bypasses enforcement check)
|
||||
|
||||
---
|
||||
|
||||
## Viewing Pull Requests
|
||||
|
||||
### Listing PRs
|
||||
|
||||
```bash
|
||||
# List all PRs
|
||||
gh pr list
|
||||
|
||||
# List PRs with custom filters
|
||||
gh pr list --state open --limit 50
|
||||
gh pr list --author username
|
||||
gh pr list --label bug
|
||||
|
||||
# List PRs as JSON for parsing
|
||||
gh pr list --json number,title,state,author
|
||||
```
|
||||
|
||||
### Viewing Specific PRs
|
||||
|
||||
```bash
|
||||
# View specific PR details
|
||||
gh pr view 123
|
||||
|
||||
# View PR in browser
|
||||
gh pr view 123 --web
|
||||
|
||||
# View PR diff
|
||||
gh pr diff 123
|
||||
|
||||
# View PR checks/status
|
||||
gh pr checks 123
|
||||
|
||||
# View PR with comments
|
||||
gh pr view 123 --comments
|
||||
|
||||
# Get PR info as JSON for parsing
|
||||
gh pr view 123 --json number,title,state,author,reviews
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Managing Pull Requests
|
||||
|
||||
### Editing PRs
|
||||
|
||||
```bash
|
||||
# Edit PR title/body
|
||||
gh pr edit 123 --title "New title" --body "New description"
|
||||
|
||||
# Add reviewers
|
||||
gh pr edit 123 --add-reviewer username1,username2
|
||||
|
||||
# Add labels
|
||||
gh pr edit 123 --add-label "bug,priority-high"
|
||||
|
||||
# Remove labels
|
||||
gh pr edit 123 --remove-label "wip"
|
||||
```
|
||||
|
||||
### Merging PRs
|
||||
|
||||
```bash
|
||||
# Merge PR (various strategies)
|
||||
gh pr merge 123 --merge # Regular merge commit
|
||||
gh pr merge 123 --squash # Squash and merge
|
||||
gh pr merge 123 --rebase # Rebase and merge
|
||||
|
||||
# Auto-merge after checks pass
|
||||
gh pr merge 123 --auto --squash
|
||||
```
|
||||
|
||||
### PR Lifecycle Management
|
||||
|
||||
```bash
|
||||
# Close PR without merging
|
||||
gh pr close 123
|
||||
|
||||
# Reopen closed PR
|
||||
gh pr reopen 123
|
||||
|
||||
# Checkout PR locally for testing
|
||||
gh pr checkout 123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PR Comments and Reviews
|
||||
|
||||
### Adding Comments
|
||||
|
||||
```bash
|
||||
# Add comment to PR
|
||||
gh pr comment 123 --body "Your comment here"
|
||||
|
||||
# Add comment from file
|
||||
gh pr comment 123 --body-file comment.txt
|
||||
```
|
||||
|
||||
### Reviewing PRs
|
||||
|
||||
```bash
|
||||
# Add review comment
|
||||
gh pr review 123 --comment --body "Review comments"
|
||||
|
||||
# Approve PR
|
||||
gh pr review 123 --approve
|
||||
|
||||
# Approve with comment
|
||||
gh pr review 123 --approve --body "LGTM! Great work."
|
||||
|
||||
# Request changes
|
||||
gh pr review 123 --request-changes --body "Please fix X"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced PR Operations
|
||||
|
||||
### Checking PR Status
|
||||
|
||||
```bash
|
||||
# Check CI/CD status
|
||||
gh pr checks 123
|
||||
|
||||
# Watch PR checks in real-time
|
||||
gh pr checks 123 --watch
|
||||
|
||||
# Get checks as JSON
|
||||
gh pr checks 123 --json name,status,conclusion
|
||||
```
|
||||
|
||||
### PR Metadata Operations
|
||||
|
||||
```bash
|
||||
# Add assignees
|
||||
gh pr edit 123 --add-assignee username
|
||||
|
||||
# Add to project
|
||||
gh pr edit 123 --add-project "Project Name"
|
||||
|
||||
# Set milestone
|
||||
gh pr edit 123 --milestone "v2.0"
|
||||
|
||||
# Mark as draft
|
||||
gh pr ready 123 --undo
|
||||
|
||||
# Mark as ready for review
|
||||
gh pr ready 123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output Formatting
|
||||
|
||||
### JSON Output for Scripting
|
||||
|
||||
```bash
|
||||
# Get PR data as JSON
|
||||
gh pr view 123 --json number,title,state,author,reviews,comments
|
||||
|
||||
# List PRs with specific fields
|
||||
gh pr list --json number,title,author,updatedAt
|
||||
|
||||
# Process with jq
|
||||
gh pr list --json number,title | jq '.[] | select(.title | contains("bug"))'
|
||||
```
|
||||
|
||||
### Template Output
|
||||
|
||||
```bash
|
||||
# Custom format with Go templates
|
||||
gh pr list --template '{{range .}}#{{.number}}: {{.title}} (@{{.author.login}}){{"\n"}}{{end}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
### Operating on Multiple PRs
|
||||
|
||||
```bash
|
||||
# Close all PRs with specific label
|
||||
gh pr list --label "wip" --json number -q '.[].number' | \
|
||||
xargs -I {} gh pr close {}
|
||||
|
||||
# Add label to all open PRs
|
||||
gh pr list --state open --json number -q '.[].number' | \
|
||||
xargs -I {} gh pr edit {} --add-label "needs-review"
|
||||
|
||||
# Approve all PRs from specific author
|
||||
gh pr list --author username --json number -q '.[].number' | \
|
||||
xargs -I {} gh pr review {} --approve
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Creating Effective PRs
|
||||
|
||||
1. **Use descriptive titles** - Include ticket reference and clear description
|
||||
2. **Write meaningful descriptions** - Explain what, why, and how
|
||||
3. **Keep PRs focused** - One feature/fix per PR
|
||||
4. **Request specific reviewers** - Tag people with relevant expertise
|
||||
5. **Link related issues** - Use "Closes #123" in description
|
||||
|
||||
### Review Workflow
|
||||
|
||||
1. **Review promptly** - Don't let PRs sit for days
|
||||
2. **Be constructive** - Focus on code quality, not personal style
|
||||
3. **Test locally** - Use `gh pr checkout 123` to test changes
|
||||
4. **Approve clearly** - Use explicit approval, not just comments
|
||||
5. **Follow up** - Check that your feedback was addressed
|
||||
|
||||
### Automation Tips
|
||||
|
||||
1. **Use templates** - Create PR description templates
|
||||
2. **Auto-assign** - Set up CODEOWNERS for automatic reviewers
|
||||
3. **Branch protection** - Require reviews before merging
|
||||
4. **CI/CD integration** - Ensure checks pass before merge
|
||||
5. **Auto-merge** - Use `--auto` flag for trusted changes
|
||||
391
skills/github-ops/references/workflow_operations.md
Normal file
391
skills/github-ops/references/workflow_operations.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# Workflow Operations Reference
|
||||
|
||||
Comprehensive guide for GitHub Actions workflow management using gh CLI.
|
||||
|
||||
## Listing Workflows
|
||||
|
||||
### View Available Workflows
|
||||
|
||||
```bash
|
||||
# List all workflows in repository
|
||||
gh workflow list
|
||||
|
||||
# List with detailed status
|
||||
gh workflow list --all
|
||||
|
||||
# List workflows as JSON
|
||||
gh workflow list --json name,id,state,path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viewing Workflow Details
|
||||
|
||||
### Inspect Workflow Configuration
|
||||
|
||||
```bash
|
||||
# View workflow details
|
||||
gh workflow view workflow-name
|
||||
|
||||
# View workflow by ID
|
||||
gh workflow view 12345
|
||||
|
||||
# View workflow YAML
|
||||
gh workflow view workflow-name --yaml
|
||||
|
||||
# View workflow in browser
|
||||
gh workflow view workflow-name --web
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Enabling and Disabling Workflows
|
||||
|
||||
### Workflow State Management
|
||||
|
||||
```bash
|
||||
# Enable workflow
|
||||
gh workflow enable workflow-name
|
||||
|
||||
# Enable workflow by ID
|
||||
gh workflow enable 12345
|
||||
|
||||
# Disable workflow
|
||||
gh workflow disable workflow-name
|
||||
|
||||
# Disable workflow by ID
|
||||
gh workflow disable 12345
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running Workflows
|
||||
|
||||
### Manual Workflow Triggers
|
||||
|
||||
```bash
|
||||
# Run workflow manually
|
||||
gh workflow run workflow-name
|
||||
|
||||
# Run workflow on specific branch
|
||||
gh workflow run workflow-name --ref feature-branch
|
||||
|
||||
# Run workflow with inputs
|
||||
gh workflow run workflow-name -f input1=value1 -f input2=value2
|
||||
|
||||
# Run workflow with JSON inputs
|
||||
gh workflow run workflow-name \
|
||||
-f config='{"env":"production","debug":false}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viewing Workflow Runs
|
||||
|
||||
### List Workflow Runs
|
||||
|
||||
```bash
|
||||
# List all workflow runs
|
||||
gh run list
|
||||
|
||||
# List runs for specific workflow
|
||||
gh run list --workflow=workflow-name
|
||||
|
||||
# List runs with filters
|
||||
gh run list --status success
|
||||
gh run list --status failure
|
||||
gh run list --branch main
|
||||
|
||||
# List recent runs
|
||||
gh run list --limit 20
|
||||
|
||||
# List runs as JSON
|
||||
gh run list --json databaseId,status,conclusion,headBranch,event
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viewing Specific Run Details
|
||||
|
||||
### Inspect Run Information
|
||||
|
||||
```bash
|
||||
# View specific run details
|
||||
gh run view run-id
|
||||
|
||||
# View run in browser
|
||||
gh run view run-id --web
|
||||
|
||||
# View run logs
|
||||
gh run view run-id --log
|
||||
|
||||
# View failed run logs only
|
||||
gh run view run-id --log-failed
|
||||
|
||||
# Get run as JSON
|
||||
gh run view run-id --json status,conclusion,jobs,createdAt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring Runs
|
||||
|
||||
### Real-Time Monitoring
|
||||
|
||||
```bash
|
||||
# Watch workflow run in real-time
|
||||
gh run watch run-id
|
||||
|
||||
# Watch with log output
|
||||
gh run watch run-id --exit-status
|
||||
|
||||
# Watch interval (check every N seconds)
|
||||
gh run watch run-id --interval 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Downloading Artifacts and Logs
|
||||
|
||||
### Retrieve Run Data
|
||||
|
||||
```bash
|
||||
# Download workflow run logs
|
||||
gh run download run-id
|
||||
|
||||
# Download specific artifact
|
||||
gh run download run-id --name artifact-name
|
||||
|
||||
# Download to specific directory
|
||||
gh run download run-id --dir ./downloads
|
||||
|
||||
# List available artifacts
|
||||
gh run view run-id --log | grep "artifact"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Canceling and Rerunning Workflows
|
||||
|
||||
### Run Control Operations
|
||||
|
||||
```bash
|
||||
# Cancel workflow run
|
||||
gh run cancel run-id
|
||||
|
||||
# Rerun workflow
|
||||
gh run rerun run-id
|
||||
|
||||
# Rerun only failed jobs
|
||||
gh run rerun run-id --failed
|
||||
|
||||
# Rerun with debug logging
|
||||
gh run rerun run-id --debug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow Jobs
|
||||
|
||||
### Viewing Job Details
|
||||
|
||||
```bash
|
||||
# List jobs for a run
|
||||
gh api repos/{owner}/{repo}/actions/runs/{run_id}/jobs
|
||||
|
||||
# View specific job logs
|
||||
gh run view run-id --log --job job-id
|
||||
|
||||
# Download job logs
|
||||
gh api repos/{owner}/{repo}/actions/jobs/{job_id}/logs > job.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Workflow Operations
|
||||
|
||||
### Workflow Timing Analysis
|
||||
|
||||
```bash
|
||||
# Get run timing
|
||||
gh run view run-id --json createdAt,startedAt,updatedAt,conclusion
|
||||
|
||||
# List slow runs
|
||||
gh run list --workflow=ci --json databaseId,createdAt,updatedAt | \
|
||||
jq '.[] | select((.updatedAt | fromdate) - (.createdAt | fromdate) > 600)'
|
||||
```
|
||||
|
||||
### Workflow Success Rate
|
||||
|
||||
```bash
|
||||
# Calculate success rate for workflow
|
||||
gh run list --workflow=ci --limit 100 --json conclusion | \
|
||||
jq '[.[] | .conclusion] | group_by(.) | map({conclusion: .[0], count: length})'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
### Managing Multiple Runs
|
||||
|
||||
```bash
|
||||
# Cancel all running workflows
|
||||
gh run list --status in_progress --json databaseId -q '.[].databaseId' | \
|
||||
xargs -I {} gh run cancel {}
|
||||
|
||||
# Rerun all failed runs from today
|
||||
gh run list --status failure --created today --json databaseId -q '.[].databaseId' | \
|
||||
xargs -I {} gh run rerun {}
|
||||
|
||||
# Download artifacts from multiple runs
|
||||
gh run list --workflow=build --limit 5 --json databaseId -q '.[].databaseId' | \
|
||||
xargs -I {} gh run download {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow Secrets and Variables
|
||||
|
||||
### Managing Secrets (via API)
|
||||
|
||||
```bash
|
||||
# List repository secrets
|
||||
gh api repos/{owner}/{repo}/actions/secrets
|
||||
|
||||
# Create/update secret
|
||||
gh secret set SECRET_NAME --body "secret-value"
|
||||
|
||||
# Create secret from file
|
||||
gh secret set SECRET_NAME < secret.txt
|
||||
|
||||
# Delete secret
|
||||
gh secret delete SECRET_NAME
|
||||
|
||||
# List secrets
|
||||
gh secret list
|
||||
```
|
||||
|
||||
### Managing Variables
|
||||
|
||||
```bash
|
||||
# List repository variables
|
||||
gh variable list
|
||||
|
||||
# Set variable
|
||||
gh variable set VAR_NAME --body "value"
|
||||
|
||||
# Delete variable
|
||||
gh variable delete VAR_NAME
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow Dispatch Events
|
||||
|
||||
### Triggering with workflow_dispatch
|
||||
|
||||
Example workflow file configuration:
|
||||
```yaml
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Deployment environment'
|
||||
required: true
|
||||
default: 'staging'
|
||||
type: choice
|
||||
options:
|
||||
- staging
|
||||
- production
|
||||
debug:
|
||||
description: 'Enable debug mode'
|
||||
required: false
|
||||
type: boolean
|
||||
```
|
||||
|
||||
Trigger with inputs:
|
||||
```bash
|
||||
gh workflow run deploy.yml \
|
||||
-f environment=production \
|
||||
-f debug=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring and Debugging
|
||||
|
||||
### Common Debugging Techniques
|
||||
|
||||
```bash
|
||||
# View recent failures
|
||||
gh run list --status failure --limit 10
|
||||
|
||||
# Check specific run logs
|
||||
gh run view run-id --log-failed
|
||||
|
||||
# Download logs for analysis
|
||||
gh run download run-id
|
||||
|
||||
# Rerun with debug logging
|
||||
gh run rerun run-id --debug
|
||||
|
||||
# Check workflow syntax
|
||||
gh workflow view workflow-name --yaml
|
||||
```
|
||||
|
||||
### Workflow Performance Monitoring
|
||||
|
||||
```bash
|
||||
# Get average run duration
|
||||
gh run list --workflow=ci --limit 50 --json createdAt,updatedAt | \
|
||||
jq '[.[] | ((.updatedAt | fromdate) - (.createdAt | fromdate))] | add / length'
|
||||
|
||||
# Find longest running jobs
|
||||
gh api repos/{owner}/{repo}/actions/runs/{run_id}/jobs | \
|
||||
jq '.jobs | sort_by(.started_at) | reverse | .[0:5]'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Workflow Organization
|
||||
|
||||
1. **Use descriptive names** - Make workflow purpose clear
|
||||
2. **Modular workflows** - Break complex workflows into reusable actions
|
||||
3. **Cache dependencies** - Speed up builds with caching
|
||||
4. **Matrix strategies** - Test across multiple environments
|
||||
5. **Workflow dependencies** - Use `needs` to control execution order
|
||||
|
||||
### Workflow Triggers
|
||||
|
||||
1. **Selective triggers** - Use path filters to run only when needed
|
||||
2. **Schedule wisely** - Avoid resource waste with cron triggers
|
||||
3. **Manual triggers** - Provide workflow_dispatch for flexibility
|
||||
4. **PR workflows** - Separate validation from deployment
|
||||
5. **Branch protection** - Require status checks before merge
|
||||
|
||||
### Secrets Management
|
||||
|
||||
1. **Use secrets** - Never hardcode credentials
|
||||
2. **Scope appropriately** - Use environment-specific secrets
|
||||
3. **Rotate regularly** - Update secrets periodically
|
||||
4. **Audit access** - Review who can access secrets
|
||||
5. **Use OIDC** - Prefer token-less authentication when possible
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
1. **Conditional execution** - Skip unnecessary jobs
|
||||
2. **Parallel jobs** - Run independent jobs concurrently
|
||||
3. **Artifact management** - Clean up old artifacts
|
||||
4. **Self-hosted runners** - Use for resource-intensive workloads
|
||||
5. **Job timeouts** - Set reasonable timeout limits
|
||||
|
||||
### Monitoring and Alerts
|
||||
|
||||
1. **Enable notifications** - Get alerted on failures
|
||||
2. **Status badges** - Display workflow status in README
|
||||
3. **Metrics tracking** - Monitor success rates and duration
|
||||
4. **Log retention** - Configure appropriate retention policies
|
||||
5. **Dependency updates** - Automate with Dependabot
|
||||
Reference in New Issue
Block a user