Upstream PR Staging
目的
AI 可以生成代码、测试和 PR 文案,但贡献者仍须对最终提交的正确性、风险和表述负责。不要把未经本人审查的 AI 输出直接交给上游 maintainer 筛选和纠错。
默认先在用户 fork 中创建预审 PR。它提供接近真实上游 PR 的代码审查、文案审查和 GitHub Actions 环境,同时不提前打扰上游。预审通过后,再整理或重放为正式上游 PR。
这套流程用于履行贡献者的审查责任,不用于规避上游对 AI 辅助贡献的政策。
信息分层
fork 预审 PR 使用两个互不混杂的区域。分层依据不是信息属于“代码”“测试”或“审计”等哪一类,而是它面向谁、离开预审上下文后是否仍然成立:
- PR 标题和正文是正式贡献文案的预演。默认中文,但采用目标仓库的模板、叙述视角和信息密度,内容应能在去掉预审 PR 后直接交给目标仓库 reviewer。正文把目标仓库视为当前语境,不从 fork 贡献者的外部视角称其为“上游”,也不依赖 fork、bottom PR、预审阶段或内部讨论才能理解。
- 内部记录 comment是贡献者侧的预审账本。凡是其意义依赖 fork 与目标仓库的关系、预审过程、内部判断来源或正式提交前状态的信息,都留在这里,不进入正式贡献文案。
同一事实可能同时产生对 reviewer 有用的结论和仅用于内部追溯的依据。此时不要整段复制或二选一:正文只保留会影响 reviewer 判断且在目标仓库语境中自足的结论;内部 comment 保留调查方法、具体快照、过程证据和决策演变。若一段话去掉“这是 fork 预审”“目标仓库在别处”这层背景后就失去意义,它属于内部 comment。
两处内容不应互相充当摘要或备份。每条信息只承担与其受众相关的作用;需要从内部证据转写到正文时,重新按正式 reviewer 的问题组织,而不是把内部记录原样搬过去。
内部记录 comment 首行固定为:
<!-- upstream-pr-staging:internal-notes -->
后续先按 marker 查找并编辑这一条 comment;不要为每次进展新增 comment。正式提交上游时不迁移它,只转写已经证实且对 reviewer 有价值的结论。
核心规则
- 低干扰:预审阶段不触发上游 issue、PR 或 discussion 的 backlink、timeline mention 和通知,也不使用
fixes、closes、resolves。 - 链接:预审阶段引用上游资源时使用带描述的
redirect.github.comMarkdown 链接;正式上游 PR 再改为 repo-native 引用或普通链接。同仓库 issue/PR 需要展开标题时用独立列表项- #123;commit 证据默认写完整 40 位 SHA。workflow、job 和 artifact 使用[失败记录](...)、[通过记录](...)、[CI](...)等短文本。 - 命名:预审分支名、标题和 commit message 不包含上游
#123、owner/repo#123、完整 GitHub URL 或 closing keyword。“GitHub Draft PR”只表示平台状态,不用作预审流程名称。 - 正文:始终仿佛已直接提交到目标仓库。只写 reviewer 为理解动机、净变化、兼容性与风险所需的最终信息;预审关系、贡献者侧调查过程和内部工作状态统一写入 internal-notes comment。
- 提交默认值:预审阶段的后续修改默认提交并推送到预审分支;正式上游 PR 阶段默认只改本地,除非用户明确要求推送或正在执行正式 PR 重放。
- 工具:提交、推送和 reviewer-facing 文案使用
repository-workflow;GitHub PR、comment、checks 和 workflow 操作使用github-cli;正文先写入/tmp/*.md,再通过--body-file创建或更新。
Fork 预审流程
- 确认基准
- 获取上游目标分支和 fork 基准分支,确认二者一致。
- 可 fast-forward 时按用户授权更新;出现分叉或额外提交时停下来确认。
- 创建分支和 PR
- 从 fork 基准创建只包含当前任务的分支。
- PR 开在用户 fork 内,base 指向 fork 基准;标题和正文默认中文并遵循目标仓库模板。
- 创建带 marker 的内部记录 comment,建议包含“当前状态、内部证据、待确认、正式提交前清理”。
- 收敛
- 运行必要 CI 和内部 review;通过 follow-up commit 正常推进,不默认改写历史。
- PR 正文只随最终净变化更新;过程信息只更新到原内部记录 comment。
用户明确要求跳过预审时,直接进入正式上游 PR 流程。用户要求“像预审 PR 没存在过”时,从最新上游基准重建正式分支,不复用预审历史。
Red / Green / Cleanup
仅在 bugfix 需要证明回归测试有效,或临时 CI 能提供关键证据时使用。三个阶段必须分别推送并等待结果,否则通常无法获得独立 job URL。
- Red:只加入能在旧实现上编译、并因目标行为断言而失败的测试或临时 CI。记录 commit、job URL 和失败摘要;配置、依赖、lint 或缺少修复符号导致的失败无效。
- Green:只加入修复,不修改已证明有效的 red 测试。等待同一检查或等价检查通过并记录证据。
- Cleanup:删除临时 workflow、脚本、配置和 matrix,保留修复与正式回归测试。最终 CI 尚在运行时可以更新正文,但要继续观察结果。
PR 正文先解释验证方法,再给简洁证据,不用阶段名代替结论。完整过程留在内部记录 comment。正文不重复列出 CI 已自然覆盖的 fmt、lint、build 和普通测试命令。
转为正式上游 PR
- 从最新上游基准创建正式分支,或从预审分支整理出只包含最终改动的分支。
- 按最终 diff 和目标仓库语言复核或翻译标题、正文与提交历史;移除预审、实验、rerun 和临时方案痕迹。
- 使用目标仓库自身的叙述视角和 repo-native 链接;不要迁移内部记录 comment。若需采用其中的结论,按正式 reviewer 的信息需求重新表述,不复制依赖预审上下文的记录。
- 优先使用正式 PR 自己的 CI 证据。若需要该 PR 自己的 red/green URL,在 GitHub Draft PR 中依次重放 red、green、cleanup,最后更新正文并标记 ready for review。
- 只有无法取得正式 PR 的证据且用户接受时,才引用 fork CI,并在正文说明来源。
停下来确认
- fork 基准与上游分叉,或包含无法解释的额外提交。
- 需要 force-push 或重写 fork 基准历史。
- red 失败不是目标行为断言导致,或 green 必须修改 red 测试才能通过。
- 无法判断某个上游引用是否会产生不希望的关联或通知。