GitHub PR 生命周期:分支、提交、开启、CI、合并
完整的 PR 生命周期管理指南。每个部分先展示 gh,再展示 git + curl 备选方案(适用于没有 gh 的机器)。
github-auth skill)
# 确定整个工作流中使用哪种方法
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then
AUTH="gh"
else
AUTH="git"
# 确保我们有 API 调用的令牌
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 'nr')
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"
# HTTPS 和 SSH remote URL 均可用
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"
---
这部分是纯 git——两种方式完全相同:
# 确保已更新
git fetch origin
git checkout main && git pull origin main
# 创建并切换到新分支
git checkout -b feat/add-user-authentication
分支命名约定:
feat/description — 新功能fix/description — bug 修复refactor/description — 代码重构docs/description — 文档ci/description — CI/CD 更改使用 agent 的文件工具(write_file、patch)进行更改,然后提交:
# 暂存特定文件
git add src/auth.py src/models/user.py tests/test_auth.py
# 提交并使用 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"
提交信息格式(Conventional Commits):
type(scope): 简短描述 需要的话提供更详细的说明。72 字符换行。
类型:feat、fix、refactor、docs、test、ci、chore、perf
git push -u origin HEAD
用 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"
选项:--draft、--reviewer user1,user2、--label "enhancement"、--base develop
用 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": "## SummarynAdds login and register API endpoints.nnCloses #42",
"head": "$BRANCH",
"base": "main"
}"
响应 JSON 包含 PR number——保存以供后续命令使用。
要创建为草稿,在 JSON body 中添加 "draft": true。
用 gh:
# 单次检查
gh pr checks
# 持续监控直到所有检查完成(每 10s 轮询)
gh pr checks --watch
用 git + curl:
# 获取当前分支的最新提交 SHA
SHA=$(git rev-parse HEAD)
# 查询组合状态
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', '')}")"
# 同时检查 GitHub Actions check runs(独立端点)
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'}")"
# 简单轮询循环——每 30 秒检查一次,最多 10 分钟
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
当 CI 失败时,诊断并修复。这个循环适用于两种认证方式。
用 gh:
# 列出此分支最近的 workflow 运行
gh run list --branch $(git branch --show-current) --limit 5
# 查看失败日志
gh run view --log-failed
用 git + curl:
BRANCH=$(git branch --show-current)
# 列出此分支的 workflow 运行
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']}")"
# 获取失败 job 日志(下载为 zip,解压,读取)
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
确定问题后,使用文件工具(patch、write_file)修复:
git add
git commit -m "fix: resolve CI failure in "
git push
使用上面第 4 节的命令重新检查 CI 状态。
当被要求自动修复 CI 时,遵循此循环:
read_file + patch/write_file → 修复代码git add . && git commit -m "fix: ..." && git push用 gh:
# Squash 合并 + 删除分支(功能分支最干净)
gh pr merge --squash --delete-branch
# 启用自动合并(所有检查通过后合并)
gh pr merge --auto --squash --delete-branch
用 git + curl:
PR_NUMBER=
# 通过 API 合并 PR(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)"
}"
# 合并后删除远程分支
BRANCH=$(git branch --show-current)
git push origin --delete $BRANCH
# 在本地切回 main 并拉取
git checkout main && git pull origin main
git branch -d $BRANCH
合并方法:"merge"(merge 提交)、"squash"、"rebase"
# 自动合并需要在仓库设置中启用。
# 这使用 GraphQL API,因为 REST 不支持自动合并。
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. 从干净的 main 开始
git checkout main && git pull origin main
# 2. 创建分支
git checkout -b fix/login-redirect-bug
# 3. (Agent 使用文件工具进行代码更改)
# 4. 提交
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. 推送
git push -u origin HEAD
# 6. 创建 PR(根据可用性选择 gh 或 curl)
# ...(见第 3 节)
# 7. 监控 CI(见第 4 节)
# 8. 变绿后合并(见第 6 节)
| 操作 | gh | git + curl |
| 列出我的 PR | `gh pr list --author @me` | `curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$OWNER/$REPO/pulls?state=open"` |
| 查看 PR diff | `gh pr diff` | `git diff main...HEAD`(本地)或 `curl -H "Accept: application/vnd.github.diff" ...` |
| 添加评论 | `gh pr comment N --body "..."` | `curl -X POST .../issues/N/comments -d '{"body":"..."}'` |
| 请求 review | `gh pr edit N --add-reviewer user` | `curl -X POST .../pulls/N/requested_reviewers -d '{"reviewers":["user"]}'` |
| 关闭 PR | `gh pr close N` | `curl -X PATCH .../pulls/N -d '{"state":"closed"}'` |
| 检出具他人的 PR | `gh pr checkout N` | `git fetch origin pull/N/head:pr-N && git checkout pr-N` |
评论区