adopt native GitHub stack workflow

This commit is contained in:
Tianyi Cui
2026-08-02 03:17:34 +08:00
parent ad686ea40a
commit 9a07380c23
12 changed files with 267 additions and 68 deletions

View File

@@ -1,6 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-26-incremental-pr-base-retargeting.md: e2097ac4c32a926c8c0271df19dbc9796d0ed19d
2026-07-26-incremental-pr-base-retargeting.zh.md: a6c94b66732b6c037fee1b0726b31ecb6f3b48c5
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-26-incremental-pr-base-retargeting.md
2026-07-26-incremental-pr-base-retargeting.md: b2e644d99877b4214b5a6edb2775b3962e6b7da2
2026-07-26-incremental-pr-base-retargeting.zh.md: 5014fef644f9907c4d16a9a2a3767d6f55633688

View File

@@ -10,9 +10,9 @@ A PR base can advance while its current tip is being merged into the PR branch.
## Decision
Each observed base tip gets its own merge checkpoint. If the base advances during the work, finish and validate the merge already in progress, commit it, and push it when the task authorizes a push. Only then fetch and merge the newer base in a separate merge commit. Never abandon, amend, rebase, or otherwise rewrite the earlier work.
When merge-forward is chosen, each observed base tip gets its own merge checkpoint. If the base advances during the work, finish and validate the merge already in progress, commit it, and push it when the task authorizes a push. Only then fetch and merge the newer base in a separate merge commit. Do not abandon or rewrite a checkpoint within that merge-forward sequence.
The root [AGENTS.md](../../../../AGENTS.md) states the standing order. The [stacked-PR landing skill](../../../skills/dsh-merging-stacked-prs/SKILL.md) applies it while retargeting dependent PRs, and the [stack review guide](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md) owns merging fixes down a stack.
The [native-stack and optional-rebase decision](2026-08-02-native-github-stacks-and-optional-rebases.md) also permits a lease-protected rebase for standalone or stacked PRs, including after review. This note owns the merge-forward path only. The [stacked-PR landing skill](../../../skills/dsh-merging-stacked-prs/SKILL.md) selects either history under the root [AGENTS.md](../../../../AGENTS.md), and the [stack review guide](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md) owns propagating fixes through dependent layers.
## Alternatives considered

View File

@@ -10,9 +10,9 @@ Status: implemented
## 决策
每次观察到的 base 分支顶端提交都保留为独立的合并检查点。如果处理期间 base 分支继续前移,先完成并验证正在进行的合并,再将其提交;任务授权推送时,还要完成推送。完成这些步骤后,才能拉取较新的 base并通过单独的合并提交将其合入。绝不放弃先前工作,也不通过 amend、rebase 或其他方式重写它
选择 merge-forward 时,每次观察到的 base 分支顶端提交都保留为独立的合并检查点。如果处理期间 base 分支继续前移,先完成并验证正在进行的合并,再将其提交;任务授权推送时,还要完成推送。完成这些步骤后,才能拉取较新的 base并通过单独的合并提交将其合入。在这条 merge-forward 序列中,不得放弃或重写任何检查点
根 [AGENTS.md](../../../../AGENTS.md) 规定了这项常设指令。[堆叠 PR 落地 skill技能](../../../skills/dsh-merging-stacked-prs/SKILL.md)在调整依赖 PR 的 base 时执行这一规则[堆叠评审指南](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md)则负责说明如何将修复沿堆叠向下合并
[原生堆叠与可选 rebase 决策](2026-08-02-native-github-stacks-and-optional-rebases.md)也允许独立或堆叠 PR 使用受 lease 保护的 rebase评审后同样如此。本文只负责 merge-forward 路径。[堆叠 PR 落地 skill技能](../../../skills/dsh-merging-stacked-prs/SKILL.md)根据根 [AGENTS.md](../../../../AGENTS.md) 选择其中一种历史更新方式[堆叠评审指南](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md)则负责说明如何在依赖层之间传播修复
## 曾考虑的替代方案

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.md
2026-08-02-native-github-stacks-and-optional-rebases.md: a349ed18a27ab006384310e4318f057dbf8873b1
2026-08-02-native-github-stacks-and-optional-rebases.zh.md: 0205eb475bfe951f8382d61bf19df988027afb13

View File

@@ -0,0 +1,43 @@
# Agent Note: Native GitHub stacks and optional PR rebases
Status: implemented
English | [中文](2026-08-02-native-github-stacks-and-optional-rebases.zh.md)
## Problem
A dependent PR chain represented only by base branches has no official stack identity. Landing it requires manually merging one PR at a time, preserving intermediate branches, retargeting every child, and reconstructing whether the chain survived. GitHub's native stacked-PR feature instead carries the order, applies trunk rules and CI to every layer, and owns bottom-up merges and retargeting.
A blanket prohibition on rewriting reviewed branches also excludes the native `gh stack` synchronization workflow, whose cascading rebase updates each active layer and publishes it with lease protection. Applying that prohibition only outside stacks would give standalone and stacked PRs inconsistent history choices.
## Decision
Every same-repository chain of two or more dependent PRs uses GitHub's official stack object before landing. Live `PullRequest.stack` and `stackEntry.position` fields are authoritative. An unstacked chain whose PRs have one author is linked automatically in bottom-to-top order with `gh stack link`; mixed or unavailable authors require user confirmation. Missing native support and cross-fork chains hard-stop. Existing membership in conflicting stacks or an official order that disagrees with the branch topology requires user direction before any stack is dissolved or rebuilt.
"Land the stack" merges the complete official stack through `gh stack merge <stack-number> --yes --merge`. A partial landing requires an explicit boundary PR and merges the bottom prefix through that PR. The workflow never falls back to per-PR `gh pr merge` and manual retargeting. A direct native merge is all-or-nothing; a merge queue may process the selected PRs in separate groups, so every selected PR must independently reach `MERGED` before the landing is complete.
Merge-forward and rebase are both allowed refresh histories for standalone and officially stacked PRs, including after review. A remote history rewrite uses an exact lease or the lease-protected `gh stack` push path and aborts if the remote moved; raw `--force` is forbidden. The [incremental base-retargeting decision](2026-07-26-incremental-pr-base-retargeting.md) remains the owner of the merge-forward option.
Relevant checks normally run before publication. `gh stack sync` is the explicit exception because it fetches, cascade-rebases, and pushes as one operation: every rewritten layer is validated immediately afterward, and no affected PR merges until that evidence passes. After any rewritten push, current heads, unresolved review threads, approvals, mergeability, and checks are re-audited because earlier commit OIDs and inline anchors may be outdated.
## Verification
The [stack landing skill](../../../skills/dsh-merging-stacked-prs/SKILL.md) verifies native support, same-repository branches, live authors, official membership and order, merge range, and final merged state. The [stack review guide](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md) keeps fixes on their introducing layer and covers both propagation histories. The [pre-push workflow](../../../skills/dsh-pre-push-checks/SKILL.md) owns lease protection and immediate post-sync evidence.
## Alternatives considered
**Keep branch chains as the only stack representation.** This preserves the manual procedure but gives GitHub no stack object through which to show order, enforce trunk rules across every layer, or merge a range atomically.
**Adopt native stacks while forbidding their rebase commands after review.** This keeps commit OIDs stable but disables the official synchronization path when a stack is under active review and leaves standalone PRs under a different policy.
**Require rebase for every PR refresh.** A linear history is useful, but merge checkpoints remain a valid choice when preserving completed conflict resolution and its recovery point matters more than compact history.
**Automatically dissolve conflicting stacks.** This would make local branch inference override shared GitHub metadata and could disturb PRs or authors outside the requested chain; merged and queued entries cannot always be removed.
## Consequences
- Reviewers and automation receive GitHub's stack map, stack-wide rules, CI, and native merge state.
- A same-author legacy chain becomes official without an extra prompt, while mixed ownership and conflicting metadata retain a human decision boundary.
- Rebases can invalidate commit hashes, approvals, or comment anchors after review, so every rewritten push carries a live review and check audit.
- `gh stack sync` can briefly publish code whose local evidence is pending; the affected PRs remain blocked from merging until immediate post-sync validation passes.
- Merge-forward remains available and preserves completed checkpoints, at the cost of additional merge commits.

View File

@@ -0,0 +1,43 @@
# Agent Note: GitHub 原生堆叠与可选 PR rebase
Status: implemented
[English](2026-08-02-native-github-stacks-and-optional-rebases.md) | 中文
## 问题
仅以 base 分支表示的依赖 PRPull Request链没有官方的堆叠身份。要让它落地就必须逐个手动合并 PR、保留中间分支、调整每个子 PR 的 base并重新查证这条链是否仍然完整。GitHub 原生的堆叠 PR 功能则会承载顺序,对每一层应用 trunk 规则和 CI并负责自底向上的合并与 base 调整。
一概禁止改写已评审分支,也会排除原生的 `gh stack` 同步工作流:该工作流通过级联 rebase 更新每个活跃层,并在 lease 保护下发布。如果只在堆叠之外实施这项禁令,就会让独立 PR 和堆叠 PR 面临不一致的历史选择。
## 决策
同一仓库内由两个或更多个相互依赖的 PR 组成的每条链,在落地前都必须使用 GitHub 的官方 stack 对象。以实时 `PullRequest.stack``stackEntry.position` 字段为权威依据。对于尚未形成官方堆叠且所有 PR 作者相同的链,系统使用 `gh stack link` 按自底向上的顺序自动关联;作者不一或作者信息不可用时,必须取得用户确认。缺少原生支持或跨 fork 的链会使流程硬性停止。如果现有成员属于相互冲突的堆叠,或者官方顺序与分支拓扑不一致,则在解散或重建任何堆叠之前都必须取得用户指示。
「落地堆叠」通过 `gh stack merge <stack-number> --yes --merge` 合并整个官方堆叠。部分落地需要明确指定边界 PR并合并从底部到该 PR 的前缀。工作流绝不回退到逐个执行 `gh pr merge` 和手动调整 base。原生直接合并要么全部成功要么全部不合并合并队列可能分组处理所选 PR因此只有每个所选 PR 都分别达到 `MERGED`,落地才算完成。
merge-forward 和 rebase 都可以作为独立 PR 与官方堆叠 PR 的历史刷新方式,包括评审后。改写远端历史时,必须使用精确 lease 或受 lease 保护的 `gh stack` 推送路径;如果远端已经前移,操作必须中止。禁止直接使用 `--force`。[增量更新 base 的决策](2026-07-26-incremental-pr-base-retargeting.md)仍负责 merge-forward 选项。
相关检查通常在发布前运行。`gh stack sync` 是明确的例外,因为它在一次操作中完成获取、级联 rebase 和推送:随后立即验证每个已改写的层;这些验证通过前,不得合并任何受影响的 PR。每次改写推送后都要重新审计当前 head、未解决的评审线程、批准状态、可合并性和检查结果因为先前的 commit OID 和内联锚点可能已经过时。
## 验证
[堆叠落地 skill技能](../../../skills/dsh-merging-stacked-prs/SKILL.md)验证原生支持、同仓库分支、实时作者信息、官方成员关系与顺序、合并范围以及最终合并状态。[堆叠评审指南](../../../../docs/cookbook/responding-to-pr-review-on-a-stack.md)让修复留在引入问题的层,并涵盖两种用于传播修复的历史策略。[推送前工作流](../../../skills/dsh-pre-push-checks/SKILL.md)负责 lease 保护和同步后立即验证所得的证据。
## 曾考虑的替代方案
**仅以分支链表示堆叠。** 这种做法保留手动流程,但 GitHub 没有 stack 对象可用于展示顺序、对每一层执行 trunk 规则或以原子操作合并整个范围。
**采用原生堆叠,但禁止在评审后使用其 rebase 命令。** 这会保持 commit OID 稳定,但也会在堆叠正在接受评审时禁用官方同步路径,并让独立 PR 遵循不同的政策。
**要求每次刷新 PR 都使用 rebase。** 线性历史很有价值,但当保存已经完成的冲突解决及其恢复点比紧凑历史更重要时,合并检查点仍然是有效选择。
**自动解散相互冲突的堆叠。** 这会让本地分支推断凌驾于共享的 GitHub 元数据之上,并可能干扰所请求链之外的 PR 或作者;已经合并或进入队列的条目不一定都能移除。
## 后果
- 评审者和自动化会获得 GitHub 的堆叠图、覆盖整个堆叠的规则、CI 和原生合并状态。
- 同一作者的遗留链无需额外询问即可成为官方堆叠;链由多名作者共同拥有或元数据发生冲突时,仍保留人工决策边界。
- 评审后rebase 可能使 commit hash、批准状态或评论锚点失效因此每次改写推送后都要对实时评审状态和检查结果进行审计。
- `gh stack sync` 可能短暂发布本地验证仍待完成的代码;受影响的 PR 在同步后立即验证通过前仍禁止合并。
- merge-forward 仍然可用,并以增加合并提交为代价保留已完成的检查点。