Skip to content

ci: give e2e/timed its own shard so shard 3 fits the step cap - #4771

Merged
tyler-dane merged 3 commits into
mainfrom
claude/kind-dirac-p8igbj
Oct 23, 2026
Merged

tyler-dane merged 3 commits into
mainfrom
claude/kind-dirac-p8igbj

Conversation

@tyler-dane

Copy link
Copy Markdown
Contributor

Fixes #

What and why

No issue: found by the weekly technical-debt sweep, which hit this problem
head-on while landing #4770.

e2e-shard (3) runs e2e/timed e2e/dst e2e/event-form e2e/parity against a
timeout-minutes: 8 step cap. The timezone and parity work of the last week
added e2e/dst, e2e/event-form and e2e/parity and grew e2e/timed to 46
tests, and all four landed on shard 3. It is now the critical path by a wide
margin and close enough to the cap to fail at random:

shard specs duration on 47703fb (main)
1 accessibility, allday 2m36s
2 booking, oauth, auth, billing 2m13s
3 timed, dst, event-form, parity 6m06s
4 onboarding, calendars, life, navigation, attendees 3m09s

On #4770, a diff that touches no spec and no test helper, shard 3 went:

run result
PR attempt 1 timed out at 8m00s, 64 of 67 specs passed, 0 failed
PR attempt 2 passed, 5m23s
merge-queue attempt 1 timed out at 8m00s, 64 of 67 passed, 0 failed
merge-queue attempt 2 passed

Two timeouts in four runs, every one at the cap with zero assertion failures.
That ejected the PR from the merge queue once and cost four extra shard runs.
It is not specific to that PR: any PR that reaches the shards gets the same
coin flip.

The change

Measured locally, e2e/timed is 3.2m of shard 3's load (46 tests) and dst +
event-form + parity together are 1.8m (21 tests). So timed gets a leg to
itself and the other three move to a new shard 5. Scaled to CI that is about
3m54s and 2m12s, in line with shards 1 (3m53s) and 2 (2m34s) as measured on
the merge-queue run, and it drops the e2e critical path from the 8m cap to
about 3m54s.

The workflow already anticipated this: "the shard legs can change count
without touching branch protection" and "Resize by moving directories between
lists". The required context is the e2e gate, which aggregates the whole
matrix via needs.e2e-shard.result, so a fifth leg needs no
branch-protection change.

What this deliberately does not do:

  • The timeout-minutes: 8 step cap is unchanged. Raising it would hide the
    problem rather than fix it.
  • No test is skipped, quarantined, retried or altered. The same 67 specs run,
    just across two legs.
  • Shards 1, 2 and 4 are untouched, so nothing currently green is put at risk.

packages/scripts/src/testing/e2e-shards.test.ts still proves every e2e/
directory with specs lands on exactly one shard, and it passes. I also checked
that nothing else hardcodes the shard count: only
docs/CI-CD/workflows.md said "four shards", updated here.
docs/CI-CD/ci-audit-2026-09.md is left alone as a dated historical record.

Verify

VERDICT: PASS
Selected packages: scripts
Checks run: test:scripts, type-check, lint, knip

bun test packages/scripts/src/testing/e2e-shards.test.ts 2 pass / 0 fail,
bun test:scripts:fast 224 pass / 0 fail, bun lint passed
(semantic-colors, agent-constraints, todo-copy, prosemirror-dedupe, biome).
This PR's own e2e run is the real check: it exercises the new five-leg
matrix end to end.

The branch carries a merge of main because #4770 squash-merged while this
follow-up was being prepared; the diff against main is the two files above.


Generated by Claude Code

Behavior-preserving cleanup of debt introduced by last week's merges
(#4763, #4762, #4740, #4722, #4741).

- booking-web hand-rolled two partial HTML escapers while `escapeHtml`
  already existed in the backend. Move it to `@core/util/escape-html.util`
  so both callers share one implementation.
- Collapse five copy-pasted `html.replace` calls for superseded base meta
  tags into one pattern list, dropping the reassigned `let html`.
- `autoEffectiveTimeZone` returned the browser zone from both arms of its
  `isUtcLikeTimeZone` guard. Drop the dead branch and the two pass-through
  wrappers (`applyDayjsDefault`, `getStoredBrowserTimeZone`).
- The welcome step guard probed sessionStorage three times and tested set
  membership twice, with one branch unreachable. One probe, one check.
- Derive the event-form date key unions from the key lists instead of
  keeping hand-maintained `Set<string>` literals in sync with them.
- Resolve the view zone and civil day once per day-column scan instead of
  once per timed event.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzeokDYpEzrNDZeYkA1DzW
The timezone and parity work added e2e/dst, e2e/event-form and e2e/parity
and grew e2e/timed to 46 tests, all on shard 3. That leg reached 6m06s of
its 8 minute step cap on main and then timed out twice in a row, on this
PR and on its merge-queue run, both at 64 of 67 specs passed with zero
failures.

Measured locally, e2e/timed is 3.2m of that load and dst, event-form and
parity together are 1.8m. Give timed a leg of its own and move the other
three to a new shard 5: scaled to CI that is about 3m54s and 2m12s, in
line with shards 1 (3m53s) and 2 (2m34s), and it drops the e2e critical
path from the 8m cap to about 3m54s.

The step cap stays at 8 minutes and no test changes. The required check is
the `e2e` gate, which aggregates the whole matrix, so adding a leg needs no
branch-protection change; e2e-shards.test.ts still proves every e2e
directory lands on exactly one shard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzeokDYpEzrNDZeYkA1DzW
@tyler-dane tyler-dane added the agent-automerge Agent-loop finished; merge-guard may squash-merge label Oct 23, 2026 — with Claude
@tyler-dane
tyler-dane enabled auto-merge October 23, 2026 11:12
@tyler-dane
tyler-dane added this pull request to the merge queue Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Measured on this PR's own e2e run, which exercised the new five-leg matrix end
to end. Both new legs passed; my predicted numbers in the description were low,
so the actuals:

leg Run e2e tests predicted cap
e2e-shard (3, e2e/timed) 4m51s 3m54s 8m
e2e-shard (5, e2e/dst e2e/event-form e2e/parity) 3m02s 2m12s 8m

Both came in about 1.3x my estimate, which scaled from a local run, and shard 5
overshot by the same factor as shard 3. That points at this run's runners being
slow across the board rather than at the split being wrong, and it makes the
result stronger than a fast run would have: on runners this slow the old
four-way list would have blown the cap again, and shard 3 still finished with
over three minutes of headroom.

Headroom on the critical path goes from 0-24% (6m06s-8m00s of 8m) to about 39%
(4m51s of 8m). I have left the description's estimates as written rather than
editing them after the fact; these are the numbers to trust.


Generated by Claude Code

Merged via the queue into main with commit 03cccaf Oct 23, 2026
31 checks passed
@tyler-dane
tyler-dane deleted the claude/kind-dirac-p8igbj branch October 23, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-automerge Agent-loop finished; merge-guard may squash-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants