From d49c57b11e347736fde661396caeaad33b278371 Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Tue, 23 Jun 2026 23:21:21 +0800 Subject: [PATCH] ci: add PR-Agent review workflow (#5994) --- .github/workflows/pr-agent.yml | 126 ++++++++++++++++++++++++++++++++ docs/pr-agent.md | 130 +++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 .github/workflows/pr-agent.yml create mode 100644 docs/pr-agent.md diff --git a/.github/workflows/pr-agent.yml b/.github/workflows/pr-agent.yml new file mode 100644 index 00000000..3340aaed --- /dev/null +++ b/.github/workflows/pr-agent.yml @@ -0,0 +1,126 @@ +name: PR Agent + +on: + pull_request: + # PR-Agent 读取 PR diff,并写入 Review 评论或更新 PR 描述。 + # synchronize 用于在 PR 推送新 commit 后刷新审查结果。 + types: + - opened + - reopened + - ready_for_review + - review_requested + - synchronize + issue_comment: + # 手动命令如 "/review"、"/describe"、"/improve" 和 "/ask ..." 只在 PR 评论中有意义。 + # issue_comment 同时覆盖普通 issue,因此 job 里还会再判断是否属于 PR。 + types: + - created + - edited + +permissions: + # 读取仓库内容和 PR diff。 + contents: read + # 更新 PR 描述、发布 PR Review 或修改 PR 相关元数据。 + pull-requests: write + # PR 评论在 GitHub API 中属于 issue comments,手动命令和总结评论需要该权限。 + issues: write + +jobs: + pr-agent: + name: PR-Agent review and describe + # 同仓 PR 可自动处理;fork PR 由允许身份在 PR 下用评论命令触发,避免任意评论消耗模型配额。 + if: >- + github.event.sender.type != 'Bot' && + ( + ( + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository + ) || + ( + github.event_name == 'issue_comment' && + github.event.issue.pull_request != null && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIME_CONTRIBUTOR"]'), github.event.comment.author_association) && + ( + github.event.comment.body == '/review' || + startsWith(github.event.comment.body, '/review ') || + github.event.comment.body == '/describe' || + startsWith(github.event.comment.body, '/describe ') || + github.event.comment.body == '/improve' || + startsWith(github.event.comment.body, '/improve ') || + github.event.comment.body == '/ask' || + startsWith(github.event.comment.body, '/ask ') + ) + ) + ) + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Run PR-Agent + id: pragent + # 使用版本号加 digest 固定容器构建,避免 tag 被重推后改变运行内容。 + uses: docker://pragent/pr-agent:0.37.0-github_action@sha256:4ec7bac814050a1bc8c96ab2fab6b7b0f65df0049a5ec43f3fee1a0b551c28ca + env: + # PR-Agent 使用该 token 读取 PR 元数据并发布评论。 + GITHUB_TOKEN: ${{ github.token }} + + # 仓库设置中添加的 Secret:Settings -> Secrets and variables -> Actions。 + # 该 key 只传给 PR-Agent 运行时,不写入仓库。 + OPENAI_KEY: ${{ secrets.OPENAI_KEY }} + + # 仓库设置中添加的 Secret。OpenAI 兼容服务通常需要填写以 "/v1" 结尾的 API 根地址。 + OPENAI.API_BASE: ${{ secrets.OPENAI_API_BASE }} + + # 模型、输出语言和大 diff 处理策略。 + config.model: "gpt-5.5" + config.fallback_models: '["gpt-5.4"]' + config.reasoning_effort: "xhigh" + config.ai_timeout: "900" + config.response_language: "zh-CN" + config.large_patch_policy: "clip" + config.ignore_pr_title: '["^\\[Auto\\]", "^Auto"]' + config.ignore_pr_labels: '["skip pr-agent"]' + + # pull_request 事件默认自动执行 /review 和 /describe;/improve 保持手动触发。 + github_action_config.auto_review: "true" + github_action_config.auto_describe: "true" + github_action_config.auto_improve: "false" + + # 允许触发自动工具的 PR 动作。包含 synchronize,便于新 commit 推送后刷新结果。 + github_action_config.pr_actions: '["opened", "reopened", "ready_for_review", "review_requested", "synchronize"]' + + # 保留 action outputs,便于后续 workflow 编排或排查。 + github_action_config.enable_output: "true" + + # /describe 行为控制;与自动触发配置放在同一层,避免使用默认图表和标签策略。 + pr_description.generate_ai_title: "false" + pr_description.publish_labels: "false" + pr_description.enable_pr_diagram: "false" + pr_description.collapsible_file_list: "adaptive" + pr_description.add_original_user_description: "true" + + # /review 输出策略,聚焦维护者需要处理的风险和缺口。 + pr_reviewer.extra_instructions: | + 请用中文输出。 + 优先指出 P0/P1 风险,避免纠结纯格式问题。 + 重点检查安全、权限、状态一致性、异步/缓存、副作用和测试缺口。 + pr_reviewer.num_max_findings: "5" + pr_reviewer.persistent_comment: "true" + pr_reviewer.publish_output_no_suggestions: "true" + pr_reviewer.require_tests_review: "true" + pr_reviewer.require_security_review: "true" + pr_reviewer.require_estimate_effort_to_review: "true" + pr_reviewer.require_can_be_split_review: "true" + pr_reviewer.require_todo_scan: "false" + pr_reviewer.enable_review_labels_effort: "false" + pr_reviewer.enable_review_labels_security: "true" + + # /improve 和 /ask 的手动命令策略。 + pr_code_suggestions.focus_only_on_problems: "true" + pr_code_suggestions.suggestions_score_threshold: "7" + pr_code_suggestions.commitable_code_suggestions: "false" + pr_questions.use_conversation_history: "true" + + # 可选成本和噪音控制: + # github_action_config.auto_improve: "true" + # config.verbosity_level: "1" + # pr_reviewer.num_max_findings: "3" diff --git a/docs/pr-agent.md b/docs/pr-agent.md new file mode 100644 index 00000000..8fdc0abd --- /dev/null +++ b/docs/pr-agent.md @@ -0,0 +1,130 @@ +# PR-Agent 使用说明 + +本仓库通过 GitHub Actions 运行开源 PR-Agent,用于自动生成 PR 说明和进行 AI Review。 + +## Secrets + +在仓库的 `Settings -> Secrets and variables -> Actions -> Repository secrets` 中配置: + +- `OPENAI_KEY`:OpenAI 或 OpenAI 兼容服务的 API Key。 +- `OPENAI_API_BASE`:OpenAI 兼容接口的 API Base,通常需要包含 `/v1`,以服务商文档为准。 + +`GITHUB_TOKEN` 使用 GitHub Actions 自动注入的 `${{ github.token }}`,不需要手工添加。 + +## 触发方式 + +`.github/workflows/pr-agent.yml` 监听: + +- `pull_request`:PR 打开、重新打开、标记 ready、请求 review、推送新 commit 时自动运行。 +- `issue_comment`:允许身份在 PR 评论里写允许的命令时手动运行。 + +`pull_request` 自动运行仅处理同仓 PR。fork PR 不自动注入仓库 secret 和写权限,允许身份可以在 PR +评论中使用允许的命令触发受控审查。允许身份包括 `OWNER`、`MEMBER`、`COLLABORATOR`、 +`CONTRIBUTOR` 和 `FIRST_TIME_CONTRIBUTOR`。 + +## Workflow 权限 + +workflow 设置了最小可用权限: + +- `contents: read`:读取仓库内容和 PR diff。 +- `pull-requests: write`:更新 PR 描述、发布 PR Review 或修改 PR 相关元数据。 +- `issues: write`:PR 评论在 GitHub API 中属于 issue comments,手动命令和总结评论需要该权限。 + +没有开启 `contents: write`。当前配置不让 PR-Agent 往仓库推代码或提交 changelog,因此不需要内容写权限。 + +默认自动执行: + +- `/review`:检查 PR 风险、潜在 bug、安全问题、测试缺口和可维护性问题。 +- `/describe`:生成或更新 PR 描述、变更摘要和文件说明。 + +默认不自动执行: + +- `/improve`:给出代码改进建议。这个工具更容易产生噪音和额外成本,建议先用评论命令手动触发。 + +## 常用评论命令 + +以下身份可在 PR 评论中使用: + +- `OWNER`:仓库所有者。 +- `MEMBER`:组织仓库中的组织成员。 +- `COLLABORATOR`:仓库协作者。 +- `CONTRIBUTOR`:曾经向仓库提交并合入过代码的贡献者。 +- `FIRST_TIME_CONTRIBUTOR`:首次向仓库贡献 PR 的用户。 + +```text +/review +/describe +/improve +/ask 这次改动有没有遗漏权限校验? +``` + +评论触发依赖 `issue_comment` 事件。普通 issue 评论、Bot 评论、非允许身份评论、以及不以允许命令开头的评论都会跳过。 + +## 配置来源 + +PR-Agent 配置集中在 `.github/workflows/pr-agent.yml` 的 `env` 中维护。 + +当前主要设置: + +- `config.model = "gpt-5.5"`:默认使用 GPT-5.5。 +- `config.fallback_models = ["gpt-5.4"]`:主模型不可用时降级到 GPT-5.4。 +- `config.reasoning_effort = "xhigh"`:使用更高审查推理强度。 +- `config.ai_timeout = "900"`:模型调用最长等待 900 秒。 +- `config.response_language = "zh-CN"`:让 PR-Agent 默认中文输出。 +- `config.large_patch_policy = "clip"`:大 PR 截断分析,不直接跳过。 +- `config.ignore_pr_title` / `config.ignore_pr_labels`:跳过自动生成 PR 或带 `skip pr-agent` 标签的 PR。 +- `pr_reviewer.extra_instructions`:要求中文输出,优先指出 P0/P1 风险,并关注安全、权限、状态一致性、异步/缓存、副作用和测试缺口。 +- `pr_reviewer.require_security_review = true`:要求输出安全审查部分。 +- `pr_reviewer.require_tests_review = true`:要求输出测试审查部分。 +- `pr_reviewer.enable_review_labels_effort = false`:不添加 `Review effort x/5` 工作量标签。 +- `pr_reviewer.enable_review_labels_security = true`:保留明确安全风险标签。 +- `pr_description.generate_ai_title = false`:默认不改 PR 标题。 +- `pr_description.publish_labels = false`:默认不添加 PR 类型标签。 +- `pr_description.enable_pr_diagram = false`:默认不生成图表。 +- `pr_code_suggestions.focus_only_on_problems = true`:手动 `/improve` 时优先输出问题型建议。 +- `pr_code_suggestions.suggestions_score_threshold = 7`:过滤低置信度建议。 + +标签来源: + +- `/review` 可添加安全标签和工作量标签;当前只保留安全标签,关闭工作量标签。 +- `/describe` 可按 PR 类型添加 `Bug fix`、`Tests`、`Bug fix with tests`、`Enhancement`、`Documentation`、`Other` 等标签;当前 `pr_description.publish_labels = false`,不会添加类型标签。 +- 自定义标签默认未启用。 + +可按需再启用的工具配置: + +- `[pr_update_changelog]`:配合 `/update_changelog` 生成 changelog 建议。 +- `[pr_add_docs]`:配合 `/add_docs` 生成文档建议。 +- `[pr_test]`:配合 `/test` 生成测试建议;它不会替代仓库自己的测试命令。 +- `[pr_questions]`:配合 `/ask ...` 回答 PR 相关问题。 + +## 安全边界 + +PR-Agent Action 会读取 `OPENAI_KEY`,因此依赖的 Docker 镜像在 workflow 中固定版本号和 digest, +不使用浮动的 `latest` 或仅依赖可变 tag。 + +当前使用 `pull_request` 而不是 `pull_request_target`。这样更适合避免 fork PR 直接获得仓库 secrets,但 fork PR 自动运行通常因为拿不到 `OPENAI_KEY` 而无法完整执行。`issue_comment` 属于 base repo 事件,因此评论命令只允许指定身份触发。若以后要支持 fork PR 自动审查,需要重新评估 `pull_request_target` 的安全模型,不能 checkout 或执行来自 fork 的代码。 + +API Key 建议使用低额度、可轮换的专用 key。`OPENAI_API_BASE` 本身通常不是敏感信息,但继续按 secret 管理可以避免暴露服务商信息。 + +## 调整自动行为 + +自动行为在 workflow 的 `env` 中控制: + +```yaml +config.model: "gpt-5.5" +config.fallback_models: '["gpt-5.4"]' +config.reasoning_effort: "xhigh" +config.ai_timeout: "900" +config.response_language: "zh-CN" +github_action_config.auto_review: "true" +github_action_config.auto_describe: "true" +github_action_config.auto_improve: "false" +github_action_config.pr_actions: '["opened", "reopened", "ready_for_review", "review_requested", "synchronize"]' +pr_description.generate_ai_title: "false" +pr_description.publish_labels: "false" +pr_description.enable_pr_diagram: "false" +pr_reviewer.enable_review_labels_effort: "false" +pr_reviewer.enable_review_labels_security: "true" +``` + +如果需要自动运行 `/improve`,把 `github_action_config.auto_improve` 改为 `"true"`。建议先观察手动 `/improve` 的质量和成本,再决定是否开启。