github / github/gh-stack

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

Offen
#319 3 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen
bug topic: stale refs
Vorherrschende Sprache
Go
Sterne
1.5k
Forks
70
Ø Merge
1 T. 8 Std.
Gemergte PRs (30 T.)
7

Beschreibung

### 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`.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Start with the gh stack behavior for a stacked PR whose refs/pull/N/merge ref is missing or stale, and compare it with the actual base and head commits using git merge-tree. Check the pull_request and pull_request_target workflow paths and the discussion in #229. Done means the merge ref is recomputed on push or the PR clearly exposes its stale merge state instead of showing an empty check list.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
git, github, go
Bereich
ci-cd, cli, devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.