<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CI/CD on Svtter's Blog</title><link>https://svtter.cn/tags/ci/cd/</link><description>Recent content in CI/CD on Svtter's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 22 May 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://svtter.cn/tags/ci/cd/index.xml" rel="self" type="application/rss+xml"/><item><title>OpenCode 的 GitHub Actions 自动化体系：27 个 Workflow 背后的工程实践</title><link>https://svtter.cn/p/opencode-%E7%9A%84-github-actions-%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BD%93%E7%B3%BB27-%E4%B8%AA-workflow-%E8%83%8C%E5%90%8E%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/</link><pubDate>Fri, 22 May 2026 10:00:00 +0800</pubDate><guid>https://svtter.cn/p/opencode-%E7%9A%84-github-actions-%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BD%93%E7%B3%BB27-%E4%B8%AA-workflow-%E8%83%8C%E5%90%8E%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/</guid><description>&lt;img src="https://svtter.cn/p/opencode-%E7%9A%84-github-actions-%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BD%93%E7%B3%BB27-%E4%B8%AA-workflow-%E8%83%8C%E5%90%8E%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/cover.jpg" alt="Featured image of post OpenCode 的 GitHub Actions 自动化体系：27 个 Workflow 背后的工程实践" /&gt;&lt;p&gt;opencode 是一个 16 万 star 的 AI 编码工具，它的 &lt;code&gt;.github/workflows/&lt;/code&gt; 目录下有 27 个 workflow 文件。这个数量在开源项目里不算少，但真正有意思的不是数量，而是这些 workflow 覆盖的范围：从常规的 CI/CD 到 AI 驱动的社区治理，几乎把 GitHub Actions 能做的事情都做了一遍。&lt;/p&gt;
&lt;p&gt;这篇文章逐类分析这些 workflow 的设计，讨论这种自动化程度的利弊，以及对我们自己项目的启示。&lt;/p&gt;
&lt;h2 id="总览"&gt;总览
&lt;/h2&gt;&lt;p&gt;27 个 workflow 可以分成四类：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;数量&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CI/测试&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;typecheck、单元测试、e2e、Nix 构建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;发布/交付&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;CLI 发布、容器构建、VS Code 插件、GitHub Action 发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自动化/Bot&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;issue 治理、PR 合规、AI code review、文档更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文档/其他&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;统计、Discord 通知&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;16 个自动化 workflow 占了总数的 60%。opencode 不只是用 Actions 来跑测试和发布，而是把社区治理和代码质量审查也交给了自动化系统。&lt;/p&gt;
&lt;h2 id="ci测试扎实但克制"&gt;CI/测试：扎实但克制
&lt;/h2&gt;&lt;p&gt;四个测试相关的 workflow：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;typecheck.yml&lt;/strong&gt; — PR 和 push 到 dev 时跑 &lt;code&gt;bun typecheck&lt;/code&gt;。简单直接，没有多余动作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;test.yml&lt;/strong&gt; — 跨平台测试矩阵（Linux + Windows），跑单元测试和 Playwright e2e。有 concurrency 控制，同一个 PR 的新 commit 会取消旧运行。测试结果生成 JUnit 报告上传为 artifact。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;nix-eval.yml&lt;/strong&gt; — 验证 Nix flake 在四种架构（x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin）下的构建。必选包失败会阻断，可选包失败只是警告。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;storybook.yml&lt;/strong&gt; — UI 组件的 Storybook 构建，只在 storybook/ui 相关文件变更时触发。路径触发避免了不必要的运行。&lt;/p&gt;
&lt;p&gt;几个值得注意的设计选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;concurrency group + cancel-in-progress&lt;/strong&gt;：多个 workflow 都用了这个模式，同一个 PR 不会堆叠多次运行。对于一个接受大量社区 PR 的项目，这能省下不少 CI 资源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路径触发&lt;/strong&gt;：containers.yml 只在容器文件变更时运行，storybook.yml 只在 UI 变更时运行。不是所有东西都全量跑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合 Runner 策略&lt;/strong&gt;：大部分 workflow 使用 &lt;a class="link" href="https://blacksmith.sh/" target="_blank" rel="noopener"
&gt;Blacksmith&lt;/a&gt; 提供的第三方托管 runner（&lt;code&gt;blacksmith-4vcpu-ubuntu-2404&lt;/code&gt;、&lt;code&gt;blacksmith-4vcpu-windows-2025&lt;/code&gt;）。Blacksmith 是一个兼容 GitHub Actions API 的加速 runner 服务，底层用自建基础设施，比 GitHub 免费 runner 快不少。只有轻量级 bot 任务（close-issues、close-prs、compliance-close、pr-standards、deploy）留在 GitHub 原生的 &lt;code&gt;ubuntu-latest&lt;/code&gt; 上。计算密集的编译、测试、发布全走 Blacksmith，简单的脚本任务用 GitHub 原生 runner，按任务负载分配资源。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="发布交付全平台覆盖"&gt;发布/交付：全平台覆盖
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;publish.yml&lt;/strong&gt; 是最复杂的 workflow，一个文件处理了完整的发布流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;版本号计算&lt;/li&gt;
&lt;li&gt;CLI 构建矩阵（多平台多架构）&lt;/li&gt;
&lt;li&gt;Windows 代码签名（Azure Signing）&lt;/li&gt;
&lt;li&gt;macOS 代码签名（Apple Developer）&lt;/li&gt;
&lt;li&gt;Electron 应用构建&lt;/li&gt;
&lt;li&gt;npm 发布&lt;/li&gt;
&lt;li&gt;GitHub Release 创建&lt;/li&gt;
&lt;li&gt;AUR（Arch Linux）发布&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一个 workflow 覆盖了 CLI、桌面应用、npm 包、Linux 包的分发。这种&amp;quot;全平台一次发布&amp;quot;的模式对用户友好——无论什么平台都能在同一天拿到新版本。&lt;/p&gt;
&lt;p&gt;其他发布 workflow 按产物类型拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;publish-github-action.yml&lt;/strong&gt; — 监听 &lt;code&gt;github-v*&lt;/code&gt; tag，发布 GitHub Action 到 Marketplace&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;publish-vscode.yml&lt;/strong&gt; — 监听 &lt;code&gt;vscode-v*&lt;/code&gt; tag，同时发布到 VS Code Marketplace 和 Open VSX&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;containers.yml&lt;/strong&gt; — 多架构容器镜像构建，推送到 GHCR&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;release-github-action.yml&lt;/strong&gt; — dev 分支有 github 目录变更时创建预发布&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;tag 触发是一个好的实践：发布是显式动作，不会因为误推代码就触发。&lt;code&gt;publish.yml&lt;/code&gt; 会在 push 到 &lt;code&gt;ci/dev/beta/fix&lt;/code&gt; 分支时自动构建 snapshot，但正式发布需要手动 dispatch 或 tag。&lt;/p&gt;
&lt;h2 id="自动化botai-驱动的社区治理"&gt;自动化/Bot：AI 驱动的社区治理
&lt;/h2&gt;&lt;p&gt;这是 opencode 最有特色的部分。16 个自动化 workflow 中，多个直接调用了 opencode 自己的 AI 能力来处理社区事务。&lt;/p&gt;
&lt;h3 id="issue-管理"&gt;Issue 管理
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;triage.yml&lt;/strong&gt; — 新 issue 创建时，用 opencode AI 自动分流，添加标签和分类。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;duplicate-issues.yml&lt;/strong&gt; — 新 issue 创建/编辑时，用 opencode AI 分析是否与已有 issue 重复。同时检查是否遵循了三种 issue 模板之一，是否包含 AI 生成内容。不合规的会被加上 &lt;code&gt;needs:compliance&lt;/code&gt; 标签。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;compliance-close.yml&lt;/strong&gt; — 每 30 分钟检查一次，带有 &lt;code&gt;needs:compliance&lt;/code&gt; 标签的 issue/PR 如果 2 小时内没有修正，自动关闭。关闭时会根据是 issue 还是 PR 给出不同的提示信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;close-issues.yml&lt;/strong&gt; — 每天凌晨 2 点 UTC 关闭过期的 stale issue。&lt;/p&gt;
&lt;p&gt;这四层形成了完整的 issue 生命周期管理：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;新 issue → AI 分流(triage) → 重复/合规检查(duplicate) → 合规宽限期(compliance) → 过期清理(close)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="pr-管理"&gt;PR 管理
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;pr-standards.yml&lt;/strong&gt; 是最长的 workflow 之一，做了两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;标题格式检查&lt;/strong&gt;：强制 conventional commits 格式（feat/fix/refactor/&amp;hellip;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模板合规检查&lt;/strong&gt;：PR 描述必须包含 issue 引用、变更类型、验证方法等必要章节&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不合规的 PR 会被加上 &lt;code&gt;needs:compliance&lt;/code&gt; 标签，2 小时后自动关闭。team 成员和 bot 豁免。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pr-management.yml&lt;/strong&gt; — PR 创建时查重，并为社区贡献者添加标签。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;close-prs.yml&lt;/strong&gt; — 每天晚上 10 点 UTC 关闭超过 1 个月且点赞数不够的 PR。默认阈值是 2 个 reaction，可配置。&lt;/p&gt;
&lt;h3 id="ai-code-review"&gt;AI Code Review
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;review.yml&lt;/strong&gt; — 在 PR 评论中输入 &lt;code&gt;/review&lt;/code&gt;，opencode AI 会分析代码并在具体的行上留下 review 评论。只对 repo owner/member 开放。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;opencode.yml&lt;/strong&gt; — 在 issue 或 PR 评论中输入 &lt;code&gt;/oc&lt;/code&gt; 或 &lt;code&gt;/opencode&lt;/code&gt;，触发 opencode AI 进行更通用的交互。&lt;/p&gt;
&lt;p&gt;这两个 workflow 展示了&amp;quot;AI 作为协作者&amp;quot;的思路：不是全自动的 code review，而是按需触发，人在回路中做最终决定。&lt;/p&gt;
&lt;h3 id="文档与维护"&gt;文档与维护
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;docs-update.yml&lt;/strong&gt; — 每 12 小时检查最近的 commit，用 opencode AI 判断是否需要更新文档。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;generate.yml&lt;/strong&gt; — push 到 dev 时运行代码生成脚本，自动提交变更。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;beta.yml&lt;/strong&gt; — 每小时同步 beta 分支。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stats.yml&lt;/strong&gt; — 每天更新下载统计到 STATS.md。&lt;/p&gt;
&lt;h2 id="值得借鉴的设计模式"&gt;值得借鉴的设计模式
&lt;/h2&gt;&lt;h3 id="1-分层治理"&gt;1. 分层治理
&lt;/h3&gt;&lt;p&gt;opencode 没有把所有自动化塞进一个 workflow，而是按职责拆分。issue 从创建到关闭经过了四个 workflow 的接力处理。每个 workflow 只做一件事，组合起来形成完整的治理链。&lt;/p&gt;
&lt;p&gt;这种设计的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单个 workflow 可以独立修改、禁用，不影响其他环节&lt;/li&gt;
&lt;li&gt;每个 workflow 的触发条件、权限范围都是最小化的&lt;/li&gt;
&lt;li&gt;出问题时容易定位是哪个环节&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-合规宽限期"&gt;2. 合规宽限期
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;compliance-close.yml&lt;/code&gt; 不是检测到不合规就立即关闭，而是给 2 小时的宽限期。这对全球不同时区的贡献者来说是合理的——你可能正好在睡觉的时候提交了一个 issue，醒来发现有时间修正。&lt;/p&gt;
&lt;h3 id="3-ai-用在决策点而不是执行点"&gt;3. AI 用在决策点而不是执行点
&lt;/h3&gt;&lt;p&gt;triage、duplicate 检测、code review 这些都是 AI 做初步判断，人做最终决定。而代码构建、发布这些执行层面的事情完全不用 AI。这是一个务实的分工：AI 擅长模式识别和初步分类，但不擅长精确执行。&lt;/p&gt;
&lt;h3 id="4-显式触发-vs-自动触发"&gt;4. 显式触发 vs 自动触发
&lt;/h3&gt;&lt;p&gt;发布用 tag 触发，日常维护用 schedule 触发，社区治理用事件触发。三种触发方式对应三种不同的自动化信任等级：发布需要人工确认，维护可以定时自动，治理需要即时响应。&lt;/p&gt;
&lt;h2 id="过度自动化的风险"&gt;过度自动化的风险
&lt;/h2&gt;&lt;p&gt;opencode 的自动化体系很完善，但也有需要注意的地方：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;社区门槛&lt;/strong&gt;：新贡献者提交 issue 需要遵循特定模板，PR 需要符合 conventional commits，否则 2 小时后自动关闭。对于一个 16 万 star 的项目，这种严格是合理的——它能过滤掉大量低质量贡献。但对于小项目，这种程度的自动化会吓跑潜在贡献者。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;维护成本&lt;/strong&gt;：27 个 workflow 意味着 27 个需要维护的自动化脚本。opencode 有专门的自定义 runner 和专用脚本。如果某个 workflow 的逻辑需要调整，维护者需要在 GitHub Actions 的 YAML + 自定义脚本之间来回切换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI 的不确定性&lt;/strong&gt;：duplicate-issues 和 triage 用 AI 做判断，但 AI 可能误判。一个合理的 issue 被标记为 duplicate 并关闭，对贡献者的体验是负面的。opencode 用宽限期和人工复核来缓解这个问题，但风险依然存在。&lt;/p&gt;
&lt;h2 id="对我们项目的启示"&gt;对我们项目的启示
&lt;/h2&gt;&lt;p&gt;不是每个项目都需要 27 个 workflow。但 opencode 的分层治理和&amp;quot;AI 在决策点&amp;quot;的思路值得参考：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;从 issue 模板开始&lt;/strong&gt;：如果项目开始收到大量重复或低质量 issue，先加模板和 duplicate 检查，而不是手动处理每一个。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;合规检查用宽限期&lt;/strong&gt;：自动关闭不合规贡献时，始终给一个宽限期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 用于分类不用于执行&lt;/strong&gt;：让 AI 帮你分流 issue、检查 PR 格式，但不要让 AI 自动合并代码或发布版本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;发布用 tag 触发&lt;/strong&gt;：这是最安全的做法。自动发布的 snapshot 可以接受，正式版本需要人工确认。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;按需添加&lt;/strong&gt;：先有痛点再加自动化。opencode 的 27 个 workflow 不是一天建成的，是随着社区规模增长逐步增加的。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="总结"&gt;总结
&lt;/h2&gt;&lt;p&gt;opencode 的 GitHub Actions 体系展示了大型开源项目的自动化实践：CI/CD 覆盖全平台发布，社区治理用多层 workflow 接力处理，AI 被用在分流和审查等决策环节。这套系统的核心不是技术复杂度，而是&amp;quot;分层、宽限、显式触发&amp;quot;这三个原则。对于自己的项目，不需要照搬 27 个 workflow，但这些原则可以直接用上。&lt;/p&gt;</description></item><item><title>使用 OpenCode + GLM-5 实现 GitHub PR 自动代码审查</title><link>https://svtter.cn/p/%E4%BD%BF%E7%94%A8-opencode--glm-5-%E5%AE%9E%E7%8E%B0-github-pr-%E8%87%AA%E5%8A%A8%E4%BB%A3%E7%A0%81%E5%AE%A1%E6%9F%A5/</link><pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate><guid>https://svtter.cn/p/%E4%BD%BF%E7%94%A8-opencode--glm-5-%E5%AE%9E%E7%8E%B0-github-pr-%E8%87%AA%E5%8A%A8%E4%BB%A3%E7%A0%81%E5%AE%A1%E6%9F%A5/</guid><description>&lt;img src="https://svtter.cn/p/%E4%BD%BF%E7%94%A8-opencode--glm-5-%E5%AE%9E%E7%8E%B0-github-pr-%E8%87%AA%E5%8A%A8%E4%BB%A3%E7%A0%81%E5%AE%A1%E6%9F%A5/cover.png" alt="Featured image of post 使用 OpenCode + GLM-5 实现 GitHub PR 自动代码审查" /&gt;&lt;blockquote&gt;
&lt;p&gt;大模型会磨洋工，需要另一个 agent 或 AI 来监督。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;最近在项目中集成了 OpenCode 的 AI 代码审查功能，使用智谱 AI 的 GLM-5 模型自动 review PR 代码。本文记录完整的集成过程和踩过的坑。&lt;/p&gt;
&lt;h2 id="背景"&gt;背景
&lt;/h2&gt;&lt;p&gt;项目需要一个自动化的代码审查机制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当 PR 创建或更新时，自动触发 AI 审查&lt;/li&gt;
&lt;li&gt;AI 只提供 review 建议，不修改代码&lt;/li&gt;
&lt;li&gt;将审查结果以 comment 形式添加到 PR 中&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="技术选型"&gt;技术选型
&lt;/h2&gt;&lt;h3 id="opencode"&gt;OpenCode
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://opencode.ai" target="_blank" rel="noopener"
&gt;OpenCode&lt;/a&gt; 是一个开源的 AI coding agent，支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多种 LLM 提供商（OpenAI、Anthropic、智谱等）&lt;/li&gt;
&lt;li&gt;GitHub/GitLab 集成&lt;/li&gt;
&lt;li&gt;在 CI 环境中运行&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="glm-5-coding-plan"&gt;GLM-5 Coding Plan
&lt;/h3&gt;&lt;p&gt;选择智谱 AI 的 &lt;a class="link" href="https://docs.z.ai/guides/llm/glm-5" target="_blank" rel="noopener"
&gt;GLM Coding Plan&lt;/a&gt; 原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;专为 AI 编程优化，支持 OpenCode&lt;/li&gt;
&lt;li&gt;价格实惠（$3/月起）&lt;/li&gt;
&lt;li&gt;国内访问稳定&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tldr"&gt;TL;DR
&lt;/h2&gt;&lt;p&gt;如果只是想快速引入 code review，不需要处理权限、凭据等配置，可以直接使用封装好的 action。这是最快引入 code review 的方法，review 结果是中文：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Run OpenCode review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Svtter/opencode-actions/review@v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;github-token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# only one is enough.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;zhipu-api-key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.ZHIPU_API_KEY }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;opencode-go-api-key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.OPENCODE_GO_API_KEY }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只需要配置对应的 secret 即可使用。&lt;/p&gt;
&lt;h2 id="配置详解"&gt;配置详解
&lt;/h2&gt;&lt;h3 id="1-确定模型格式"&gt;1. 确定模型格式
&lt;/h3&gt;&lt;p&gt;OpenCode 的模型格式为 &lt;code&gt;provider_id/model_id&lt;/code&gt;。对于智谱 GLM-5：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置项&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;环境变量&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ZHIPU_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model 格式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zhipuai-coding-plan/glm-5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="2-创建-workflow-文件"&gt;2. 创建 Workflow 文件
&lt;/h3&gt;&lt;p&gt;创建 &lt;code&gt;.github/workflows/opencode-review.yml&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenCode PR Review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;opened, synchronize, reopened, ready_for_review]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;AI Code Review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 仅在 PR 准备就绪时运行（跳过 draft PR）&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github.event.pull_request.draft == false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;self-hosted&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id-token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pull-requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Checkout repository&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persist-credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Run OpenCode Review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;anomalyco/opencode/github@latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ZHIPU_API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.ZHIPU_API_KEY }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;zhipuai-coding-plan/glm-5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;use_github_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Review this pull request (read-only mode, DO NOT modify any code):
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Please check:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Code quality issues
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Potential bugs or logic errors
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Code style consistency
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Security concerns
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Performance issues
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - Suggest improvements
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Please respond in Chinese. DO NOT modify any code, only provide review comments.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-配置-github-secrets"&gt;3. 配置 GitHub Secrets
&lt;/h3&gt;&lt;p&gt;在仓库 Settings → Secrets and variables → Actions 中添加：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ZHIPU_API_KEY&lt;/code&gt;: 从 &lt;a class="link" href="https://z.ai/manage-apikey/apikey-list" target="_blank" rel="noopener"
&gt;Z.AI Console&lt;/a&gt; 获取&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="踩坑记录"&gt;踩坑记录
&lt;/h2&gt;&lt;h3 id="坑-1-权限不足-403-forbidden"&gt;坑 1: 权限不足 (403 Forbidden)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Resource not accessible by integration - https://docs.github.com/rest/issues/comments#create-an-issue-comment
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：permissions 配置为 &lt;code&gt;read&lt;/code&gt;，无法写入 PR comment。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：将权限改为 &lt;code&gt;write&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pull-requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;write &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 不是 read&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;write &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 不是 read&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="坑-2-git-凭据问题"&gt;坑 2: Git 凭据问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fatal: could not read Username for &amp;#39;https://github.com&amp;#39;: No such device or address
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：checkout 时 &lt;code&gt;persist-credentials: false&lt;/code&gt; 导致后续 git 操作无法认证。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persist-credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 不是 false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="坑-3-draft-pr-不应触发审查"&gt;坑 3: Draft PR 不应触发审查
&lt;/h3&gt;&lt;p&gt;Draft PR 还在开发中，不需要 AI 审查，浪费资源。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：添加条件判断：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github.event.pull_request.draft == false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="工作流程"&gt;工作流程
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PR opened/updated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;检查是否为 Draft PR
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ (非 Draft)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GitHub Actions 触发
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OpenCode 下载并分析 diff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GLM-5 生成审查意见
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;自动添加 PR comment
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;开发者查看建议，手动决定是否采纳
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="效果展示"&gt;效果展示
&lt;/h2&gt;&lt;p&gt;配置完成后，每次 PR 更新都会自动触发 AI 审查，审查结果会以 comment 形式出现在 PR 页面。&lt;/p&gt;
&lt;p&gt;审查内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码质量问题&lt;/li&gt;
&lt;li&gt;潜在 bug&lt;/li&gt;
&lt;li&gt;风格一致性&lt;/li&gt;
&lt;li&gt;安全隐患&lt;/li&gt;
&lt;li&gt;性能问题&lt;/li&gt;
&lt;li&gt;改进建议&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="成本估算"&gt;成本估算
&lt;/h2&gt;&lt;p&gt;使用 GLM Coding Plan：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基础套餐 $3/月&lt;/li&gt;
&lt;li&gt;中等项目每月约 10-20 次 PR，成本可控&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结
&lt;/h2&gt;&lt;p&gt;通过 OpenCode + GLM-5 实现自动代码审查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置简单&lt;/strong&gt;：一个 workflow 文件即可&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成本低&lt;/strong&gt;：GLM Coding Plan 价格友好&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;效果好&lt;/strong&gt;：GLM-5 在编程任务上表现优秀&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全&lt;/strong&gt;：只读模式，不会修改代码&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="参考链接"&gt;参考链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://opencode.ai/docs/" target="_blank" rel="noopener"
&gt;OpenCode 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://opencode.ai/docs/github/" target="_blank" rel="noopener"
&gt;OpenCode GitHub 集成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.z.ai/guides/llm/glm-5" target="_blank" rel="noopener"
&gt;GLM-5 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.z.ai/coding-plan/overview" target="_blank" rel="noopener"
&gt;GLM Coding Plan&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="相关文章"&gt;相关文章
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://svtter.cn/p/%E6%9C%80%E8%BF%91%E5%8F%91%E7%8E%B0%E5%A5%BD%E7%94%A8%E7%9A%84-mcp-%E5%B7%A5%E5%85%B7/" &gt;最近发现好用的 MCP 工具&lt;/a&gt; - OpenCode/Claude Code 配套工具推荐&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://svtter.cn/p/%E9%AB%98%E6%95%88%E7%9C%81%E9%92%B1%E6%88%91%E7%9A%84-ai-agent-%E5%B7%A5%E4%BD%9C%E6%B5%81%E9%80%89%E6%8B%A9/" &gt;高效省钱：我的 AI Agent 工作流选择&lt;/a&gt; - OpenCode + Gemini 的高性价比工作流&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://svtter.cn/p/%E5%9C%A8%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%8A%E8%BF%90%E8%A1%8C-claude-code-%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E4%B8%8E%E5%BC%80%E5%8F%91/" &gt;在虚拟机上运行 Claude Code 实现自动化测试与开发&lt;/a&gt; - 使用 VM + Playwright MCP 实现自动化测试&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://svtter.cn/p/git-mcp-tools.md/" &gt;Git MCP Tools&lt;/a&gt; - 让大模型操作 Git 的 MCP 服务&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>