Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions .github/workflows/ci-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,24 +255,31 @@ jobs:
needs: web-subarea-scope
if: ${{ inputs.web == 'true' && needs.web-subarea-scope.outputs.react_apps == 'true' }}
# `bun test` grows memory across the suite and was SIGKILLed (exit 137) on the
# 4 vCPU runner (run 37666132324), so this job takes the 8 vCPU size, which
# has twice the memory. Fork pull requests run the same suite on it.
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
# 4 vCPU runner (run 37666132324). The 32 vCPU size has the memory and runs
# 32 files and 8 dev-server files at once (run-webviews-tests.sh). Fork pull
# requests run the same suite on the hosted runner.
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
# The 10-minute siblings in this workflow, plus the browser engines and the
# browser-lane suites they run. The full suite grew to 22 min in one process;
# two deterministic file shards keep per-file isolation while shortening the
# critical path. Keep the existing cap until hosted timing proves a tighter
# bound for the shard with the longer browser files.
# browser-lane suites they run. The full suite grew to 22 min in one process.
# Deterministic file shards keep per-file isolation. Each shard warms one
# Vite cache per dev-server config, cold, so many small shards each paid
# that warm-up and ran their dev-server files two at a time: 12 shards on
# 8 vCPU took 14.3 min (run 39347314726), barely under 2 shards' 15.5.
# Fewer, wider shards share each warm cache across more files.
timeout-minutes: 40
name: react-apps-check (${{ matrix.shard }})
strategy:
fail-fast: false
matrix:
include:
- shard: 1
shard_count: 2
shard_count: 4
- shard: 2
shard_count: 2
shard_count: 4
- shard: 3
shard_count: 4
- shard: 4
shard_count: 4
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -324,20 +331,26 @@ jobs:
run: ./scripts/cmux-next/build-web-bundles.sh --force

# ci-guards runs this on main; feat-cmux-next PRs skip ci-guards.
# The checks from here to the engines do not depend on the shard, so
# they run once, on shard 1: one red check, not one per shard.
- name: Generated bundle merge driver
if: matrix.shard == 1
run: python3 tests/test_install_git_hooks.py

# A budget miss must not hide the checks and tests below: the step records its outcome and
# the job fails on it in the last step. A failed build still stops everything after it.
- name: Check diff viewer eager JS budget
id: eager-js-budget
if: matrix.shard == 1
continue-on-error: true
run: node ./scripts/check-webviews-diff-budget.mjs

- name: Verify React Compiler for webviews
if: matrix.shard == 1
run: ./scripts/check-webviews-react-compiler.mjs

- name: Check webviews (Oxlint, Oxfmt, type check)
if: matrix.shard == 1
working-directory: webviews
run: bun run check

Expand Down
5 changes: 4 additions & 1 deletion schemas/defaults/cmux-next.json
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@
"setting.history.terminalCommands": false,
"setting.home.attachments.keepLocation": false,
"setting.home.channelsEnabled": false,
"setting.home.chiefPetEnabled": false,
"setting.home.chiefPetMascot": "orb",
"setting.labs.classicHome": false,
"setting.labs.previewFeatures": false,
"setting.layout.centerFocusedColumn": "never",
Expand All @@ -463,7 +465,8 @@
"setting.layout.stripMargin": 0,
"setting.layout.stripScrollbar": "system",
"setting.layout.tileBrowsers": false,
"setting.markdown.code.blockSize": 14,
"setting.markdown.code.blockSize": null,
"setting.markdown.code.scale": 0.875,
Comment on lines +468 to +469

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Defaults check fails

cmux-next.json no longer matches the committed settings schema. That schema still gives markdown.code.blockSize a default of 14 and has no markdown.code.scale or home.chiefPet* rows. defaults_guard.py builds the snapshot from that schema and rejects any mismatch, so the defaults guard check fails on this head. Regenerate and commit the matching settings exports and snapshot together, or remove these unrelated snapshot changes.

"setting.markdown.font.lineHeight": 1.6,
"setting.markdown.font.preset": "system",
"setting.markdown.font.size": 16,
Expand Down
25 changes: 24 additions & 1 deletion tests/test_web_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,30 @@ def test_webviews_tests_run_on_a_runner_with_room_for_the_suite(self):
self.assertIn("scripts/ci/run-webviews-tests.sh", block)
self.assertNotIn("vars.LINUX_RUNNER", runs_on)
self.assertNotIn("4vcpu", runs_on)
self.assertIn("'blacksmith-8vcpu-ubuntu-2404'", runs_on)
self.assertIn("'blacksmith-32vcpu-ubuntu-2404'", runs_on)

def test_webviews_tests_shard_on_wide_runners(self):
"""Two 8 vCPU shards each ran about 65 dev-server files two at a time for 12 of
their 14-16 minutes. Twelve 8 vCPU shards took 14.3 min: each paid a cold Vite
warm-up. Four 32 vCPU shards run eight dev-server files at once on a shared warm
cache; Blacksmith runners are free and ran 256 jobs at 32 vCPU without queueing."""
workflow = (ROOT / ".github/workflows/ci-web.yml").read_text()
start = workflow.index(" react-apps-check-shard:")
match = re.search(r"\n [A-Za-z0-9_-]+:", workflow[start + 3 :])
block = workflow[start:] if match is None else workflow[start : start + 3 + match.start()]
shards = [int(n) for n in re.findall(r"^ - shard: (\d+)$", block, re.MULTILINE)]
counts = set(re.findall(r"^ shard_count: (\d+)$", block, re.MULTILINE))
self.assertEqual(len(shards), 4)
self.assertIn("'blacksmith-32vcpu-ubuntu-2404'", block)
self.assertEqual(shards, list(range(1, len(shards) + 1)))
self.assertEqual(counts, {str(len(shards))})
for step in ("Generated bundle merge driver", "Check diff viewer eager JS budget",
"Verify React Compiler for webviews", "Check webviews (Oxlint, Oxfmt, type check)",
"Check PR-scoped webview rules"):
with self.subTest(step=step):
body = block[block.index(f"- name: {step}"):]
body = body[: body.index("\n - name:", 1)] if "\n - name:" in body[1:] else body
self.assertIn("if: matrix.shard == 1", body)

def test_pr_and_merge_group_checks_belong_to_ci(self):
delegated = {"changes": {"result": "success", "outputs": {"required": "true"}},
Expand Down