[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DFDXZ2G1MBPXYYC9S8S554":3,"skill-same:01M6DFDXZ2G1MBPXYYC9S8S554":87},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":65,"commitSha":66,"skillDirectory":67,"forksCount":68,"repositoryHtmlUrl":69,"repositoryHomepageUrl":6,"ownerHtmlUrl":70,"ownerBlogUrl":6,"ownerDescription":71,"updatedAt":72,"install":73,"resources":86},"01M6DFDXZ2G1MBPXYYC9S8S554","github-pr-workflow",null,"GitHub PR lifecycle: branch, commit, open, CI, merge.","zapabob\u002FSkills","zapabob","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F130830376?v=4","01M6DBMYZAGRTFQDSQYW3W764P","峯岸 亮","01M6DBMZ3GKDSJ01NZ9XTZD7JD",2,"MIT","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002F4b\u002F4b5a3e0af0fad2e0fd235d40facb67944f94b45e6bc84518dcbc4e6e240d4e1c\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"github pr","github","workflow","pr workflow","pr","github pr workflow","git","branch","open","ci","pull","code-review","pull-requests","macos","code","windows","merge","commit","auth","review","2026-11-10 10:12:30",false,"---\r\nname: github-pr-workflow\r\ndescription: \"GitHub PR lifecycle: branch, commit, open, CI, merge.\"\r\nversion: 1.1.0\r\nauthor: Hermes Agent\r\nlicense: MIT\r\nplatforms: [linux, macos, windows]\r\nmetadata:\r\n  hermes:\r\n    tags: [GitHub, Pull-Requests, CI\u002FCD, Git, Automation, Merge]\r\n    related_skills: [github-auth, github-code-review]\r\n---\r\n\r\n# GitHub Pull Request Workflow\r\n\r\nComplete guide for managing the PR lifecycle. Each section shows the `gh` way first, then the `git` + `curl` fallback for machines without `gh`.\r\n\r\n## Prerequisites\r\n\r\n- Authenticated with GitHub (see `github-auth` skill)\r\n- Inside a git repository with a GitHub remote\r\n\r\n### Quick Auth Detection\r\n\r\n```bash\r\n# Determine which method to use throughout this workflow\r\nif command -v gh &>\u002Fdev\u002Fnull && gh auth status &>\u002Fdev\u002Fnull; then\r\n  AUTH=\"gh\"\r\nelse\r\n  AUTH=\"git\"\r\n  # Ensure we have a token for API calls\r\n  if [ -z \"$GITHUB_TOKEN\" ]; then\r\n    if [ -f ~\u002F.hermes\u002F.env ] && grep -q \"^GITHUB_TOKEN=\" ~\u002F.hermes\u002F.env; then\r\n      GITHUB_TOKEN=$(grep \"^GITHUB_TOKEN=\" ~\u002F.hermes\u002F.env | head -1 | cut -d= -f2 | tr -d '\\n\\r')\r\n    elif grep -q \"github.com\" ~\u002F.git-credentials 2>\u002Fdev\u002Fnull; then\r\n      GITHUB_TOKEN=$(grep \"github.com\" ~\u002F.git-credentials 2>\u002Fdev\u002Fnull | head -1 | sed 's|https:\u002F\u002F[REDACTED]@]*\\)@.*|\\1|')\r\n    fi\r\n  fi\r\nfi\r\necho \"Using: $AUTH\"\r\n```\r\n\r\n### Extracting Owner\u002FRepo from the Git Remote\r\n\r\nMany `curl` commands need `owner\u002Frepo`. Extract it from the git remote:\r\n\r\n```bash\r\n# Works for both HTTPS and SSH remote URLs\r\nREMOTE_URL=$(git remote get-url origin)\r\nOWNER_REPO=$(echo \"$REMOTE_URL\" | sed -E 's|.*github\\.com[:\u002F]||; s|\\.git$||')\r\nOWNER=$(echo \"$OWNER_REPO\" | cut -d\u002F -f1)\r\nREPO=$(echo \"$OWNER_REPO\" | cut -d\u002F -f2)\r\necho \"Owner: $OWNER, Repo: $REPO\"\r\n```\r\n\r\n---\r\n\r\n## 1. Branch Creation\r\n\r\nThis part is pure `git` — identical either way:\r\n\r\n```bash\r\n# Make sure you're up to date\r\ngit fetch origin\r\ngit checkout main && git pull origin main\r\n\r\n# Create and switch to a new branch\r\ngit checkout -b feat\u002Fadd-user-authentication\r\n```\r\n\r\nBranch naming conventions:\r\n- `feat\u002Fdescription` — new features\r\n- `fix\u002Fdescription` — bug fixes\r\n- `refactor\u002Fdescription` — code restructuring\r\n- `docs\u002Fdescription` — documentation\r\n- `ci\u002Fdescription` — CI\u002FCD changes\r\n\r\n## 2. Making Commits\r\n\r\nUse the agent's file tools (`write_file`, `patch`) to make changes, then commit:\r\n\r\n```bash\r\n# Stage specific files\r\ngit add src\u002Fauth.py src\u002Fmodels\u002Fuser.py tests\u002Ftest_auth.py\r\n\r\n# Commit with a conventional commit message\r\ngit commit -m \"feat: add JWT-based user authentication\r\n\r\n- Add login\u002Fregister endpoints\r\n- Add User model with password hashing\r\n- Add auth middleware for protected routes\r\n- Add unit tests for auth flow\"\r\n```\r\n\r\nCommit message format (Conventional Commits):\r\n```\r\ntype(scope): short description\r\n\r\nLonger explanation if needed. Wrap at 72 characters.\r\n```\r\n\r\nTypes: `feat`, `fix`, `refactor`, `docs`, `test`, `ci`, `chore`, `perf`\r\n\r\n## 3. Pushing and Creating a PR\r\n\r\n### Push the Branch (same either way)\r\n\r\n```bash\r\ngit push -u origin HEAD\r\n```\r\n\r\n### Create the PR\r\n\r\n**With gh:**\r\n\r\n```bash\r\ngh pr create \\\r\n  --title \"feat: add JWT-based user authentication\" \\\r\n  --body \"## Summary\r\n- Adds login and register API endpoints\r\n- JWT token generation and validation\r\n\r\n## Test Plan\r\n- [ ] Unit tests pass\r\n\r\nCloses #42\"\r\n```\r\n\r\nOptions: `--draft`, `--reviewer user1,user2`, `--label \"enhancement\"`, `--base develop`\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nBRANCH=$(git branch --show-current)\r\n\r\ncurl -s -X POST \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  -H \"Accept: application\u002Fvnd.github.v3+json\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls \\\r\n  -d \"{\r\n    \\\"title\\\": \\\"feat: add JWT-based user authentication\\\",\r\n    \\\"body\\\": \\\"## Summary\\nAdds login and register API endpoints.\\n\\nCloses #42\\\",\r\n    \\\"head\\\": \\\"$BRANCH\\\",\r\n    \\\"base\\\": \\\"main\\\"\r\n  }\"\r\n```\r\n\r\nThe response JSON includes the PR `number` — save it for later commands.\r\n\r\nTo create as a draft, add `\"draft\": true` to the JSON body.\r\n\r\n## 4. Monitoring CI Status\r\n\r\n### Check CI Status\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# One-shot check\r\ngh pr checks\r\n\r\n# Watch until all checks finish (polls every 10s)\r\ngh pr checks --watch\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\n# Get the latest commit SHA on the current branch\r\nSHA=$(git rev-parse HEAD)\r\n\r\n# Query the combined status\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fstatus \\\r\n  | python3 -c \"\r\nimport sys, json\r\ndata = json.load(sys.stdin)\r\nprint(f\\\"Overall: {data['state']}\\\")\r\nfor s in data.get('statuses', []):\r\n    print(f\\\"  {s['context']}: {s['state']} - {s.get('description', '')}\\\")\"\r\n\r\n# Also check GitHub Actions check runs (separate endpoint)\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fcheck-runs \\\r\n  | python3 -c \"\r\nimport sys, json\r\ndata = json.load(sys.stdin)\r\nfor cr in data.get('check_runs', []):\r\n    print(f\\\"  {cr['name']}: {cr['status']} \u002F {cr['conclusion'] or 'pending'}\\\")\"\r\n```\r\n\r\n### Poll Until Complete (git + curl)\r\n\r\n```bash\r\n# Simple polling loop — check every 30 seconds, up to 10 minutes\r\nSHA=$(git rev-parse HEAD)\r\nfor i in $(seq 1 20); do\r\n  STATUS=$(curl -s \\\r\n    -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n    https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fstatus \\\r\n    | python3 -c \"import sys,json; print(json.load(sys.stdin)['state'])\")\r\n  echo \"Check $i: $STATUS\"\r\n  if [ \"$STATUS\" = \"success\" ] || [ \"$STATUS\" = \"failure\" ] || [ \"$STATUS\" = \"error\" ]; then\r\n    break\r\n  fi\r\n  sleep 30\r\ndone\r\n```\r\n\r\n## 5. Auto-Fixing CI Failures\r\n\r\nWhen CI fails, diagnose and fix. This loop works with either auth method.\r\n\r\n### Step 1: Get Failure Details\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# List recent workflow runs on this branch\r\ngh run list --branch $(git branch --show-current) --limit 5\r\n\r\n# View failed logs\r\ngh run view \u003CRUN_ID> --log-failed\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nBRANCH=$(git branch --show-current)\r\n\r\n# List workflow runs on this branch\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  \"https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Factions\u002Fruns?branch=$BRANCH&per_page=5\" \\\r\n  | python3 -c \"\r\nimport sys, json\r\nruns = json.load(sys.stdin)['workflow_runs']\r\nfor r in runs:\r\n    print(f\\\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\\\")\"\r\n\r\n# Get failed job logs (download as zip, extract, read)\r\nRUN_ID=\u003Crun_id>\r\ncurl -s -L \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Factions\u002Fruns\u002F$RUN_ID\u002Flogs \\\r\n  -o \u002Ftmp\u002Fci-logs.zip\r\ncd \u002Ftmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs\u002F*.txt\r\n```\r\n\r\n### Step 2: Fix and Push\r\n\r\nAfter identifying the issue, use file tools (`patch`, `write_file`) to fix it:\r\n\r\n```bash\r\ngit add \u003Cfixed_files>\r\ngit commit -m \"fix: resolve CI failure in \u003Ccheck_name>\"\r\ngit push\r\n```\r\n\r\n### Step 3: Verify\r\n\r\nRe-check CI status using the commands from Section 4 above.\r\n\r\n### Auto-Fix Loop Pattern\r\n\r\nWhen asked to auto-fix CI, follow this loop:\r\n\r\n1. Check CI status → identify failures\r\n2. Read failure logs → understand the error\r\n3. Use `read_file` + `patch`\u002F`write_file` → fix the code\r\n4. `git add . && git commit -m \"fix: ...\" && git push`\r\n5. Wait for CI → re-check status\r\n6. Repeat if still failing (up to 3 attempts, then ask the user)\r\n\r\n## 6. Merging\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# Squash merge + delete branch (cleanest for feature branches)\r\ngh pr merge --squash --delete-branch\r\n\r\n# Enable auto-merge (merges when all checks pass)\r\ngh pr merge --auto --squash --delete-branch\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nPR_NUMBER=\u003Cnumber>\r\n\r\n# Merge the PR via API (squash)\r\ncurl -s -X PUT \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls\u002F$PR_NUMBER\u002Fmerge \\\r\n  -d \"{\r\n    \\\"merge_method\\\": \\\"squash\\\",\r\n    \\\"commit_title\\\": \\\"feat: add user authentication (#$PR_NUMBER)\\\"\r\n  }\"\r\n\r\n# Delete the remote branch after merge\r\nBRANCH=$(git branch --show-current)\r\ngit push origin --delete $BRANCH\r\n\r\n# Switch back to main locally\r\ngit checkout main && git pull origin main\r\ngit branch -d $BRANCH\r\n```\r\n\r\nMerge methods: `\"merge\"` (merge commit), `\"squash\"`, `\"rebase\"`\r\n\r\n### Enable Auto-Merge (curl)\r\n\r\n```bash\r\n# Auto-merge requires the repo to have it enabled in settings.\r\n# This uses the GraphQL API since REST doesn't support auto-merge.\r\nPR_NODE_ID=$(curl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls\u002F$PR_NUMBER \\\r\n  | python3 -c \"import sys,json; print(json.load(sys.stdin)['node_id'])\")\r\n\r\ncurl -s -X POST \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Fgraphql \\\r\n  -d \"{\\\"query\\\": \\\"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\\\\\"$PR_NODE_ID\\\\\\\", mergeMethod: SQUASH}) { clientMutationId } }\\\"}\"\r\n```\r\n\r\n## 7. Complete Workflow Example\r\n\r\n```bash\r\n# 1. Start from clean main\r\ngit checkout main && git pull origin main\r\n\r\n# 2. Branch\r\ngit checkout -b fix\u002Flogin-redirect-bug\r\n\r\n# 3. (Agent makes code changes with file tools)\r\n\r\n# 4. Commit\r\ngit add src\u002Fauth\u002Flogin.py tests\u002Ftest_login.py\r\ngit commit -m \"fix: correct redirect URL after login\r\n\r\nPreserves the ?next= parameter instead of always redirecting to \u002Fdashboard.\"\r\n\r\n# 5. Push\r\ngit push -u origin HEAD\r\n\r\n# 6. Create PR (picks gh or curl based on what's available)\r\n# ... (see Section 3)\r\n\r\n# 7. Monitor CI (see Section 4)\r\n\r\n# 8. Merge when green (see Section 6)\r\n```\r\n\r\n## Useful PR Commands Reference\r\n\r\n| Action | gh | git + curl |\r\n|--------|-----|-----------|\r\n| List my PRs | `gh pr list --author @me` | `curl -s -H \"Authorization: token $GITHUB_TOKEN\" \"https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls?state=open\"` |\r\n| View PR diff | `gh pr diff` | `git diff main...HEAD` (local) or `curl -H \"Accept: application\u002Fvnd.github.diff\" ...` |\r\n| Add comment | `gh pr comment N --body \"...\"` | `curl -X POST ...\u002Fissues\u002FN\u002Fcomments -d '{\"body\":\"...\"}'` |\r\n| Request review | `gh pr edit N --add-reviewer user` | `curl -X POST ...\u002Fpulls\u002FN\u002Frequested_reviewers -d '{\"reviewers\":[\"user\"]}'` |\r\n| Close PR | `gh pr close N` | `curl -X PATCH ...\u002Fpulls\u002FN -d '{\"state\":\"closed\"}'` |\r\n| Check out someone's PR | `gh pr checkout N` | `git fetch origin pull\u002FN\u002Fhead:pr-N && git checkout pr-N` |\r\n","# GitHub Pull Request Workflow\r\n\r\nComplete guide for managing the PR lifecycle. Each section shows the `gh` way first, then the `git` + `curl` fallback for machines without `gh`.\r\n\r\n## Prerequisites\r\n\r\n- Authenticated with GitHub (see `github-auth` skill)\r\n- Inside a git repository with a GitHub remote\r\n\r\n### Quick Auth Detection\r\n\r\n```bash\r\n# Determine which method to use throughout this workflow\r\nif command -v gh &>\u002Fdev\u002Fnull && gh auth status &>\u002Fdev\u002Fnull; then\r\n  AUTH=\"gh\"\r\nelse\r\n  AUTH=\"git\"\r\n  # Ensure we have a token for API calls\r\n  if [ -z \"$GITHUB_TOKEN\" ]; then\r\n    if [ -f ~\u002F.hermes\u002F.env ] && grep -q \"^GITHUB_TOKEN=\" ~\u002F.hermes\u002F.env; then\r\n      GITHUB_TOKEN=$(grep \"^GITHUB_TOKEN=\" ~\u002F.hermes\u002F.env | head -1 | cut -d= -f2 | tr -d '\\n\\r')\r\n    elif grep -q \"github.com\" ~\u002F.git-credentials 2>\u002Fdev\u002Fnull; then\r\n      GITHUB_TOKEN=$(grep \"github.com\" ~\u002F.git-credentials 2>\u002Fdev\u002Fnull | head -1 | sed 's|https:\u002F\u002F[REDACTED]@]*\\)@.*|\\1|')\r\n    fi\r\n  fi\r\nfi\r\necho \"Using: $AUTH\"\r\n```\r\n\r\n### Extracting Owner\u002FRepo from the Git Remote\r\n\r\nMany `curl` commands need `owner\u002Frepo`. Extract it from the git remote:\r\n\r\n```bash\r\n# Works for both HTTPS and SSH remote URLs\r\nREMOTE_URL=$(git remote get-url origin)\r\nOWNER_REPO=$(echo \"$REMOTE_URL\" | sed -E 's|.*github\\.com[:\u002F]||; s|\\.git$||')\r\nOWNER=$(echo \"$OWNER_REPO\" | cut -d\u002F -f1)\r\nREPO=$(echo \"$OWNER_REPO\" | cut -d\u002F -f2)\r\necho \"Owner: $OWNER, Repo: $REPO\"\r\n```\r\n\r\n---\r\n\r\n## 1. Branch Creation\r\n\r\nThis part is pure `git` — identical either way:\r\n\r\n```bash\r\n# Make sure you're up to date\r\ngit fetch origin\r\ngit checkout main && git pull origin main\r\n\r\n# Create and switch to a new branch\r\ngit checkout -b feat\u002Fadd-user-authentication\r\n```\r\n\r\nBranch naming conventions:\r\n- `feat\u002Fdescription` — new features\r\n- `fix\u002Fdescription` — bug fixes\r\n- `refactor\u002Fdescription` — code restructuring\r\n- `docs\u002Fdescription` — documentation\r\n- `ci\u002Fdescription` — CI\u002FCD changes\r\n\r\n## 2. Making Commits\r\n\r\nUse the agent's file tools (`write_file`, `patch`) to make changes, then commit:\r\n\r\n```bash\r\n# Stage specific files\r\ngit add src\u002Fauth.py src\u002Fmodels\u002Fuser.py tests\u002Ftest_auth.py\r\n\r\n# Commit with a conventional commit message\r\ngit commit -m \"feat: add JWT-based user authentication\r\n\r\n- Add login\u002Fregister endpoints\r\n- Add User model with password hashing\r\n- Add auth middleware for protected routes\r\n- Add unit tests for auth flow\"\r\n```\r\n\r\nCommit message format (Conventional Commits):\r\n```\r\ntype(scope): short description\r\n\r\nLonger explanation if needed. Wrap at 72 characters.\r\n```\r\n\r\nTypes: `feat`, `fix`, `refactor`, `docs`, `test`, `ci`, `chore`, `perf`\r\n\r\n## 3. Pushing and Creating a PR\r\n\r\n### Push the Branch (same either way)\r\n\r\n```bash\r\ngit push -u origin HEAD\r\n```\r\n\r\n### Create the PR\r\n\r\n**With gh:**\r\n\r\n```bash\r\ngh pr create \\\r\n  --title \"feat: add JWT-based user authentication\" \\\r\n  --body \"## Summary\r\n- Adds login and register API endpoints\r\n- JWT token generation and validation\r\n\r\n## Test Plan\r\n- [ ] Unit tests pass\r\n\r\nCloses #42\"\r\n```\r\n\r\nOptions: `--draft`, `--reviewer user1,user2`, `--label \"enhancement\"`, `--base develop`\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nBRANCH=$(git branch --show-current)\r\n\r\ncurl -s -X POST \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  -H \"Accept: application\u002Fvnd.github.v3+json\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls \\\r\n  -d \"{\r\n    \\\"title\\\": \\\"feat: add JWT-based user authentication\\\",\r\n    \\\"body\\\": \\\"## Summary\\nAdds login and register API endpoints.\\n\\nCloses #42\\\",\r\n    \\\"head\\\": \\\"$BRANCH\\\",\r\n    \\\"base\\\": \\\"main\\\"\r\n  }\"\r\n```\r\n\r\nThe response JSON includes the PR `number` — save it for later commands.\r\n\r\nTo create as a draft, add `\"draft\": true` to the JSON body.\r\n\r\n## 4. Monitoring CI Status\r\n\r\n### Check CI Status\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# One-shot check\r\ngh pr checks\r\n\r\n# Watch until all checks finish (polls every 10s)\r\ngh pr checks --watch\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\n# Get the latest commit SHA on the current branch\r\nSHA=$(git rev-parse HEAD)\r\n\r\n# Query the combined status\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fstatus \\\r\n  | python3 -c \"\r\nimport sys, json\r\ndata = json.load(sys.stdin)\r\nprint(f\\\"Overall: {data['state']}\\\")\r\nfor s in data.get('statuses', []):\r\n    print(f\\\"  {s['context']}: {s['state']} - {s.get('description', '')}\\\")\"\r\n\r\n# Also check GitHub Actions check runs (separate endpoint)\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fcheck-runs \\\r\n  | python3 -c \"\r\nimport sys, json\r\ndata = json.load(sys.stdin)\r\nfor cr in data.get('check_runs', []):\r\n    print(f\\\"  {cr['name']}: {cr['status']} \u002F {cr['conclusion'] or 'pending'}\\\")\"\r\n```\r\n\r\n### Poll Until Complete (git + curl)\r\n\r\n```bash\r\n# Simple polling loop — check every 30 seconds, up to 10 minutes\r\nSHA=$(git rev-parse HEAD)\r\nfor i in $(seq 1 20); do\r\n  STATUS=$(curl -s \\\r\n    -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n    https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fcommits\u002F$SHA\u002Fstatus \\\r\n    | python3 -c \"import sys,json; print(json.load(sys.stdin)['state'])\")\r\n  echo \"Check $i: $STATUS\"\r\n  if [ \"$STATUS\" = \"success\" ] || [ \"$STATUS\" = \"failure\" ] || [ \"$STATUS\" = \"error\" ]; then\r\n    break\r\n  fi\r\n  sleep 30\r\ndone\r\n```\r\n\r\n## 5. Auto-Fixing CI Failures\r\n\r\nWhen CI fails, diagnose and fix. This loop works with either auth method.\r\n\r\n### Step 1: Get Failure Details\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# List recent workflow runs on this branch\r\ngh run list --branch $(git branch --show-current) --limit 5\r\n\r\n# View failed logs\r\ngh run view \u003CRUN_ID> --log-failed\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nBRANCH=$(git branch --show-current)\r\n\r\n# List workflow runs on this branch\r\ncurl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  \"https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Factions\u002Fruns?branch=$BRANCH&per_page=5\" \\\r\n  | python3 -c \"\r\nimport sys, json\r\nruns = json.load(sys.stdin)['workflow_runs']\r\nfor r in runs:\r\n    print(f\\\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\\\")\"\r\n\r\n# Get failed job logs (download as zip, extract, read)\r\nRUN_ID=\u003Crun_id>\r\ncurl -s -L \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Factions\u002Fruns\u002F$RUN_ID\u002Flogs \\\r\n  -o \u002Ftmp\u002Fci-logs.zip\r\ncd \u002Ftmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs\u002F*.txt\r\n```\r\n\r\n### Step 2: Fix and Push\r\n\r\nAfter identifying the issue, use file tools (`patch`, `write_file`) to fix it:\r\n\r\n```bash\r\ngit add \u003Cfixed_files>\r\ngit commit -m \"fix: resolve CI failure in \u003Ccheck_name>\"\r\ngit push\r\n```\r\n\r\n### Step 3: Verify\r\n\r\nRe-check CI status using the commands from Section 4 above.\r\n\r\n### Auto-Fix Loop Pattern\r\n\r\nWhen asked to auto-fix CI, follow this loop:\r\n\r\n1. Check CI status → identify failures\r\n2. Read failure logs → understand the error\r\n3. Use `read_file` + `patch`\u002F`write_file` → fix the code\r\n4. `git add . && git commit -m \"fix: ...\" && git push`\r\n5. Wait for CI → re-check status\r\n6. Repeat if still failing (up to 3 attempts, then ask the user)\r\n\r\n## 6. Merging\r\n\r\n**With gh:**\r\n\r\n```bash\r\n# Squash merge + delete branch (cleanest for feature branches)\r\ngh pr merge --squash --delete-branch\r\n\r\n# Enable auto-merge (merges when all checks pass)\r\ngh pr merge --auto --squash --delete-branch\r\n```\r\n\r\n**With git + curl:**\r\n\r\n```bash\r\nPR_NUMBER=\u003Cnumber>\r\n\r\n# Merge the PR via API (squash)\r\ncurl -s -X PUT \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls\u002F$PR_NUMBER\u002Fmerge \\\r\n  -d \"{\r\n    \\\"merge_method\\\": \\\"squash\\\",\r\n    \\\"commit_title\\\": \\\"feat: add user authentication (#$PR_NUMBER)\\\"\r\n  }\"\r\n\r\n# Delete the remote branch after merge\r\nBRANCH=$(git branch --show-current)\r\ngit push origin --delete $BRANCH\r\n\r\n# Switch back to main locally\r\ngit checkout main && git pull origin main\r\ngit branch -d $BRANCH\r\n```\r\n\r\nMerge methods: `\"merge\"` (merge commit), `\"squash\"`, `\"rebase\"`\r\n\r\n### Enable Auto-Merge (curl)\r\n\r\n```bash\r\n# Auto-merge requires the repo to have it enabled in settings.\r\n# This uses the GraphQL API since REST doesn't support auto-merge.\r\nPR_NODE_ID=$(curl -s \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls\u002F$PR_NUMBER \\\r\n  | python3 -c \"import sys,json; print(json.load(sys.stdin)['node_id'])\")\r\n\r\ncurl -s -X POST \\\r\n  -H \"Authorization: token $GITHUB_TOKEN\" \\\r\n  https:\u002F\u002Fapi.github.com\u002Fgraphql \\\r\n  -d \"{\\\"query\\\": \\\"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\\\\\"$PR_NODE_ID\\\\\\\", mergeMethod: SQUASH}) { clientMutationId } }\\\"}\"\r\n```\r\n\r\n## 7. Complete Workflow Example\r\n\r\n```bash\r\n# 1. Start from clean main\r\ngit checkout main && git pull origin main\r\n\r\n# 2. Branch\r\ngit checkout -b fix\u002Flogin-redirect-bug\r\n\r\n# 3. (Agent makes code changes with file tools)\r\n\r\n# 4. Commit\r\ngit add src\u002Fauth\u002Flogin.py tests\u002Ftest_login.py\r\ngit commit -m \"fix: correct redirect URL after login\r\n\r\nPreserves the ?next= parameter instead of always redirecting to \u002Fdashboard.\"\r\n\r\n# 5. Push\r\ngit push -u origin HEAD\r\n\r\n# 6. Create PR (picks gh or curl based on what's available)\r\n# ... (see Section 3)\r\n\r\n# 7. Monitor CI (see Section 4)\r\n\r\n# 8. Merge when green (see Section 6)\r\n```\r\n\r\n## Useful PR Commands Reference\r\n\r\n| Action | gh | git + curl |\r\n|--------|-----|-----------|\r\n| List my PRs | `gh pr list --author @me` | `curl -s -H \"Authorization: token $GITHUB_TOKEN\" \"https:\u002F\u002Fapi.github.com\u002Frepos\u002F$OWNER\u002F$REPO\u002Fpulls?state=open\"` |\r\n| View PR diff | `gh pr diff` | `git diff main...HEAD` (local) or `curl -H \"Accept: application\u002Fvnd.github.diff\" ...` |\r\n| Add comment | `gh pr comment N --body \"...\"` | `curl -X POST ...\u002Fissues\u002FN\u002Fcomments -d '{\"body\":\"...\"}'` |\r\n| Request review | `gh pr edit N --add-reviewer user` | `curl -X POST ...\u002Fpulls\u002FN\u002Frequested_reviewers -d '{\"reviewers\":[\"user\"]}'` |\r\n| Close PR | `gh pr close N` | `curl -X PATCH ...\u002Fpulls\u002FN -d '{\"state\":\"closed\"}'` |\r\n| Check out someone's PR | `gh pr checkout N` | `git fetch origin pull\u002FN\u002Fhead:pr-N && git checkout pr-N` |\r\n",{"name":5,"author":49,"license":15,"version":50,"metadata":51,"platforms":63,"description":7},"Hermes Agent","1.1.0",{"hermes":52},{"tags":53,"related_skills":60},[54,55,56,57,58,59],"GitHub","Pull-Requests","CI\u002FCD","Git","Automation","Merge",[61,62],"github-auth","github-code-review",[64,37,39],"linux","main","0d1434f89f4bc6b07e9d272accd8c1013768820f","archive\u002Fskill-md-reviewed\u002Fsha256\u002F4b\u002F4b5a3e0af0fad2e0fd235d40facb67944f94b45e6bc84518dcbc4e6e240d4e1c",0,"https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills","https:\u002F\u002Fgithub.com\u002Fzapabob","The Open University of JAPAN　2019-now\r\n\r\nTokyo University of Science　2007-2010","2026-10-26 16:29:01",{"source":8,"skillName":5,"commands":74,"prompt":84,"zipAvailable":85},[75,78,81],{"tool":76,"command":77},"npx","npx skills add zapabob\u002FSkills --skill github-pr-workflow",{"tool":79,"command":80},"bunx","bunx skills add zapabob\u002FSkills --skill github-pr-workflow",{"tool":82,"command":83},"pnpm","pnpm dlx skills add zapabob\u002FSkills --skill github-pr-workflow","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002F4b\u002F4b5a3e0af0fad2e0fd235d40facb67944f94b45e6bc84518dcbc4e6e240d4e1c\u002FSKILL.md",true,[],[88,118,149,176,203,220],{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":103,"publishedAt":44},"01M6GJTE1GESGGF9K028Y7753E","xurl","X\u002FTwitter via xurl CLI: post, search, DM, media, v2 API.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fxurl\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[94,97,98],{"categoryNo":95,"categoryName":96,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[90,104,37,105,25,64,39,106,107,108,109,110,111,112,113,114,65,115,116,117],"openclaw","cli","official","search","https","social-media","api","Media","hermes","hermes agent","twitter","social","via","post",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":135,"publishedAt":44},"01M6GJT8S1PXQ8WPXT1HSNBWH2","writing-plans","Write implementation plans: bite-sized tasks, paths, code.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwriting-plans\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[124,127,130,131,132],{"categoryNo":125,"categoryName":126,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":128,"categoryName":129,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},{"categoryNo":133,"categoryName":134,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000036","内容创作者",[136,137,138,139,37,43,64,26,39,140,141,142,38,143,35,144,145,146,147,148],"writing","writing plans","plans","design","documentation","tasks","development","planning","subagent","write","superpowers","paths","test-driven-development",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":158,"publishedAt":44},"01M6GJST0H5X7WHBJ3BZK0DVKH","whisper","OpenAI's general-purpose speech recognition model. Supports 99 languages, transcription, translation to English, and language identification. Six model sizes from tiny (39M params) to large (1550M params). Use for speech-to-text, podcast transcription, or multilingual audio processing. Best for robust, multilingual ASR.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwhisper\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[155],{"categoryNo":156,"categoryName":157,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",[151,37,64,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175],"openai","speech","multimodal","Transformers","ASR","Audio","text","model","speech recognition","use","general","multilingual","translation","english","identification","processing","Audio Processing",{"skillNo":177,"name":178,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":185,"publishedAt":44},"01M6GJSMRQ8EETZTYMG72P70EA","weights-and-biases","W&B: log ML experiments, sweeps, model registry, dashboards.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fweights-and-biases\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[182],{"categoryNo":183,"categoryName":184,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000013","分析与可视化",[186,37,187,188,39,189,190,191,192,193,194,166,195,196,197,198,199,200,201,202],"weights and biases","tensorflow","experiments","pytorch","visualization","registry","real-time","tuning","dashboards","experiment","log","time","Experiment Tracking","Model Registry","Hyperparameter Tuning","WandB","Real-Time Visualization",{"skillNo":204,"name":205,"nameZh":6,"description":206,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":207,"categories":208,"keywords":210,"publishedAt":44},"01M6GJS19KDPRY112JTR326S06","watchers","Poll RSS, JSON APIs, and GitHub with watermark dedup.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwatchers\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[209],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[205,37,211,25,64,212,213,214,215,216,217,112,113,218,219],"terminal","automation","http","monitoring","cron","json","rss","devops","with",{"skillNo":221,"name":222,"nameZh":6,"description":223,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":224,"categories":225,"keywords":228,"publishedAt":44},"01M6GJRHJD2A6Q830SWF9W48BC","serving-llms-vllm","vLLM: high-throughput LLM serving, OpenAI API, quantization.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fvllm\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[226,227],{"categoryNo":95,"categoryName":96,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},[229,230,231,64,232,159,233,234,235,162,236,110,237,238,239,240,241,242,243,244],"llms","vLLM","serving llms vllm","research","openai api","tensor","Inference Serving","Production","llm serving","High Throughput","PagedAttention","Continuous Batching","Quantization","Tensor Parallelism","high-throughput","throughput"]