ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

gemini-cli 的 Issue 与 PR 自动化分诊:从 Bot 触发规则到源码级实现解析

gemini-cli 的 Issue 与 PR 自动化分诊:从 Bot 触发规则到源码级实现解析 gemini-cli 的 Issue 与 PR 自动化分诊从 Bot 触发规则到源码级实现解析【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli本文基于 gemini-cli 仓库中的 自动化与分诊流程文档 展开系统拆解该项目用于管理 Issue 与 Pull Request 的七条自动化工作流谁触发、何时运行、做了什么、以及贡献者应该配合做什么。读完本文你不仅能理解该项目机器人系统的完整运作方式包括标签体系、Gemini 模型分诊提示词、防重复注释策略等还能直接对照仓库中每个工作流的 YAML 定义与配套脚本将其作为你自己项目 CI/分诊自动化的设计参考。核心原则Issue 描述是什么PR 描述怎么做整套自动化建立在一个基本约定上几乎每个 PR 都应关联一个对应的 Issue。Issue 描述是什么和为什么缺陷或功能需求PR 描述怎么做具体实现。这种分离让团队可以追踪工作量、排定优先级并保留清晰的历史上下文仓库里的标签同步、链接检查等自动化都围绕这一原则构建。注意带有 Maintainers only 标签的 Issue 是保留给项目维护者的不会接受与之相关的 PR。这一约定不是空话仓库中有多处证据支撑PR 模板 pull_request_template.md 中的 Related Issues 一节明确要求使用关键字自动关闭 IssueCloses #123、Fixes #456如果只是部分相关则直接引用编号Related to #123定时 PR 分诊脚本 pr-triage.sh 会扫描 PR 的closingIssuesReferences甚至用正则(^|[^a-zA-Z0-9])#(?num[0-9])从 PR 正文中兜底提取#编号见该脚本第 141 行附近找不到任何关联 Issue 的非 Draft PR 会被打上status/need-issue标签。标签体系分诊输出的结构化语言理解各工作流之前先了解它们共同操作的一组标签前缀。从 定时 Issue 分诊工作流 的检索语句中可以看到完整标签空间前缀含义示例取值area/*功能领域area/agent、area/core、area/enterprise、area/non-interactive、area/security、area/platform、area/extensions、area/documentation、area/unknownkind/*Issue 类型kind/bug、kind/enhancement、kind/customer-issue、kind/questionpriority/*优先级P0 严重到 P3 低priority/p0、priority/p1、priority/p2、priority/p3、priority/unknowneffort/*工作量估计effort/small、effort/medium、effort/largestatus/*状态status/need-triage、status/need-information、status/need-issue、status/bot-triaged、status/manual-triagesize/*PR 改动规模size/XS到size/XL其中area/*、kind/*、priority/*三类都遵循每个 Issue 有且只有一个的约束后面的分诊工作流正是围绕补齐缺失项、消除冲突项运转的。工作流一开 Issue 时的即时分诊Automated Issue Triage工作流文件gemini-automated-issue-triage.yml触发时机Issue 创建或重新打开issues: opened/reopened也支持workflow_dispatch手动传入 Issue 编号以及被其他工作流以workflow_call复用。运行条件可从文件头部if表达式读出仓库必须是官方主仓库Issue 尚未带有area/标签避免重复分诊issue_comment触发的重分诊要求评论包含gemini-cli /triage且评论者为 OWNER/MEMBER/COLLABORATOR。它做的事情是把给 Issue 打标签这件事交给 Gemini 模型完成流程如下准备上下文将 Issue 标题与正文写入工作区的issue_context.md文件Prepare Issue Data 步骤。列出可用标签通过 GitHub API 拉取仓库标签并硬编码一个allowedLabels白名单9 个area/*标签见工作流文件第 118–128 行只允许模型在这些标签中做选择。运行 Gemini CLI 分析使用google-github-actions/run-gemini-cli动作提示词要求模型用read_file读取issue_context.md根据内嵌的 Reference 1: Area Definitions对每个area/*的定义与典型 Issue 举例选出恰好一个area/标签无法确定时回退到area/unknown只输出 JSON{labels_to_set: [area/core]}。这里的安全约束值得注意运行环境显式设置GITHUB_TOKEN: 注释写明此处不传任何认证 token因为这是在不可信输入上运行并通过settings把可用工具限制为run_shell_command(echo)和read_filemaxSessionTurns限制为 25。也就是说分诊 Agent 是一个只读、无凭证、工具白名单收窄的受限实例。容错解析模型输出apply-issue-labels相关脚本先直接JSON.parse模型输出失败后尝试从 Markdown 代码块json ...中提取再失败则用正则(\{[\s\S]*labels_to_set[\s\S]*\})在含调试日志的输出里定位 JSON 对象。解析后还会验证必须恰好一个标签先移除旧的冲突area/*标签再添加新标签见工作流文件第 296–375 行。失败兜底如果 Gemini 分析步骤失败会在 Issue 下发布评论提示查看 Action 运行日志Post Issue Analysis Failure Comment 步骤。贡献者该做什么尽量完整填写 Issue 模板仓库提供了 bug_report.yml、feature_request.yml 等模板如果被打上status/need-information在评论中补充缺失的日志或复现步骤。工作流二PR 的持续集成CI工作流文件ci.yml触发时机每次推送到 PRpull_request目标分支main与release/**、直接推送这些分支push、合并队列merge_group以及手动触发。从源码看CI 由七个并行 Job 组成最后由一个聚合 Job 汇总判定Job做什么lint依据 .nvmrc 装 Node 后依次执行ESLint、actionlint、shellcheck、yamllint、npm run buildnpm run typecheck、Prettier、设置文档一致性检查npm run docs:settings -- --check、敏感词检查、GitHub Actions 版本钉死检查--check-github-actions-pinning。所有 linter 统一由 scripts/lint.js 驱动link_checker用 lychee 检查仓库内所有.md文件中的链接有效性test_linux在 Node 20.x/22.x/24.x × 两个测试分片cli/others矩阵上运行npm run test:ci随后npm run bundle打包并做node ./bundle/gemini.js --version、npx安装冒烟测试非 fork 仓库用dorny/test-reporter发布 JUnit 报告fork 仓库则上传产物test_mac与 Linux 相同的矩阵另上传 coverage 报告codeql对 JavaScript 做 CodeQL 静态安全分析bundle_size用preactjs/compressed-size-action监控bundle/**产物体积变化阈值 1000 字节test_windows在 16 核 Windows 自定义 Runner 上跑慢测试60 分钟超时几个从配置中能读出的工程细节每个仓库 Job 都先经过merge_queue_skipper用于合并队列场景下避免重复跑 CILinux 测试前会安装bubblewrap沙箱依赖并放宽 AppArmor 限制Ubuntu 24.04 需要测试环境变量包含GEMINI_CLI_TRUST_WORKSPACE: true即在 CI 中预信任工作区测试按 workspace 分片cli分片只跑google/gemini-cliothers分片跑google/gemini-cli-core、google/gemini-cli-a2a-server、gemini-cli-vscode-ide-companion、google/gemini-cli-test-utils以及npm run test:scripts保证分片互不重叠最终ciJob 逐一检查七个 Job 的needs.*.result任何一个非 success/skipped 即整体失败。关于Post Coverage Comment文档提到测试全部通过后机器人会在 PR 上发布覆盖度总结评论。该能力由 post-coverage-comment 复合 Action 实现用jq从 CLI 与 Core 两个包的coverage-summary.json中取出 Lines/Statements/Functions/Branches 百分比拼成 Markdown 表格附可折叠的完整文本报告并通过thollander/actions-comment-pull-request以code-coverage-summary标签写入或更新评论——同一标签下重复运行是更新而非新发避免刷屏。贡献者该做什么确保所有检查通过绿色对勾出现红色叉号时点击 Details 查看日志、定位问题并推送修复。工作流三PR 的持续审计与标签同步PR Auditing and Label Sync工作流文件gemini-scheduled-pr-triage.yml触发时机cron: */15 * * * *即每 15 分钟对所有打开的 PR 审计一次也可手动触发整个 Job 限时 15 分钟。核心逻辑全部在 Bash 脚本 pr-triage.sh 中约 183 行可以逐段读懂批量拉取gh pr list --state open --limit 1000一次性取回每个 PR 的number、isDraft、closingIssuesReferences、body、labels五个字段再用jq压缩成 TSV 逐行处理。关联 Issue 的识别优先用 GraphQL 的closingIssuesReferences兜底才用正则从正文提取#数字。无关联 Issue 的处理非 Draft PR添加status/need-issue标签如尚未有并把 PR 编号记入prs_needing_comment输出供后续步骤通知Draft PR相反地移除status/need-issue——草稿阶段不催关联 Issue。有关联 Issue 的标签同步先移除status/need-issue然后拉取 Issue 标签但只关心area/*、priority/*、help wanted、 maintainer only这几类脚本第 43 行的grep -x -E过滤把 PR 上缺失的补齐。Issue 标签有进程内缓存兼容 Bash 3.2 的扁平字符串缓存避免重复请求 API。原子更新最终用一条gh pr edit --add-label ... --remove-label ...完成增删。一个微妙的设计点同步方向是Issue → PR 单向补齐只添加、只移除status/need-issue不会把 PR 上多余的area/*/priority/*删掉因此不会误伤人工调整。贡献者该做什么永远把 PR 关联到 Issue在描述中写Resolves #issue-number之类这是整个流程中最重要的一步——它会保证 PR 被正确归类并顺畅地走评审。工作流四Issue 的定时兜底分诊Scheduled Issue Triage工作流文件gemini-scheduled-issue-triage.yml触发时机cron: 0 * * * *每小时对全部打开的 Issue 运行一次Job 限时 60 分钟也支持手动触发。它是即时分诊的安全网但能力比即时版更强。从源码看一次定时运行会依次做同步 Issue 类型sync-issue-types.cjs 通过 GraphQL 查询最近更新的 50 个打开 Issue对尚未设置 GitHub Issue Type 的依据kind/bug或kind/feature/kind/enhancement标签回填 Bug/Feature 类型运行前后各同步一次。找出冲突 Issue一次拉取最多 2000 个打开 Issue筛出带多个area/或多个priority/标签的上限 50 个——违反每类唯一约束。找出漏网 Issue分别检索缺失area/*、缺失kind/*、缺失priority/*的 Issue各限 50 个合并去重另外为area/core、area/extensions、area/site、area/non-interactive中的 Issue 单独检查缺失的effort/*标签限 20 个。标准分诊Gemini与即时分诊相同的方式运行run-gemini-cli模型gemini-3-flash-preview工具白名单只有echo与read_file不传GITHUB_TOKEN但提示词是一整套标签策略已有唯一area/、唯一kind/、唯一priority/的不动缺失或有冲突时必须恰好选一个冲突项写入labels_to_removeP0 不能自动打判定为 P0 时改打priority/p1status/manual-triage留给人工升级对kind/bug检查正文中的 CLI 版本若比当前版本运行时从 package.json 读取旧超过 6 个 minor 版本打status/need-information并留言请用户在最新版上复测信息不足如缺复现步骤、缺版本号同样打status/need-information输出 JSON 数组每个对象含issue_number、labels_to_add、labels_to_remove与面向用户措辞的explanation明确规定解释中不得暴露标签机制。工作量分诊EffortGemini这是定时分诊独有的深度环节。针对缺effort/*标签的 Issue提示词要求模型扮演资深软件架构师必须用grep_search、glob、read_file实际搜索代码库定位涉及的文件与组件后再评级并输出必须引用具体文件路径、禁止likely式猜测的effort_analysis。分级标准内嵌在提示词中effort/small≤1 天schema 更新、单文件逻辑修复、UI 微调、文案修改effort/medium2–3 天React/Ink 状态管理调试、异步流与 IDE 伴生扩展问题、跨包packages/cli与packages/core重构effort/large3 天node-pty/信号等跨平台复杂度、Scheduler 与 A2A/MCP 协议级重构、大规模性能内存问题并特别规定间歇性、难复现、平台相关的缺陷不得评为effort/small。应用与清理由 apply-issue-labels.cjs 统一应用标签随后 cleanup-triage-labels.cjs 清理互斥的status/*组合如同时带status/bot-triaged与status/need-triage的 Issue。贡献者该做什么通常什么都不用做——这正是兜底工作流确保即使即时分诊失败每个 Issue 最终也会被归类。工作流五自动移除失联的 Issue 处理人Unassign Inactive Assignees工作流文件unassign-inactive-assignees.yml触发时机每天 09:00 UTCcron: 0 9 * * *也可手动触发并传dry_run: true做无副作用演练。目的让help wantedIssue 的处理权保持在流动状态。完整算法内嵌在该工作流的github-script步骤中约 250 行找出所有带help wanted标签且至少有一个 assignee 的打开 Issue豁免特权用户三个组织团队gemini-cli-maintainers、gemini-cli-askmode-approvers、gemini-cli-docs成员、仓库协作者中权限为admin/maintain/write/triage者、以及googlers/google组织成员全部跳过——他们永远不会被自动移除对每个普通 assignee 读取 Issue 时间线assigned/unassigned事件确定精确的分配时刻找不到事件则回退到 Issue 创建时间从时间线的cross-referenced事件中提取所有关联 PR逐个拉取详情验证就绪状态open 且非 Draft或已 mergedDraft PR 明确不算数工作流头部注释解释了原因——防止贡献者用一个空 Draft PR 刷掉检查若分配超过 7 天GRACE_PERIOD_DAYS 7且无合格 PR则调用removeAssignees并留言说明原因、如何重新认领评论/assign以及如何避免再次发生7 天内开出含Fixes #issue-number的非 Draft PR。贡献者该做什么被分配后7 天内开一个真正可评审的 PR非 Draft并在描述中写Fixes #issue-numberDraft PR 不满足条件若被误移除评论/assign重新认领若放弃处理评论/unassign释放给其他人。工作流六按改动规模自动打 PR 标签PR Size Labeler工作流文件pr-size-labeler.yml触发时机PR 创建、同步推送新提交、重新打开pull_request_target注意它运行在主仓库权限下也可用workflow_dispatch手动指定 PR 编号。实现是一个纯ghCLI 脚本逻辑清晰可逐行对照自愈标签先gh label create确保五个size/*标签存在带规定颜色与描述失败则忽略单次 API 取数gh pr view --json additions,deletions,changedFiles,labels一次拿全TOTAL additions deletions计算标签边界与文档一致标签改动行数size/XS 10size/S10–49size/M50–249size/L250–999size/XL≥ 1000原子更新对比现有标签只把新增正确标签 移除过时标签合并成一条gh pr edit调用防刷屏评论构造形如 PR Size: **size/M** …的评论后先在 Issue 评论区检索由github-actions[bot]发布且以 PR Size:开头的旧评论——找到就PATCH原地更新找不到才新建。这样无论推多少轮提交PR 时间线上永远只有一条尺寸说明。贡献者该做什么无需任何操作标签与评论会随推送自动更新。工作流七发布自动化Release Automation工作流文件release-manual.yml触发时机官方 patch/minor 版本通过workflow_dispatch手动触发nightly 版本由定时任务仓库另有 release-nightly.yml触发。手动发布工作流的workflow_dispatch输入本身就是一套发布参数表输入说明version要发布的版本号带v前缀的合法 semver如v0.1.11ref发布所用的分支、tag 或 SHAnpm_channel发布渠道dev/preview/nightly/latest默认latestdry_run干跑模式默认true不创建分支、不发布 npm 包、不创建 GitHub Releaseforce_skip_tests是否跳过测试步骤默认不跳过正式版本应跑测试skip_github_release是否跳过创建 GitHub Release仅 prod 环境有意义environmentprod/dev执行链先通过可复用工作流构建 macOS 二进制再在release子目录检出目标 ref、npm ci、下载二进制、计算PREVIOUS_TAGgit describe --tags --abbrev0、可选跑测试最后调用 publish-release 复合 Action 完成版本号提升、发布到 npm 并创建带生成说明的 GitHub Release。若正式发布dry_run false中途失败会自动创建一个带release-failure,priority/p0标签的 Issue 并附上运行链接——发布失败本身也被纳入了 Issue 分诊体系。贡献者该做什么不需要参与发布流程PR 合入main后其变更会进入下一次 nightly 发布。小结这套自动化体系的设计要点把七条工作流放在一起看可以提炼出几个可复用的模式模型做判断脚本做执行Gemini 只负责输出结构化 JSON选哪个标签、为什么真正调用 GitHub API 增删标签的始终是确定性脚本且对模型输出做多级容错解析与数量校验最小权限 不可信输入隔离在用户可控的 Issue 正文上运行的 Gemini 实例不持有任何 GitHub token工具白名单收窄到只读幂等与防刷屏评论一律找到就更新覆盖率评论按 tag、尺寸评论按前缀匹配标签操作先对比再批量原子提交定时任务只处理缺失或冲突的增量分层兜底即时分诊秒级→ 每小时定时分诊补齐漏网 冲突治理 工作量评估→ 每天清理失联 assignee层层递进保证仓库状态最终一致人机边界清晰P0 永远留给status/manual-triage人工升级特权用户永远豁免自动 unassign自动化只处理机械性环节。对希望为自己的开源仓库搭建类似体系的开发者而言本仓库的 docs/issue-and-pr-automation.md 是给用户看的说明而.github/workflows/与.github/scripts/目录则是可直接抄的参考实现——从触发器设计、标签约束策略到防重复注释的小技巧都能从中找到答案。【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表