wait-for-status-checks
is a GitHub Action that polls the GitHub Check Runs on a Pull Request and waits until all runs succeed (or are skipped) or one of them fails. It provides a way to enforce "require triggered checks pass" vs. GitHub's naive "require checks to pass".
- Wait for GitHub Check Runs on a Pull Request
- Configure the poll
interval
,timeout
anddelay
- Use as a "required check" to monitor other check runs
GitHub Actions Workflows can be triggered conditionally based on paths
, branches
, or commit message modifiers. This feature allows workflows (and their jobs) to run (or not) on a Pull Request based on what files changed, what branch was targeted, or whether a commit message skips checks (break glass).
name: workflow
on:
pull_request:
paths:
- 'go/**'
branches:
- main
However, only GitHub jobs that always run can be made a "required check" in a branch protection rule or ruleset (see discussion). If a job is skipped because it's workflow wasn't triggered, making the job status "required" will block merges.
This arises frequently in large repos. For example, a workflow that runs a go fmt
job only needs to run if *.go
files were changed, but adding the paths
filter means the status can't be marked as a "required check". Otherwise, PRs that don't modify Go files would be blocked from merging.
wait-for-status-checks
polls the check runs for the head commit of a Pull Request until they all succeed or one fails. The action monitors check runs at some interval
until a timeout
is reached, which makes it a suitable way to enforce that all triggered checks succeeded.
success
- All check runs completed as eithersuccess
orskipped
failure
- One or more check runs completed as with a non-successful conclusion (e.g.failure
,stale
,timed_out
,cancelled
)
name: summary
on:
pull_request:
jobs:
enforce-all-checks:
runs-on: ubuntu-latest
permissions:
checks: read
steps:
- name: GitHub Checks
uses: poseidon/wait-for-status-checks@v0.6.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
The action knows to exclude its own check run (i.e. the GitHub Actions job that runs wait-for-status-check
)
Input | Example | Default | Description |
---|---|---|---|
token | ${{ secrets.GITHUB_TOKEN }} | GitHub token with checks: read |
|
interval | 10s | 10s | Interval in seconds to poll GitHub Check runs |
timeout | 300s | 3600s | Timeout in seconds to poll GitHub Check runs |
delay | 5s | 0s | Period in seconds to wait before first poll of GitHub Check Runs |
match_pattern | prod.* | Regex match GitHub checks that should be watched | |
ignore_pattern | lint.* | Regex match GitHub checks that should be ignored | |
ignore | foo,bar | GitHub checks that should be ignored |
Many alternatives have been tried:
- GitHub used to suggest that for each conditional workflow you wish to make required, create a dummy workflow job of the same name, that runs in the inverse case and passes to satisfy the required check. This is messy and was removed from their docs.
- Mixpanel built an internal GitHub App using GCP Pub/Sub
- Instead of using conditional GitHub Workflows, try to make each job conditional since skipped jobs are considered successes. This is obviously a workaround and 3rd party actions are needed to support
paths
filtering at the job level (e.g. dorny/paths-filter)