用途
address-pr-feedback 是一个用于处理 GitHub 拉取请求(PR)反馈的变更型工作流技能,适用于用户要求处理 PR 评审评论或回应 PR 反馈的场景。根据资料,该工作流执行修改类操作:可以编辑文件、重写提交、推送分支、回复评论、解决线程,以及隐藏符合条件的机器人评论。除非用户明确要求设置检查点,否则它会立即执行操作。
主要能力
- 读取并分析目标 PR 的元数据、差异、评论、评审和评审线程。
- 区分已解决/已最小化/已驳回/过时的反馈,并在分析前忽略它们。
- 对每条剩余反馈判断其是否有效、是否可立即处理、是否可能导致当前 PR 或前后栈 PR 回归,以及应由哪个 PR 与提交承载修复。
- 处理有效的反馈;对会引入回归的请求不执行修改,而是回复说明原因。
- 将修复修正(amend)到相关既有提交中,仅在无既有提交承载修复时创建新提交。
- 在堆叠(stack)场景下,从受影响的最低分支开始,逐层重新堆叠并推送受影响分支。
- 回复每条被考虑的反馈,并在有权限时解决对应评审线程。
- 仅在 viewerCanMinimize == true 且作者可确认为自动化机器人时,最小化已处理的顶层评论。
使用方式
工作流要求所有直接的 GitHub API、评论、评审和 PR 元数据操作都通过 gh 命令行工具完成,不使用 curl、gh api 之外的直接 API URL 或网页抓取;当 Graphite 适用时,gt 可用于栈感知的重新堆叠与提交。
前置条件包括:运行 gh auth status 检查认证,若失败则停止并提示用户运行 gh auth login;通过 gh api user --jq .login 记录已认证的 GitHub 登录名,用于避免此前运行发出的重复回复;用 git status --short 检查工作树,不覆盖无关的未提交更改;用 git branch --show-current 确定当前分支。
目标 PR 的确定方式为:使用用户提供的 PR URL、PR 编号或分支;若未提供,则使用当前检出分支对应的 PR。对每个目标 PR,加载元数据与差异,并在编辑前验证 PR 头分支可写。对于跨仓库 PR,要求 maintainerCanModify == true 且 gh pr checkout 成功,否则在编辑前停止并报告分支无法更新。不得把修复应用到恰好被检出的任意分支。
在堆叠处理上,默认启用栈感知行为:若 PR 属于某个栈,则收集整个栈的反馈;若用户指定栈中的某个 PR,则收集从栈基到该 PR 的所有 PR 的反馈。
关于 Graphite,只有目标检出中两项检查都通过时才视为可用:command -v gt 与 gt --no-interactive log short --stack。仅当目标 PR 的 headRefName 作为精确分支名出现在 Graphite 跟踪的栈中时才使用 Graphite,不能仅因安装了 gt 就使用。若 gt 存在但目标分支未被 Graphite 跟踪、Graphite 命令失败、缺少 Graphite 认证/初始化,或目标 PR 分支不在 gt --no-interactive log short --stack 中,则回退到基于 gh 的栈推断。
Graphite 适用时,用 gt --no-interactive log short --stack 识别祖先与后代;在修正非尖端分支后使用 gt --no-interactive restack --upstack;修复后用 gt --no-interactive submit --stack --update-only 推送当前分支及后续栈分支;若安装的 Graphite 版本支持 --no-edit,可添加该参数,但不能依赖它;优先使用 Graphite 原生的提交操作,如 gt --no-interactive absorb 或 gt --no-interactive modify。
回退栈推断方面,在没有适用的 Graphite 时,通过开放 PR 的分支关系推断栈链接:使用 gh pr list 查询开放 PR,并通过 --head/--base 定位栈链路。当 PR B 的 baseRefName 等于 PR A 的 headRefName 时,视为 B 堆叠在 A 之上。若多个开放 PR 共享同一 headRefName,则通过 headRepositoryOwner.login 和 headRepository.name 消歧;若归属仓库仍不明确,则停止而非猜测栈。
收集反馈时,忽略已解决的反馈:跳过 isResolved == true 的评审线程;跳过 isMinimized == true 的被最小化或隐藏评论;跳过已驳回的评审、正文为空的评审条目,以及 GraphQL 状态不是 SUBMITTED 的评审线程评论;对 outdated == true 的评审线程评论视为过时,除非同一线程中有更新的未解决评论使其仍然有效。顶层 PR 评论通过 REST 获取,REST 响应包含 node_id 和 user.type,可用 user.type 做机器人检测;由于 REST 顶层评论不暴露最小化状态,需在分析或隐藏前用 GraphQL 检查这些评论节点的 isMinimized。评审正文通过 gh pr view --json reviews 快速查看,或通过 GraphQL 分页获取完整评审正文,仅使用未驳回且正文非空的评审。未解决的评审线程通过 GraphQL 分页获取,若某线程 comments.totalCount 大于已获取的评论节点数,则用单独的线程节点查询获取剩余评论后再评估。
在修正修复时,除非用户另有说明,将修复修正到相关的既有提交中;用 PR 差异和提交历史找到承载该修复的提交。对于栈反馈,从拥有相关提交的分支逐层应用修复,先处理受影响的最低分支,再在向上移动前重新堆叠后代。若 Graphite 适用,优先使用 gt --no-interactive absorb 或 gt --no-interactive modify;若不适用,则使用常规 Git amend/rebase 操作,并用 --force-with-lease 推送受影响的当前/后续分支。仅在无既有提交承载修复时才创建新提交。遵循仓库的提交信息规则,包括必需的尾部标记;对于 Codex 编写的提交,需包含:
Co-authored-by: Codex noreply@openai.com
推送前运行与改动代码相称的聚焦测试或检查;若无法运行检查,则在最终报告中说明原因。
推送栈更新时,当反馈在栈中被处理,推送当前分支及每个历史发生变化的后续分支。有适用的 Graphite 时依次执行 gt --no-interactive restack --upstack 与 gt --no-interactive submit --stack --update-only;无 Graphite 时手动重新堆叠/变基后代,并用 git push --force-with-lease 推送变更分支。遇到冲突时停止并报告,而不是在冲突的重新堆叠或变基中猜测。
回复与解决方面,对每条被考虑的反馈都进行回复,无论是否已处理。回复应简明:已处理的说明改了什么;未处理的说明为何无效、过时、重复、受阻或风险过高;有风险的说明回归方面的顾虑。对于包含多条评论的评审线程,评估每条未解决评论,但优先使用一条合并的线程回复覆盖该线程中所有被考虑的点。发布前检查已认证用户已有的 PR 评论与评审线程回复;若先前回复已引用同一原始评论或线程,且此后没有新反馈,则不再发布重复回复。对于评审线程,仅在 viewerCanReply == true 时回复;若为 false,则不尝试该变更,并报告无法回复该线程。对顶层 PR 评论或评审正文,由于 GitHub 评论是扁平的,需新增一条引用原评论/评审 URL 或作者的 PR 评论。回复之后,在 viewerCanResolve == true 时用 GraphQL 解决每条被考虑的评审线程,包括反馈无效、过时、重复、受阻或风险过高的线程;仅当 viewerCanResolve == false、API 拒绝该操作、缺少权限,或用户明确要求保持开启时,才让线程保持未解决。
隐藏/最小化已处理的顶层评论,仅在 viewerCanMinimize == true 且作者可确认为自动化机器人时进行:GitHub 报告 user.type == "Bot",或用户名与已知的 Codex GitHub 用户精确匹配(若没有已知的精确 Codex 用户名,则不使用该例外)。若 user.type 缺失或含糊,则不隐藏评论;不基于用户名子串隐藏评论;绝不隐藏来自不确定或看起来像人类的账户的评论。最小化操作使用 REST 评论的 node_id 或 GraphQL 评论 id 作为 subjectId,而非数字数据库 ID。
最后返回简明报告,列出处理的 PR、改动内容、推送内容、已解决或保持开启的内容,以及运行了哪些检查。
适用场景
- 用户要求处理 PR 评审评论或回应 PR 反馈。
- 需要跨堆叠 PR 收集并处理反馈的场景。
- 需要在修复后回复线程、解决线程并推送分支的场景。
限制
- 所有 GitHub 操作必须使用 gh CLI,不使用 curl、直接 API URL 或网页抓取。
- Graphite 仅在其两项检查通过且目标分支被其跟踪时使用。
- 对会引入回归的请求不执行修改,仅回复原因。
- 跨仓库 PR 需 maintainerCanModify == true 且成功检出,否则停止。
- 隐藏评论有严格条件,不确定或类似人类的账户一律不隐藏。
- 其他未在资料中说明的功能、收费、价格、平台或效果暂未提供。