Skip to content

ci(test): reduce test shards to three - #1481

Merged
juliopolycarpo merged 2 commits into
mainfrom
ci/test-shard-count-three
Oct 12, 2026
Merged

juliopolycarpo merged 2 commits into
mainfrom
ci/test-shard-count-three

Conversation

@juliopolycarpo

@juliopolycarpo juliopolycarpo commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Reduce the Test matrix from four shards to three after #1480 enabled four isolated API unit workers per shard. This removes one runner job and its fixed setup. The wall-clock tradeoff remains a projection pending a hosted three-versus-four comparison.

Changes

  • Set SHARD_COUNT, the matrix and the job-name denominator to three.
  • Keep the 240s watchdog bound and count-independent retry documentation.
  • Record the newer four-worker hosted baseline, the revised projection and rejection criteria. Keep integration unisolated while the upstream runner-hang issue remains open.

Test Plan

  • bun run check passes
  • bun run test passes
  • bun run build passes
  • New UI strings use @mangostudio/shared/i18n (no hardcoded strings)
  • Manually smoke-tested: login, chat creation, image generation

Local validation at a5754c27: bun run check && bun run test passed, plus 181 focused tests covering workflow/lane guards, qualification, shard/timing merges, metrics and watchdog retries. Built the runtime and fake agent from this checkout with --locked; the runtime checksum remained unchanged after the fixture build.

Local bun run build and manual UI smoke were not run. No UI strings changed. Current-head hosted Test jobs and the coverage/timings merge passed: 14,136 tests passed, 82 skipped, no failures or retries. The three shard steps took 108s, 107s and 53s, all below 147s. Broader CI is still running. This single first-attempt sample does not establish a paired three-versus-four performance benefit.

Screenshots / GIFs

Not applicable.

Notes

Ref #889. This changes CI shard count; the broader worker defaults and override remain outside this PR.

Timing evidence and limits

The earlier hosted 4/6/8 comparison ran API unit coverage at one worker per shard and does not rank three. The initial projection used this four-shard main run, 38202725009, at a39ca7ec on Bun 1.4.3:

Shard api unit api integration root scripts Test step
1 50s 32s 58s 82s
2 55s 30s 65s 86s
3 39s 29s 30s 68s
4 46s 73s 25s 119s

Assuming about 2.5x for unit coverage on a shared runner gave a three-shard estimate near 80s.

The parent's first four-worker run, 38208603805, at 74f557a5 on Bun 1.4.3, showed root scripts bounding two shards:

Shard api unit api integration root scripts Test step
1 21.0s 38.1s 62.7s 62.8s
2 25.4s 31.2s 72.9s 73.0s
3 27.7s 29.8s 43.3s 57.8s
4 19.2s 73.6s 28.3s 93.2s

Redistributing these totals over three shards gives about 31s unit, 58s integration and 69s root scripts. Unit and integration run sequentially, so the revised estimate is near 90s; an imbalanced shard could exceed 110s. These source revisions differ, and the observations are neither a paired speedup nor a distribution for three shards.

Reject three shards if any shard test step reaches 147s or Test completion is clearly worse than four over several first-attempt runs on matched source, worker width and timing baseline. Keep the 240s watchdog.

Two shards remains a later candidate, projecting to about 133s before imbalance from the newer totals. Integration parallelism needs separate qualification while oven-sh/bun#39709 remains open; unit-lane soak does not clear that gate.

@juliopolycarpo juliopolycarpo added type: test Test coverage, test infrastructure, or test reliability work. type: ci CI, release, checks, automation, or GitHub workflow changes. area: docs Documentation tree, guides, reference docs, or contributor docs. labels Oct 12, 2026
@github-actions github-actions Bot added the area: build Binary build, runtime paths, packaging, or standalone output. label Oct 12, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good to merge from a config-consistency standpoint. No prior review threads; this is the first pass on d039bbdc vs stacked base perf/unit-coverage-parallel-workers (74f557a5).

What changed: SHARD_COUNT, the shard matrix, and the job name all moved from 4 → 3 together. The 240s watchdog is intentionally unchanged. Docs record that this count is a projection from run 38202725009, not a hosted 3-vs-4 bake-off, and why two shards is out of scope. Existing workflow tests already derive the expected matrix and job-name denominator from SHARD_COUNT, so no new regression test was required.

Correctness: The three-line change contract is satisfied. Merge/metrics still take $SHARD_COUNT, so a missing shard still fails as partial rather than a quiet green. Watchdog math still fits timeout-minutes: 10 (2 × 240s + ~60s other steps). The 25s / 55s / 60s projection is internally consistent with the table (unit scaled ~2.5×, integration and root scripts redistributed over three).

Risk (accepted, already written down): worst-shard integration imbalance. Shard 4 was already 73s of serial integration; three shards can still land a step well above the ~80s mean. Rejection criteria (step ≥ 147s, or Test completion clearly worse than four shards) are the right gate. Stacked targeting means this PR’s current check suite is not evidence the projection holds — that only happens after #1480 merges and this is retargeted.

Nit, not blocking: the new watchdog comment in .github/workflows/test.yml wraps mid-sentence (…bound is kept. Both attempts have to fit this job's on one line). Wrap it if you touch the file again.

No P0/P1. No inline threads.

Open in Web View Automation 

Sent by Cursor Automation: Mango Ecosystem CodeReview

Base automatically changed from perf/unit-coverage-parallel-workers to main October 12, 2026 20:01
Reduce the Test matrix from four shards to three. With the api unit
lane at four in-process workers per shard, that lane no longer bounds
the shard test step: the serial, unisolated integration lane does, with
root scripts next. Projected from the per-lane times of a four-shard
run on main, three shards land near an 80s step, about where four stood
at one unit worker, for one runner and one job setup fewer.

Set `SHARD_COUNT`, the matrix and the job name to three. The 240s
watchdog bound is kept: it was sized to the 120s worst step at four
shards, and the projected step is shorter.

Record the projection, its assumptions and why two shards is not the
next step in the testing reference. The hosted 4/6/8 comparison stays
as the record of the previous count; it ran the unit lane at one worker
and does not rank three.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>
Record the first hosted four-worker baseline and revise the three-shard estimate to about 90 seconds. Preserve the initial estimate as historical evidence and require a matched hosted comparison before claiming a timing gain.

Keep the 147-second rejection limit, the integration isolation gate, and count-independent watchdog comments visible.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>
@juliopolycarpo
juliopolycarpo force-pushed the ci/test-shard-count-three branch from d039bbd to a5754c2 Compare October 12, 2026 20:13
@github-actions

Copy link
Copy Markdown

PR head: a5754c2 • base: 5c11163 • CI run

CI duration (wall clock, critical path, slowest jobs)

CI Duration

Report-only timing from the Actions jobs API; runner variance does not affect the gate.
Comparisons cover the jobs both runs share, so main-only stages never skew the baseline.

Metric Base Head Δ
Wall clock (shared jobs) 16m 56s 17m 9s 🔴 ▲ +13s
Critical path Distribution / Runtime / Runtime windows-arm64 · 12m 30s Distribution / Runtime / Runtime darwin-arm64 · 9m 42s 🟢 ▼ -2m 48s

Since previous PR run: n/a — no previous successful CI run found for this pull request

Five slowest head jobs

Job Base Head Δ
Distribution / Runtime / Runtime darwin-arm64 9m 33s 9m 42s 🔴 ▲ +9s
Distribution / Runtime / Runtime windows-arm64 12m 30s 9m 21s 🟢 ▼ -3m 9s
Distribution / Runtime / Runtime windows-x64 10m 18s 8m 56s 🟢 ▼ -1m 22s
Distribution / Runtime / Runtime darwin-x64 4m 55s 7m 26s 🔴 ▲ +2m 31s
Distribution / Runtime / Runtime linux-arm64-musl 5m 59s 5m 24s 🟢 ▼ -35s

QA Gate — Coverage & Quality

Base: 5c11163 • Head: f2d08b9 • generated 2026-10-12T20:18:30.547Z

✅ No attention signals — collected metrics look healthy against base.

LoC (code): ⚪ ▲ = 0 • Line coverage (all workspaces): 🟢 ▲ +0.01pp • Quick check: pass • Duplication: ⚪ ▲ = 0 • Bundle gzip: ⚪ ▲ = 0 • Locked deps: ⚪ ▲ = 0 • Tests passed: ⚪ ▲ = 0

Metric details (coverage, LoC, bundle, dependencies, tests, duplication, tooling)

Coverage

API/shared branches and statements are source-derived from LCOV line hits because Bun LCOV does not emit branch or statement records.

Rust crates: line, function and region coverage from cargo llvm-cov over the ubuntu libtest run. Branch coverage is not collected and doctests are not instrumented. A crate shows n/a when the Rust lane did not run for the change or its profile data is incomplete.

Component Metric Base Head Δ
apps/api lines 90.06% (80,311/89,173) 90.08% (80,311/89,151) 🟢 ▲ +0.02pp
apps/api statements 80.89% (32,692/40,413) 80.89% (32,692/40,413) ⚪ ▲ = 0
apps/api functions 87.67% (8,088/9,226) 87.86% (8,106/9,226) 🟢 ▲ +0.19pp
apps/api branches 55.98% (12,494/22,319) 55.97% (12,492/22,319) 🔴 ▼ -0.01pp
apps/frontend lines 86.69% (57,552/66,388) 86.69% (57,552/66,388) ⚪ ▲ = 0
apps/frontend statements 83.82% (15,761/18,804) 83.82% (15,761/18,804) ⚪ ▲ = 0
apps/frontend functions 80.02% (4,118/5,146) 80.02% (4,118/5,146) ⚪ ▲ = 0
apps/frontend branches 55.43% (7,769/14,017) 55.45% (7,772/14,017) 🟢 ▲ +0.02pp
apps/shared lines 89.75% (22,054/24,572) 89.75% (22,054/24,572) ⚪ ▲ = 0
apps/shared statements 80.29% (4,667/5,813) 80.29% (4,667/5,813) ⚪ ▲ = 0
apps/shared functions 79.91% (851/1,065) 80.00% (852/1,065) 🟢 ▲ +0.09pp
apps/shared branches 50.64% (1,574/3,108) 50.64% (1,574/3,108) ⚪ ▲ = 0
crates/mango-protocol lines 94.82% (7,469/7,877) n/a n/a
crates/mango-protocol functions 94.34% (984/1,043) n/a n/a
crates/mango-protocol regions 94.88% (11,159/11,761) n/a n/a
crates/mangostudio-launcher lines 35.78% (78/218) n/a n/a
crates/mangostudio-launcher functions 36.36% (12/33) n/a n/a
crates/mangostudio-launcher regions 34.94% (123/352) n/a n/a
crates/mangostudio-runtime lines 92.35% (55,414/60,005) n/a n/a
crates/mangostudio-runtime functions 91.06% (6,186/6,793) n/a n/a
crates/mangostudio-runtime regions 92.08% (85,969/93,363) n/a n/a
crates/mangostudio-runtime-contract lines 99.61% (763/766) n/a n/a
crates/mangostudio-runtime-contract functions 100.00% (111/111) n/a n/a
crates/mangostudio-runtime-contract regions 99.64% (1,111/1,115) n/a n/a

Lines of Code

Authored source: production and test files of every discovered component. Generated, fixture, config and docs lines are recorded in the envelope but not counted here.

Component Base Head Δ
apps/api 1,319 files / 204,426 lines 1,319 files / 204,426 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
apps/frontend 999 files / 106,298 lines 999 files / 106,298 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
apps/shared 306 files / 40,732 lines 306 files / 40,732 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mango-protocol 74 files / 15,735 lines 74 files / 15,735 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-launcher 1 files / 284 lines 1 files / 284 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-runtime 250 files / 105,519 lines 250 files / 105,519 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-runtime-contract 8 files / 1,468 lines 8 files / 1,468 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
packages/cli 1 files / 76 lines 1 files / 76 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
packages/protocol 71 files / 9,140 lines 71 files / 9,140 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
scripts 464 files / 67,849 lines 464 files / 67,849 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
total 3,493 files / 551,527 lines 3,493 files / 551,527 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0

Frontend Bundle

Metric Base Head Δ
gzip total 1.32 MiB 1.32 MiB ⚪ ▲ = 0
gzip JavaScript 1.30 MiB 1.30 MiB ⚪ ▲ = 0
gzip CSS 20.3 KiB 20.3 KiB ⚪ ▲ = 0
gzip HTML 808 B 808 B ⚪ ▲ = 0
tracked files 121 121 ⚪ ▲ = 0

Dependencies

Metric Base Head Δ
locked packages 513 513 ⚪ ▲ = 0
direct dependencies 42 42 ⚪ ▲ = 0
direct devDependencies 39 39 ⚪ ▲ = 0
workspace manifests 5 5 ⚪ ▲ = 0

Tests

Single full-suite pass (unit + integration, from the coverage run).

Base Head Δ passed
14,136 passed (root 3,472 / frontend 2,868 / api 6,605 / shared 1,191) · exit 0 · 80s 14,136 passed (root 3,472 / frontend 2,868 / api 6,605 / shared 1,191) · exit 0 · 108s ⚪ ▲ = 0

Test lanes

One row per lane, deduplicated by test. ≥ marks a lower bound: a shard report or process receipt was missing, cut off or timed out. A partial or unavailable lane is never counted as zero, and a total over one is never complete.

Component Lane Base Head Δ passed
apps/api api-unit 5,443 passed · 1 skipped 5,443 passed · 1 skipped ⚪ ▲ = 0
apps/api api-integration 1,162 passed · 22 skipped 1,162 passed · 22 skipped ⚪ ▲ = 0
apps/api total 6,605 passed · 23 skipped 6,605 passed · 23 skipped ⚪ ▲ = 0
apps/frontend frontend 2,868 passed 2,868 passed ⚪ ▲ = 0
apps/frontend total 2,868 passed 2,868 passed ⚪ ▲ = 0
apps/shared shared 1,191 passed · 1 skipped 1,191 passed · 1 skipped ⚪ ▲ = 0
apps/shared total 1,191 passed · 1 skipped 1,191 passed · 1 skipped ⚪ ▲ = 0
scripts root 3,472 passed · 58 skipped 3,472 passed · 58 skipped ⚪ ▲ = 0
scripts total 3,472 passed · 58 skipped 3,472 passed · 58 skipped ⚪ ▲ = 0
repository total 14,136 passed · 82 skipped 14,136 passed · 82 skipped ⚪ ▲ = 0

Code Duplication (jscpd)

Metric Base Head Δ
clones 1,781 1,781 ⚪ ▲ = 0
duplicated lines 25,226 25,226 ⚪ ▲ = 0
percentage 5.37% 5.37% ⚪ ▲ = 0

Repo Tooling

Metric Base Head Δ
Full repo check pass pass ⚪ ▲ = 0
TS errors (total) 0 0 ⚪ ▲ = 0
Circular dependencies 0 0 ⚪ ▲ = 0

@github-actions

Copy link
Copy Markdown

Commits — 2 commits

Base 5c11163 → head a5754c2, oldest first.

  • bd07121 ci(test): reduce test shards to three
  • a5754c2 docs(ci): qualify the three-shard timing projection
Full commit messages

bd07121 ci(test): reduce test shards to three

ci(test): reduce test shards to three

Reduce the Test matrix from four shards to three. With the api unit
lane at four in-process workers per shard, that lane no longer bounds
the shard test step: the serial, unisolated integration lane does, with
root scripts next. Projected from the per-lane times of a four-shard
run on main, three shards land near an 80s step, about where four stood
at one unit worker, for one runner and one job setup fewer.

Set `SHARD_COUNT`, the matrix and the job name to three. The 240s
watchdog bound is kept: it was sized to the 120s worst step at four
shards, and the projected step is shorter.

Record the projection, its assumptions and why two shards is not the
next step in the testing reference. The hosted 4/6/8 comparison stays
as the record of the previous count; it ran the unit lane at one worker
and does not rank three.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>

a5754c2 docs(ci): qualify the three-shard timing projection

docs(ci): qualify the three-shard timing projection

Record the first hosted four-worker baseline and revise the three-shard estimate to about 90 seconds. Preserve the initial estimate as historical evidence and require a matched hosted comparison before claiming a timing gain.

Keep the 147-second rejection limit, the integration isolation gate, and count-independent watchdog comments visible.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>

📝 Changelog Preview

Entries this branch would add to the changelog on release:

[Unreleased]

📚 Documentation

  • (ci) Qualify the three-shard timing projection

👷 CI

  • (test) Reduce test shards to three

@juliopolycarpo
juliopolycarpo merged commit 02db64a into main Oct 12, 2026
67 checks passed
@juliopolycarpo
juliopolycarpo deleted the ci/test-shard-count-three branch October 12, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: build Binary build, runtime paths, packaging, or standalone output. area: docs Documentation tree, guides, reference docs, or contributor docs. type: ci CI, release, checks, automation, or GitHub workflow changes. type: test Test coverage, test infrastructure, or test reliability work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant