github / github/gh-stack

Stack view shows "not ready" / "unable to merge as a stack" on approved mergeable PRs (stale stack UI cache)

Aberta
#450 3 comentários 0 reações 0 responsáveis Ver no GitHub
bug topic: mergeability
Linguagem predominante
Go
Estrelas
1.5k
Forks
70
Merge médio
1d 8h
PRs com merge (30d)
7

Descrição

## Summary

The GitHub stack view (native stack feature, not CLI) shows "not ready" on some PRs in a 13-level stack, and displays "unable to merge as a stack" globally, even though every PR in the stack reports `mergeable=MERGEABLE`, `mergeStateStatus=CLEAN` (or `UNSTABLE`), `reviewDecision=APPROVED`, and all status checks passing via both REST and GraphQL APIs.

## Stack structure (anonymized)

```
base-branch
└── feat/base → PR #1 (base: base-branch) ← trunk base
└── feat/layer-2 → PR #2 (base: feat/base)
└── feat/layer-3 → PR #3 (base: feat/layer-2)
└── feat/layer-4 → PR #4 (base: feat/layer-3)
└── feat/layer-5 → PR #5 (base: feat/layer-4)
└── feat/layer-6 → PR #6 (base: feat/layer-5)
└── feat/layer-7 → PR #7 (base: feat/layer-6)
└── feat/layer-8 → PR #8 (base: feat/layer-7)
└── feat/layer-9 → PR #9 (base: feat/layer-8)
└── feat/layer-A → PR #10 (base: feat/layer-9)
└── feat/layer-B → PR #11 (base: feat/layer-A)
└── feat/layer-C → PR #12 (base: feat/layer-B)
└── feat/layer-D → PR #13 (base: feat/layer-C)
```

13 PRs in total. The bottom PR targets `base-branch`; each subsequent PR targets its predecessor's branch. All PRs are open, non-draft, created via `gh stack submit`.

## Environment

- `gh` 2.97.0
- `gh-stack` v0.1.0
- Repository: private, no branch protection, no repository rulesets, no merge queue, no CODEOWNERS.
- "Dismiss stale pull request approvals when new commits are pushed": disabled.

## Observed behavior

### In the GitHub stack UI (native stack view)

- Bottom 7 PRs (#1–#7): show **"Ready"**
- PR #8: shows **"Not ready"** (no tooltip / reason shown)
- PR #9: shows **"Blocked downstack"**
- PR #10: shows **"Not ready"** (no tooltip / reason shown)
- PRs #11–#13: show **"Blocked downstack"**
- At the top: global message **"Unable to merge as a stack"**

### Via the API (both REST and GraphQL, confirmed multiple times over several minutes)

Every PR in the stack (including #8 and #10) consistently reports:

| Field | Value |
|---|---|
| `mergeable` | `MERGEABLE` |
| `mergeStateStatus` | `CLEAN` (or `UNSTABLE` — only non-required checks pending like CodeRabbit) |
| `reviewDecision` | `APPROVED` (multiple approvals from different reviewers) |
| `statusCheckRollup.state` | `SUCCESS` |
| `isDraft` | `false` |
| `requested_reviewers` | `[]` (no pending reviewer requests) |
| No branch protection | (none exists on any branch in the stack) |
| No repository rulesets | (none exist) |

GraphQL query used:
```graphql
{
repository(owner: "O", name: "R") {
pullRequest(number: N) {
mergeable
mergeStateStatus
reviewDecision
isDraft
statusCheckRollup { state }
}
}
}
```

### Context about the "not ready" PRs (#8 and #10)

- Both are **history-import PRs** — they contain 500+ commits each (preserved full history of the imported repositories), adding ~48k lines across 180+ files.
- The remaining PRs are smaller (single-digit to low-double-digit commits).
- All PRs (including #8 and #10) were created via the same `gh stack submit` flow, all with the same review/check configuration.
- The status checks on #8 and #10 all show **green/success**. Only CodeRabbit (not required) shows as not completed.

## Attempted workaround: close + reopen the "not ready" PRs

We closed and reopened PR #8 (the first "not ready" PR in the stack) to force a full server-side recompute:

```
gh pr close 8 && gh pr reopen 8
```

**Result:**
- The individual PR returned to `mergeable=MERGEABLE, reviewDecision=APPROVED` correctly.
- The stack view took ~30 seconds to reload, but **the state did not change**: PR #8 remained "not ready", PR #9 remained "blocked downstack", and the global message stayed "unable to merge as a stack".

Close+reopen did **not** invalidate the stack view's cached state. The stack view appears to maintain its own independent cache that is not invalidated by PR state changes.

## Expected behavior

Given that:
1. All PRs are mergeable (no conflicts, `MERGEABLE`).
2. All PRs are approved (`APPROVED`).
3. All required status checks pass (`SUCCESS`).
4. No branch protection, rulesets, CODEOWNERS, or merge queue block merging.
5. Close+reopen did not help.

GitHub's native stack view should reflect the actual PR state and show all 13 PRs as **"Ready"**, with the **"Merge stack (13)"** option enabled and functional. A stale cached state rendering the stack unmergeable is a blocking UX bug.

## Related

- **#323** — "Can't merge a stacked PR with no clear reason (all PRs show mergeable)". Same class of bug: stack UI state differs from API state. In our case the stack never shows as mergeable at all (no attempt to merge fails — the UI never allows the attempt). We confirm the `MERGEABLE`/`CLEAN`/`APPROVED` symptom. Our close+reopen attempt did not resolve it, suggesting a different cache invalidation path.

Guia de contribuição

Abrir o guia de contribuição

Direção de pesquisa

No repository files or tests are named. Start by reproducing the 13-level stack in GitHub's native stack view and compare its displayed readiness with the REST and GraphQL fields listed in the report; done means the UI reflects the approved, mergeable PRs and enables "Merge stack (13)".

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
github
Domínio
frontend
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Ativa
Clareza
Razoavelmente clara
Facilidade para iniciantes
45/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.