Mid-stack PRs miss stack-aware `pull_request` triggers: PRs are created before the stack object exists
- Langage dominant
- Go
- Étoiles
- 1.5k
- Forks
- 70
- Merge moyen
- 1 j 8 h
- PR mergées (30 j)
- 7
Description
### What happened
On `gh stack submit`, PRs are created a few seconds before the stack object itself exists. `pull_request` workflows with a `branches:` filter are evaluated against each PR's literal base at open time, so mid-stack PRs are filtered out and never dispatched. They are not re-evaluated once the stack is registered, so they permanently show no checks.
This contradicts the documented behaviour in [Optimizing CI for stacked pull requests](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/optimizing-ci-for-stacked-pull-requests): "A workflow configured to run on `pull_request` events targeting `main` runs for every pull request in the stack."
### Reproduction
1. In a repo with the stacks preview enabled, add a workflow with:
```yaml
on:
pull_request:
branches: [ "main" ]
```
2. Create a 4-branch stack and `gh stack submit`.
3. Observe CI runs only on the bottom PR and the topmost PR. The middle PRs get a check suite with zero runs.
### Observed timeline
Stack of 4 (PRs #10–#13, stack #14, `stack.base.ref = main`, `size: 4`):
| Time (UTC) | Event | Workflow dispatched |
|---|---|---|
| 13:24:13 | PR #10 opened (`7` → `main`) | yes — literal base is already `main` |
| 13:24:17 | PR #11 opened (`8` → `7`) | no — check suite `85146388656`, `latest_check_runs_count: 0` |
| 13:24:21 | PR #12 opened (`9` → `8`) | no — check suite `85146406327`, `latest_check_runs_count: 0` |
| 13:24:24 | PR #13 opened (`10` → `9`) | no — first check suite, 0 runs |
| **13:24:26** | **stack #14 created** (`GET /repos/{owner}/{repo}/stacks/14` → `created_at`) | |
| 13:24:31 | second check suite on PR #13's head | yes — this is the run that appears |
The bottom PR runs because its base is literally `main`, independent of any stack awareness. The top PR runs because its dispatch landed *after* stack registration at 13:24:26 and got a second check suite. PRs #11 and #12 had their `opened` events fully processed before the stack existed, were rejected by the `branches: [main]` filter, and nothing re-dispatched them afterwards.
Reproduced identically on an earlier stack of 3 in the same repo: bottom PR ran, middle skipped, top ran.
### Expected behavior
Every PR in the stack is evaluated against `stack.base.ref`, as documented — either by creating the stack before its PRs, or by re-evaluating `pull_request` workflow triggers for all member PRs once the stack is registered.
### Actual behavior
Only PRs whose trigger evaluation happens after stack registration get stack-aware treatment. Mid-stack PRs are silently left with no checks, which is indistinguishable from "queued" and blocks merge on repos with required checks.
### Not a duplicate of
- **#319** — merge refs are healthy here: `refs/pull/{10,11,12,13}/merge` all exist and point at current commits, and all four PRs report `mergeable: true`.
- **#379** — that concerns `paths` filters being selected from the topmost PR. This is `branches` filters and a registration-ordering race; the affected PRs get a check suite with zero runs rather than a workflow selected from the wrong PR.
### Workaround
Remove the `branches:` filter from the `pull_request` trigger so CI runs regardless of base.
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par le flux `gh stack submit` et reproduisez la stack à quatre branches avec un workflow `pull_request` filtré sur `main`. Suivez le moment où les PR membres sont créées, celui où la stack est enregistrée, et la manière dont le comportement du déclenchement du workflow est observé via les suites de checks. C’est terminé lorsque chaque PR membre reçoit l’exécution de workflow attendue, y compris les PR intermédiaires de la stack créées avant l’enregistrement de la stack.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- github, go
- Domaine
- api, cli
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 45/100