Problem
.github/workflows/ci.yml has a changes job that detects which areas a pull
request touches, but it emits exactly one output:
outputs:
companion: ${{ steps.areas.outputs.companion }}
Only the macOS Companion jobs use it. Everything else runs in full for every
pull request — the API suite with its ~2,900 tests, the web build, the container
builds — including on a change that touches one markdown file.
The cost is not abstract. Both branches require checks to be up to date before
merging, so a pull request that goes stale has to re-run the whole matrix. A
documentation-only change currently pays the same ~15 minutes as a change to the
API, and while it runs, every other pull request behind it is invalidated by the
merge.
What to do
Extend changes with outputs for the other areas and gate the expensive jobs on
them, following exactly the pattern the Companion jobs already use.
The trap to avoid
The required status checks are configured by name. A job that is skipped
outright never reports its check, and the merge blocks forever waiting for it.
That is why companion-macos does not skip — it falls back to
ubuntu-24.04 and reports success without doing the expensive work:
runs-on: ${{ needs.changes.outputs.companion == 'true' && matrix.os || 'ubuntu-24.04' }}
Any new gating has to keep reporting the check. Copy that shape rather than
adding if: at the job level.
Careful about what counts as "touched"
services/api changes affect the web contract test. A lockfile change affects
everything. Err toward running: a skipped job that should have run is a bug that
reaches main, while a job that ran unnecessarily only costs minutes.
Acceptance criteria
Problem
.github/workflows/ci.ymlhas achangesjob that detects which areas a pullrequest touches, but it emits exactly one output:
Only the macOS Companion jobs use it. Everything else runs in full for every
pull request — the API suite with its ~2,900 tests, the web build, the container
builds — including on a change that touches one markdown file.
The cost is not abstract. Both branches require checks to be up to date before
merging, so a pull request that goes stale has to re-run the whole matrix. A
documentation-only change currently pays the same ~15 minutes as a change to the
API, and while it runs, every other pull request behind it is invalidated by the
merge.
What to do
Extend
changeswith outputs for the other areas and gate the expensive jobs onthem, following exactly the pattern the Companion jobs already use.
The trap to avoid
The required status checks are configured by name. A job that is skipped
outright never reports its check, and the merge blocks forever waiting for it.
That is why
companion-macosdoes not skip — it falls back toubuntu-24.04and reports success without doing the expensive work:Any new gating has to keep reporting the check. Copy that shape rather than
adding
if:at the job level.Careful about what counts as "touched"
services/apichanges affect the web contract test. A lockfile change affectseverything. Err toward running: a skipped job that should have run is a bug that
reaches
main, while a job that ran unnecessarily only costs minutes.Acceptance criteria
and after in the pull request
ci.ymlitself) runs everything