Skip to content

fix(review-pr): 支持 pull_request_target 事件 - #293

Merged
Terry-Mao merged 7 commits into
mainfrom
fix/pull-request-target-event-wiring
Oct 16, 2026
Merged

Terry-Mao merged 7 commits into
mainfrom
fix/pull-request-target-event-wiring

Conversation

@Terry-Mao

@Terry-Mao Terry-Mao commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

摘要

  • 让 review-pr.yml 监听 pull_request_target 的 PR 生命周期事件,并仅放行同仓库 head PR。
  • 让 resolve_pr_event 支持该事件,并在 resolver 层拒绝 fork PR,形成 workflow gate 与运行时双重防线。
  • 增加触发器、门控、事件解析、同仓库与 fork review 状态测试。
  • 同步更新 raw 与 wiki 文档,明确触发方式和 fork PR 安全边界。

验证

  • PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s .github/aicodingflow-tests -p 'test_resolve_pr_event.py'(18 项通过)
  • PYTHONPYCACHEPREFIX=/tmp/aicodingflow-pycache python3 -m py_compile .github/scripts/resolve_pr_event.py .github/aicodingflow-tests/test_resolve_pr_event.py .github/aicodingflow-tests/test_review_workflow_dispatch.py
  • git diff --check

工作流测试未运行:当前环境缺少 yaml Python 模块。

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

改动范围与声明目标不匹配:PR 标题与摘要声称「支持 pull_request_target 事件」,但快照实际只让 resolve_pr_event.resolve_event 接受该事件名。该事件并未接入任何工作流触发器,因此本次改动不会产生所宣称的行为。

证据

  • .github/workflows/review-pr.yml 的 on: 仅有 workflow_dispatch 与 issue_comment,preflight 的 if 也只放行 workflow_dispatch / issue_comment(并显式排除了 pull_request)。没有任何工作流会以 pull_request_target 触发 resolve_event,新增分支在现有仓库中不可达。
  • .github/aicodingflow-tests/test_review_workflow_dispatch.py 的 test_review_workflow_uses_manual_and_comment_triggers_only 明确断言 pull_request_target 不得出现在 review 工作流触发器中,看起来是有意的设计边界(该事件运行在具备写权限的默认分支上下文中)。
  • 新增测试只直接调用 resolver.resolve_event(...) / review_state(...),只验证脚本层行为,未覆盖端到端触发路径,无法证明 pull_request_target 真正被支持。

影响

改动本身无害(不影响 pull_request / issue_comment,也未新增触发器),但一旦后续 PR 真的接通 pull_request_target,review-pr.yml 中「Mark PR review status pending/complete」步骤的 github.event_name != 'pull_request' 条件会在缺少 head_repo == github.repository 防护时对该事件成立;对 fork PR 使用 pull_request_target 会让基于 head_repo 的校验变得关键而不透明,需同步澄清与加固。

建议

  1. 修正标题/摘要以反映实际范围(仅运行时事件解析与 review 状态校验),或补齐触发器、工作流门控及其测试,使改动与声明一致。
  2. 若确有意启用 pull_request_target,请同步更新 test_review_workflow_uses_manual_and_comment_triggers_only 的断言,并在工作流中显式加上 head_repo == github.repository 等限制,避免 fork PR 在具备写权限的上下文中被自动评审。

Comment thread .github/scripts/resolve_pr_event.py

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整体判断:触发器、preflight 门控、resolve_pr_event.resolve_event 解析与新增测试改动彼此一致,先前的 open thread(resolve_pr_event.py:77 分支在仓库内不可达)在本 PR 补齐触发器和门控后已经不再成立,无需重复提出。

但本 PR 把一个已验证的产品行为事实改掉了却没有同步文档与安全说明,因此不建议直接合并:

  • pull_request_target 会评审来自 fork 的 PR,与 docs/product/raw/pr-review-verdict.md、docs/product/wiki/concepts/ai-pr-review-workflow.md、docs/product/wiki/summaries/pr-review-verdict.md 中「来自 fork 的 PR 会被跳过、不运行 agent、不发布 review、不上传 artifact」的声明矛盾。
  • 该触发器会在 base 仓库上下文中运行,并可用 secrets.CODEX_API_KEY 与 pull-requests: write 的 token,而门控对 PR 来源没有任何限制。

请同步更新 raw 与 wiki 文档,或者为新的触发路径保留同仓库 head 门控;若确认要评审 fork PR,请在 PR 描述与文档中写明这是有意的信任边界变更及相应缓解措施。

Comment thread .github/workflows/review-pr.yml Outdated
Comment thread .github/workflows/review-pr.yml

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论:变更方向正确,未发现阻塞级问题,建议合并。

已核对:

  • review-pr.yml 新增 pull_request_target 触发器,preflight 增加同仓库门控(github.event.pull_request.head.repo.full_name == github.repository);resolve_pr_event.resolve_event 接受该事件,review_state 用 is_same_repo 在 resolver 层再次拒绝 fork PR,gate 与 resolver 两层口径一致;.github/skills、.agents/contracts 仍从 base 分支受控 checkout 覆盖 pr-worktree,信任边界未被放宽。
  • docs/product/raw/pr-review-verdict.md 与两个 wiki 页面同步了触发方式、fork PR 跳过以及「只有 open、非 draft、同仓库 head PR 才进入 review」的口径,raw 与 wiki 一致。
  • 本地复核:python3 -m unittest discover -s .github/aicodingflow-tests 511 项、-s .github/tests 13 项全部通过,含新增的 pull_request_target 与 fork 用例。

未解决的既有讨论

  • 该 PR 上仍有两条未关闭线程(review-pr.yml,comment 4291375605、4291375609)。其中「fork PR 会进入带 secrets 的 pull_request_target 运行」与「文档口径不一致」两点已由本次的同仓库门控、resolver 双重判断和 raw/wiki 更新覆盖;但同一线程提到的另一项仍未处理:同仓库 PR 会先被 pull_request_target 评审,再被参考 CI 成功后的 workflow_dispatch 评审,两条路径共用 ai-pr-review-<number> 并发组且 cancel-in-progress: true,可能出现重复 review 评论 / 重复 API 消耗,或相互取消导致 AI PR Review commit status 与最终结果不一致。建议在关闭该线程时明确是否保留 CI dispatch 入口,或同步更新说明。

其他(无精确改动行可挂载)

  • docs/github-collaboration-flow.md 的触发规则表与 PR Review 段落仍只描述「CI 成功后 dispatch」,未提及 pull_request_target 生命周期触发;如果该文档仍是权威入口说明,建议一并同步。
  • docs/product/wiki/log.md 未记录本次 wiki 页面改动,两个页面的 last_reviewed 仍为 2026-06-09;如需保持编译日志可追溯,建议补记。

Comment thread docs/product/raw/pr-review-verdict.md Outdated
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

workflow gate 与 resolver 双重防线的方向正确,新增/更新的测试在本地通过(.github/aicodingflow-tests/test_review_workflow_dispatch.py 9 项、.github/aicodingflow-tests/test_resolve_pr_event.py 18 项),pull_request_target 的同仓库门控(.github/workflows/review-pr.yml:37)与 review_state 的判定一致。阻塞项见 inline:同仓库门控让 non-member PR 在所有入口都不可评审,而已发布的 non-member gate / reviewer 请求流程及其文档没有同步说明。

其他发现(无精确改动行,按契约放在 body)

  • 测试覆盖缺口:review_state 的新测试只覆盖 pull_request_target 与默认分支,未覆盖 .github/scripts/resolve_pr_event.py:117 的 workflow_dispatch 也要求同仓库这一新行为。此前手动 dispatch 可以评审 fork PR,现在会被静默跳过(preflight 只打印 skip_reason),建议在 .github/aicodingflow-tests/test_resolve_pr_event.py 补一个 workflow_dispatch + fork 用例。
  • 状态写入文档滞后:pull_request_target 触发同样会写 AI PR Review commit status(review job 的 pending / complete 步骤条件只排除 github.event_name != 'pull_request',见 .github/workflows/review-pr.yml:103 与 :256),但 docs/product/raw/pr-review-verdict.md 的「Comment 与手动触发的 PR 关联」与 docs/product/wiki/concepts/comment-manual-review-status.md 仍只列 comment 与 workflow_dispatch 两种触发,建议同步为三种触发。

与既有讨论的关系

review_discussion_context.json 中 4 条已解决评论(fork 门控缺失、raw/wiki 文档同步、raw 文档换行)按重复抑制未再提出。

Comment thread .github/scripts/resolve_pr_event.py Outdated
…ring' into fix/pull-request-target-event-wiring

# Conflicts:
#	docs/product/raw/pr-review-verdict.md

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

本 PR 为 review-pr.yml 增加 pull_request_target 生命周期触发器,并在 workflow gate 与 resolve_pr_event.review_state 两层把自动入口限制为同仓库 head,同时保留 workflow_dispatch / 有效 comment 显式评审 fork PR 的路径,并同步 raw 与 wiki 文档。改动与既有行为自洽:gate 条件(.github/workflows/review-pr.yml:37)与 resolver 的 is_same_repo_target(.github/scripts/resolve_pr_event.py:114、:121、:127)一致,issue_comment 与 workflow_dispatch 的 fork 评审入口没有被误伤,post_pr_review.py 的 non-member 流程仍可达。本地运行 .github/aicodingflow-tests 全量用例通过(含 test_resolve_pr_event.py、test_review_workflow_dispatch.py,本环境有 yaml),未发现阻塞级发现。

未附行的提示

  • commit status 文档未同步:新增 pull_request_target 后,Mark PR review status pending/complete 的条件是 github.event_name != 'pull_request' 且 head_repo == github.repository,因此自动入口的 review 也会写入 AI PR Review commit status;docs/product/raw/pr-review-verdict.md 的「Comment 与手动触发的 PR 关联」与 docs/product/wiki/concepts/comment-manual-review-status.md 仍只描述 comment / manual 触发,建议在本 PR 内补一句。
  • 未附 recommended_reviewers:.github/CODEOWNERS 中相关路径的 owner 只有 PR 作者本人,作为人工 reviewer 无意义。

Security

新增门控已覆盖 pull_request_target,但同一 workflow 的 comment 入口仍是任意用户可触发的 fork head 评审路径(见按行评论)。该行为早于本 PR,且 specs/issue-77 明确把触发权限模型列为 non-goal,因此不作为本次合并的阻塞项,建议记入后续任务。

重复反馈

review_discussion_context.json 中已 resolved 的三条历史评论(resolve_event 可达性、pull_request_target 的 fork 门控、CI dispatch 与自动入口的 concurrency 冲突)未再重复:当前 diff 已补齐触发器、门控、文档与测试。

Comment thread .github/workflows/review-pr.yml
Comment thread docs/product/raw/pr-review-verdict.md Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

APPROVE,无阻塞级发现。

变更核查

  • 触发器:review-pr.yml 新增 pull_request_target(opened/reopened/synchronize/ready_for_review),preflight gate 追加 github.event.pull_request.head.repo.full_name == github.repository,与 ci.yml、plan-approved.yml 既有的同仓库 head 门控写法一致。
  • 运行时防线:resolve_event 接受 pull_request_target,review_state 对 pull_request_target 与 issue_comment 都要求同仓库 head;workflow_dispatch 仍保留显式评审 fork/draft PR 的路径,因此 non-member/reviewer 请求相关流程没有变成不可达代码。
  • 安全边界:自动 pull_request_target 入口只放行同仓库 head,review job 的 PR head checkout 只使用同仓库 repo/sha,session 上的 secrets.CODEX_API_KEY 与 pull-requests: write / statuses: write 不会用于未受信任的 fork head 内容,gate 与 resolver 判断同源(同一 payload 的 head.repo.full_name),未发现绕过路径。
  • 文档:raw 与 wiki(concepts/summaries)同步了触发入口、reviewable 条件、fork 边界与 draft 语义,逐条与 resolve_pr_event.py、review-pr.yml 的实际行为核对一致,raw 与编译后的 wiki 在本次 PR 内互相支持。

验证

  • PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s .github/aicodingflow-tests -p 'test_resolve_pr_event.py':21 项通过。
  • ... -p 'test_review_workflow*.py':9 项通过(本环境 yaml 可用,工作流触发器/门控断言已真实执行)。
  • 整套 .github/aicodingflow-tests 与 .github/tests 均通过。

非阻塞说明

前轮讨论中「PR 事件自动触发与 CI dispatch 路径并存」这一点的背景仍成立:同仓库 PR 会先由 PR 事件触发一次 review,CI 成功后 workflow_dispatch 再触发一次,两者共享 ai-pr-review-<number> 并发组。该线索在前轮已被 resolve,且本次改动没有引入更高severity的新风险,因此不再作为 inline 意见重复。若要收口,可考虑让参考 CI 不再重复 dispatch,或把 docs/product/raw/pr-review-verdict.md:9-13(未改动上下文行)「默认由目标项目 CI 成功路径触发」的表述与新入口顺序对齐——编译后的 wiki 页面已改成「可由 pull_request_target 触发,也可由 CI dispatch 触发」。

@Terry-Mao
Terry-Mao merged commit 3c424bf into main Oct 16, 2026
3 checks passed
@Terry-Mao
Terry-Mao deleted the fix/pull-request-target-event-wiring branch October 16, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant