Issue To Pr

根据 GitHub 问题自动生成修复代码并提交 Pull Request。

已扫描
适合谁
开源项目维护者、希望高效响应 Issue 的开发者
不适合谁
无 GitHub 权限的用户、无法使用 gh CLI 的环境
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @4ydx3906/issue-to-pr

Skill 说明

命令、参数、文件名以原文为准

issue-to-pr — Agent Skill

你是一个自主代理,能够读取 GitHub 问题,理解其中的问题,定位相关代码,实现修复,并准备所有内容以供审查。请按以下阶段依次执行,并使用检查清单跟踪进度。


进度检查清单

使用此检查清单跟踪工作流的进展:

  • [ ] 阶段 1:解析问题引用
  • [ ] 阶段 2:获取问题详情
  • [ ] 阶段 3:克隆或定位仓库
  • [ ] 阶段 4:分析问题
  • [ ] 阶段 5:实现修复
  • [ ] 阶段 6:验证修复
  • [ ] 阶段 7:展示变更并获取确认
  • [ ] 阶段 8:提交拉取请求(用户批准后)

阶段 1:解析问题引用

从用户输入中提取 GitHub 问题引用。

支持的输入格式:

格式示例
完整 URLhttps://github.com/owner/repo/issues/123
简写形式owner/repo#123
仅问题编号#123123(需处于 git 仓库中)

解析逻辑

  1. 完整 URL: 扫描 https://github.com/{owner}/{repo}/issues/{number} 格式,直接提取各组件。
  2. 简写形式: 匹配 {owner}/{repo}#{number} 模式。
  3. 仅问题编号: 如果仅提供数字(或 #number):

- 运行 git remote -v 检测当前仓库的 GitHub 远程地址。

- 从远程 URL 中解析出 ownerrepo(支持 HTTPS 和 SSH 格式)。

- 若不在 git 仓库中或未找到 GitHub 远程地址,向用户询问完整 URL。

  1. 若未识别出有效引用,提示用户提供有效的 GitHub 问题 URL。
  2. 在继续前确认已解析的值:

已解析的问题:{owner}/{repo}#{number}


阶段 2:获取问题详情

获取问题的完整内容,包括标题、正文、标签和评论。

策略 A:使用 gh CLI(首选)

在终端中运行:

gh issue view {number} --repo {owner}/{repo} --comments

若命令成功执行,从中提取以下信息:

  • 标题
  • 正文 / 描述
  • 标签
  • 评论(可能包含重要上下文、复现步骤或临时解决方案)

策略 B:降级使用 fetch_content

gh 未安装或命令失败:

  1. 使用 fetch_content 工具获取问题页面内容:https://github.com/{owner}/{repo}/issues/{number}
  2. 解析获取的页面内容,提取:

- 问题标题和正文

- 任何提及的文件路径、错误信息或堆栈追踪

- 维护者或报告者发布的评论

提取关键信息

从问题内容中识别并记录以下信息:

字段说明
问题摘要用一句话描述缺陷或功能缺失
复现步骤触发该问题的操作流程
预期行为正常情况下应发生的结果
实际行为实际发生的情况
错误信息堆栈追踪、日志输出、错误码
文件路径提示问题中提到的文件、模块或函数
相关问题/拉取请求提供上下文的交叉引用

阶段 3:克隆或定位仓库

确保你拥有对仓库源代码的本地访问权限。

步骤 1:检查当前工作区

git remote -v 2>/dev/null
  • 若输出包含 github.com/{owner}/{repo}(或 github.com:{owner}/{repo}),表示你已在目标仓库中。跳至步骤 3。

步骤 2:如需则进行克隆

若当前工作区不是目标仓库,执行克隆操作:

gh repo clone {owner}/{repo} /tmp/{repo} 2>/dev/null || git clone https://github.com/{owner}/{repo}.git /tmp/{repo}

然后通知用户克隆的位置。

步骤 2.5:进入仓库目录

在定位或克隆仓库后,进入仓库目录再执行任何 git 命令:

cd {repo_path}

步骤 2.7:检查推送权限并准备 fork(如需)

判断是否具有对仓库的推送权限:

gh api repos/{owner}/{repo}/collaborators/$(gh api user --jq '.login') --silent 2>/dev/null
has_push=$?

has_push 不为零(无写入权限),立即 fork 该仓库:

gh repo fork {owner}/{repo} --remote-name fork --clone=false

这可确保在创建修复分支前已有 fork。注意后续应推送到哪个远程:

  • 若有写入权限:推送到 origin
  • 若已 fork:推送到 fork

步骤 3:确保处于正确分支

首先检测默认分支:

# 检测默认分支(优先使用 GitHub API,备选使用 git)
default_branch=$(gh api repos/{owner}/{repo} --jq '.default_branch' 2>/dev/null)
if [ -z "$default_branch" ]; then
  default_branch=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
fi
if [ -z "$default_branch" ]; then
  default_branch="main"
fi

然后检出默认分支并拉取最新更改:

git checkout $default_branch
git pull --ff-only

检查修复分支是否已存在:

if git show-ref --verify --quiet refs/heads/fix/issue-{number} 2>/dev/null || \
   git show-ref --verify --quiet refs/remotes/origin/fix/issue-{number} 2>/dev/null; then
  echo "分支 fix/issue-{number} 已存在"
fi

若分支已存在,向用户询问是否:

  • 复用现有分支并从上次中断处继续
  • 重新创建分支(基于最新的默认分支,删除原有工作)
  • 重命名为 fix/issue-{number}-v2(或递增后缀)

创建修复分支:

git checkout -b fix/issue-{number}

阶段 4:分析问题

系统性地在代码库中定位问题所在。

4.1 关键词搜索

使用问题中提供的错误信息、文件路径和函数名进行搜索:

  • 使用 grep_code 搜索问题中提到的错误信息、函数名或变量名。
  • 当问题描述的是行为而非具体代码时,使用 search_codebase 进行语义搜索。
  • 如果问题提到了特定文件名,使用 search_file 根据文件名查找文件。

4.2 理解上下文

找到候选文件后:

  1. 阅读相关文件,理解当前实现逻辑。
  2. 跟踪导致报告缺陷的代码路径。
  3. 查看相关测试,了解预期行为。
  4. 如有必要,检查受影响文件的近期 Git 提交历史:
   git log --oneline -10 -- {file_path}

4.3 根因分析

在编写任何代码之前,生成结构化的分析结果:

### 分析结果
- **根本原因:** {缺陷发生的原因}
- **受影响文件:** {file1 (函数名), file2 (函数名)}
- **修复策略:** {应采取的最小改动方案}
- **风险评估:** 低 / 中 / 高
- **预计修改:** {N 个文件,约 M 行代码}

此结构化输出将在第 5 阶段(实现)和第 7 阶段(总结)中被引用。

4.4 作用域评估

在进入实现阶段前,评估工作范围:

  • 多个子问题: 若问题描述了多个独立的问题,优先解决最关键的一个。其余事项可记录为后续问题或拆分为单独的 PR。
  • 多包仓库检测: 检查 package.jsonpnpm-workspace.yamllerna.json 或类似的工作区配置文件中是否存在 workspaces。若发现,将搜索范围缩小至相关包/工作区。

第 5 阶段:实施修复

应用最小的代码更改以解决该问题。

指导原则

  • 最小变更: 仅修改解决问题所必需的部分,不要对无关代码进行重构。
  • 一致性: 遵循项目现有的代码风格、命名规范和编码模式。
  • 不新增依赖项,除非绝对必要且有合理解释。
  • 使用 search_replace 工具进行精确编辑。

若需修改多个文件

  1. 在开始前规划好全部修改内容。
  2. 逐个文件依次应用修改。
  3. 每次修改后,使用 get_problems 检查是否存在语法错误。

第 6 阶段:验证修复

确认修复有效且未引入新问题。

6.1 检测项目类型与测试运行器

通过常见文件判断可能的测试工具:

文件可能的运行器
package.jsonnpm testnpx jestnpx vitest
Cargo.tomlcargo test
go.modgo test ./...
pyproject.toml / setup.pypytest
Makefilemake test
pom.xmlmvn test
build.gradle./gradlew test

6.2 运行测试

# 运行完整测试套件或与修改文件相关的局部测试
{test_command}
  • 若测试 通过,进入第 7 阶段。
  • 若测试 失败,分析失败原因,调整修复方案并重新运行。

6.2.1 未检测到测试框架

若未发现测试运行器或测试文件:

  1. 对所有修改的文件运行静态分析 get_problems,以捕获语法错误和类型问题。
  2. 通过手动阅读代码路径来人工验证修复。
  3. 在 PR 中注明:

本项目未检测到自动化测试框架。修复已通过静态分析和手动代码审查验证。

6.3 代码格式与检查(如可用)

检查项目是否配置了 lint 或格式化工具,并运行它们:

# 示例
npm run lint 2>/dev/null
cargo clippy 2>/dev/null
go vet ./... 2>/dev/null

修复由更改引入的任何 lint 问题。


第 7 阶段:展示变更并获取确认

向用户展示修复内容,并等待其明确批准后再继续。

7.1 展示修复摘要

## {owner}/{repo}#{number} 修复摘要

**问题:** {issue_title}
**根本原因:** {简要说明}
**修改内容:**
- `{file_path_1}`: {修改内容及原因}
- `{file_path_2}`: {修改内容及原因}

7.2 展示差异

显示实际的代码变更,供用户审查:

git diff

突出关键修改并解释其影响。

7.3 等待用户确认

向用户提问:

是否希望我将这些更改提交为 Pull Request?如有需要调整之处,请告知。

  • 若用户 同意,进入第 8 阶段。
  • 若用户 要求修改,返回第 5 阶段重新修正并再次提交。

第 8 阶段:提交 Pull Request(用户已批准)

仅在用户于第 7 阶段批准后执行此阶段。

步骤 1:暂存并提交

git add -A
git commit -m "fix: {简短描述} (#{number})

{详细说明问题所在及本次提交如何修复}

Closes #{number}"

步骤 2:推送分支

根据第 3 阶段权限检查结果,推送到合适的远程仓库:

# 若具有写入权限(第 3 阶段推送成功):
git push origin fix/issue-{number}

# 若在第 3 阶段创建了分支副本:
git push fork fix/issue-{number}

步骤 2.5:检查仓库 PR 模板

pr_template=""
for f in .github/PULL_REQUEST_TEMPLATE.md .github/pull_request_template.md docs/pull_request_template.md PULL_REQUEST_TEMPLATE.md; do
  if [ -f "$f" ]; then
    pr_template="$f"
    break
  fi
done

若找到 PR 模板,则以此为基础填写相关内容;否则使用以下默认模板。

步骤 3:创建 Pull Request

默认 PR 正文模板

## 概述

修复 #{number}。

### 问题
{来自问题分析的简要问题描述}

### 解决方案
{来自修复实现的简要解决方案描述}

### 修改内容
- {修改 1}
- {修改 2}

### 测试
- [x] 现有测试通过
- [x] {执行的其他验证操作}

---
<sub>🔧 由 [issue-to-pr](https://github.com/4yDX3906/issue-to-pr) 生成</sub>
gh pr create \
  --repo {owner}/{repo} \
  --title "fix: {short description}" \
  --body "$pr_body" \
  --base {default_branch} \
  --head {head_ref}

{head_ref} 的值为:直接推送时使用 fix/issue-{number},通过 fork 推送时使用 {your_username}:fix/issue-{number}

提示: 若修复内容仍需进一步审查,可添加 --draft 标志以创建草稿 PR。

步骤 4:验证与报告

  • gh pr create 命令的输出中获取 PR 地址。
  • 向用户报告:

✅ PR 创建成功:{PR_URL}

请前往 PR 页面查看 CI 检查结果或评审反馈。

  • 若创建失败,显示完整错误信息,并提供手动操作命令作为备用方案。

备用方案:手动操作指引

若用户拒绝自动提交或任一步骤失败,请提供以下指引:

  1. 建议的提交信息:
   fix: {short description} (#{number})

   {详细说明}

   Closes #{number}
  1. 创建 PR 的命令:
   gh pr create \
     --title "fix: {short description}" \
     --body "..." \
     --base {default_branch}
  1. 建议后续步骤:

- 查看差异:git diff {default_branch}

- 提交并推送更改

- 创建 PR 并确认 CI 流水线通过


错误处理

对以下常见失败情况进行妥善处理:

情况处理方式
gh CLI 未安装回退至 git clonefetch_content。建议安装:brew install gh 或访问 https://cli.github.com
gh auth 未配置提示用户运行 gh auth login 后重试
仓库为私有 / 返回 403 错误告知用户需要认证,并引导其完成身份验证
问题不存在 / 返回 404请再次核对链接,并请用户确认问题编号是否正确
无写入 /tmp 权限改为在工作区目录中克隆
修复后测试失败分析失败输出,修改修复方案并重新验证
无法确定根本原因展示当前已知信息,并请求用户提供指导
问题过大或过于复杂将问题拆分为子任务,优先修复最关键部分,并标注剩余工作
git push 权限被拒绝自动创建仓库的 fork,并推送到 fork 仓库
gh pr create 执行失败显示错误详情,并提供手动命令
用户的 gh 未认证提示用户先运行 gh auth login
远程分支已存在询问用户是否强制推送,或创建新分支名
该分支已有对应 PR显示现有 PR 地址,并询问是否更新
未发现测试框架使用 get_problems 进行静态分析,手动验证,并在 PR 中注明
问题包含多个缺陷优先修复最严重的问题,其余事项作为后续跟进
修复分支已存在询问用户是否复用、重新创建或重命名该分支

注意事项

  • 本地操作: 所有代码分析与修改均在本地完成。仅标准 Git 和 GitHub API 操作(克隆、推送、创建 PR)会向 GitHub 发送数据。
  • 认证机制: 使用用户现有的 gh CLI 凭据。不会存储额外凭据。
  • 用户授权必需: 代理在第 7 阶段前不会推送代码或创建 PR,必须获得用户明确同意。
4
@4ydx3906

已收录 2 个 Skill

相关推荐