关于 1k-monitor-pr-ci
用于监控 GitHub Pull Request 的 CI 检查和评审讨论串的 Skill。它可轮询状态、修复可处理的 CI 失败、回复评审意见并解决讨论串,同时区分合并门槛阻塞与普通失败。
主要功能
- 01轮询 CI 与评审状态
- 02生成机器可读状态报告
- 03修复可处理的 CI 失败
- 04回复并解决评审讨论串
- 05识别 release-ready 门槛阻塞
适用场景
- 01跟踪进行中 PR 的 CI 状态
- 02批量处理评审反馈
- 03识别 release-ready 合并阻塞
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ onekeyhq/ app-monorepo --skill 1k-monitor-pr-ci安装后在 Claude Code 中输入/1k-monitor-pr-ci确认已加载。
附带文件agents/openai.yaml
详细介绍
监控 PR CI 和评审
监控拉取请求的 CI 检查和评审评论。自动修复 CI 失败、处理行内评审评论、回复评审者并解决讨论串。
如需一次性获取低上下文的 PR 状态摘要,请使用:
yarn agent:check --profile ci --pr <PR_NUMBER>
如需自动化监控,请优先使用稳定的机器可读契约:
yarn agent:check --profile ci --pr <PR_NUMBER> --json-file /tmp/agent-check.json
请读取 /tmp/agent-check.json,而不是解析终端文本。该报告包含
schemaVersion: 1、顶层字段 status / exitCode / failureReasons,以及
remote.pr、remote.checks 和 remote.review 中稳定的嵌套对象。
如需在不启动监控的情况下回复并解决特定评审讨论串:
yarn agent:review-thread --pr <PR_NUMBER> --list
yarn agent:review-thread --pr <PR_NUMBER> --thread <THREAD_ID> --reply-file <FILE>
请使用 --list 或
remote.review.threads.unresolvedItems[].id 中的 GraphQL 讨论串 ID;数字索引仅用于 --dry-run 验证。
仅当用户需要轮询、自动修复或批量处理评审讨论串时,才使用此监控工作流。
用法
/1k-monitor-pr-ci https://github.com/OneKeyHQ/app-monorepo/pull/10717 3m
/1k-monitor-pr-ci 10717 5m
/1k-monitor-pr-ci https://github.com/OneKeyHQ/app-monorepo/pull/10717
/1k-monitor-pr-ci 10717
/1k-monitor-pr-ci
输入
$ARGUMENTS — 由空格分隔的两部分:
- PR 标识符(如果当前分支没有 PR,则必填):PR 编号、GitHub PR URL
- 轮询间隔(可选,默认为
6m):例如30s、1m、2m、3分钟、5min、6m
如果 $ARGUMENTS 为空,则从当前分支自动检测 PR,并使用默认的 6m 间隔。
步骤 0:初始设置
-
解析参数:将
$ARGUMENTS拆分为 PR 标识符和轮询间隔。- PR 标识符:编号或类似
https://github.com/{owner}/{repo}/pull/{number}的 URL - 轮询间隔:匹配时间格式(数字 + 时间单位)的任意标记。识别:
s/sec/秒、m/min/分钟/分。默认值:6m - 如果
$ARGUMENTS为空,则从当前分支检测 PR:gh pr list --head "$(git branch --show-current)" --json number --jq '.[0].number' - 如果未找到 PR,且未提供参数,则向用户询问 PR 链接
- PR 标识符:编号或类似
-
确定 owner/repo:
- 如果提供了完整的 GitHub URL,则从中提取 owner 和 repo
- 否则,从本地仓库检测:
gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'
-
确认并启动(无需再提问):
Monitoring PR #10717 (OneKeyHQ/app-monorepo) Polling interval: 3m Starting...
步骤 1:轮询循环
每次迭代([Check N/30]):
1a. 获取 agent-check JSON — 每次迭代都必须执行
将 agent:check 用作唯一的读取路径。它会获取 CI 检查、PR 元数据、
行内评论和 GraphQL 评审讨论串状态,然后写入稳定的
schemaVersion: 1 JSON 报告。
AGENT_CHECK_JSON="$(mktemp -t agent-check.XXXXXX.json)"
yarn agent:check --profile ci --pr <PR_NUMBER> --json-file "$AGENT_CHECK_JSON" || true
不要仅凭 agent:check 的非零退出代码就将其视为命令失败。
对于监控,非零表示 JSON 中包含需要处理的状态,例如
CI 待处理、CI 失败、未解决的评审讨论串、草稿 PR、合并受阻状态
或被截断的评审数据。
从 JSON 报告中读取以下字段:
status、exitCode、failureReasonsremote.pr.{number,url,state,reviewDecision,mergeStateStatus,isDraft}remote.checks.counts、remote.checks.failed、remote.checks.pending、remote.checks.gateFailedremote.review.threads.{unresolved,activeUnresolved,dataComplete,unresolvedItems}remote.review.changesRequestedBy
回退方案:如果 agent:check 不可用,或返回了不受支持的
schemaVersion,则使用原始 gh 查询获取相同的四项信号。讨论串 ID 和解决状态仍需通过 GraphQL 获取。如果 GraphQL 失败,则回退到 REST API 获取行内评论:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
--jq '.[] | {id: .id, body: .body, path: .path, line: .original_line, user: .user.login, in_reply_to_id: .in_reply_to_id, created_at: .created_at}'
注意:REST 回退方案可以获取评论并回复,但无法解决讨论串(GitHub 仅支持通过 GraphQL 执行此操作)。使用 REST 回退方案时,跳过解决步骤(步骤 3d),并记录警告,说明必须手动解决讨论串。
仅筛选未解决的讨论串(isResolved: false)。跳过最后一条评论来自当前 gh 用户的讨论串(表示已回复)。
1b. 显示状态摘要
[Check 3/30]
CI Status:
| Check | Status | Duration |
|------------------|---------|----------|
| lint (24.x) | pass | 5m34s |
| unittest (24.x) | pending | - |
Unresolved threads: 3
- src/views/Example.tsx:42 (@reviewer): "Consider using useCallback here"
- src/utils/format.ts:15 (@reviewer): "This should handle null case"
- src/components/Card.tsx:88 (@reviewer): "Typo in variable name"
1c. 决定下一步操作
选择操作前,先将 agent:check JSON 分为以下三类:
- 常规失败检查:
remote.checks.failed - 门禁失败:
remote.checks.gateFailed - 待处理检查:
remote.checks.pending
如果 release-ready-merge-gate 失败,应将其视为预期的合并阻塞项,而不是需要自动修复的 CI 失败。
| CI 状态 | 未解决的讨论串 | 操作 |
|---|---|---|
| 常规失败检查 | - | 自动修复 CI 失败(步骤 2) |
| 门禁失败 | 有讨论串 | 处理讨论串(步骤 3),然后报告因缺少 release-ready 而受阻 |
| 门禁失败 | 没有讨论串 | 停止等待,并报告因缺少 release-ready 而受阻 |
| 有待处理项 | 有讨论串 | 处理讨论串(步骤 3),继续等待 CI |
| 有待处理项 | 没有讨论串 | 等待后重新检查 |
| 全部通过 | 有讨论串 | 处理讨论串(步骤 3) |
| 全部通过 | 没有讨论串 | 完成(步骤 4) |
步骤 2:自动修复 CI 失败
对于每项失败的检查:
-
从最新的轮询结果中找出可处理的失败检查。
- 使用当前迭代的
remote.checks.failed输出,不要使用之前迭代的过时输出。 - 保留失败检查的
name和link。 - 在修复先前错误后,重新运行可能会在同一检查中暴露出不同的后续失败。例如,
lint (24.x)可能先因格式问题失败,修复后又因包版本一致性问题失败。如果推送后同名检查再次失败,应将其视为新的步骤 2 项目,并继续修复,直到不再有常规失败检查。
- 使用当前迭代的
-
从失败检查的
link中提取RUN_ID。- 链接示例:
https://github.com/{owner}/{repo}/actions/runs/<RUN_ID>/job/<JOB_ID>https://github.com/{owner}/{repo}/runs/<RUN_ID>
- 从 URL 中提取
<RUN_ID>,获取日志时使用该确切运行编号。
- 链接示例:
-
获取失败日志:
gh run view <RUN_ID> --log-failed 2>&1 | tail -100 -
分析失败并确定原因。
-
可修复(lint 错误、类型错误、由我们的改动导致的测试失败):
- 修复代码
- 提交:
fix: resolve CI <check-name> failure - 推送到 PR 分支
- 等待 30s,返回步骤 1
-
可能与 PR 无关或已存在(仓库范围的包/版本一致性失败、PR 未修改的文件中出现失败,或可能早于 PR 就存在的问题):
- 对照
origin/x快速验证,或检查失败条件是否已存在于 PR 差异之外。 - 如果基础分支上已存在相同失败,应将其报告为既有阻塞项,而不是假称它是由 PR 工作修复的。
- 询问用户是否仍要在此 PR 中修复该阻塞项,还是将其作为无关问题保留。
- 对照
-
无法修复(基础设施问题、不稳定测试、用户不希望在此处修复的无关失败):
- 向用户报告失败详情
- 建议采取的操作(重新运行、跳过、手动修复)
- 询问用户如何继续
步骤 3:处理评审讨论串
对于每个未解决的讨论串:
3a. 对评论分类
阅读评论内容及相关代码上下文,并进行分类:
- 需要修复代码 — 需要修改文件 → 自动修复
- 问题 — 只需解释,无需更改代码 → 自动回复
- 不同意/不予修复 — 回复前必须询问用户。绝不要自动解决意见分歧。
为每个讨论串显示一行日志,说明将采取的操作,然后立即继续处理。不要等待用户确认——只有在不同意/不予修复的情况下才暂停。
3b. 修复代码
对于每个需要修复代码的讨论串:
- 读取指定路径和行号处的文件
- 使用 Edit 工具进行修复
- 快速检查时,验证修复不会导致 lint/类型检查失败
3c. 回复评论
使用 REST API 回复并说明已完成的处理:
gh api --method POST \
repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_database_id}/replies \
-f body='Fixed: [concise explanation of the change]'
对于问题(无需更改代码):
gh api --method POST \
repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_database_id}/replies \
-f body='[answer to the question]'
回复应简洁。说明改了什么以及为什么。
3d. 解决对话串
回复后,通过 GraphQL 解决对话串:
gh api graphql -f query='
mutation($threadId: ID!) {
resolveReviewThread(input: {threadId: $threadId}) {
thread {
isResolved
}
}
}' -f threadId="THREAD_NODE_ID"
注意:解决对话串需要使用 GraphQL,没有对应的 REST API。如果步骤 1b 回退到 REST,请跳过此步骤并记录警告:“已跳过解决对话串(GraphQL 不可用)。请手动解决。”
3e. 提交并推送
本轮处理完所有对话串后:
- 暂存已更改的文件:
git add <specific files> - 使用描述性消息提交:
git commit -m "fix: address PR review feedback - [list each fix made]" - 推送:
git push
3f. 请求重新审核
推送修复后,请求留下评论的审核者重新审核:
-
获取留下评论的审核者(从步骤 1b 的对话串数据中收集
author.login字段) -
请求重新审核:
gh pr edit <PR_NUMBER> --add-reviewer <reviewer1>,<reviewer2>或者,如果
--add-reviewer未触发重新审核,则通过 API 请求:gh api --method POST \ repos/{owner}/{repo}/pulls/{pr_number}/requested_reviewers \ -f 'reviewers[]=reviewer1' -f 'reviewers[]=reviewer2' -
返回步骤 1(等待 CI 重新运行)
步骤 3g:报告阻止发布就绪的门禁检查
如果唯一剩下的失败检查是 release-ready-merge-gate,则停止轮询并报告:
CI is complete, but merge is blocked by the release-ready gate.
Blocking check:
- release-ready-merge-gate: expected failure until the PR gets the `release-ready` label
Action:
- Add the `release-ready` label to the PR, then run the monitor again if needed
请勿:
- 尝试自动修复此检查
- 将其视为不稳定的基础设施
- 继续等待它自行通过
步骤 4:最终报告
所有常规 CI 检查均已通过且没有未解决的对话串时:
All normal CI checks passed. All review threads resolved.
CI:
| Check | Status | Duration |
|------------------|--------|----------|
| lint (24.x) | pass | 5m34s |
| unittest (24.x) | pass | 4m42s |
Review threads: 5 resolved, 0 remaining
PR: <URL>
Status: Ready for re-review / Ready to merge
如果 release-ready-merge-gate 仍然失败,请勿使用此最终报告。请改用步骤 3g 中的阻塞状态报告。
轮询规则
- 两次检查间默认间隔 6 分钟(用户可在步骤 0 中自定义)
- 修复并推送后等待 30 秒,以便 CI 重新启动
- 最多 30 轮,之后询问用户是继续还是停止
- 始终显示
[Check N/30]
重要说明
- CI 失败:自动修复,无需询问
- 如果重新运行后又出现其他常规失败检查,不要在修复第一个 CI 错误后停止。每次出现新的失败检查时,都继续执行步骤 2,直到所有常规 CI 检查通过。
- 审核评论:自动修复,无需询问——简要说明将采取的措施,然后立即继续
- 不同意/不予修复:回复或解决之前必须先询问用户——这是唯一需要用户输入的情况
- 绝不强制推送或修改已有提交
- 每轮修复都创建一个新提交
- 尽可能在一个提交中修复多个 CI 失败
- 不要自动重新运行检查(只有用户请求
gh run rerun时才运行) - 提交消息中不要包含“Co-Authored-By”或“Generated with”
- 追踪已处理的对话串,避免不同轮次间重复处理
错误处理
- 非阻塞错误:如果某个步骤失败(解决对话串、回复评论、请求重新审核),记录警告并继续处理下一个对话串/步骤。绝不要因单个对话串的失败而中止整个循环。
- GraphQL 不可用:回退到 REST API 获取评论。跳过解决步骤并记录警告。
- 回复失败:记录包含对话串路径/行号的警告,然后继续处理下一个对话串。代码修复仍会提交。
- 解决失败:记录警告并继续。对话串会保持未解决状态,但修复会推送。
- 重新审核请求失败:记录警告并继续。审核者仍会收到推送通知。
- 阻塞错误:出现以下情况时中止循环:
ghCLI 未通过身份验证- PR 不存在
- PR 已关闭或已合并(每轮通过
gh pr view <PR_NUMBER> --json state --jq '.state'检查——如果状态为CLOSED或MERGED,则停止并告知用户)