| name | github-cli |
| description | GitHub CLI utilities for repository management, branch protection setup, CI workflows, release tagging, and deployment automation. Handles repo operations via gh API calls with proper JSON payload formatting. Use when adjusting PR scope, isolating commits to specific files, or creating a clean focused pull request from an existing branch. |
| allowed-tools | Bash, Read, Glob, Grep |
| disable-model-invocation | false |
GitHub CLI Skill
This skill provides expertise in using the GitHub CLI (gh) to automate common repository management tasks including:
- Branch protection configuration
- Repository settings updates (visibility, templates, etc.)
- Issue and PR automation
- Release creation and tagging
- Workflow triggers and actions
- Webhook configuration
Trigger Phrases
"Use the GitHub CLI", "configure branch protection via gh api", "set up repo settings with gh", "automate releases using GitHub CLI", "manage repository with gh command".
Known Issue: JSON Payload Formatting
Problem: The gh api command has limitations when passing nested JSON objects for certain endpoints. For complex payloads like branch protection, it's more reliable to use a file-based approach.
Solution Pattern:
- Create a JSON configuration file with the full payload structure
- Use
--input <file> to pass the complete JSON object
- Avoid using
-f/--raw-field for nested objects
Example: Branch Protection Setup
cat > /tmp/protection.json << 'EOF'
{
"enforce_admins": true,
"required_status_checks": {
"strict": true,
"contexts": ["ci"]
},
"allow_deletions": false,
"required_pull_request_reviews": {
"require_code_owner_reviews": false,
"dismiss_stale_reviews_by_mergers": false,
"dismiss_stale_reviews": false,
"require_last_pushers_can_review": false,
"required_approving_review_count": 1
},
"restrictions": null
}
EOF
gh api repos/{owner}/{repo}/branches/master/protection --method PUT \
--input /tmp/protection.json
Example: Repository Settings Update
For simple field updates, you can use -f:
gh api repos/{owner}/{repo} --method PATCH -F visibility=private
For complex nested structures (branches protection, labels, etc.), always use --input <file>.
Common Operations
Branch Protection
| Setting | Field Path | Example Value |
|---|
| Enforce admins | enforce_admins | true |
| Required status checks | required_status_checks.strict | true |
| Status check contexts | required_status_checks.contexts[] | ["ci", "lint"] |
| Allow deletions | allow_deletions | false |
| PR review count | required_pull_request_reviews.required_approving_review_count | 1 |
Repository Operations
gh api repos/{owner}/{repo} --method PATCH -F visibility=private
gh api repos/{owner}/{repo}/enable-issues
gh api repos/{owner}/{repo}/git/refs/tags/v1.0.0 --method PUT \
-f sha=$(git rev-parse HEAD)
Releases
gh release create v1.0.0 --title "Release 1.0.0" --notes "Changelog..."
gh release upload v1.0.0 ./binary.exe -n binary.exe
Best Practices
1. Use Files for Complex Payloads
Never try to inline complex JSON structures in command-line flags. Use heredocs or temporary files.
2. Verify Before Apply
When using --method PUT or PATCH, consider testing with GET first:
gh api repos/{owner}/{repo}/branches/master/protection
gh api repos/{owner}/{repo}/branches/master/protection --method PUT \
--input /tmp/protection.json
3. Handle Personal vs Organization Repos
Some settings (like restrictions) are only available for organization repositories. For personal repos, omit or set to null.
4. Error Handling
Always check the HTTP status code in scripts:
if ! gh api ...; then
echo "Failed to update branch protection" >&2
exit 1
fi
Validation Checklist
When setting up production repositories, verify:
Gotchas (hard-won)
Actions can't create or approve PRs by default
Workflows that open PRs (release-please, dependabot-style bots, "create-pull-request" actions) fail
with:
GitHub Actions is not permitted to create or approve pull requests.
This is a separate setting from the workflow's permissions: block — granting
pull-requests: write in YAML does not cover it. Enable the repo toggle Settings → Actions →
General → Workflow permissions → "Allow GitHub Actions to create and approve pull requests":
gh api repos/{owner}/{repo}/actions/permissions/workflow
gh api -X PUT repos/{owner}/{repo}/actions/permissions/workflow \
-f default_workflow_permissions=read -F can_approve_pull_request_reviews=true
An org-level setting (gh api orgs/{org}/actions/permissions/workflow, needs admin:org) can
override the repo. On a public repo this is low-risk: fork PRs get a read-only token with no secrets,
and the capability is only usable by workflows triggered from trusted refs.
Pin Actions to commit SHAs (supply-chain)
On public repos, pin every uses: to a full 40-char commit SHA with a version comment, so a moving
tag can't be repointed at malicious code:
- uses: actions/checkout@<40-char-sha>
Resolve the SHA for a tag (dereferences annotated tags to the commit):
gh api repos/actions/checkout/commits/v4 --jq .sha
Pin to the current major you already use; don't silently jump majors inside a security pin.
gh api leading slash on Git Bash (Windows)
On Windows Git Bash / MSYS, a leading-slash path is rewritten to a filesystem path:
invalid API endpoint: "C:/Program Files/Git/repos/owner/repo/..."
Fix: drop the leading slash (gh api repos/owner/repo/..., not /repos/...), or prefix with
MSYS_NO_PATHCONV=1.
Renamed repos redirect
After a repo rename, the old owner/oldname URL still works via redirect, but gh repo view --json nameWithOwner shows the canonical new name. Use the canonical name for gh api repos/... calls to
avoid surprises.
Scoping a PR to Specific Files
When a branch has commits that touch too many things and you want a focused PR containing only certain files:
The Problem: git cherry-pick <commit> -- <files> is not valid syntax and will fail with fatal: bad revision.
The Solution: Use git show <commit>:<file> > <file> to extract specific files from a commit, then create a clean commit manually.
Step-by-Step: Extract Files from a Commit
git log --oneline origin/<branch>
git checkout master
git checkout -b feature/focused-change
git show <commit-sha>:LICENSE > LICENSE
git show <commit-sha>:CONTRIBUTING.md > CONTRIBUTING.md
git show <commit-sha>:CHANGELOG.md > CHANGELOG.md
git add LICENSE CONTRIBUTING.md CHANGELOG.md
git commit -m "docs: add repo production elements"
git push origin feature/focused-change --set-upstream
gh pr create --title "..." --base master --head feature/focused-change --body "..."
Auditing What a PR Contains
Before creating or adjusting a PR, audit what files are actually in the branch vs master:
git diff <base-branch>...HEAD --name-only | sort -u
git log --oneline origin/<pr-branch>
git show <commit-sha> --stat
git diff <commit-sha>^..<commit-sha> --stat
Checking Remote Branch State
git branch -r | grep <pattern>
git log --oneline master..origin/<branch>
Creating a PR with Body via Heredoc
Always use a heredoc to avoid quoting issues in PR body:
gh pr create --title "Add production files" --base master --head feature/my-branch --body "$(cat <<'EOF'
## Summary
- LICENSE - MIT License
- CONTRIBUTING.md - Contribution guidelines
- CHANGELOG.md - Release tracking
## Why
Makes the repo safer and more professional for contributors.
EOF
)"
Related Skills
dotnet-cli-release: Full release pipeline for a .NET CLI (MinVer + release-please + edge channel); the gotchas above came from that work.
litellm: For OpenCode plugin development and LiteLLM configuration
orchestrator: For complex multi-step deployment tasks involving GitHub operations