github-pr-workflow

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GitHub Pull Request Workflow

GitHub Pull Request 工作流程

Complete guide for managing the PR lifecycle. Each section shows the
gh
way first, then the
git
+
curl
fallback for machines without
gh
.
管理PR生命周期的完整指南。每个部分先展示使用
gh
的方法,然后提供针对没有
gh
的机器的
git
+
curl
替代方案。

Prerequisites

前提条件

  • Authenticated with GitHub (see
    github-auth
    skill)
  • Inside a git repository with a GitHub remote
  • 已通过GitHub认证(参考
    github-auth
    技能)
  • 处于带有GitHub远程仓库的git本地仓库中

Quick Auth Detection

快速认证检测

bash
undefined
bash
undefined

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"
undefined
if command -v gh &>/dev/null && gh auth status &>/dev/null; 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 '\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"
undefined

Extracting Owner/Repo from the Git Remote

从Git远程仓库提取所有者/仓库名

Many
curl
commands need
owner/repo
. Extract it from the git remote:
bash
undefined
许多
curl
命令需要
owner/repo
信息。从git远程仓库中提取:
bash
undefined

Works for both HTTPS and SSH remote URLs

适用于HTTPS和SSH两种远程仓库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"

---
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"

---

1. Branch Creation

1. 分支创建

This part is pure
git
— identical either way:
bash
undefined
这部分完全使用
git
——两种方式操作一致:
bash
undefined

Make sure you're up to date

确保本地代码是最新的

git fetch origin git checkout main && git pull origin main
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 features
- `fix/description` — bug fixes
- `refactor/description` — code restructuring
- `docs/description` — documentation
- `ci/description` — CI/CD changes
git checkout -b feat/add-user-authentication

分支命名规范:
- `feat/description` —— 新功能
- `fix/description` —— Bug修复
- `refactor/description` —— 代码重构
- `docs/description` —— 文档更新
- `ci/description` —— CI/CD变更

2. Making Commits

2. 提交代码

Use the agent's file tools (
write_file
,
patch
) to make changes, then commit:
bash
undefined
使用代理的文件工具(
write_file
patch
)修改代码,然后提交:
bash
undefined

Stage specific files

暂存指定文件

git add src/auth.py src/models/user.py tests/test_auth.py
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 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`

3. Pushing and Creating a PR

3. 推送分支并创建PR

Push the Branch (same either way)

推送分支(两种方式操作一致)

bash
git push -u origin HEAD
bash
git push -u origin HEAD

Create the PR

创建PR

With gh:
bash
gh pr create \
  --title "feat: add JWT-based user authentication" \
  --body "## Summary
- Adds login and register API endpoints
- JWT token generation and validation
使用gh:
bash
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

Test Plan

  • Unit tests pass
Closes #42"

Options: `--draft`, `--reviewer user1,user2`, `--label "enhancement"`, `--base develop`

**With git + curl:**

```bash
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.
  • Unit tests pass
Closes #42"

可选参数:`--draft`(创建草稿PR)、`--reviewer user1,user2`(指定审核人)、`--label "enhancement"`(添加标签)、`--base develop`(指定目标分支)

**使用git + curl:**

```bash
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\"
  }"
返回的JSON中包含PR的
number
——请保存该值用于后续命令。
如需创建草稿PR,在JSON体中添加
"draft": true

4. Monitoring CI Status

4. 监控CI状态

Check CI Status

检查CI状态

With gh:
bash
undefined
使用gh:
bash
undefined

One-shot check

单次检查

gh pr checks
gh pr checks

Watch until all checks finish (polls every 10s)

持续监控直到所有检查完成(每10秒轮询一次)

gh pr checks --watch

**With git + curl:**

```bash
gh pr checks --watch

**使用git + curl:**

```bash

Get the latest commit SHA on the current branch

获取当前分支最新提交的SHA值

SHA=$(git rev-parse HEAD)
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', '')}")"
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)

同时检查GitHub Actions的检查运行情况(独立接口)

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'}")"
undefined
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'}")"
undefined

Poll Until Complete (git + curl)

持续轮询直到完成(git + curl)

bash
undefined
bash
undefined

Simple polling loop — check every 30 seconds, up to 10 minutes

简单轮询循环——每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
undefined
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
undefined

5. Auto-Fixing CI Failures

5. 自动修复CI失败

When CI fails, diagnose and fix. This loop works with either auth method.
当CI失败时,诊断问题并修复。以下循环适用于两种认证方式。

Step 1: Get Failure Details

步骤1:获取失败详情

With gh:
bash
undefined
使用gh:
bash
undefined

List recent workflow runs on this branch

列出当前分支最近的工作流运行记录

gh run list --branch $(git branch --show-current) --limit 5
gh run list --branch $(git branch --show-current) --limit 5

View failed logs

查看失败日志

gh run view <RUN_ID> --log-failed

**With git + curl:**

```bash
BRANCH=$(git branch --show-current)
gh run view <RUN_ID> --log-failed

**使用git + curl:**

```bash
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']}")"
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)

获取失败任务的日志(下载为zip包,解压后查看)

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
undefined
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
undefined

Step 2: Fix and Push

步骤2:修复并推送

After identifying the issue, use file tools (
patch
,
write_file
) to fix it:
bash
git add <fixed_files>
git commit -m "fix: resolve CI failure in <check_name>"
git push
定位问题后,使用文件工具(
patch
write_file
)修复代码:
bash
git add <fixed_files>
git commit -m "fix: resolve CI failure in <check_name>"
git push

Step 3: Verify

步骤3:验证

Re-check CI status using the commands from Section 4 above.
使用第4节中的命令重新检查CI状态。

Auto-Fix Loop Pattern

自动修复循环模式

When asked to auto-fix CI, follow this loop:
  1. Check CI status → identify failures
  2. Read failure logs → understand the error
  3. Use
    read_file
    +
    patch
    /
    write_file
    → fix the code
  4. git add . && git commit -m "fix: ..." && git push
  5. Wait for CI → re-check status
  6. Repeat if still failing (up to 3 attempts, then ask the user)
当需要自动修复CI时,请遵循以下循环:
  1. 检查CI状态 → 定位失败项
  2. 查看失败日志 → 理解错误原因
  3. 使用
    read_file
    +
    patch
    /
    write_file
    → 修复代码
  4. git add . && git commit -m "fix: ..." && git push
  5. 等待CI运行 → 重新检查状态
  6. 若仍失败则重复操作(最多3次,之后询问用户)

6. Merging

6. 合并PR

With gh:
bash
undefined
使用gh:
bash
undefined

Squash merge + delete branch (cleanest for feature branches)

压缩合并 + 删除分支(功能分支的最优方式)

gh pr merge --squash --delete-branch
gh pr merge --squash --delete-branch

Enable auto-merge (merges when all checks pass)

启用自动合并(所有检查通过后自动合并)

gh pr merge --auto --squash --delete-branch

**With git + curl:**

```bash
PR_NUMBER=<number>
gh pr merge --auto --squash --delete-branch

**使用git + curl:**

```bash
PR_NUMBER=<number>

Merge the PR via API (squash)

通过API合并PR(压缩合并)

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)" }"
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
BRANCH=$(git branch --show-current) git push origin --delete $BRANCH

Switch back to main locally

本地切换回main分支

git checkout main && git pull origin main git branch -d $BRANCH

Merge methods: `"merge"` (merge commit), `"squash"`, `"rebase"`
git checkout main && git pull origin main git branch -d $BRANCH

合并方式:`"merge"`(创建合并提交)、`"squash"`(压缩合并)、`"rebase"`(变基合并)

Enable Auto-Merge (curl)

启用自动合并(curl)

bash
undefined
bash
undefined

Auto-merge requires the repo to have it enabled in settings.

启用自动合并需要仓库在设置中开启该功能。

This uses the GraphQL API since REST doesn't support auto-merge.

由于REST API不支持自动合并,此处使用GraphQL API。

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 } }"}"
undefined
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 } }"}"
undefined

7. Complete Workflow Example

7. 完整工作流程示例

bash
undefined
bash
undefined

1. Start from clean main

1. 从干净的main分支开始

git checkout main && git pull origin main
git checkout main && git pull origin main

2. Branch

2. 创建分支

git checkout -b fix/login-redirect-bug
git checkout -b fix/login-redirect-bug

3. (Agent makes code changes with file tools)

3. (代理使用文件工具修改代码)

4. Commit

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."
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

5. 推送分支

git push -u origin HEAD
git push -u origin HEAD

6. Create PR (picks gh or curl based on what's available)

6. 创建PR(根据可用工具选择gh或curl)

... (see Section 3)

...(参考第3节)

7. Monitor CI (see Section 4)

7. 监控CI状态(参考第4节)

8. Merge when green (see Section 6)

8. 检查通过后合并(参考第6节)

undefined
undefined

Useful PR Commands Reference

实用PR命令参考

Actionghgit + curl
List my PRs
gh pr list --author @me
curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$OWNER/$REPO/pulls?state=open"
View PR diff
gh pr diff
git diff main...HEAD
(local) or
curl -H "Accept: application/vnd.github.diff" ...
Add comment
gh pr comment N --body "..."
curl -X POST .../issues/N/comments -d '{"body":"..."}'
Request review
gh pr edit N --add-reviewer user
curl -X POST .../pulls/N/requested_reviewers -d '{"reviewers":["user"]}'
Close PR
gh pr close N
curl -X PATCH .../pulls/N -d '{"state":"closed"}'
Check out someone's PR
gh pr checkout N
git fetch origin pull/N/head:pr-N && git checkout pr-N
操作ghgit + 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差异
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":"..."}'
请求审核
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