github-pr-workflow
Full pull request lifecycle — create branches, commit changes, open PRs, monitor CI status, auto-fix failures, and merge. Works with gh CLI or falls back to git + GitHub REST API via curl.
Full pull request lifecycle — create branches, commit changes, open PRs, monitor CI status, auto-fix failures, and merge. Works with gh CLI or falls back to git + GitHub REST API via curl.
Real data. Real impact.
Emerging
Developers
Per week
Excellent
Skills give you superpowers. Install in 30 seconds.
Complete guide for managing the PR lifecycle. Each section shows the
gh way first, then the git + curl fallback for machines without gh.
github-auth skill)# Determine which method to use throughout this workflow if command -v gh &>/dev/null && gh auth status &>/dev/null; then AUTH="gh" else AUTH="git" # Ensure we have a token for API calls if [ -z "$GITHUB_TOKEN" ]; then if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r') elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|') fi fi fi echo "Using: $AUTH"
Many
curl commands need owner/repo. Extract it from the git remote:
# Works for both HTTPS and SSH remote URLs REMOTE_URL=$(git remote get-url origin) OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||') OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1) REPO=$(echo "$OWNER_REPO" | cut -d/ -f2) echo "Owner: $OWNER, Repo: $REPO"
This part is pure
git — identical either way:
# Make sure you're up to date git fetch origin git checkout main && git pull origin main # Create and switch to a new branch git checkout -b feat/add-user-authentication
Branch naming conventions:
feat/description — new featuresfix/description — bug fixesrefactor/description — code restructuringdocs/description — documentationci/description — CI/CD changesUse the agent's file tools (
write_file, patch) to make changes, then commit:
# Stage specific files git add src/auth.py src/models/user.py tests/test_auth.py # Commit with a conventional commit message git commit -m "feat: add JWT-based user authentication - Add login/register endpoints - Add User model with password hashing - Add auth middleware for protected routes - Add unit tests for auth flow"
Commit message format (Conventional Commits):
type(scope): short description Longer explanation if needed. Wrap at 72 characters.
Types:
feat, fix, refactor, docs, test, ci, chore, perf
git push -u origin HEAD
With gh:
gh pr create \ --title "feat: add JWT-based user authentication" \ --body "## Summary - Adds login and register API endpoints - JWT token generation and validation ## Test Plan - [ ] Unit tests pass Closes #42"
Options:
--draft, --reviewer user1,user2, --label "enhancement", --base develop
With git + curl:
BRANCH=$(git branch --show-current) curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/$OWNER/$REPO/pulls \ -d "{ \"title\": \"feat: add JWT-based user authentication\", \"body\": \"## Summary\nAdds login and register API endpoints.\n\nCloses #42\", \"head\": \"$BRANCH\", \"base\": \"main\" }"
The response JSON includes the PR
number — save it for later commands.
To create as a draft, add
"draft": true to the JSON body.
With gh:
# One-shot check gh pr checks # Watch until all checks finish (polls every 10s) gh pr checks --watch
With git + curl:
# Get the latest commit SHA on the current branch SHA=$(git rev-parse HEAD) # Query the combined status curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \ | python3 -c " import sys, json data = json.load(sys.stdin) print(f\"Overall: {data['state']}\") for s in data.get('statuses', []): print(f\" {s['context']}: {s['state']} - {s.get('description', '')}\")" # Also check GitHub Actions check runs (separate endpoint) curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/check-runs \ | python3 -c " import sys, json data = json.load(sys.stdin) for cr in data.get('check_runs', []): print(f\" {cr['name']}: {cr['status']} / {cr['conclusion'] or 'pending'}\")"
# Simple polling loop — check every 30 seconds, up to 10 minutes SHA=$(git rev-parse HEAD) for i in $(seq 1 20); do STATUS=$(curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \ | python3 -c "import sys,json; print(json.load(sys.stdin)['state'])") echo "Check $i: $STATUS" if [ "$STATUS" = "success" ] || [ "$STATUS" = "failure" ] || [ "$STATUS" = "error" ]; then break fi sleep 30 done
When CI fails, diagnose and fix. This loop works with either auth method.
With gh:
# List recent workflow runs on this branch gh run list --branch $(git branch --show-current) --limit 5 # View failed logs gh run view <RUN_ID> --log-failed
With git + curl:
BRANCH=$(git branch --show-current) # List workflow runs on this branch curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/$OWNER/$REPO/actions/runs?branch=$BRANCH&per_page=5" \ | python3 -c " import sys, json runs = json.load(sys.stdin)['workflow_runs'] for r in runs: print(f\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\")" # Get failed job logs (download as zip, extract, read) RUN_ID=<run_id> curl -s -L \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \ -o /tmp/ci-logs.zip cd /tmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs/*.txt
After identifying the issue, use file tools (
patch, write_file) to fix it:
git add <fixed_files> git commit -m "fix: resolve CI failure in <check_name>" git push
Re-check CI status using the commands from Section 4 above.
When asked to auto-fix CI, follow this loop:
read_file + patch/write_file → fix the codegit add . && git commit -m "fix: ..." && git pushWith gh:
# Squash merge + delete branch (cleanest for feature branches) gh pr merge --squash --delete-branch # Enable auto-merge (merges when all checks pass) gh pr merge --auto --squash --delete-branch
With git + curl:
PR_NUMBER=<number> # Merge the PR via API (squash) curl -s -X PUT \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/merge \ -d "{ \"merge_method\": \"squash\", \"commit_title\": \"feat: add user authentication (#$PR_NUMBER)\" }" # Delete the remote branch after merge BRANCH=$(git branch --show-current) git push origin --delete $BRANCH # Switch back to main locally git checkout main && git pull origin main git branch -d $BRANCH
Merge methods:
"merge" (merge commit), "squash", "rebase"
# Auto-merge requires the repo to have it enabled in settings. # This uses the GraphQL API since REST doesn't support auto-merge. PR_NODE_ID=$(curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \ | python3 -c "import sys,json; print(json.load(sys.stdin)['node_id'])") curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/graphql \ -d "{\"query\": \"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\"$PR_NODE_ID\\\", mergeMethod: SQUASH}) { clientMutationId } }\"}"
# 1. Start from clean main git checkout main && git pull origin main # 2. Branch git checkout -b fix/login-redirect-bug # 3. (Agent makes code changes with file tools) # 4. Commit git add src/auth/login.py tests/test_login.py git commit -m "fix: correct redirect URL after login Preserves the ?next= parameter instead of always redirecting to /dashboard." # 5. Push git push -u origin HEAD # 6. Create PR (picks gh or curl based on what's available) # ... (see Section 3) # 7. Monitor CI (see Section 4) # 8. Merge when green (see Section 6)
| Action | gh | git + curl |
|---|---|---|
| List my PRs | | |
| View PR diff | | (local) or |
| Add comment | | |
| Request review | | |
| Close PR | | |
| Check out someone's PR | | |
MIT
mkdir -p ~/.hermes/skills/github/github-pr-workflow && curl -o ~/.hermes/skills/github/github-pr-workflow/SKILL.md https://raw.githubusercontent.com/NousResearch/hermes-agent/main/skills/github/github-pr-workflow/SKILL.md1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.