github / github/gh-stack

Stale or missing `refs/pull/N/merge` on stacked PRs silently prevents all `pull_request` workflows from running

未關閉
#319 3 則留言 1 個 reaction 已指派 0 人 在 GitHub 檢視
bug topic: stale refs
主要語言
Go
星號
1.5k
分支
70
平均合併
1 天 8 小時
30 天內合併 PR
7

描述

### What happened

Three PRs in a 10-PR stack stopped running CI entirely. Not failing, not skipped: the check runs simply never get created, so the PRs look like CI has not started yet and stay that way indefinitely. `pull_request_target` workflows keep running on every push, which makes the PRs look half-alive and hides the problem.

The common factor is `refs/pull/N/merge`. `pull_request` workflows run against that ref, and on the affected PRs it is either missing or pinned to superseded commits:

| PR | position in stack | `refs/pull/N/merge` | mergeable | `pull_request` CI |
|----|-------------------|---------------------|-----------|-------------------|
| A | below the wedge | present, current | MERGEABLE | runs, green |
| B | wedge | missing | CONFLICTING | none for ~2 days |
| C | above B | stale, superseded parents | CONFLICTING | none |
| D | above C | stale, superseded parents | CONFLICTING | none |

```
PR C merge ref parents: 46c51a0a7 e1ca4188f <- both superseded
actual base/head: eb03b5605 6bc00ac9c

PR D merge ref parents: e1ca4188f d90f608e5 <- both superseded
actual base/head: 6bc00ac9c f8dbef22c
```

B, C and D each have a head that is a strict descendant of its base, so merging is a fast-forward and `git merge-tree` reports zero conflicts. The CONFLICTING state is phantom, and appears to be the same stale merge computation (see discussion #229).

The code and the runners are both fine: a `pull_request_target` labeler ran on every SHA, and `workflow_dispatch` runs of the same three workflows against the same branches all pass. It is specifically the merge-ref-backed `pull_request` path that is dead.

The failure is silent. A red X is actionable, but an empty check list is indistinguishable from "queued", so a PR can sit for days appearing to wait on CI when nothing will ever run. We only found it by comparing check-run names across sibling PRs in the same stack. Any repo with required status checks would block forever with no indication why.

### Expected

Either the merge ref is recomputed on push so `pull_request` workflows run, or the PR surfaces that its merge state is stale instead of rendering an empty check list.

### Recovery attempts, all blocked

- Pushing new commits, five times, no recompute
- Close and reopen, which deleted the merge ref instead of rebuilding it
- Retarget the base away and back: `422 Cannot change the base branch because the pull request is part of a stack`
- `gh stack unstack`: `Unstacking not allowed: Pull requests ... cannot be removed from this stack`, naming the 13 merged members

Stack membership blocks the base fix, and merged members block removing membership, so there is no way out from the client side.

### Environment

`gh` 2.68.1, `gh stack` v0.0.8. A stack of 10 open PRs on top of 13 merged ones, trunk `dev`.

貢獻指南

開啟貢獻指南

研究方向

先從 gh stack 對堆疊 PR 的行為著手:其 refs/pull/N/merge ref 缺失或已過期,然後使用 git merge-tree 將其與實際的 base 和 head commit 進行比較。檢查 pull_request 和 pull_request_target workflow 路徑,以及 #229 中的討論。完成標準是:merge ref 在 push 時重新計算,或 PR 明確顯示其已過期的 merge 狀態,而不是顯示空的檢查清單。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
git, github, go
領域
ci-cd, cli, devtools
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
活躍
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。