
Cli Gh
- 2.4k installs
- 68 repo stars
- Updated July 30, 2026
- paulrberg/agent-skills
cli-gh is an agent skill that Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, .
About
Expert guidance for GitHub CLI gh operations and workflows Use this skill for command line GitHub operations including pull request management issue tracking repository operations workflow automation and codespace management Create and manage pull requests from the terminal Track and organize issues efficiently Search across all of GitHub repos issues PRs Manage labels and project organization Trigger and monitor GitHub Actions workflows Work with codespaces Automate repository operations and releases Browse repositories PRs and files in the browser CRITICAL This skill NEVER uses destructive gh CLI operations This skill focuses exclusively on safe read only or reversible GitHub operations The following commands are PROHIBITED and must NEVER be used gh repo delete Repository deletion gh repo archive Repository archival gh release delete Release deletion gh release delete asset Asset deletion gh run delete Workflow run deletion gh cache delete Cache deletion gh secret delete Secret deletion gh variable delete Variable deletion gh label delete Label deletion gh ssh key delete SSH key deletion can lock out users gh gpg key
- description: 'Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR st
- Expert guidance for GitHub CLI (gh) operations and workflows. Use this skill for command-line GitHub operations includin
- - Create and manage pull requests from the terminal
- Follow cli-gh SKILL.md steps and documented constraints.
- Follow cli-gh SKILL.md steps and documented constraints.
Cli Gh by the numbers
- 2,387 all-time installs (skills.sh)
- +63 installs in the week ending Jul 29, 2026 (Skillselion tracking)
- Ranked #341 of 16,565 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 31, 2026 (Skillselion catalog sync)
cli-gh capabilities & compatibility
- Capabilities
- description: 'use for github cli automation: gh · expert guidance for github cli (gh) operations a · create and manage pull requests from the termi · follow cli gh skill.md steps and documented cons
- Use cases
- orchestration
What cli-gh says it does
description: 'Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, repo browsing, or command-line GitHub tasks.'
Expert guidance for GitHub CLI (gh) operations and workflows. Use this skill for command-line GitHub operations including pull request management, issue tracking, repository operations, workflow autom
- Create and manage pull requests from the terminal
npx skills add https://github.com/paulrberg/agent-skills --skill cli-ghAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.4k |
|---|---|
| repo stars | ★ 68 |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 30, 2026 |
| Repository | paulrberg/agent-skills ↗ |
When should an agent use cli-gh and what problem does it solve?
Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, repo browsing, or command-line GitHub tasks.
Who is it for?
Developers invoking cli-gh as documented in the skill source.
Skip if: Skip when requirements fall outside cli-gh documented scope.
When should I use this skill?
Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, repo browsing, or command-line GitHub tasks.
What you get
Outputs aligned with the cli-gh SKILL.md workflow and stated deliverables.
- Feature branch
- GitHub pull request
Files
GitHub CLI (gh)
Overview
Expert guidance for GitHub CLI (gh) operations and workflows. Use this skill for command-line GitHub operations including pull request management, issue tracking, repository operations, workflow automation, and codespace management.
Key capabilities:
- Create and manage pull requests from the terminal
- Track and organize issues efficiently
- Search across all of GitHub (repos, issues, PRs)
- Manage labels and project organization
- Trigger and monitor GitHub Actions workflows
- Work with codespaces
- Automate repository operations and releases
- Browse repositories, PRs, and files in the browser
Safety Rules
CRITICAL: This skill NEVER uses destructive gh CLI operations.
This skill focuses exclusively on safe, read-only, or reversible GitHub operations. The following commands are PROHIBITED and must NEVER be used:
Permanently destructive commands:
gh repo delete- Repository deletiongh repo archive- Repository archivalgh release delete- Release deletiongh release delete-asset- Asset deletiongh run delete- Workflow run deletiongh cache delete- Cache deletiongh secret delete- Secret deletiongh variable delete- Variable deletiongh label delete- Label deletiongh ssh-key delete- SSH key deletion (can lock out users)gh gpg-key delete- GPG key deletiongh codespace delete- Codespace deletiongh extension remove- Extension removalgh gist delete- Gist deletion- Bulk deletion operations using
xargswith any destructive commands - Shell commands:
rm -rf(except for temporary file cleanup)
Allowed operations:
- Creating resources (PRs, issues, releases, labels, repos)
- Viewing and listing (status, logs, information, searches)
- Updating and editing existing resources
- Closing PRs/issues (reversible - can be reopened)
- Reverting pull requests (creates a new revert PR)
- Canceling workflow runs (stops execution without deleting data)
- Merging pull requests (after proper review)
- Read-only git operations (
git status,git log,git diff)
Installation & Setup
# Login to GitHub
gh auth login
# Login and copy OAuth code to clipboard automatically
gh auth login --clipboard
# Check authentication status
gh auth status
# Check auth status with JSON output
gh auth status --json
# Configure git to use gh as credential helper
gh auth setup-gitPull Requests
Creating PRs
# Create PR interactively
gh pr create
# Create PR with title and body
gh pr create --title "Add feature" --body "Description"
# Create PR to specific branch
gh pr create --base main --head feature-branch
# Create draft PR
gh pr create --draft
# Create PR from current branch
gh pr create --fill # Uses commit messages
# Create PR with Copilot Code Review
gh pr create --reviewer @copilotViewing PRs
# List PRs
gh pr list
# List my PRs
gh pr list --author @me
# View PR details
gh pr view 123
# View PR in browser
gh pr view 123 --web
# View PR diff
gh pr diff 123
# View PR diff excluding specific files
gh pr diff 123 --exclude "*.lock"
# Check PR status
gh pr statusManaging PRs
# Checkout PR locally
gh pr checkout 123
# Review PR
gh pr review 123 --approve
gh pr review 123 --comment --body "Looks good!"
gh pr review 123 --request-changes --body "Please fix X"
# Request Copilot Code Review
gh pr edit 123 --add-reviewer @copilot
# Merge PR
gh pr merge 123
gh pr merge 123 --squash
gh pr merge 123 --rebase
gh pr merge 123 --merge
# Close PR
gh pr close 123
# Reopen PR
gh pr reopen 123
# Ready draft PR
gh pr ready 123
# Update PR branch with base branch
gh pr update-branch 123
# Revert a merged PR (creates a new revert PR)
gh pr revert 123PR Checks
# View PR checks
gh pr checks 123
# Watch PR checks
gh pr checks 123 --watchIssues
Creating Issues
# Create issue interactively
gh issue create
# Create issue with title and body
gh issue create --title "Bug report" --body "Description"
# Use a Markdown issue template as interactive/editor starting body text
gh issue create --template "Bug Report"
# Create issue with labels
gh issue create --title "Bug" --label bug,critical
# Assign issue
gh issue create --title "Task" --assignee @me
# Set the issue type (GitHub.com and GHES 3.17+)
gh issue create --type Bug--template cannot be combined with --body or --body-file; use it with prompts, --editor, or --web. For YAML issue forms, fetch and render the form fields yourself for non-interactive automation, or finish in the browser.
Viewing Issues
# List issues
gh issue list
# List my issues
gh issue list --assignee @me
# List by label
gh issue list --label bug
# Filter by issue type
gh issue list --type Bug
# Advanced issue search
gh issue list --search "is:open label:bug sort:created-desc"
# View issue details
gh issue view 456
# View in browser
gh issue view 456 --webManaging Issues
# Close issue
gh issue close 456
# Close as duplicate, linking to the original issue
gh issue close 123 --duplicate-of 456
# Reopen issue
gh issue reopen 456
# Edit issue
gh issue edit 456 --title "New title"
gh issue edit 456 --add-label bug
gh issue edit 456 --add-assignee @user
# Comment on issue
gh issue comment 456 --body "Update"
# Create branch to work on issue
gh issue develop 456 --checkoutIssue Types, Sub-Issues & Relationships
Issue types and sub-issues require GitHub.com or GHES 3.17+; blocking relationships require GHES 3.19+.
# Set or remove the issue type
gh issue edit 456 --type Bug
gh issue edit 456 --remove-type
# Create a sub-issue under a parent
gh issue create --parent 100
# Organize existing issues into a parent/child hierarchy
gh issue edit 100 --add-sub-issue 123,124
gh issue edit 100 --remove-sub-issue 123
gh issue edit 123 --parent 100
gh issue edit 123 --remove-parent
# Track blocked-by / blocking relationships
gh issue create --blocked-by 200,201 --blocking 300
gh issue edit 123 --add-blocked-by 200 --add-blocking 300,301
gh issue edit 123 --remove-blocked-by 200 --remove-blocking 301Discussions
When the user asks to list, view, create, edit, or comment on GitHub Discussions, see references/discussions.md. The gh discussion command set is in preview and subject to change.
Copilot Agent Tasks
Delegate work to the Copilot coding agent and track its sessions. The gh agent-task command set (aliases gh agent, gh agents) is in preview.
# Create an agent task on the current repository
gh agent-task create "Improve the performance of the data processing pipeline"
# List your most recent agent tasks
gh agent-task list
gh agent-task list --json id,name,state
# View an agent task session (by PR number, session ID, or URL)
gh agent-task view 123
gh agent-task view <session-id> --json state --jq '.state'Agent Skills
Discover, install, and publish agent skills from GitHub repositories. The gh skill command set (alias gh skills) is in preview.
# Search for skills across GitHub
gh skill search terraform
# Preview a skill before installing
gh skill preview github/awesome-copilot documentation-writer
# Install a skill (default scope: project)
gh skill install github/awesome-copilot documentation-writer
gh skill install owner/repo skill-name --scope user --pin v1.2.0
# Include skills in hidden dirs (.claude/skills/, .agents/skills/, .github/skills/)
gh skill install owner/repo skill-name --allow-hidden-dirs
# List installed skills and update them
gh skill list
gh skill update --all
# Validate and publish your own skills
gh skill publish --dry-runRepository Operations
Repository Info
# View repository
gh repo view
# View in browser
gh repo view --web
# Clone repository
gh repo clone owner/repo
# Clone without adding upstream remote
gh repo clone owner/repo --no-upstream
# Fork repository
gh repo fork owner/repo
# List repositories
gh repo list ownerRepository Management
# Create repository
gh repo create my-repo --public
gh repo create my-repo --private
# Sync fork
gh repo sync owner/repo
# Set default repository
gh repo set-default
# Configure the squash-merge commit message default
gh repo edit --squash-merge-commit-message COMMIT_MESSAGESReading Repo Contents
Read files and directories without cloning. The gh repo read-file and gh repo read-dir commands are in preview and subject to change.
# Read a file from the default branch (paged in a TTY, raw when piped)
gh repo read-file README.md --repo cli/cli
# Read from a specific branch, tag, or commit
gh repo read-file go.mod --ref v2.94.0 --repo cli/cli
# Write to disk instead of stdout (--clobber to overwrite)
gh repo read-file README.md --output ./README.md --clobber
# Refuse escape sequences by default; opt in for TTY/piped output
gh repo read-file script.sh --allow-escape-sequences
# List a directory (root when no path given)
gh repo read-dir script --repo cli/cli
# Inspect entries as JSON for scripting
gh repo read-dir docs --repo cli/cli --json name,path,type,sizeSearch
When the user asks to search GitHub repositories, issues, or pull requests, see references/search.md.
Labels
When the user asks to list, create, edit, or clone repository labels, see references/labels.md.
Codespaces
When the user asks to list, create, connect to, or manage files within GitHub Codespaces, see references/codespaces.md.
Browse
Open repositories, files, and resources in the browser.
# Open current repo in browser
gh browse
# Open specific file
gh browse src/main.go
# Open file at specific line
gh browse src/main.go:42
# Open blame view for a file
gh browse --blame src/main.go
# Open Actions tab
gh browse --actions
# Open specific branch
gh browse --branch featureReleases
When the user asks to create, list, view, or download GitHub releases, see references/releases.md.
Gists
When the user asks to create, list, view, or edit GitHub gists, see references/gists.md.
Configuration
# Set default editor
gh config set editor vim
# Set default git protocol
gh config set git_protocol ssh
# View configuration
gh config list
# Set browser
gh config set browser firefoxQuick Reference
Common gh operations at a glance:
| Operation | Command | Common Flags |
|---|---|---|
| Create PR | gh pr create | --draft, --fill, --reviewer @copilot |
| List PRs | gh pr list | --author @me, --label, --search |
| View PR | gh pr view <number> | --web, --comments |
| Merge PR | gh pr merge <number> | --squash, --rebase, --delete-branch |
| Revert PR | gh pr revert <number> | --body |
| Create issue | gh issue create | --title, --body, --template, --type |
| List issues | gh issue list | --assignee @me, --label, --type |
| Close issue | gh issue close <number> | --duplicate-of, --reason |
| View issue | gh issue view <number> | --web, --comments |
| Link sub-issue | gh issue edit <number> | --parent, --add-sub-issue |
| Block issue | gh issue edit <number> | --add-blocked-by, --add-blocking |
| List discussions | gh discussion list | --answered, --sort, --json |
| Create agent task | gh agent-task create | --json (on list/view) |
| Install skill | gh skill install | --scope, --pin, --allow-hidden-dirs |
| Browse repo | gh browse | --blame, --actions, --branch |
| Clone repo | gh repo clone <repo> | --no-upstream |
| Fork repo | gh repo fork | --clone, --remote |
| View repo | gh repo view | --web |
| Read repo file | gh repo read-file <path> | --ref, --output, --clobber, --json |
| Read repo dir | gh repo read-dir [path] | --ref, --json |
| Create release | gh release create <tag> | --title, --notes, --draft |
| Verify release | gh release verify <tag> | --repo |
| Run workflow | gh workflow run <name> | --ref, --field |
| Watch run | gh run watch <id> | --exit-status |
| Search repos | gh search repos <query> | --language, --stars |
| Create label | gh label create <name> | --color, --description |
| Create codespace | gh codespace create | --repo, --branch |
Additional Resources
Reference Guides
For detailed patterns and advanced usage, see:
- [Discussions](references/discussions.md) - List, view, create, edit, and comment on GitHub Discussions (preview)
- [Workflows & Actions](references/workflows-actions.md) - GitHub Actions workflows, runs, cache management, and CI/CD integration patterns
- [Advanced Features](references/advanced-features.md) - Aliases, API access, extensions, secrets, SSH/GPG keys, organizations, projects, and advanced scripting
- [Automation Workflows](references/automation-workflows.md) - Common automation patterns, daily reports, release automation, and team collaboration workflows
- [Troubleshooting](references/troubleshooting.md) - Solutions for authentication, permissions, rate limiting, and common errors
Example Scripts
Practical automation scripts (see examples/ directory):
auto-pr-create.sh- Automated PR creation workflowissue-triage.sh- Bulk issue labeling and assignmentworkflow-monitor.sh- Watch and notify on workflow completionrelease-automation.sh- Complete release workflow automation
External Documentation
- Official Manual: https://cli.github.com/manual
- GitHub Community: https://github.com/cli/cli/discussions
- API Documentation: https://docs.github.com/en/rest
- Extension Marketplace: https://github.com/topics/gh-extension
JSON Output
When the user wants to use --json flags or needs the correct gh CLI JSON field names, see references/json-output.md.
Tips
1. Use --web flag to open items in browser for detailed view 2. Leverage interactive prompts by omitting parameters - most commands support interactive mode 3. Apply filters with --author, --label, --state to narrow down lists efficiently 4. Add --json flag to enable scriptable output for automation 5. Always check `--help` for valid JSON field names - they differ from GitHub API 6. Use gh repo create --template to scaffold from template repositories 7. Enable auto-merge with gh pr merge --auto for PRs that pass checks
policy:
allow_implicit_invocation: true
#!/usr/bin/env bash
# auto-pr-create.sh - Automated Pull Request Creation
# Usage: ./auto-pr-create.sh [branch-name] [--draft]
set -euo pipefail
# Configuration
DEFAULT_BASE="main"
DRAFT_FLAG=""
BRANCH_NAME="${1:-}"
# Parse arguments
for arg in "$@"; do
case $arg in
--draft)
DRAFT_FLAG="--draft"
shift
;;
esac
done
# Function to generate branch name from ticket/issue
generate_branch_name() {
echo "Enter issue/ticket number (or leave empty):"
read -r ISSUE_NUM
echo "Brief description (kebab-case):"
read -r DESCRIPTION
if [ -n "$ISSUE_NUM" ]; then
echo "issue-${ISSUE_NUM}-${DESCRIPTION}"
else
echo "${DESCRIPTION}"
fi
}
# Get or generate branch name
if [ -z "$BRANCH_NAME" ]; then
BRANCH_NAME=$(generate_branch_name)
fi
# Determine PR labels based on branch name
determine_labels() {
local branch=$1
local labels=()
case "$branch" in
*bug*|*fix*)
labels+=("bug")
;;
*feat*|*feature*)
labels+=("enhancement")
;;
*docs*|*documentation*)
labels+=("documentation")
;;
*test*)
labels+=("tests")
;;
*refactor*)
labels+=("refactoring")
;;
esac
# Join labels with comma
IFS=','
echo "${labels[*]}"
}
# Check if on correct branch
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "$BRANCH_NAME" ]; then
echo "Creating and switching to branch: $BRANCH_NAME"
git checkout -b "$BRANCH_NAME"
else
echo "Already on branch: $BRANCH_NAME"
fi
# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo "⚠️ You have uncommitted changes. Commit them first."
exit 1
fi
# Push branch to remote
echo "Pushing branch to remote..."
git push -u origin "$BRANCH_NAME"
# Determine labels
LABELS=$(determine_labels "$BRANCH_NAME")
# Create PR with smart defaults
echo "Creating pull request..."
PR_ARGS=(
"--base" "$DEFAULT_BASE"
"--head" "$BRANCH_NAME"
"--fill" # Auto-fill from commits
)
# Add draft flag if specified
if [ -n "$DRAFT_FLAG" ]; then
PR_ARGS+=("$DRAFT_FLAG")
fi
# Add labels if any
if [ -n "$LABELS" ]; then
PR_ARGS+=("--label" "$LABELS")
fi
# Create PR and capture URL
PR_URL=$(gh pr create "${PR_ARGS[@]}")
echo "✅ Pull request created: $PR_URL"
# Optionally open in browser
read -p "Open PR in browser? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
gh pr view --web
fi
#!/usr/bin/env bash
# issue-triage.sh - Bulk Issue Labeling and Assignment
# Usage: ./issue-triage.sh [--repo owner/repo]
set -euo pipefail
# Configuration
REPO=""
DRY_RUN=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--repo)
REPO="$2"
shift 2
;;
--dry-run)
DRY_RUN=true
shift
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Set repo context
if [ -n "$REPO" ]; then
REPO_FLAG="--repo $REPO"
else
REPO_FLAG=""
fi
# Function to apply triage rules
triage_issues() {
echo "🔍 Fetching unlabeled issues..."
# Get all unlabeled issues
ISSUES=$(gh issue list $REPO_FLAG --label="" --limit 100 --json number,title,body,author)
if [ -z "$ISSUES" ] || [ "$ISSUES" = "[]" ]; then
echo "No unlabeled issues found."
return
fi
echo "Found $(echo "$ISSUES" | jq 'length') unlabeled issues"
echo ""
# Process each issue
echo "$ISSUES" | jq -c '.[]' | while read -r issue; do
NUMBER=$(echo "$issue" | jq -r '.number')
TITLE=$(echo "$issue" | jq -r '.title')
BODY=$(echo "$issue" | jq -r '.body // ""')
AUTHOR=$(echo "$issue" | jq -r '.author.login')
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Issue #$NUMBER: $TITLE"
echo "Author: $AUTHOR"
LABELS=()
ASSIGNEE=""
# Auto-label based on keywords
if echo "$TITLE $BODY" | grep -qi "bug\|error\|crash\|broken"; then
LABELS+=("bug")
fi
if echo "$TITLE $BODY" | grep -qi "feat\|feature\|enhance"; then
LABELS+=("enhancement")
fi
if echo "$TITLE $BODY" | grep -qi "doc\|documentation"; then
LABELS+=("documentation")
fi
if echo "$TITLE $BODY" | grep -qi "security\|vulnerability"; then
LABELS+=("security")
LABELS+=("priority: high")
fi
if echo "$TITLE $BODY" | grep -qi "performance\|slow\|optimize"; then
LABELS+=("performance")
fi
if echo "$TITLE $BODY" | grep -qi "question\|how to\|help"; then
LABELS+=("question")
fi
# Priority detection
if echo "$TITLE $BODY" | grep -qi "urgent\|critical\|asap"; then
LABELS+=("priority: high")
fi
# Check if first-time contributor
CONTRIB_COUNT=$(gh api "/repos/{owner}/{repo}/issues?creator=$AUTHOR&state=all&per_page=100" $REPO_FLAG | jq 'length')
if [ "$CONTRIB_COUNT" -eq 1 ]; then
LABELS+=("good first issue")
echo "👋 First-time contributor!"
fi
# Apply labels
if [ ${#LABELS[@]} -gt 0 ]; then
LABEL_STR=$(IFS=,; echo "${LABELS[*]}")
echo "📝 Suggested labels: $LABEL_STR"
if [ "$DRY_RUN" = false ]; then
gh issue edit "$NUMBER" $REPO_FLAG --add-label "$LABEL_STR"
echo "✅ Labels applied"
else
echo "🔍 [DRY RUN] Would apply labels: $LABEL_STR"
fi
else
echo "⚠️ No automatic labels identified"
fi
echo ""
done
}
# Function to assign stale issues
assign_stale_issues() {
echo "🕐 Finding stale issues without assignees..."
# Issues older than 7 days without assignee
STALE=$(gh issue list $REPO_FLAG --json number,title,createdAt,assignees --jq '.[] | select(.assignees | length == 0) | select(.createdAt | fromdateiso8601 < (now - 604800)) | .number')
if [ -z "$STALE" ]; then
echo "No stale unassigned issues found."
return
fi
echo "Found stale issues: $STALE"
echo "Enter assignee username (or leave empty to skip):"
read -r ASSIGNEE
if [ -n "$ASSIGNEE" ]; then
for issue_num in $STALE; do
if [ "$DRY_RUN" = false ]; then
gh issue edit "$issue_num" $REPO_FLAG --add-assignee "$ASSIGNEE"
echo "✅ Assigned #$issue_num to $ASSIGNEE"
else
echo "🔍 [DRY RUN] Would assign #$issue_num to $ASSIGNEE"
fi
done
fi
}
# Function to close duplicate issues
close_duplicates() {
echo "🔍 Finding potential duplicates..."
# This is a simplified approach - in production, use semantic matching
ISSUES=$(gh issue list $REPO_FLAG --limit 100 --json number,title --state open)
echo "$ISSUES" | jq -r '.[] | "\(.number)|\(.title)"' | sort -t'|' -k2 | \
awk -F'|' 'prev==$2 {print prev_num, $1} {prev=$2; prev_num=$1}' | \
while read -r dup_pair; do
if [ -n "$dup_pair" ]; then
echo "Potential duplicates: $dup_pair"
echo "Review manually and close if needed"
fi
done
}
# Main menu
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "GitHub Issue Triage Tool"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "1) Auto-label unlabeled issues"
echo "2) Assign stale issues"
echo "3) Find duplicate issues"
echo "4) Run all"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
read -p "Select option (1-4): " -n 1 -r OPTION
echo ""
case $OPTION in
1)
triage_issues
;;
2)
assign_stale_issues
;;
3)
close_duplicates
;;
4)
triage_issues
echo ""
assign_stale_issues
echo ""
close_duplicates
;;
*)
echo "Invalid option"
exit 1
;;
esac
echo ""
echo "✅ Triage complete!"
#!/usr/bin/env bash
# release-automation.sh - Complete Release Workflow Automation
# Usage: ./release-automation.sh <version> [--draft] [--prerelease]
set -euo pipefail
# Configuration
VERSION="${1:-}"
DRAFT_FLAG=""
PRERELEASE_FLAG=""
BUILD_DIR="dist"
# Parse arguments
shift || true
for arg in "$@"; do
case $arg in
--draft)
DRAFT_FLAG="--draft"
;;
--prerelease)
PRERELEASE_FLAG="--prerelease"
;;
--build-dir=*)
BUILD_DIR="${arg#*=}"
;;
esac
done
# Validate version provided
if [ -z "$VERSION" ]; then
echo "❌ Error: Version required"
echo "Usage: $0 <version> [--draft] [--prerelease]"
echo "Example: $0 1.2.0"
exit 1
fi
# Normalize version (add 'v' prefix if not present)
if [[ ! $VERSION =~ ^v ]]; then
VERSION="v$VERSION"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Release Automation: $VERSION"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Step 1: Pre-flight checks
echo "1️⃣ Running pre-flight checks..."
# Check we're on main/master
CURRENT_BRANCH=$(git branch --show-current)
if [[ ! $CURRENT_BRANCH =~ ^(main|master)$ ]]; then
echo "⚠️ Warning: You're on branch '$CURRENT_BRANCH', not main/master"
read -p "Continue anyway? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo "❌ Error: You have uncommitted changes"
git status --short
exit 1
fi
# Check if tag already exists
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "❌ Error: Tag $VERSION already exists"
exit 1
fi
# Pull latest changes
echo "Pulling latest changes..."
git pull origin "$CURRENT_BRANCH"
echo "✅ Pre-flight checks passed"
echo ""
# Step 2: Run tests (if test command exists)
echo "2️⃣ Running tests..."
if [ -f "package.json" ] && jq -e '.scripts.test' package.json >/dev/null 2>&1; then
npm test
elif [ -f "Makefile" ] && grep -q "^test:" Makefile; then
make test
elif [ -f "pytest.ini" ] || [ -f "setup.py" ]; then
pytest
else
echo "⚠️ No test command found, skipping..."
fi
echo "✅ Tests passed"
echo ""
# Step 3: Build project (if build command exists)
echo "3️⃣ Building project..."
if [ -f "package.json" ] && jq -e '.scripts.build' package.json >/dev/null 2>&1; then
npm run build
elif [ -f "Makefile" ] && grep -q "^build:" Makefile; then
make build
else
echo "⚠️ No build command found, skipping..."
fi
echo "✅ Build complete"
echo ""
# Step 4: Update version in files
echo "4️⃣ Updating version in project files..."
VERSION_NUM="${VERSION#v}" # Remove 'v' prefix
if [ -f "package.json" ]; then
jq ".version = \"$VERSION_NUM\"" package.json > package.json.tmp
mv package.json.tmp package.json
echo "Updated package.json"
fi
if [ -f "pyproject.toml" ]; then
sed -i.bak "s/^version = .*/version = \"$VERSION_NUM\"/" pyproject.toml
rm -f pyproject.toml.bak
echo "Updated pyproject.toml"
fi
# Commit version bump if files were modified
if ! git diff-index --quiet HEAD --; then
git add -A
git commit -m "chore: bump version to $VERSION"
git push origin "$CURRENT_BRANCH"
echo "✅ Version bump committed"
fi
echo ""
# Step 5: Create git tag
echo "5️⃣ Creating git tag..."
git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"
echo "✅ Tag created and pushed"
echo ""
# Step 6: Generate release notes
echo "6️⃣ Generating release notes..."
# Get commits since last tag
LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
RELEASE_NOTES=$(git log "$LAST_TAG..HEAD" --pretty=format:"- %s (%h)" --reverse)
else
RELEASE_NOTES=$(git log --pretty=format:"- %s (%h)" --reverse)
fi
# Save to temporary file
NOTES_FILE=$(mktemp)
cat > "$NOTES_FILE" <<EOF
## What's Changed
$RELEASE_NOTES
## Installation
```bash
# Install via package manager
npm install package@$VERSION_NUM
# Or download from releases
gh release download $VERSION
```
---
**Full Changelog**: https://github.com/$(gh repo view --json nameWithOwner -q '.nameWithOwner')/compare/${LAST_TAG}...${VERSION}
EOF
echo "✅ Release notes generated"
echo ""
# Step 7: Create GitHub release
echo "7️⃣ Creating GitHub release..."
RELEASE_ARGS=(
"$VERSION"
"--title" "$VERSION"
"--notes-file" "$NOTES_FILE"
)
# Add draft/prerelease flags
if [ -n "$DRAFT_FLAG" ]; then
RELEASE_ARGS+=("$DRAFT_FLAG")
fi
if [ -n "$PRERELEASE_FLAG" ]; then
RELEASE_ARGS+=("$PRERELEASE_FLAG")
fi
# Create release
RELEASE_URL=$(gh release create "${RELEASE_ARGS[@]}")
echo "✅ Release created: $RELEASE_URL"
echo ""
# Step 8: Upload artifacts (if build directory exists)
if [ -d "$BUILD_DIR" ] && [ -n "$(ls -A "$BUILD_DIR")" ]; then
echo "8️⃣ Uploading build artifacts..."
gh release upload "$VERSION" "$BUILD_DIR"/*
echo "✅ Artifacts uploaded"
else
echo "8️⃣ No build artifacts found in $BUILD_DIR, skipping upload..."
fi
echo ""
# Cleanup
rm -f "$NOTES_FILE"
# Final summary
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Release $VERSION Complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📋 Summary:"
echo " • Tag: $VERSION"
echo " • Branch: $CURRENT_BRANCH"
echo " • URL: $RELEASE_URL"
echo ""
echo "Next steps:"
echo " • Announce the release"
echo " • Update documentation if needed"
echo " • Monitor for issues"
echo ""
# Optionally open release in browser
read -p "Open release in browser? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
gh release view "$VERSION" --web
fi
#!/usr/bin/env bash
# workflow-monitor.sh - Watch and Notify on Workflow Completion
# Usage: ./workflow-monitor.sh [run-id] [--notify]
set -euo pipefail
# Configuration
RUN_ID="${1:-}"
NOTIFY=false
CHECK_INTERVAL=30 # seconds
# Parse arguments
for arg in "$@"; do
case $arg in
--notify)
NOTIFY=true
;;
--interval=*)
CHECK_INTERVAL="${arg#*=}"
;;
esac
done
# Function to send notification (macOS)
send_notification() {
local title="$1"
local message="$2"
local sound="${3:-default}"
if command -v terminal-notifier &> /dev/null; then
terminal-notifier -title "$title" -message "$message" -sound "$sound"
elif command -v osascript &> /dev/null; then
osascript -e "display notification \"$message\" with title \"$title\""
else
echo "🔔 $title: $message"
fi
}
# Function to get workflow run status
get_run_status() {
local run_id=$1
gh run view "$run_id" --json status,conclusion,displayTitle,workflowName --jq '{status, conclusion, title: .displayTitle, workflow: .workflowName}'
}
# Function to watch a single run
watch_run() {
local run_id=$1
echo "👀 Watching run #$run_id..."
# Get initial info
RUN_INFO=$(get_run_status "$run_id")
WORKFLOW=$(echo "$RUN_INFO" | jq -r '.workflow')
TITLE=$(echo "$RUN_INFO" | jq -r '.title')
echo "Workflow: $WORKFLOW"
echo "Title: $TITLE"
echo ""
# Watch until complete
while true; do
STATUS=$(echo "$RUN_INFO" | jq -r '.status')
CONCLUSION=$(echo "$RUN_INFO" | jq -r '.conclusion')
if [ "$STATUS" = "completed" ]; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
case $CONCLUSION in
success)
echo "✅ Workflow completed successfully!"
if [ "$NOTIFY" = true ]; then
send_notification "✅ Workflow Success" "$WORKFLOW: $TITLE" "Glass"
fi
;;
failure)
echo "❌ Workflow failed!"
if [ "$NOTIFY" = true ]; then
send_notification "❌ Workflow Failed" "$WORKFLOW: $TITLE" "Basso"
fi
# Show failed jobs
echo ""
echo "Failed jobs:"
gh run view "$run_id" --json jobs --jq '.jobs[] | select(.conclusion == "failure") | " - \(.name)"'
;;
cancelled)
echo "🚫 Workflow was cancelled"
if [ "$NOTIFY" = true ]; then
send_notification "🚫 Workflow Cancelled" "$WORKFLOW: $TITLE"
fi
;;
*)
echo "⚠️ Workflow completed with status: $CONCLUSION"
if [ "$NOTIFY" = true ]; then
send_notification "⚠️ Workflow $CONCLUSION" "$WORKFLOW: $TITLE"
fi
;;
esac
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "View details: gh run view $run_id --web"
break
else
# Show progress
printf "\r🔄 Status: %s... (checking every %ds)" "$STATUS" "$CHECK_INTERVAL"
sleep "$CHECK_INTERVAL"
RUN_INFO=$(get_run_status "$run_id")
fi
done
}
# Function to watch latest run for a workflow
watch_latest_workflow() {
local workflow_name="$1"
echo "Finding latest run for workflow: $workflow_name"
LATEST_RUN=$(gh run list --workflow="$workflow_name" --limit 1 --json databaseId --jq '.[0].databaseId')
if [ -z "$LATEST_RUN" ] || [ "$LATEST_RUN" = "null" ]; then
echo "❌ No runs found for workflow: $workflow_name"
exit 1
fi
watch_run "$LATEST_RUN"
}
# Function to show active runs and let user select
interactive_select() {
echo "Active workflow runs:"
echo ""
gh run list --limit 20 --json databaseId,displayTitle,status,workflowName,createdAt --jq '.[] | select(.status != "completed")' > /tmp/gh_runs.json
if [ ! -s /tmp/gh_runs.json ]; then
echo "No active runs found."
exit 0
fi
# Display runs with numbers
jq -r 'to_entries | .[] | "\(.key + 1)) [\(.value.workflowName)] \(.value.displayTitle) - \(.value.status)"' /tmp/gh_runs.json
echo ""
read -p "Select run number to watch: " -r SELECTION
RUN_ID=$(jq -r ".[$((SELECTION - 1))].databaseId" /tmp/gh_runs.json)
if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
echo "Invalid selection"
exit 1
fi
watch_run "$RUN_ID"
}
# Main logic
if [ -z "$RUN_ID" ]; then
# No run ID provided - show menu
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Workflow Monitor"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "1) Watch specific run ID"
echo "2) Watch latest run for workflow"
echo "3) Select from active runs"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
read -p "Select option (1-3): " -n 1 -r OPTION
echo ""
case $OPTION in
1)
read -p "Enter run ID: " RUN_ID
watch_run "$RUN_ID"
;;
2)
gh workflow list
echo ""
read -p "Enter workflow name (or file): " WORKFLOW_NAME
watch_latest_workflow "$WORKFLOW_NAME"
;;
3)
interactive_select
;;
*)
echo "Invalid option"
exit 1
;;
esac
else
# Run ID provided as argument
watch_run "$RUN_ID"
fi
Advanced Features
Advanced gh CLI capabilities for power users and automation.
Aliases
Create custom shortcuts for frequently used commands.
# Create alias
gh alias set pv "pr view"
gh alias set bugs "issue list --label bug"
# List aliases
gh alias list
# Use alias
gh pv 123API Access
Direct access to GitHub's REST API through gh CLI.
# Make API call
gh api repos/:owner/:repo/issues
# With JSON data
gh api repos/:owner/:repo/issues -f title="Bug" -f body="Description"
# Paginated results
gh api --paginate repos/:owner/:repo/issuesExtensions
Extend gh CLI functionality with community extensions.
# List extensions
gh extension list
# Install extension
gh extension install owner/gh-extension
# Upgrade extensions
gh extension upgrade --allSecrets and Variables
Manage GitHub Actions secrets and variables.
Secrets
# List secrets
gh secret list
# Set secret
gh secret set SECRET_NAME
# Set secret from file
gh secret set SECRET_NAME < secret.txtVariables
# List variables
gh variable list
# Set variable
gh variable set VAR_NAME --body "value"SSH and GPG Keys
SSH Keys
# List SSH keys
gh ssh-key list
# Add SSH key
gh ssh-key add ~/.ssh/id_ed25519.pub --title "My laptop"GPG Keys
# List GPG keys
gh gpg-key list
# Add GPG key
gh gpg-key add <key-file>Organizations
Manage organization settings and resources.
# List organizations
gh org list
# View organization info
gh org view <org-name>Projects
Work with GitHub Projects.
# List projects
gh project list --owner <org-name>
# View project
gh project view <project-number>
# Create project
gh project create --owner <org-name> --title "Project Name"
# List project items with a filter query
gh project item-list <project-number> --query "status:Done"Repository Rulesets
View information about repository rulesets.
# List rulesets
gh ruleset list
# View ruleset
gh ruleset view <ruleset-id>Attestations
Work with artifact attestations for supply chain security.
# Verify release attestation
gh release verify <tag>
# Verify specific asset
gh release verify-asset <file> --repo owner/repoAdvanced Scripting Patterns
Using jq with gh
# Extract specific fields from JSON output
gh pr list --json number,title,author --jq '.[] | select(.author.login=="username")'
# Count open PRs
gh pr list --json state --jq 'length'
# Get PR numbers only
gh pr list --json number --jq '.[].number'Error Handling in Scripts
# Check if PR exists before operating
if gh pr view 123 &>/dev/null; then
gh pr merge 123
else
echo "PR not found"
fiBatch Operations
# Add label to multiple issues
gh issue list --assignee @me --json number --jq '.[].number' | xargs -I {} gh issue edit {} --add-label "in-progress"Automation Workflows
Common workflow patterns and automation examples using gh CLI.
Common Workflows
Code Review Workflow
# List PRs assigned to you
gh pr list --assignee @me
# Checkout PR for testing
gh pr checkout 123
# Run tests, review code...
# Approve PR
gh pr review 123 --approve --body "LGTM!"
# Merge PR
gh pr merge 123 --squashQuick PR Creation
# Create feature branch, make changes, commit
git checkout -b feature/new-feature
# ... make changes ...
git add .
git commit -m "Add new feature"
git push -u origin feature/new-feature
# Create PR from commits
gh pr create --fill
# View PR
gh pr view --webIssue Triage
# List open issues
gh issue list
# Add labels to issues
gh issue edit 456 --add-label needs-triage
gh issue edit 456 --add-label bug
# Assign issue
gh issue edit 456 --add-assignee @developerAdvanced Automation Patterns
Daily Standup Report
#!/bin/bash
# Generate daily activity report
echo "## My GitHub Activity - $(date +%Y-%m-%d)"
echo ""
echo "### PRs Created"
gh pr list --author @me --search "created:$(date +%Y-%m-%d)"
echo ""
echo "### PRs Reviewed"
gh search prs "reviewed-by:@me created:$(date +%Y-%m-%d)"
echo ""
echo "### Issues Closed"
gh issue list --author @me --state closed --search "closed:$(date +%Y-%m-%d)"Auto-label PRs by Files Changed
#!/bin/bash
# Auto-label PR based on changed files
PR_NUMBER=$1
FILES=$(gh pr diff $PR_NUMBER --name-only)
if echo "$FILES" | grep -q "^docs/"; then
gh pr edit $PR_NUMBER --add-label "documentation"
fi
if echo "$FILES" | grep -q "\.test\."; then
gh pr edit $PR_NUMBER --add-label "tests"
fi
if echo "$FILES" | grep -q "package\.json"; then
gh pr edit $PR_NUMBER --add-label "dependencies"
fiSync Fork with Upstream
#!/bin/bash
# Keep fork in sync with upstream
gh repo sync owner/fork --source upstream/repo --branch main
git fetch origin main
git merge origin/mainRelease Checklist Automation
#!/bin/bash
# Automated release checklist
VERSION=$1
# 1. Ensure on main branch
git checkout main && git pull
# 2. Run tests
npm test || exit 1
# 3. Create release tag
git tag -a "v$VERSION" -m "Release $VERSION"
git push origin "v$VERSION"
# 4. Create GitHub release
gh release create "v$VERSION" --generate-notes
# 5. Upload artifacts
gh release upload "v$VERSION" dist/*Bulk PR Operations
#!/bin/bash
# Approve all PRs from dependabot
gh pr list --author app/dependabot --json number --jq '.[].number' | \
xargs -I {} gh pr review {} --approve --body "Auto-approved dependency update"Monitor CI Status
#!/bin/bash
# Monitor all active PRs for CI failures
gh pr list --json number,title,statusCheckRollup --jq '.[] |
select(.statusCheckRollup.state == "FAILURE") |
"\(.number): \(.title)"'Notifications and Monitoring
Watch for PR Reviews
# Monitor PR for new reviews
while true; do
REVIEWS=$(gh pr view 123 --json reviews --jq '.reviews | length')
echo "Reviews: $REVIEWS"
sleep 60
doneGet Notified on Workflow Completion
#!/bin/bash
# Wait for workflow and send notification
RUN_ID=$1
gh run watch $RUN_ID
STATUS=$(gh run view $RUN_ID --json conclusion --jq '.conclusion')
if [ "$STATUS" = "success" ]; then
osascript -e 'display notification "Workflow passed!" with title "GitHub Actions"'
else
osascript -e 'display notification "Workflow failed!" with title "GitHub Actions"'
fiPR Staleness Check
#!/bin/bash
# Find stale PRs (no activity in 30 days)
gh pr list --json number,title,updatedAt --jq '.[] |
select((now - (.updatedAt | fromdateiso8601)) > (30*86400)) |
"\(.number): \(.title)"'Team Collaboration Patterns
Assign PR Reviewers by Team
# Auto-assign team members as reviewers
gh pr create --reviewer team/backend,team/security --assignee @meBulk Issue Assignment
# Assign all bugs to triage team
gh issue list --label bug --json number --jq '.[].number' | \
xargs -I {} gh issue edit {} --add-assignee @triagerWeekly Team Report
#!/bin/bash
# Generate weekly team activity summary
TEAM="myteam"
SINCE=$(date -v-7d +%Y-%m-%d)
echo "# Team Activity Report - Week of $(date +%Y-%m-%d)"
echo ""
echo "## PRs Merged"
gh search prs "team:$TEAM is:merged merged:>=$SINCE" --limit 100
echo ""
echo "## Issues Closed"
gh search issues "team:$TEAM is:closed closed:>=$SINCE" --limit 100Repository Management
Batch Repository Creation
#!/bin/bash
# Create multiple repositories from template
TEMPLATE="org/template-repo"
REPOS=("project-a" "project-b" "project-c")
for repo in "${REPOS[@]}"; do
gh repo create "org/$repo" --template "$TEMPLATE" --private
doneClone All Organization Repos
#!/bin/bash
# Clone all repos from an organization
ORG="myorg"
gh repo list "$ORG" --limit 1000 --json name --jq '.[].name' | \
xargs -I {} gh repo clone "$ORG/{}"Sync Multiple Forks
#!/bin/bash
# Sync all your forks with upstream
gh repo list @me --fork --json name,parent --jq '.[] |
"\(.name) \(.parent.owner.login)/\(.parent.name)"' | \
while read fork upstream; do
gh repo sync "$fork" --source "$upstream"
doneCodespaces
When to read: Read when the user asks to list, create, connect to, or manage files within GitHub Codespaces from the terminal.
Manage GitHub Codespaces directly from the terminal.
List and Create Codespaces
# List codespaces
gh codespace list
# Create new codespace
gh codespace create --repo owner/repoConnect to Codespaces
# SSH into codespace
gh codespace ssh
# Open in VS Code
gh codespace code
# Open in JupyterLab
gh codespace jupyterManage Codespace Files
# Copy files to/from codespace
gh codespace cp local-file.txt remote:~/path/
gh codespace cp remote:~/path/file.txt ./local-dir/
# View logs
gh codespace logsDiscussions
When to read: Read when the user asks to list, view, create, edit, or comment on GitHub Discussions.
The gh discussion command set is in preview and subject to change. A discussion is supplied by number (123) or URL.
# List discussions
gh discussion list
gh discussion list --answered
gh discussion list --sort created --order asc
gh discussion list --json number,title,category,answeredAt
# View a discussion, its comments, or replies to a comment
gh discussion view 123
gh discussion view 123 --comments
gh discussion view 123 --order oldest
# Create a discussion (interactive when flags omitted)
gh discussion create
gh discussion create --title "My question" --category "Q&A" --body "Details here"
gh discussion create --title "Notes" --category "General" --body-file notes.md --label question
# Edit a discussion
gh discussion edit 123 --title "New title"
gh discussion edit 123 --add-label answered --remove-label question
# Comment on a discussion, or reply to a comment using its URL
gh discussion comment 123 --body "Thanks!"
gh discussion comment <comment-url> --body "Reply text"
# Edit or delete a comment
gh discussion comment <comment-url> --edit --body "Updated"
gh discussion comment <comment-url> --delete --yesGists
When to read: Read when the user asks to create, list, view, or edit GitHub gists.
# Create gist
gh gist create file.txt
# Create gist from stdin
echo "content" | gh gist create -
# List gists
gh gist list
# View gist
gh gist view <gist-id>
# Edit gist
gh gist edit <gist-id>JSON Output
When to read: Read when the user wants to use the --json flag for scriptable output, or needs to know the correct gh CLI JSON field names (which differ from GitHub API names).Use --json flag for structured output. Always verify field names with `--help` as they differ from GitHub API names.
# Check available JSON fields for any command
gh repo view --help | grep -A 50 "JSON FIELDS"
gh pr list --help | grep -A 50 "JSON FIELDS"Common JSON Field Corrections
| Wrong (API-style) | Correct (gh CLI) |
|---|---|
stargazersCount | stargazerCount |
forksCount | forkCount |
watchersCount | watchers |
openIssuesCount | issues |
Repository View Fields
# Common fields for gh repo view --json
gh repo view owner/repo --json name,description,stargazerCount,forkCount,updatedAt,url,readmeLabels
When to read: Read when the user asks to list, create, edit, or clone repository labels for issue and PR organization.
Manage repository labels for issue and PR organization.
List and View Labels
# List all labels in repository
gh label listCreate and Edit Labels
# Create new label
gh label create "priority: high" --color FF0000 --description "High priority items"
# Edit existing label
gh label edit "bug" --color FFAA00 --description "Something isn't working"Clone Labels Between Repos
# Clone labels from another repository
gh label clone owner/source-repoReleases
When to read: Read when the user asks to create, list, view, or download GitHub releases and their assets.
Creating Releases
# Create release
gh release create v1.0.0
# Create release with notes
gh release create v1.0.0 --notes "Release notes"
# Create release with files
gh release create v1.0.0 dist/*.tar.gz
# Create draft release
gh release create v1.0.0 --draft
# Generate release notes automatically
gh release create v1.0.0 --generate-notesManaging Releases
# List releases
gh release list
# View release
gh release view v1.0.0
# Download release assets
gh release download v1.0.0Search
When to read: Read when the user asks to search GitHub repositories, issues, or pull requests using the gh search family of commands.Search across all of GitHub for repositories, issues, and pull requests.
Search Repositories
# Search for repositories
gh search repos "machine learning" --language=python
# Search with filters
gh search repos --stars=">1000" --topic=kubernetesSearch Issues
# Search issues across GitHub
gh search issues "bug" --label=critical --state=open
# Exclude results (note the -- to prevent flag interpretation)
gh search issues -- "memory leak -label:wontfix"Scope to one repository
Two repo-scoped paths; pick by whether you want search-ranked results or a plain filtered list.
# Search API, scoped to a repo (relevance-ranked; repeat --repo for several)
gh search issues "panic" --repo cli/cli --state=open
# List a single repo's issues with a search filter (defaults to current repo)
gh issue list --repo cli/cli --search "is:open label:bug sort:created-desc"gh search issues hits GitHub's search index (cross-repo, relevance-ranked, ~1000-result cap). gh issue list --search lists one repo's issues with the same is:/label:/sort: qualifiers and honors --limit.
Search Pull Requests
# Search PRs
gh search prs --author=@me --state=open
# Search with date filters
gh search prs "refactor" --created=">2024-01-01"Troubleshooting
Common issues and solutions when using gh CLI.
Authentication Issues
Not Authenticated
Error: gh: To get started with GitHub CLI, please run: gh auth login
Solution:
# Login with web browser
gh auth login
# Login with token
gh auth login --with-token < token.txt
# Check auth status
gh auth statusToken Expired
Error: HTTP 401: Bad credentials (HTTP 401)
Solution:
# Refresh authentication
gh auth refresh
# Re-login if refresh fails
gh auth logout
gh auth loginWrong Account
Problem: Authenticated as wrong user
Solution:
# Check current authentication
gh auth status
# Switch accounts
gh auth login --hostname github.com
# Use multiple accounts with different hosts
export GH_HOST=github.com
gh auth loginMissing Scopes
Error: HTTP 403: Resource not accessible by personal access token
Solution:
# Add required scopes (use --clipboard to auto-copy OAuth code)
gh auth refresh -h github.com -s repo,workflow,admin:org
# Common scopes needed:
# - repo: Full control of private repositories
# - workflow: Update GitHub Action workflows
# - admin:org: Full control of orgs and teams
# - write:packages: Upload packages to GitHub Package RegistryPermission Issues
Insufficient Permissions
Error: HTTP 403: Resource not accessible by personal access token
Solution:
- Ensure your token has required scopes (repo, workflow, admin:org, etc.)
- Re-run
gh auth refresh -h github.com -s <scope>to add scopes - Check if you're a member of the organization/repository
Repository Access Denied
Error: HTTP 404: Not Found (when repo exists)
Possible Causes:
1. Repository is private and you don't have access 2. Repository name is incorrect 3. You're authenticated with wrong account
Solution:
# Verify repository access
gh repo view owner/repo
# Check if you're using correct repo name
gh repo list owner --limit 100 | grep repo-name
# Verify authentication
gh auth statusCannot Push to Repository
Error: Permission to owner/repo denied to user
Solution:
# Check if you have write access
gh api repos/owner/repo --jq '.permissions'
# Verify git remote uses correct authentication
gh auth setup-git
# Check remote URL
git remote -vRate Limiting
API Rate Limit Exceeded
Error: API rate limit exceeded for user
Solution:
# Check rate limit status
gh api rate_limit
# Use authenticated requests (higher limit: 5000/hr vs 60/hr)
gh auth login
# Wait for rate limit reset or use conditional requests
gh api rate_limit --jq '.rate.reset' | xargs -I {} date -r {}Secondary Rate Limit
Error: You have exceeded a secondary rate limit
Solution:
- Slow down request rate
- Add delays between API calls
- Use
--paginatecarefully with large result sets
Common Command Errors
PR Already Exists
Error: pull request create failed: a pull request for branch "feature" into branch "main" already exists
Solution:
# Find existing PR
gh pr list --head feature
# Update existing PR instead
gh pr edit <number> --title "New title" --body "New description"
# Or checkout and update the branch
gh pr checkout <number>
git commit --amend
git push --force-with-leaseCannot Merge PR
Error: GraphQL: Pull Request is not mergeable
Causes & Solutions:
- Merge conflicts:
gh pr checkout <number>
git merge main # or base branch
# Resolve conflicts
git push- Required checks failing:
gh pr checks <number> # View status
# Wait for checks or fix failures- Required reviews missing:
gh pr view <number> --json reviewDecision
# Get required approvals- Branch protection:
gh api repos/:owner/:repo/branches/main/protection
# Ensure all rules are satisfiedWorkflow Not Found
Error: could not resolve to a Workflow
Solution:
# List available workflows
gh workflow list
# Use exact workflow file name (not display name)
gh workflow run ci.yml # not "CI" or "ci"
# Use workflow ID
gh api repos/:owner/:repo/actions/workflows --jq '.workflows[] | "\(.id): \(.name)"'
gh workflow run <workflow-id>Cannot Checkout PR
Error: failed to check out PR: could not find a branch for this pull request
Solution:
# Fetch PR branch manually
gh pr view <number> --json headRefName,headRepository --jq '.headRefName'
# Checkout with fetch
git fetch origin pull/<number>/head:pr-<number>
git checkout pr-<number>Issue/PR Not Found
Error: could not resolve to a PullRequest/Issue with the number of <number>
Solution:
# Verify you're in correct repository
gh repo view
# Set default repository
gh repo set-default owner/repo
# Specify repository explicitly
gh pr view <number> --repo owner/repoInstallation Issues
gh Command Not Found
Solutions:
# macOS with Homebrew
brew install gh
# Update Homebrew if gh is outdated
brew upgrade gh
# Update PATH (if installed but not in PATH)
export PATH="/opt/homebrew/bin:$PATH"
# Verify installation
which gh
gh --versionExtension Installation Fails
Error: failed to install extension
Solution:
# Check extension name is correct
gh extension search <keyword>
# Install with full repository path
gh extension install owner/gh-extension-name
# Update existing extension
gh extension upgrade extension-name
# Reinstall if corrupted
gh extension remove extension-name
gh extension install owner/gh-extension-nameUpgrade Issues
Error: failed to upgrade gh
Solution:
# macOS
brew upgrade gh
# Check for conflicts
brew doctor
# Reinstall if needed
brew reinstall ghConfiguration Issues
Default Repository Not Set
Error: no default repository has been set
Solution:
# Set default repository interactively
gh repo set-default
# Set default repository explicitly
gh repo set-default owner/repo
# Or use --repo flag
gh pr list --repo owner/repoEditor Not Opening
Problem: gh pr create doesn't open editor
Solution:
# Set default editor
gh config set editor vim
gh config set editor "code --wait" # VS Code
gh config set editor "nano"
# Or use EDITOR environment variable
export EDITOR=vimGit Protocol Issues
Error: Issues with SSH/HTTPS
Solution:
# Set preferred protocol
gh config set git_protocol https
# or
gh config set git_protocol ssh
# Setup git credentials
gh auth setup-gitDebugging Tips
Enable Verbose Output
# Debug mode - shows API calls
GH_DEBUG=api gh pr list
# Trace OAuth flow
GH_DEBUG=oauth gh auth login
# Full debugging
GH_DEBUG=api,oauth gh <command>Check Configuration
# View current config
gh config list
# Check git remotes
git remote -v
# Verify default repository
gh repo view
# Check authentication
gh auth statusInspect JSON Output
# Get full JSON response
gh pr view <number> --json
# Pretty print with jq
gh pr view <number> --json | jq .
# Inspect specific fields
gh pr view <number> --json state,title,numberClear Cache
# If experiencing odd behavior, re-authenticate to refresh state
gh auth logout
gh auth login
# Or restart gh by closing all terminals and reopening
# Note: Cache will be automatically refreshed on next useNetwork Issues
Connection Timeout
Error: dial tcp: i/o timeout
Solution:
# Check network connectivity
ping github.com
# Test GitHub API
curl -I https://api.github.com
# Use different network or VPN
# Check firewall/proxy settingsSSL Certificate Issues
Error: x509: certificate signed by unknown authority
Solution:
# Update ca-certificates
# macOS
brew install ca-certificates
# Set custom CA bundle if needed
export GH_CA_BUNDLE=/path/to/ca-bundle.crtGetting Additional Help
Built-in Help
# Command-specific help
gh pr create --help
gh pr --help
gh --help
# View manual pages
man gh
man gh-prCheck Version
# Current version
gh --version
# Check for updates
gh extension upgrade gh
brew upgrade gh # macOSCommunity Resources
- Official Manual: https://cli.github.com/manual
- GitHub CLI Repository: https://github.com/cli/cli
- Discussions: https://github.com/cli/cli/discussions
- Report Bugs: https://github.com/cli/cli/issues
- Stack Overflow: Tag
github-cli
Common Error Codes
- 401: Authentication failed
- 403: Forbidden / insufficient permissions
- 404: Not found / no access
- 422: Validation failed / malformed request
- 500: GitHub server error
2.95.0
Workflows & Actions
Comprehensive guide for managing GitHub Actions workflows and runs using gh CLI.
Viewing Workflows
# List workflows
gh workflow list
# View workflow runs
gh run list
# View specific run
gh run view 789
# Watch run
gh run watch 789
# View run logs
gh run view 789 --logManaging Workflows
# Trigger workflow
gh workflow run workflow.yml
# Cancel run
gh run cancel 789
# Rerun workflow
gh run rerun 789
# Download artifacts
gh run download 789Workflow Runs
Advanced commands for managing workflow runs.
List and View Runs
# List recent workflow runs
gh run list
# List runs for specific workflow
gh run list --workflow=ci.yml
# List runs on specific branch
gh run list --branch=main
# List failed runs only
gh run list --status=failure
# Limit number of results
gh run list --limit=10
# View specific run details
gh run view 123456
# View run with logs
gh run view 123456 --log
# View run and open in browser
gh run view 123456 --web
# View specific job in a run
gh run view 123456 --job=123
# View run with exit status (also works with --log and --log-failed)
gh run view 123456 --exit-status
gh run view 123456 --log --exit-status
gh run view 123456 --log-failed --exit-statusMonitor and Control Runs
# Watch a run in real-time
gh run watch 123456
# Watch with interval (default 3s)
gh run watch 123456 --interval=5
# Cancel running workflow
gh run cancel 123456
# Force cancel (skip confirmation)
gh run cancel 123456 --force
# Rerun failed jobs only
gh run rerun 123456 --failed
# Rerun all jobs in a workflow run
gh run rerun 123456
# Rerun specific job
gh run rerun 123456 --job=123Download Artifacts
# Download all artifacts from a run
gh run download 123456
# Download specific artifact by name
gh run download 123456 --name artifact-name
# Download to specific directory
gh run download 123456 --dir ./downloads
# Download artifacts from latest run
gh run download
# Download artifacts from specific workflow
gh run download --name=build-artifactsWorkflow Dispatch
Trigger workflows with custom inputs. Since v2.87, gh workflow run immediately returns the workflow run URL.
# Trigger workflow with inputs
gh workflow run deploy.yml -f environment=production -f version=v1.2.3
# Trigger workflow on specific branch
gh workflow run ci.yml --ref feature-branch
# Trigger workflow - the run URL is printed immediately
gh workflow run ci.ymlGitHub Actions Cache
Manage GitHub Actions cache to optimize workflow performance.
# List caches in repository
gh cache list
# List caches for specific branch
gh cache list --ref refs/heads/main
# List caches with specific key
gh cache list --key npm-cache
# Sort caches by size
gh cache list --sort size
# Limit number of results
gh cache list --limit 10CI/CD Integration Patterns
Trigger Workflow and Wait
# Trigger workflow - the run URL is returned immediately (v2.87+)
gh workflow run ci.yml --ref main
# Trigger and watch in one go (extract run ID from the returned URL)
RUN_URL=$(gh workflow run ci.yml --ref main 2>&1 | grep -oE 'https://[^ ]+')
RUN_ID=$(echo "$RUN_URL" | grep -oE '[0-9]+$')
gh run watch "$RUN_ID"Check CI Status Before Merge
# Check all checks pass before merging
gh pr checks 123 && gh pr merge 123 --squash
# Wait for checks to complete
gh pr checks 123 --watch && gh pr merge 123 --squash
# Check specific required checks
gh pr view 123 --json statusCheckRollup --jq '.statusCheckRollup[] | select(.conclusion != "SUCCESS")'Auto-merge on Success
# Enable auto-merge when checks pass
gh pr merge 123 --auto --squash
# Enable auto-merge with specific merge method
gh pr merge 123 --auto --merge
gh pr merge 123 --auto --rebase
# Disable auto-merge
gh pr merge 123 --disable-autoMonitor Multiple Workflows
# Watch all active workflow runs
gh run list --status=in_progress --json databaseId,name,headBranch | \
jq -r '.[] | "\(.databaseId) - \(.name) on \(.headBranch)"'
# Check status of all workflows for current commit
COMMIT=$(git rev-parse HEAD)
gh run list --commit=$COMMIT --json status,conclusion,nameWorkflow Run Analytics
# Get average duration for workflow
gh run list --workflow=ci.yml --limit=50 --json createdAt,updatedAt,conclusion | \
jq '[.[] | select(.conclusion == "success") |
((.updatedAt | fromdateiso8601) - (.createdAt | fromdateiso8601))] |
add / length / 60'
# Count failed runs in last 30 days
gh run list --created=">=$(date -v-30d +%Y-%m-%d)" --status=failure --json id | jq '. | length'
# List slowest workflow runs
gh run list --workflow=ci.yml --limit=20 --json databaseId,createdAt,updatedAt,conclusion | \
jq 'sort_by((.updatedAt | fromdateiso8601) - (.createdAt | fromdateiso8601)) | reverse | .[:5]'Conditional Workflow Execution
# Trigger workflow only if tests pass locally
npm test && gh workflow run deploy.yml -f environment=staging
# Chain workflows
gh workflow run build.yml && \
sleep 10 && \
gh run watch $(gh run list --workflow=build.yml --limit 1 -q '.[0].databaseId') && \
gh workflow run deploy.ymlRetrieve Workflow Job Logs
# Download logs for a specific run
gh run view 123456 --log > workflow-logs.txt
# Download logs for failed jobs only
gh run view 123456 --log-failed > failed-jobs.txt
# View logs for specific job
gh api repos/:owner/:repo/actions/jobs/JOB_ID/logs > job.logAdvanced Workflow Management
Using JSON Output for Scripting
# Get workflow run details as JSON
gh run view 123456 --json status,conclusion,startedAt,url
# Parse specific fields
gh run view 123456 --json conclusion -q '.conclusion'
# List all failed runs with details
gh run list --status=failure --json databaseId,name,headBranch,conclusion,createdAt
# Get workflow run URL programmatically
gh run view 123456 --json url -q '.url'Workflow Environment Secrets
# List repository secrets (requires admin access)
gh secret list
# Set a secret
gh secret set SECRET_NAME < secret.txt
gh secret set SECRET_NAME --body "secret-value"
# List organization secrets
gh secret list --org organization-nameWorkflow Variables
# List repository variables
gh variable list
# Set a variable
gh variable set VAR_NAME --body "value"Troubleshooting
Debug Failed Runs
# View failed run with logs
gh run view 123456 --log-failed
# List failed jobs in a run
gh run view 123456 --json jobs --jq '.jobs[] | select(.conclusion == "failure") | {name, conclusion}'
# Rerun failed jobs with debug logging
gh run rerun 123456 --failed --debugCheck Workflow File Syntax
# View workflow file
gh workflow view ci.yml
# Download workflow file
gh api repos/:owner/:repo/contents/.github/workflows/ci.yml --jq '.content' | base64 -d
# List all workflow files
gh api repos/:owner/:repo/contents/.github/workflows --jq '.[] | .name'Best Practices
01. Use specific workflow names when triggering or listing runs to avoid ambiguity 02. Enable auto-merge for PRs to merge automatically when CI passes 03. Monitor workflow cache regularly to prevent cache bloat 04. Use JSON output for scripting and automation 05. Watch runs interactively during development to catch failures quickly 06. Clean up old workflow runs to keep repository tidy 07. Use workflow dispatch inputs for flexible, reusable workflows 08. Set appropriate timeouts to prevent workflows from running indefinitely 09. Use artifacts judiciously - they count against storage limits 10. Leverage caching to speed up workflows and reduce costs
Related skills
How it compares
Pick cli-gh over generic git skills when the goal is ticket-linked branch naming plus gh PR creation in one scripted step rather than manual checkout and label commands.
FAQ
What is cli-gh?
Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, repo browsing, or command-line GitHub tasks.
When should I use cli-gh?
Use for GitHub CLI automation: gh commands, repo info, workflow triggers, GitHub search, codespaces, PR status, issues, repo browsing, or command-line GitHub tasks.
Is cli-gh safe to install?
Review the Security Audits panel on this page before production use.