babysit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Babysit PR

值守PR

Stay with the PR until it is actually clean. Do not stop after one check pass if comments or review threads are still unresolved.
持续跟进PR,直至其完全符合合并条件。即使某次检查通过,但如果仍有未解决的评论或评审线程,也不能停止监控。

Workflow

工作流程

  1. Identify the PR number, branch, and base branch.
  2. Confirm the PR is not draft and inspect mergeability, checks, review decision, comments, and review threads.
  3. Watch pending checks until they finish. Poll at a practical interval, usually 30-60 seconds unless the user asks for a different cadence.
  4. Read new comments and unresolved review threads. Treat bot summaries as useful, but verify actionable findings against the code.
  5. Fix real issues in focused commits, run relevant tests/builds, push, and return to step 2.
  6. Resolve stale review threads only after verifying the code or generated artifact now addresses the comment.
  7. Stop only when checks are passing or intentionally skipped, review decision is acceptable, no actionable comments remain, and no unresolved review threads remain.
  1. 确定PR编号、分支以及基准分支。
  2. 确认PR不是草稿状态,检查其可合并性、检查状态、评审结论、评论以及评审线程。
  3. 监控待处理的检查任务直至完成。按合理的间隔轮询,通常为30-60秒,除非用户要求不同的频率。
  4. 查看新评论和未解决的评审线程。机器人的总结内容可作为参考,但需对照代码核实其中可处理的问题。
  5. 针对具体问题提交聚焦的修复提交,运行相关测试/构建,推送代码后回到步骤2。
  6. 只有在验证代码或生成的产物已解决评论中的问题后,才能标记陈旧的评审线程为已解决。
  7. 仅当检查通过或被有意跳过、评审结论符合要求、无待处理的评论且无未解决的评审线程时,才停止监控。

GitHub CLI Checks

GitHub CLI 检查

Use
gh pr view
for the coarse status:
bash
gh pr view <number> --json \
  number,state,isDraft,mergeable,mergeStateStatus,reviewDecision,headRefOid,statusCheckRollup,url
Resolve the repository owner/name before using GraphQL:
bash
repo_json=$(gh repo view --json owner,name)
owner=$(jq -r '.owner.login // .owner.name' <<<"$repo_json")
repo=$(jq -r '.name' <<<"$repo_json")
Use GraphQL for unresolved review threads. Include
pageInfo
; omit
cursor
on the first page, then pass the previous
endCursor
with
-f cursor="$cursor"
while
hasNextPage
is
true
.
bash
gh api graphql \
  -f query='query($owner:String!,$repo:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$repo){pullRequest(number:$number){reviewThreads(first:100,after:$cursor){pageInfo{hasNextPage endCursor}nodes{id,isResolved,isOutdated,path,line,comments(last:1){nodes{author{login},body,createdAt,url}}}}}}}' \
  -f owner="$owner" -f repo="$repo" -F number=<number>
Use this loop when a PR may have many review threads:
bash
thread_query='query($owner:String!,$repo:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$repo){pullRequest(number:$number){reviewThreads(first:100,after:$cursor){pageInfo{hasNextPage endCursor}nodes{id,isResolved,isOutdated,path,line,comments(last:1){nodes{author{login},body,createdAt,url}}}}}}}'
cursor_args=()

while :; do
  page=$(gh api graphql -f query="$thread_query" -f owner="$owner" -f repo="$repo" -F number=<number> "${cursor_args[@]}")
  printf '%s\n' "$page" | jq -r '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved==false)
    | [.id,.path,(.line//""),(.isOutdated|tostring),(.comments.nodes[-1].author.login//""),(.comments.nodes[-1].body|gsub("\n";" ")|.[0:240])]
    | @tsv'

  jq -e '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage' >/dev/null <<<"$page" || break
  cursor=$(jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.endCursor' <<<"$page")
  cursor_args=(-f cursor="$cursor")
done
Filter unresolved threads with
jq
:
bash
jq -r '.data.repository.pullRequest.reviewThreads.nodes[]
  | select(.isResolved==false)
  | [.id,.path,(.line//""),(.isOutdated|tostring),(.comments.nodes[-1].author.login//""),(.comments.nodes[-1].body|gsub("\n";" ")|.[0:240])]
  | @tsv'
Resolve a stale thread only when the fix is verified:
bash
gh api graphql \
  -f query='mutation($threadId:ID!){resolveReviewThread(input:{threadId:$threadId}){thread{id,isResolved}}}' \
  -f threadId=<thread-id>
使用
gh pr view
获取大致状态:
bash
gh pr view <number> --json \
  number,state,isDraft,mergeable,mergeStateStatus,reviewDecision,headRefOid,statusCheckRollup,url
在使用 GraphQL 前先确定仓库的所有者/名称:
bash
repo_json=$(gh repo view --json owner,name)
owner=$(jq -r '.owner.login // .owner.name' <<<"$repo_json")
repo=$(jq -r '.name' <<<"$repo_json")
使用 GraphQL 查询未解决的评审线程。需包含
pageInfo
;首次查询时省略
cursor
,之后在
hasNextPage
true
时,传入上一次的
endCursor
,参数为
-f cursor="$cursor"
bash
gh api graphql \
  -f query='query($owner:String!,$repo:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$repo){pullRequest(number:$number){reviewThreads(first:100,after:$cursor){pageInfo{hasNextPage endCursor}nodes{id,isResolved,isOutdated,path,line,comments(last:1){nodes{author{login},body,createdAt,url}}}}}}}' \
  -f owner="$owner" -f repo="$repo" -F number=<number>
当PR可能包含大量评审线程时,使用以下循环:
bash
thread_query='query($owner:String!,$repo:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$repo){pullRequest(number:$number){reviewThreads(first:100,after:$cursor){pageInfo{hasNextPage endCursor}nodes{id,isResolved,isOutdated,path,line,comments(last:1){nodes{author{login},body,createdAt,url}}}}}}}'
cursor_args=()

while :; do
  page=$(gh api graphql -f query="$thread_query" -f owner="$owner" -f repo="$repo" -F number=<number> "${cursor_args[@]}")
  printf '%s\n' "$page" | jq -r '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved==false)
    | [.id,.path,(.line//""),(.isOutdated|tostring),(.comments.nodes[-1].author.login//""),(.comments.nodes[-1].body|gsub("\n";" ")|.[0:240])]
    | @tsv'

  jq -e '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage' >/dev/null <<<"$page" || break
  cursor=$(jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.endCursor' <<<"$page")
  cursor_args=(-f cursor="$cursor")
done
使用
jq
过滤未解决的线程:
bash
jq -r '.data.repository.pullRequest.reviewThreads.nodes[]
  | select(.isResolved==false)
  | [.id,.path,(.line//""),(.isOutdated|tostring),(.comments.nodes[-1].author.login//""),(.comments.nodes[-1].body|gsub("\n";" ")|.[0:240])]
  | @tsv'
仅在验证修复完成后,标记陈旧线程为已解决:
bash
gh api graphql \
  -f query='mutation($threadId:ID!){resolveReviewThread(input:{threadId:$threadId}){thread{id,isResolved}}}' \
  -f threadId=<thread-id>

Operating Rules

操作规则

  • Keep the watcher running while long checks are pending.
  • If a generated file is part of the distribution, verify the source and generated artifact agree before resolving comments.
  • If a bot reports an issue against stale code, confirm whether the thread is outdated or addressed in the latest head.
  • Before final reporting, do one fresh sweep of PR status, unresolved threads, recent comments, and local
    git status
    .
  • Report concrete evidence: latest commit SHA, check names and results, unresolved thread count, tests run, and any dirty local files left untouched.
  • 当有长时间运行的检查任务待处理时,保持监控程序运行。
  • 如果生成文件属于分发内容,在标记评论为已解决前,需验证源文件和生成产物是否一致。
  • 如果机器人针对陈旧代码报告问题,需确认该线程是否已过时或在最新的提交中已得到解决。
  • 在最终报告前,重新检查一次PR状态、未解决线程、最新评论以及本地
    git status
  • 报告需包含具体证据:最新提交SHA、检查任务名称及结果、未解决线程数量、已运行的测试,以及任何未处理的本地脏文件。