fix-pull-request

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Fix Pull Request

修复Pull Request

Goal

目标

  • CI failures addressed.
  • Conflicts resolved.
  • Comment suggestions addressed (fixed/replied).
  • Branch published.
  • PR description updated (if needed).
  • 解决CI构建失败问题
  • 解决代码冲突
  • 处理评审意见(修复或回复)
  • 推送分支至远程仓库
  • 更新PR描述(如有需要)

Input

输入

  • PR identifier (optional): PR number, PR URL, or ticket ID. Passed through to
    vcs-tools
    '
    identify-pr
    command; falls back to the current branch's open PR if omitted.
  • PR标识符(可选):PR编号、PR链接或工单ID。将传递给
    vcs-tools
    identify-pr
    命令;如果省略,则默认使用当前分支对应的已打开PR。

Prerequisites

前置条件

  • vcs-tools
    skill available (
    gh
    CLI for GitHub repos,
    glab
    CLI for GitLab repos)
  • gather-merge-blockers
    skill available
  • resolve-conflicts
    skill available
  • perform-task
    skill available
  • fix-feedback
    skill available
  • feedback-loop
    skill available
  • scratch
    skill available
  • 已具备
    vcs-tools
    技能(GitHub仓库使用
    gh
    CLI,GitLab仓库使用
    glab
    CLI)
  • 已具备
    gather-merge-blockers
    技能
  • 已具备
    resolve-conflicts
    技能
  • 已具备
    perform-task
    技能
  • 已具备
    fix-feedback
    技能
  • 已具备
    feedback-loop
    技能
  • 已具备
    scratch
    技能

Steps

步骤

Step 1: Identify PR

步骤1:识别PR

Invoke:
Skill(skill: "vcs-tools", args: "identify-pr <input>")
Capture
pr_number
from its output, and reuse this value for the rest of this skill.
调用:
Skill(skill: "vcs-tools", args: "identify-pr <input>")
从输出中获取
pr_number
,并在后续步骤中复用该值。

Step 2: Gather merge blockers

步骤2:收集合并阻塞项

Invoke:
Skill(skill: "gather-merge-blockers", args: "<pr_number>")
Capture
url
,
source_branch
,
target_branch
,
merge_state
,
ci_failures
,
reviews
, and
threads
from its output, and reuse these values for the rest of this skill instead of re-deriving them.
调用:
Skill(skill: "gather-merge-blockers", args: "<pr_number>")
从输出中获取
url
source_branch
target_branch
merge_state
ci_failures
reviews
threads
,并在后续步骤中复用这些值,无需重新获取。

Step 3: Resolve conflicts

步骤3:解决代码冲突

If
merge_state
(captured in Step 2) is not
CONFLICTING
, skip this step.
Invoke:
Skill(skill: "resolve-conflicts", args: "<target_branch>")
This may force-push without Step 6's gate - intentional, since
resolve-conflicts
is mechanical and escalates ambiguity itself. Step 6 gates only the judgment-call fixes from Steps 4-5.
Check its output
status
. If
aborted
, stop here and report to the user that conflicts could not be resolved - do not proceed to Step 4.
如果步骤2中获取的
merge_state
不是
CONFLICTING
,则跳过此步骤。
调用:
Skill(skill: "resolve-conflicts", args: "<target_branch>")
此操作可能会跳过步骤6的校验直接强制推送——这是有意设计的,因为
resolve-conflicts
是机械性操作,自身会处理歧义情况。步骤6仅针对步骤4-5中需要主观判断的修复操作进行校验。
检查输出的
status
。如果状态为
aborted
,则停止操作并告知用户无法解决冲突,无需继续执行步骤4。

Step 4: Resolve CI failures

步骤4:解决CI构建失败问题

If
ci_failures
is empty, skip this step.
Form
ci_tasks
list:
From each item in
ci_failures
, form a single task in
perform-task
's item shape (
{id, body}
):
  • id: synthesized as
    ci-<index>
  • body: "fixup mode. CI check '<name>' failed with status '<status>'. Logs: <log_file_path>".
Invoke:
Skill(skill: "perform-task", args: "<ci_tasks>")
如果
ci_failures
为空,则跳过此步骤。
构建
ci_tasks
列表:
ci_failures
的每个项中,生成符合
perform-task
格式的任务项(
{id, body}
):
  • id:命名为
    ci-<index>
  • body:"fixup mode. CI check '<name>' failed with status '<status>'. Logs: <log_file_path>"
调用:
Skill(skill: "perform-task", args: "<ci_tasks>")

Step 5: Address Threads

步骤5:处理评审线程

If
threads
and
reviews
are both empty, skip this step.
Map
threads
and
reviews
(from
gather-merge-blockers
) into
fix-feedback
's item shape (
{id, body}
), then invoke it in one call:
  • Threads:
    id
    =
    thread_id
    ,
    body
    =
    location
    folded in, then comments concatenated in order (
    author
    :
    body
    per comment).
  • Reviews: skip entries with
    state: APPROVED
    or an empty
    body
    - not actionable feedback. For the rest:
    id
    = synthesized (e.g.
    review-<index>
    ),
    body
    = the review's
    body
    (no
    location
    - not anchored to a file/line).
Invoke:
Skill(skill: "fix-feedback", args: "fixup mode. <items>")
如果
threads
reviews
均为空,则跳过此步骤。
gather-merge-blockers
输出的
threads
reviews
转换为
fix-feedback
的格式(
{id, body}
),然后一次性调用:
  • 线程(Threads):
    id
    =
    thread_id
    body
    = 包含
    location
    信息,然后按顺序拼接评论内容(每条评论格式为
    author
    :
    body
    )。
  • 评审(Reviews):跳过
    state: APPROVED
    body
    为空的条目——这些无需处理。对于其余条目:
    id
    = 自定义命名(例如
    review-<index>
    ),
    body
    = 评审的
    body
    内容(无需包含
    location
    ,因为未锚定到文件/行)。
调用:
Skill(skill: "fix-feedback", args: "fixup mode. <items>")

Step 6: Confirm and squash fixups

步骤6:确认并合并修复提交

If Steps 4 and 5 made no changes and Step 3 was skipped, skip this step.
Invoke:
Skill(skill: "feedback-loop", args: "<target_branch>")
如果步骤4和5未产生任何变更,且步骤3被跳过,则跳过此步骤。
调用:
Skill(skill: "feedback-loop", args: "<target_branch>")

Step 7: Push to remote

步骤7:推送至远程仓库

If Steps 4 and 5 made no changes and Step 3 was skipped, skip this step.
bash
git push origin $(git branch --show-current) --force-with-lease
如果步骤4和5未产生任何变更,且步骤3被跳过,则跳过此步骤。
bash
git push origin $(git branch --show-current) --force-with-lease

Step 8: Post replies

步骤8:发布回复

For each thread and review addressed in Step 5, prepare a reply comment, keyed by its
id
to
fix-feedback
's output (
status
/
description
per original input
id
):
Tone: Brief and factual. No fluff, apologies, or fillers.
  • Per
    status
    (
    fix-feedback
    's output; use its
    description
    as the source text):
    • implemented: Describe the fix. Example:
      "Fixed. Added missing X."
      (for fixes) /
      "Done. Replaced X with Y."
      (for improvements).
    • declined: Explain without confrontational words.
      "Existing convention is relative imports throughout this package"
      .
    • deferred:
      "Will address in a future PR"
      or
      "Created <Ticket URL>"
      .
    • explained: Provide the requested clarification.
Post all replies concurrently.
  • Threads: write the reply body to a scratch file via
    scratch
    :
    Skill(skill: "scratch", args: "write pr-reply-<id> md")
    Pass the returned path as
    <reply_file_path>
    to
    vcs-tools
    :
    Skill(skill: "vcs-tools", args: "post-reply <pr_number> <thread_id> <reply_file_path>")
    <pr_number>
    comes from Step 1;
    <thread_id>
    comes from the
    gather-merge-blockers
    skill's output.
  • Reviews: no
    thread_id
    to anchor to - write a payload file instead (
    {body: "<reply text>", event: "COMMENT", comments: []}
    ) via
    scratch
    :
    Skill(skill: "scratch", args: "write pr-review-reply-<id> json")
    Pass the returned path as
    <payload_file_path>
    to
    vcs-tools
    :
    Skill(skill: "vcs-tools", args: "submit-review <pr_number> <payload_file_path>")
    event: "COMMENT"
    posts the reply as a top-level note without approving or requesting changes.
针对步骤5中处理的每个线程和评审,根据
fix-feedback
的输出(对应原始输入
id
status
/
description
)准备回复评论:
语气:简洁、客观。无需冗余内容、道歉或填充语。
  • 根据
    status
    (来自
    fix-feedback
    的输出;使用其
    description
    作为回复文本来源):
    • implemented:描述修复内容。示例:
      "已修复。添加了缺失的X。"
      (针对修复)/
      "已完成。将X替换为Y。"
      (针对优化)。
    • declined:用非对抗性语言解释。例如
      "本包内统一使用相对导入的约定"
    • deferred
      "将在后续PR中处理"
      "已创建<工单链接>"
    • explained:提供所需的说明。
同时发布所有回复。
  • 线程(Threads):通过
    scratch
    技能将回复内容写入临时文件:
    Skill(skill: "scratch", args: "write pr-reply-<id> md")
    将返回的路径作为
    <reply_file_path>
    传递给
    vcs-tools
    Skill(skill: "vcs-tools", args: "post-reply <pr_number> <thread_id> <reply_file_path>")
    <pr_number>
    来自步骤1;
    <thread_id>
    来自
    gather-merge-blockers
    技能的输出。
  • 评审(Reviews):没有可锚定的
    thread_id
    ——通过
    scratch
    技能写入payload文件(格式为
    {body: "<reply text>", event: "COMMENT", comments: []}
    ):
    Skill(skill: "scratch", args: "write pr-review-reply-<id> json")
    将返回的路径作为
    <payload_file_path>
    传递给
    vcs-tools
    Skill(skill: "vcs-tools", args: "submit-review <pr_number> <payload_file_path>")
    event: "COMMENT"
    会将回复作为顶级备注发布,不会触发批准或变更请求操作。

Step 9: Update PR description

步骤9:更新PR描述

If Steps 4 and 5 made no changes, skip this step.
  • Summarize the fixes and improvements applied in this iteration.
  • Reflect the final state of the PR compared to the previous version.
  • Do not include intermediate technical fixes (e.g., squashed fixups).
Write the description to a scratch file via
scratch
:
Skill(skill: "scratch", args: "write pr-description md")
Pass the returned path as
<pr_description_file_path>
to
vcs-tools
:
Skill(skill: "vcs-tools", args: "update-pr-description <pr_number> <pr_description_file_path>")
如果步骤4和5未产生任何变更,则跳过此步骤。
  • 总结本次迭代中应用的修复和优化内容。
  • 说明PR相较于之前版本的最终状态。
  • 无需包含中间技术性修复(例如合并修复提交)。
通过
scratch
技能将描述内容写入临时文件:
Skill(skill: "scratch", args: "write pr-description md")
将返回的路径作为
<pr_description_file_path>
传递给
vcs-tools
Skill(skill: "vcs-tools", args: "update-pr-description <pr_number> <pr_description_file_path>")

Output

输出

PR URL:
url
(captured in Step 2). Summary: Short report of what was implemented (from Step 9's PR description)
PR链接:
url
(步骤2中获取) 摘要:简短报告本次实现的内容(来自步骤9的PR描述)