GitHub: checks run on every pull request in a stack
Every pull request in a stack is evaluated as if it targets the base of the stack, such as main. A workflow configured to run on pull_request events targeting main runs for every pull request in the stack, not just the bottom one, so a large stack multiplies your CI usage (GitHub's optimizing CI for stacked pull requests, checked October 27, 2026).
main <- PR1 <- PR2 <- PR3 on: pull_request, branches: [main] runs for PR1, PR2 and PR3 required status checks evaluated against the stack base github.event.pull_request.stack present only in a stack
Why it runs for every pull request
- The stack base counts: GitHub Actions workflows trigger as if each pull request in the stack targets the base of the stack, so no workflow changes are needed for checks to run across the whole stack (GitHub's stacked pull requests).
- The rules too: required reviews, required status checks, code owners and code scanning workflows are evaluated against the stack base, not the branch directly below (GitHub's branch protections and required checks). The base is the base branch of the bottom pull request, the repository's default branch by default, and can be any branch, such as a release branch.
- Merging needs the ones below: merging PR3 requires PR1 and PR2 to also pass checks (see stacked pull request not merging).
Running jobs only where needed
- The stack fields: in workflow expressions, github.event.pull_request.stack gives number (the stack, in the repository), size (pull requests in the stack), position (1 is the bottom), base.ref (the branch the whole stack targets) and base.sha. The property is present only when the pull request belongs to a stack, so check that it is not null first (GitHub's accessing stack metadata).
- The lowest unmerged pull request: where github.event.pull_request.stack.base.ref equals github.event.pull_request.base.ref, the one that targets the stack base directly. When the bottom pull request merges, the next one is rebased to target the stack base and becomes the lowest unmerged one on the following run.
- The top pull request: where stack.position equals stack.size, the one with the full set of changes. stack.position == 1 picks the original bottom one (GitHub's reducing CI usage).
if: github.event.pull_request.stack != null && github.event.pull_request.stack.position == github.event.pull_request.stack.size
When the job is a required check
- Skipped by a condition: a job skipped by a conditional reports Success, so it does not block the merge (GitHub's handling skipped but required checks).
- Skipped as a whole workflow: a workflow skipped by path filtering, branch filtering or a commit message leaves its checks Pending, which blocks merging; GitHub advises against requiring workflows that can be skipped (see checks skipped by [skip ci]).
- A job after a failed one: a job that depends on a failed job is skipped and may not block merging; GitHub suggests always() with needs for such required checks.
What to do
- Too many runs: keep the cheap checks on every pull request, and gate the expensive jobs on the lowest unmerged or the top pull request with the stack fields.
- A run you did not expect: compare the workflow filter with the stack base, not with the branch directly below the pull request.
- After a rebase: the merge box shows Rebase stack when a rebase is needed; rebasing a stack generates signed commits, and approvals are kept when the diff does not change (GitHub's rebasing).
GitHub pull requests in IntelliJ IDEA
Pull Request Inbox for GitHub, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, lists the checks GitHub reports on a pull request's head commit, with links to their runs, next to the diff. For a pull request in a stack, its merge checks say that it is part of a stack and read the rules of the stack base, and Merge lands it together with the open pull requests below it. It does not rerun checks or change workflows. The review inbox, diffs and conversations are free; approving, commenting, resolving and merging are Pro (US$1.50 a month, with a 30-day trial).
GitHub is a trademark of GitHub, Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by GitHub, Inc. or JetBrains.
More: GitHub merge refused (405, 409) · GitHub review refused (422) · GitHub search 422 "Validation Failed" · "Resource not accessible by personal access token" · 401 "Bad credentials" · "Resource protected by organization SAML enforcement" · "API rate limit exceeded" · GitHub diff 406 "too_large", 3,000 files · GitHub line comment 422 "must be part of the diff" · GitHub branch update refused (422) · GitHub pull request not created (422, 403) · GitHub auto-merge refused · GitHub draft, ready for review or close refused · GitHub conversation not resolved · GitHub checks not shown (check runs 403) · GitHub file contents not read · GitHub compare refused (404, 422) · GitHub comment or reply refused (403 locked, archived) · GitHub merge method not allowed (405) · GitHub branch not found (404, 301) · GitHub Enterprise Server not reached · GitHub review request not shown · GitHub pull request list incomplete · GitHub 404 Not Found, renamed repositories (301, 307) · GitHub line comment outdated or not on the diff · GitHub pull requests not updating, notifications late · GitHub suggested change cannot be applied · GitHub required check stuck at "Expected" · GitHub code owner review required · GitHub merge blocked by unresolved conversations · GitHub merge blocked by unsigned commits · GitHub branch that merges through a merge queue · GitHub merge waiting for an approval of the most recent push · GitHub merge waiting for code scanning results · GitHub merge waiting for code quality results · GitHub merge blocked by a code coverage threshold · GitHub merge blocked by license compliance results · GitHub branch locked or its updates restricted · GitHub branch not deleted after merging · GitHub merge waiting for a team's approval (Required reviewers) · GitHub merge blocked by secret scanning alerts · GitHub stacked pull request not merging · GitHub push blocked by push rules · GitHub merge blocked by commit metadata rules · GitHub force push blocked · GitHub issue not closed by a merged pull request · GitHub pull request not checked out locally · GitHub pull request has merge conflicts · GitHub changes requested and dismissing a review · GitHub co-author not credited for a commit · GitHub dependency review check failed · GitHub Dependabot not rebasing its pull request · GitHub fork not syncing with upstream · GitHub pull request base branch not changing · GitHub pull request not reverting · GitHub pull request template not showing · GitHub pull request labels or assignees not added · GitHub pull request not closing or reopening · GitHub push blocked by push protection · GitHub pull request comment hidden · GitHub pull request blocked until deployments succeed · GitHub team review request replaced by members · GitHub pull request file no longer marked Viewed · GitHub pull request marked merged without being merged · GitHub Copilot review does not count as an approval · GitHub checks not running on a pull request a workflow created · GitHub Update branch button not shown on a pull request · GitHub checks failing on a Dependabot pull request · GitHub checks failing on a pull request from a fork · GitHub checks skipped by [skip ci] in a commit message · GitHub checks gone after the retention period · GitHub code review limits in a public repository · GitHub pull requests turned off or limited in a repository · GitHub pull request showing commits already squash merged · GitHub pull request not showing a file diff · GitHub push to a pull request branch from a fork refused · GitHub check cancelled on a pull request · GitHub Rebase and merge not available · GitHub merge commit message not what you expected · GitHub pull request shows every line changed · GitHub API request timed out · GitHub pull request image or document diff not shown · GitHub review request refused (422) · GitHub pull request from Copilot: checks not running, approval not counted · GitHub push refused: GH006 and GH013 on a protected branch · GitHub "At least 1 approving review is required", approvals that do not count · GitHub pull request plugins for IntelliJ IDEA, compared · 日本語