mcpField
G
greploop

greploop

github.com/greptileai测试与质量4282.7k 次安装2 天前更新
代码仓库

关于 greploop

Greploop 是用于反复处理 PR、MR 或 Perforce changelist 中 Greptile 审查反馈的技能,最多运行五轮。它会识别平台、获取审查结果、修复可执行的问题并报告最终状态。

主要功能

  1. 01识别 GitHub、GitLab 或 Perforce
  2. 02定位待审查的变更
  3. 03触发并轮询 Greptile 审查
  4. 04处理可执行的审查意见
  5. 05解决已处理的讨论线程
  6. 06报告置信度和未解决意见

适用场景

  1. 01处理 GitHub PR 的审查反馈
  2. 02处理 GitLab MR 上的 Greptile 意见
  3. 03迭代修改 Perforce changelist
  4. 04检查未解决意见和审查置信度

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/greptileai/skills --skill greploop

安装后在 Claude Code 中输入/greploop确认已加载。

附带文件references/gitlab-api.mdreferences/graphql-queries.md

详细介绍

Greploop

迭代修复 PR/MR/CL,直到 Greptile 给出完美评审:置信度为 5/5,且没有未解决的评论。

输入

  • PR/MR/CL 编号(可选):如果未提供,则检测当前分支对应的 PR/MR,或 p4 中默认的待处理变更列表。

说明

0. 检测平台

先检查 Perforce,再回退到通过 git remote 检测:

# Check for Perforce environment
if p4 info >/dev/null 2>&1; then
  VCS="perforce"
else
  REMOTE_URL=$(git remote get-url origin)
  if echo "$REMOTE_URL" | grep -qi "gitlab"; then
    VCS="gitlab"
  else
    VCS="github"
  fi
fi

对于主机名中不含“gitlab”的自托管 GitLab 实例,用户可以传入 --vcs gitlab 作为输入来覆盖默认设置。对于 Perforce,传入 --vcs perforce。

1. 确定 PR/MR/CL

GitHub:

gh pr view --json number,headRefName -q '{number: .number, branch: .headRefName}'

GitLab:

glab mr view --output json | jq '{iid: .iid, branch: .source_branch}'

如果当前不在 PR/MR 分支上,则切换到该分支。

Perforce:

# List pending changelists for current user/client
p4 changes -s pending -u $P4USER -c $P4CLIENT

# Describe a specific CL
p4 describe -s <CL_NUMBER>

继续操作前,请确保已设置正确的工作区(p4 client)。

主要字段差异:

  • GitHub:number、headRefName、headRefOid
  • GitLab:iid、source_branch、sha
  • Perforce:变更列表编号、P4CLIENT、已搁置的文件
2. 循环

重复以下周期。最多迭代 5 次,以避免无限循环。

A. 触发 Greptile 评审

推送/搁置最新更改(如果有):

GitHub/GitLab:

git push

Perforce:

# Re-shelve to update the shelved files for review
p4 shelve -f -c <CL_NUMBER>

推送/搁置后,等待检查开始:

sleep 5

GitHub — 发布新的触发评论前,检查 Greptile 是否已在运行:

GREPTILE_STATE=$(gh pr checks <PR_NUMBER> --json name,state | jq -r '.[] | select(.name | test("greptile"; "i")) | .state')

如果 Greptile 尚未运行(状态为 PENDING 或 IN_PROGRESS),则请求新的评审:

if [ "$GREPTILE_STATE" != "PENDING" ] && [ "$GREPTILE_STATE" != "IN_PROGRESS" ]; then
  gh pr comment <PR_NUMBER> --body "@greptile review"
fi

然后轮询 Greptile 检查运行,直到完成:

HEAD_SHA=$(gh pr view <PR_NUMBER> --json headRefOid -q .headRefOid)
ATTEMPTS=0
MAX_ATTEMPTS=60
POLL_INTERVAL_SECONDS=10

while true; do
  ATTEMPTS=$((ATTEMPTS + 1))
  if [ "$ATTEMPTS" -gt "$MAX_ATTEMPTS" ]; then
    echo "Timed out waiting for the Greptile check run after approximately 10 minutes." >&2
    exit 1
  fi

  GREPTILE_CHECK=$(gh api "repos/{owner}/{repo}/commits/$HEAD_SHA/check-runs" \
    --jq '.check_runs[] | select(.name | test("greptile"; "i"))' 2>/dev/null)
  
  if [ -z "$GREPTILE_CHECK" ]; then
    echo "Waiting for Greptile check to appear..."
    sleep "$POLL_INTERVAL_SECONDS"
    continue
  fi
  
  STATUS=$(echo "$GREPTILE_CHECK" | jq -r '.status // "completed"')
  CONCLUSION=$(echo "$GREPTILE_CHECK" | jq -r '.conclusion // "pending"')
  
  if [ "$STATUS" = "completed" ]; then
    if [ "$CONCLUSION" = "success" ]; then
      echo "Greptile check passed!"
    else
      echo "Greptile check completed with: $CONCLUSION"
    fi
    break
  fi
  
  echo "Waiting for Greptile... (status: $STATUS)"
  sleep "$POLL_INTERVAL_SECONDS"
done

如果轮询超时,则停止 greploop 工作流并报告超时。不要继续使用过期或缺失的评审结果。

GitLab — 发布触发评论前,检查 Greptile 是否已在运行:

PIPELINES=$(glab api "projects/:fullpath/merge_requests/<MR_IID>/pipelines")
GREPTILE_RUNNING=$(echo "$PIPELINES" | jq '[.[] | select(.status == "running" or .status == "pending")] | length')

如果没有正在运行的流水线,则发布触发评论:

if [ "$GREPTILE_RUNNING" = "0" ]; then
  glab mr note <MR_IID> --message "@greptile review"
fi

Perforce — Perforce 没有原生的检查运行。如果 Greptile 通过 p4 shelve 触发的 webhook 集成,请等待其处理。检查 Greptile 安装的 webhook 端点或仪表板,查看评审状态。通过重新获取 CL 上的 Greptile 评审评论进行轮询,直到出现评分。

然后轮询 Greptile 流水线作业,直到完成(参见 GitLab API 参考):

HEAD_SHA=$(glab mr view <MR_IID> --output json | jq -r '.sha')
ATTEMPTS=0
MAX_ATTEMPTS=60
POLL_INTERVAL_SECONDS=10

while true; do
  ATTEMPTS=$((ATTEMPTS + 1))
  if [ "$ATTEMPTS" -gt "$MAX_ATTEMPTS" ]; then
    echo "Timed out waiting for the Greptile pipeline job after approximately 10 minutes." >&2
    exit 1
  fi

  PIPELINES=$(glab api "projects/:fullpath/merge_requests/<MR_IID>/pipelines")
  # Find the most recent pipeline for this SHA
  PIPELINE_ID=$(echo "$PIPELINES" | jq -r --arg sha "$HEAD_SHA" \
    '[.[] | select(.sha == $sha)] | sort_by(.id) | last | .id // empty')

  if [ -z "$PIPELINE_ID" ]; then
    echo "Waiting for Greptile pipeline to appear..."
    sleep "$POLL_INTERVAL_SECONDS"
    continue
  fi

  JOBS=$(glab api "projects/:fullpath/pipelines/$PIPELINE_ID/jobs")
  GREPTILE_JOB=$(echo "$JOBS" | jq '.[] | select(.name | test("greptile"; "i"))')

  if [ -z "$GREPTILE_JOB" ]; then
    echo "Waiting for Greptile job to appear..."
    sleep "$POLL_INTERVAL_SECONDS"
    continue
  fi

  JOB_STATUS=$(echo "$GREPTILE_JOB" | jq -r '.status')

  if [ "$JOB_STATUS" = "success" ] || [ "$JOB_STATUS" = "failed" ] || [ "$JOB_STATUS" = "canceled" ]; then
    echo "Greptile job completed with: $JOB_STATUS"
    break
  fi

  echo "Waiting for Greptile... (status: $JOB_STATUS)"
  sleep "$POLL_INTERVAL_SECONDS"
done

如果轮询超时,则停止 greploop 工作流并报告超时。不要继续使用过期或缺失的评审结果。

B. 获取 Greptile 审查结果

Greptile 可能会在多个位置显示评分——请检查所有相关来源:

GitHub:

1. PR 描述(正文):

gh pr view <PR_NUMBER> --json body -q '.body'

2. 常规 PR 评论(议题评论):

gh api --paginate "repos/{owner}/{repo}/issues/<PR_NUMBER>/comments?per_page=100"

筛选 Greptile 撰写的评论,并使用最近更新的评论(updated_at)正文,而不是最近创建的评论。Greptile 可能会在每轮审查时编辑同一条常规 PR 评论;在确定没有剩余问题之前,请解析当前正文,包括“Prompt to fix all with AI”部分。

3. PR 审查:

gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/reviews

查找来自 greptile-apps[bot] 或 greptile-apps-staging[bot] 的最新条目。

GitLab:

1. MR 描述(正文):

glab mr view <MR_IID> --output json | jq -r '.description'

2. MR 备注(评论):

glab api "projects/:fullpath/merge_requests/<MR_IID>/notes"

筛选来自 Greptile 机器人用户的备注(检查 author.username 字段——确切用户名可能因安装而异;首次运行时请确认)。

Perforce:

1. CL 描述:

p4 describe -s <CL_NUMBER>

检查描述字段中是否有 Greptile 附加的评分块。

2. CL 评论/审查备注: 如果你的安装使用 Helix Swarm 等审查工具,请通过其 API 获取评论。

示例(Swarm API): GET /api/v11/comments?topic=reviews/<REVIEW_ID>

通常需要关注的响应字段包括:

  • user(作者用户名)
  • body(评论文本)
  • 表示评论是否已解决的 flags/state

筛选由 Greptile 机器人撰写的评论:

  • 如果知道确切用户名,优先使用精确匹配
  • 否则,使用启发式方法:作者名称包含“greptile”(不区分大小写)

对于所有平台,请解析文本以获取:

  • 置信度评分:类似 3/5 或 5/5(或 Confidence: 3/5)的模式。
  • 评论数:摘要中提到的行内审查评论数量。

使用最近更新的评分来源。在比较经过编辑的 Greptile 摘要与较早的审查条目时,GitHub 优先使用议题评论中的 updated_at。

同时获取所有未解决的行内评论:

GitHub:

gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments

即使行内评论端点返回零条未解决评论,也要保留最新 Greptile 常规 PR 评论中的可执行事项,尤其是“Prompt to fix all with AI”部分。

GitLab:

glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions"

筛选来自 Greptile、属于 DiffNote 类型讨论(notes[0].type == "DiffNote")、位于最新提交上且尚未解决("resolved": false)的讨论。

Perforce: 如果使用 Swarm:

获取与 CL 关联的审查中的行内差异评论

GET /api/v11/comments?topic=reviews/<REVIEW_ID>

筛选来自 Greptile 机器人用户且尚未标记为已解决/已处理的评论。

C. 检查退出条件

满足以下任一条件时,停止循环:

  • 置信度评分为 5/5 且没有未解决评论
  • 达到最大迭代次数(报告当前状态)
D. 修复可执行评论

对于每条未解决的 Greptile 评论:

  1. 阅读文件并结合上下文理解评论。
  2. 判断评论是否可执行(需要更改代码)还是仅提供信息。
  3. 如果可执行,则进行修复。
  4. 如果仅提供信息或属于误报,请记录下来,但仍要解决该讨论串。
E. 解决讨论串

GitHub — 获取未解决的审查讨论串,并解决所有已处理的讨论串(参见 GraphQL 参考):

gh api graphql -f query='
query($cursor: String) {
  repository(owner: "OWNER", name: "REPO") {
    pullRequest(number: PR_NUMBER) {
      reviewThreads(first: 100, after: $cursor) {
        pageInfo { hasNextPage endCursor }
        nodes {
          id
          isResolved
          comments(first: 1) {
            nodes { body path author { login } }
          }
        }
      }
    }
  }
}'

解决已处理的讨论串:

gh api graphql -f query='
mutation {
  t1: resolveReviewThread(input: {threadId: "ID1"}) { thread { isResolved } }
  t2: resolveReviewThread(input: {threadId: "ID2"}) { thread { isResolved } }
}'

GitLab — 获取未解决的讨论,并逐一解决(参见 GitLab API 参考):

glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions?per_page=100"

筛选 "resolved": false 的讨论。然后通过各自的 id 逐一解决:

glab api --method PUT \
  "projects/:fullpath/merge_requests/<MR_IID>/discussions/<DISCUSSION_ID>" \
  --field resolved=true

对每个未解决的讨论 ID 重复此操作。(GitLab 不支持批量解决——请逐一处理。)

F. 提交并推送/重新搁置

GitHub/GitLab:

git add -A
git commit -m "address greptile review feedback (greploop iteration N)"
git push

Perforce:

# Stage changes back into the CL and re-shelve for the next review round
p4 shelve -f -c <CL_NUMBER>

推送/搁置后,等待检查开始运行:

sleep 5

然后返回步骤 A。

3. 报告

退出循环后,汇总:

字段值
平台GitHub / GitLab / Perforce
迭代次数N
最终信心度X/5
已解决的评论N
剩余评论N(如有)

如果因达到最大迭代次数而退出循环,请列出尚未解决的评论,并建议后续步骤。

输出格式

Greploop complete.
  Platform:      GitHub
  Iterations:    2
  Confidence:    5/5
  Resolved:      7 comments
  Remaining:     0

如果未完全解决:

Greploop stopped after 5 iterations.
  Platform:      GitLab
  Confidence:    4/5
  Resolved:      12 comments
  Remaining:     2

Remaining issues:
  - src/auth.ts:45 — "Consider rate limiting this endpoint"
  - src/db.ts:112 — "Missing index on user_id column"

Perforce 示例:

Greploop complete.
  Platform:      Perforce
  Changelist:    12345
  Iterations:    3
  Confidence:    5/5
  Resolved:      9 comments
  Remaining:     0

评论

支持 Markdown