ci: feat-cmux-next pushes run the web checks and cmux-next checks again
Every push to feat-cmux-next runs ci-web's checks (web / react-apps-check, typecheck, tests) and the cmux-next checks job again, under the same check names a pull request gets. Routing now covers everything the push brought, not just its last commit.
Why
On 2026-10-10, cx-g34i removed this workflow's push trigger ("push CI is the Swift build only"). Since then, nothing has run the web checks on the base:
- Direct pushes go unchecked. A direct push that breaks webviews stays red until some pull request trips over it. Example: 219ae289fc pushed four unformatted files, which made every webviews PR's
react-apps-checkfail. - New reds pass as base reds. CLAUDE.md lets a merger excuse a red that also shows on "a recent base run". The base had no web run, so any web red looked like a base red. #20633 merged with
react-apps-checkred: the merger read it as the known eager-JS-budget red, but the job had also failed at the lint step on the PR's own new test. Every webviews PR's lint then went red, and #22118 fixed it.
What changed
cmux-next-web.yml: apushtrigger on feat-cmux-next, with no paths filter. A path list here would drift fromweb_subareas.py.ci-web.yml: a new optional input,push_base(the push'sevent.before). The scope job fetches that commit and routes frompush_base..HEAD. Pull requests leave it empty and route from the merge commit, as before.web_subareas.py route: honorsWEB_SUBAREAS_BASE. If it can't resolve the base (a new branch's zero SHA, or a base GitHub won't serve), it runs every subarea and writes a::warning::.cmux-next.ymlchecksjob (god files, concurrency, crash safety, l10n): it runs on feat-cmux-next pushes again. cx-g34i had excluded them, so its reds also went unseen until a PR hit them. It is a 10-minute Linux job.
Cost
A push that touches no web path runs two small Linux jobs: the scope job and web-status. This is the push volume cx-g34i was protecting, and those pushes cost little now. A webviews push runs the same lanes a webviews PR does. Concurrency is per SHA, so a later push doesn't cancel an earlier verdict that base-aware excusal reads.
Testing
tests/test_cmux_next_web_base_push.py is committed red first, in its own commit, then fixed:
- base: 4/4 FAIL (no push trigger, no
push_baseinput, a multi-commit push routed from its last commit only, and the checks job excluded on push); - head: 4/4 PASS. The checks-job assertion came in the second commit; it fails on the base because the exclusion is there.
Observed / Not run
- Ran: the new test (red, then green),
tests/test_ci_change_areas.py(227 passed),tests/test_cmux_next_checks_workflow.py(77 passed), the route, route-replay, next-batch and generated-catch-up tests,test_web_validation,test_webviews_tests_per_file,test_cmux_binaries_prune,test_web_bundle_key_inputs.sh,test_ci_self_hosted_guard.sh, and actionlint on both workflows. - Fails on base too:
tests/test_ci_workflow_run_sources.py("ci.yml has no tests job"), identically without this change. - Not run: a real push event. That happens on the first push to feat-cmux-next after merge. A
workflow_dispatchrun on this branch is linked below.
Review: subagent at db9e05df, no blockers (zero or force-push base, callers, push-sensitive steps, cost, test, body). I applied its minor points (a ::warning:: on an unfetchable base, and wording) in 0927e1b67f.
Runtime test: https://github.com/manaflow-ai/cmux/actions/runs/39341605218 (workflow_dispatch of cmux-next-web.yml on db9e05df). Every web lane ran. The two react-apps-check shards failed at check:browser-lanes on test/agent-pane-older-rows-fade.test.ts, the base red #22118 is fixing. That is the base red this workflow now shows on the base itself.
Changelog
none
🤖 Generated with Claude Code