Summary
PRs that only change files listed in ci.yml's paths-ignore never trigger the ci workflow, but branch protection on main still requires all 12 build (...) matrix status checks. GitHub shows those checks as "Expected — Waiting for status to be reported" indefinitely, blocking merge even when other checks (pre-commit, license/cla) pass.
Current example
Root cause
ci.yml uses workflow-level paths-ignore to skip the full build matrix for certain path-only changes:
pull_request:
paths-ignore:
- "LICENSES/**"
- "LICENSE"
- "**.md"
- .github/workflows/wheels.yml
- .github/workflows/ci-gcp.yml
- .github/workflows/ci-latest-slang.yml
When a PR touches only ignored paths, the ci workflow does not run at all. Branch protection still requires these 12 contexts (among others):
build (linux, x86_64, gcc, Debug, 3.10) … through … build (windows, x86_64, msvc, Release, 3.10)
license/cla
A workflow skipped by paths-ignore never reports status → required checks stay pending forever. This is different from a job skipped via if: (which GitHub treats as passing).
Note: the wheels workflow is workflow_dispatch-only, so PR CI does not validate wheel matrix changes either.
History
| When |
What |
| Apr 2025 |
paths-ignore added to ci.yml for docs/**, LICENSE*, **.md (Simon Kallweit) |
| May 2025 |
#175 added .github/workflows/wheels.yml to paths-ignore when macOS wheel builds were introduced |
| Mar 2026 |
#847 opened (Report passing CI status when path filter skips builds) — proposed replacing workflow-level paths-ignore with a filter job that gates the build matrix via if:, so skipped builds report as skipped rather than missing (same pattern as the shader-slang/slang repo's filter + check-ci gate). Iterated to a bash/git diff approach after feedback from Chris Cummings on third-party action dependencies. |
| Mar 12, 2026 |
#847 closed without merging, with a note to "remove the filtering altogether" — that follow-up was never implemented; paths-ignore remains in place. |
| Jul 15, 2026 |
Recurrence on #1002; comment added to closed #847. |
There is no open tracking issue for the #847 closure decision.
Prior art (slang repo)
The shader-slang/slang repo solves this with:
- A
filter job that detects docs-only changes
- Build jobs gated with
if: should-run == 'true' (skipped jobs count as passing)
- A single
check-ci aggregate gate job as the only required status check
SlangPy still lists all 12 matrix job names individually in branch protection and uses workflow-level paths-ignore instead.
Proposed fixes
Option A — Filter + aggregate gate (revive #847, align with slang):
- Remove
paths-ignore from the pull_request trigger (workflow always runs)
- Add
filter + ci gate jobs; gate build with if:
- Update branch protection to require
ci + license/cla instead of 12 matrix names
Option B — Remove filtering (alternative from #847 closure):
- Drop
paths-ignore entirely; always run the full matrix on every PR
- Simplest, but higher CI cost on docs/wheels-only changes
Workarounds (today)
- Add a trivial change to a non-ignored file to force
ci to run
- Admin merge bypassing required checks
- Manual
wheels workflow build-only run (validates wheels but does not unblock branch protection)
Acceptance criteria
Summary
PRs that only change files listed in
ci.yml'spaths-ignorenever trigger theciworkflow, but branch protection onmainstill requires all 12build (...)matrix status checks. GitHub shows those checks as "Expected — Waiting for status to be reported" indefinitely, blocking merge even when other checks (pre-commit,license/cla) pass.Current example
.github/workflows/wheels.yml)pip installon Python 3.14 falls back to v0.23.0)Root cause
ci.ymluses workflow-levelpaths-ignoreto skip the full build matrix for certain path-only changes:When a PR touches only ignored paths, the
ciworkflow does not run at all. Branch protection still requires these 12 contexts (among others):build (linux, x86_64, gcc, Debug, 3.10)… through …build (windows, x86_64, msvc, Release, 3.10)license/claA workflow skipped by
paths-ignorenever reports status → required checks stay pending forever. This is different from a job skipped viaif:(which GitHub treats as passing).Note: the
wheelsworkflow isworkflow_dispatch-only, so PR CI does not validate wheel matrix changes either.History
paths-ignoreadded toci.ymlfordocs/**,LICENSE*,**.md(Simon Kallweit).github/workflows/wheels.ymltopaths-ignorewhen macOS wheel builds were introducedpaths-ignorewith afilterjob that gates thebuildmatrix viaif:, so skipped builds report as skipped rather than missing (same pattern as theshader-slang/slangrepo'sfilter+check-cigate). Iterated to a bash/git diffapproach after feedback from Chris Cummings on third-party action dependencies.paths-ignoreremains in place.There is no open tracking issue for the #847 closure decision.
Prior art (slang repo)
The
shader-slang/slangrepo solves this with:filterjob that detects docs-only changesif: should-run == 'true'(skipped jobs count as passing)check-ciaggregate gate job as the only required status checkSlangPy still lists all 12 matrix job names individually in branch protection and uses workflow-level
paths-ignoreinstead.Proposed fixes
Option A — Filter + aggregate gate (revive #847, align with slang):
paths-ignorefrom thepull_requesttrigger (workflow always runs)filter+cigate jobs; gatebuildwithif:ci+license/clainstead of 12 matrix namesOption B — Remove filtering (alternative from #847 closure):
paths-ignoreentirely; always run the full matrix on every PRWorkarounds (today)
cito runwheelsworkflowbuild-onlyrun (validates wheels but does not unblock branch protection)Acceptance criteria
wheels.yml(or other ignored paths) can merge without stuck pending checkscimatrix still runs and gates merges for real code changes