Flutter PR 牧羊人(Shepherd)工作流:用 gh CLI 完成 PR 状态检查、陈旧分支更新与 Autosubmit 落地的标准 Runbook
本篇围绕 Flutter 仓库中 flutter/flutter 的 PR 牧羊(shepherding)技能文档,讲解一套可复制的标准作业流程:如何用 GitHub CLI(gh)查询自有及第三方 PR 的状态与检查项、在执行 autosubmit 贴标前必须完成的四项预检(历史移除原因、base commit 新鲜度、双评审人、全绿检查)、如何手动触发 LUCI 失败构建重试,以及如何用 gh pr update-branch 与 CICD 标签处理陈旧分支。读完本文,你可以独立驾驭一条 PR 从"等待 CI 变绿"到"被 autosubmit 机器人自动合并"的完整生命周期。
1. 技能定位:这是给谁用的标准 Runbook
PR 牧羊技能定义于 .agents/skills/shepherd-prs/SKILL.md,其元数据(front matter)声明如下:
- 名称:
shepherd-prs - 用途:使用原生 GitHub CLI(
gh)命令,自动化地对flutter/flutter仓库中处于开放状态或已获批准的第三方贡献者 PR 进行"牧羊"——即检查状态、更新分支、贴autosubmit标签使其落地。 - 适用时机:
- 需要查询开放 PR 或正在牧羊的第三方 PR 的状态时;
- 需要更新陈旧(stale)分支或对已批准的 PR 施加
autosubmit标签使其落地时。
- 不适用场景:
- 未获批准的 PR(除非那是你自己的 PR,仅想查看状态);
flutter/flutter以外的仓库。
该技能遵循 Flutter 仓库对共享 Agent 技能的治理规范(见 .agents/skills/README.md):技能必须面向 Flutter 贡献者、每个 CLI 工具一个专属技能、指令越结构化越好、脚本优先使用 Dart 编写,并且需通过 dart_skills_lint 工具校验。这意味着本文描述的流程不是临时经验,而是仓库内正式维护、有所有权归属的标准作业程序。
理解"牧羊"的上下文:Flutter 仓库使用 autosubmit 机器人(代码位于 flutter/cocoon 基础设施中)自动验证并合并 PR。开发者给 PR 加上 autosubmit 标签后,机器人会在所有检查通过、评审满足要求时自动合并;一旦有检查失败或条件不满足,机器人会移除标签并停止处理(见 docs/infra/Autosubmit-bot.md)。因此"牧羊人"的核心价值就是:在贴标之前把机器人会拒绝/撕掉标签的所有坑提前排掉。标签体系(autosubmit、revert、revert of、emergency)的完整说明见 docs/infra/Landing-Changes-With-Autosubmit.md。
2. 检查 PR 状态:四条核心 gh 命令
当需要查看开放或已批准 PR 的状态时,按以下顺序执行:
1. 列出自己名下的开放 PR:
gh pr list --repo flutter/flutter --author <username> --state open --json number,title,url,mergeable,reviewDecision
--json 指定的五个字段分别覆盖:PR 编号、标题、URL、可合并状态(mergeable)、评审决议(reviewDecision)——这正是判断一个 PR 是否可以推进的全部关键信号。
2. 列出自己"牧羊"中的第三方 PR(自己做过 review 但非自己作者):
gh pr list --repo flutter/flutter --search "reviewed-by:<username> -author:<username> is:open" --json number,title,url,mergeable,reviewDecision
这里的 --search 使用的是 GitHub 搜索语法:reviewed-by:<username> 表示该用户已评审过,-author:<username> 排除自己作者身份,is:open 限定开放状态。
3. 检查 PR 的详细检查项:
gh pr checks <number> --repo flutter/flutter
4. 检查评审、标签与评论:
gh pr view <number> --repo flutter/flutter --json labels,reviewDecision,reviews,comments
第 4 条命令的输出是后续所有预检判断的数据来源:labels 用于确认 autosubmit/CICD 是否在场,reviews 用于统计团队成员批准数,comments 用于检索 auto-submit 机器人历史消息。
3. 贴 autosubmit 标签前的四项预检规则
在给 PR 施加(或重新施加)autosubmit 标签之前:
gh pr edit <number> --repo flutter/flutter --add-label autosubmit
必须先完成以下四项起飞前检查(pre-flight verification),确保 auto-submit 机器人不会拒绝或撕掉该标签。
3.1 检查 autosubmit 被移除的历史记录
通过查看 PR 评论,确认 autosubmit 标签是否曾被 auto-submit 机器人移除过:
gh pr view <number> --repo flutter/flutter --json comments
在评论中查找来自 auto-submit 的 "autosubmit label was removed..." 类消息。如果标签此前被移除过,必须找出机器人陈述的确切原因(CI 检查失败、批准不足、合并冲突、分支陈旧等),并确认该问题确实已解决后再重新贴标。这与 docs/infra/Autosubmit-bot.md 中"任何测试失败都会导致标签被移除、机器人停止处理该 PR"的行为描述完全一致——盲目重贴而不排查原因只会陷入"贴标—撕标"循环。
3.2 验证 base commit 新鲜度(超过 7 天即视为陈旧)
检查 PR 的 base commit 是否已陈旧(超过 7 天)。如果 base commit 超过 7 天:
- 必须先执行分支更新,再考虑贴
autosubmit:
gh pr update-branch <number> --repo flutter/flutter
- 在分支更新完成、且更新后分支的 CI 检查全部成功之前,不得施加
autosubmit。
3.3 严格验证必需的团队成员批准
对第三方贡献者的 PR(作者角色为 CONTRIBUTOR、FIRST_TIME_CONTRIBUTOR、NONE),施加 autosubmit 之前必须确认至少存在 2 个团队成员批准(MEMBER 或 OWNER 角色),否则机器人会再次撕掉标签。通过以下命令核查:
gh pr view <number> --repo flutter/flutter --json reviews
这条规则与 autosubmit 机器人的官方评审规则互相印证:在 docs/infra/Autosubmit-bot.md 中,机器人区分作者是否为 flutter-hackers 组织成员——成员作者的 PR 需要至少 1 个组织成员的额外评审(最好来自代码所有者),非成员作者需要至少 2 个组织成员的额外评审;且只要有任何一位评审人发起"请求更改"(request changes),无论已有多少批准,PR 都不会被合并,autosubmit 标签会被移除,直到发起更改请求的评审人重新批准。
3.4 验证全部状态检查 100% 通过
Flutter 的 autosubmit 机器人在任何 CI 检查失败时会自动撕掉 autosubmit 标签。因此:
- 确认所有状态检查均处于通过状态(
SUCCESS/pass); - 如果有任何检查处于 flaky、失败或等待重试状态:
- 不要立即贴
autosubmit标签; - 告知用户哪个检查失败,并指示其先重试该检查;
- 只有当所有重试的检查都成功完成后,再执行:
- 不要立即贴
gh pr edit <number> --repo flutter/flutter --add-label autosubmit
4. 第三方贡献者 PR 的双评审人要求(专章强调)
这一条在技能文档中独立成章,因为它是机器人撕标最高频的触发点:
- 由第三方贡献者(
CONTRIBUTOR、FIRST_TIME_CONTRIBUTOR、NONE)提交的 PR,要求 Flutter 团队成员(MEMBER或OWNER)的两次明确批准,之后 autosubmit 机器人才会合并它; - 如果只有 1 个团队成员批准时就贴上
autosubmit标签,机器人会直接移除该标签; - 动作:通过
gh pr view <number> --repo flutter/flutter --json reviews严格核实至少存在 2 个团队成员批准,然后再贴标。若只有 1 个批准,提醒用户先请求第二位评审人。
5. 失败检查与手动 LUCI 重跑
由于 GitHub App 权限策略限制,第三方检查运行(例如由 flutter-dashboard 创建的 LUCI 检查)无法通过 GitHub API 重跑。因此当检查失败时,标准处置流程为:
- 打印出该失败检查对应的精确 LUCI Buildbucket 链接(形如
https://cr-buildbucket.appspot.com/build/<build_id>); - 指示用户打开该 URL,并在 LUCI 页面点击 Retry Build;
- 如果手动重试后检查仍然失败,则检查失败日志(通过
gh pr view <number> --repo flutter/flutter,或使用同仓库的 flutter-pr-checks-finder 技能)并为用户总结失败原因。
补充背景:这些检查对应 .ci.yaml 中声明的 CI 任务清单——Flutter 基础设施用该文件为每个 commit 生成待执行任务列表,其中 flutter_drone recipe 会将分片(shard)测试委托给仓库内的 dev/bots/test.dart 执行(分片如 analyze、test_general 等)。这也解释了为什么失败检查通常成组出现、且需要逐个确认重试结果。
6. 陈旧分支更新、CICD 标签与 Token 作用域
这是牧羊流程中最容易卡住的环节,技能文档给出了三条配套规则:
6.1 分支陈旧就先更新
如果 PR 分支落后于 master(包括 base commit 超过 7 天的情形),在尝试添加 autosubmit 之前,必须先执行:
gh pr update-branch <number> --repo flutter/flutter
6.2 更新分支后重新施加 CICD 标签
执行 gh pr update-branch(或牧羊一个尚未跑过 CI 的 PR)之后,CICD 标签常常被撕掉,或需要重新加上以在更新后的 commit 上触发 CI 检查。因此:
- 每次分支更新后,检查
CICD标签是否仍在; - 缺失则重新施加:
gh pr edit <number> --repo flutter/flutter --add-label CICD
关于 CICD 标签的作用机制:对于启用了 Unified Check Run 功能的账号,带有 CICD 标签的 PR 会将多个 check-run 合并为单一的 Dashboard Checks / Flutter Presubmits check-run,可通过"View more details on flutter-dashboard"链接进入 presubmit 仪表盘查看逐任务详情并重跑失败任务(见 docs/infra/Unified-Check-Run-User-Manual.md)。
6.3 处理 Token 作用域过期错误
如果分支更新因 workflow 文件权限失败(报错形如 ERROR: ... lacks the "workflow" scope),指示用户刷新 CLI 的授权作用域:
gh auth refresh -h github.com -s workflow
7. 目标分支纠正与合并冲突
- 评审作废警告:更改 PR 的目标分支(target branch)经常会导致 GitHub 自动作废(dismiss)已有的批准。如果检测到目标分支发生过变更,必须提醒用户在 GitHub 上重新执行评审批准,否则 3.3 节的双批准条件会不满足,autosubmit 必然撕标。
- 合并冲突:如果 PR 存在冲突(
mergeable字段为CONFLICTING),通知用户让作者自行解决冲突。这与 autosubmit 机器人的 merge-ability 检查对应——机器人会在合并前检查可合并性,并主动通知作者冲突情况(见 docs/infra/Autosubmit-bot.md)。
8. 牧羊流程速查
把以上规则串起来,一条 PR 的完整牧羊路径是:
# 1. 找到要牧羊的 PR
gh pr list --repo flutter/flutter --search "reviewed-by:<username> -author:<username> is:open" --json number,title,url,mergeable,reviewDecision
# 2. 看检查是否全绿(失败则先手动重跑 LUCI,见第 5 节)
gh pr checks <number> --repo flutter/flutter
# 3. 查评审数与机器人历史(确认 2 个团队批准、排查 autosubmit 撕标原因)
gh pr view <number> --repo flutter/flutter --json labels,reviewDecision,reviews,comments
# 4. base commit 超过 7 天或落后 master 时,先更新分支
gh pr update-branch <number> --repo flutter/flutter
gh pr edit <number> --repo flutter/flutter --add-label CICD # 更新后若缺 CICD 标签则补上
# 5. 全部检查成功 + 批准数达标后,最后贴标
gh pr edit <number> --repo flutter/flutter --add-label autosubmit
四条不变式贯穿始终:先看机器人撕标原因再重贴;base commit 超 7 天先更新分支;第三方 PR 必须凑齐 2 个 MEMBER/OWNER 批准;任何一项检查未通过都不贴标。遵循这套预检顺序,auto-submit 机器人就会在你贴上标签后顺利完成验证并自动合并,无需人工盯守 CI。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00