Skip to content

Share install/build across E2E shards via artifact - #921

Draft
Liam Farrelly (lfarrel6) wants to merge 9 commits into
masterfrom
claude/e2e-test-workflow-shards-99f553
Draft

Share install/build across E2E shards via artifact#921
Liam Farrelly (lfarrel6) wants to merge 9 commits into
masterfrom
claude/e2e-test-workflow-shards-99f553

Conversation

@lfarrel6

Copy link
Copy Markdown
Member

Why

Aiming to reduce CI times.

How

Adds a single build job that installs deps, builds all workspace packages, and uploads their dist outputs as one artifact. The e2e-test matrix downloads that artifact instead of rebuilding per shard, and runs on ev-runner-large (8 cores) so each shard gets ~8 Playwright workers via workers: "100%".

Adds a single build job that installs deps, builds all workspace packages,
and uploads their dist outputs as one artifact. The e2e-test matrix
downloads that artifact instead of rebuilding per shard, and runs on
ev-runner-large (8 cores) so each shard gets ~8 Playwright workers via
workers: "100%".
@changeset-bot

changeset-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1ea04fb

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

The previous `pnpm run -r --if-present build` built every package with a
build script, including 3ds, eql, js, and both react-native packages —
none of which are dependencies of any e2e-tests package. Filtering by
`{./e2e-tests/*}...` drops the build set from 11 packages to the 6 that
are actually needed (browser, card-validator, inputs, ui-components,
react, encryption), avoiding the slow rollup/bob/cjs+esm builds.
For projects whose suites are dominated by per-job setup time, sharding
adds more orchestration overhead than it saves in test runtime. The
discovery step now emits a full {project, shard, total-shards} matrix
and treats browser + crypto-harness as single-job runs (--shard=1/1).
Inputs and ui-components remain split into 2 shards.
The setup-node pnpm cache only stores the content-addressable store, not
the assembled node_modules tree. With node-linker=hoisted that hardlink
phase is the slow part of install, so add a second actions/cache step
keyed on the lockfile (plus .npmrc + pnpm-workspace.yaml so layout
changes invalidate cleanly). On a cache hit the install step is skipped
entirely; on miss it falls back to --prefer-offline.

Also align the build job's install with the other jobs (--prefer-offline)
and add a couple of pnpm tunings: higher network concurrency for cold
installs and skip store integrity re-verification (the CI store is
ephemeral so the check buys little).
The path filter previously matched any change under .github/**, so every
unrelated workflow edit triggered an iOS + Android build. Narrow it to
this workflow's own file.
Adds an optional base-ref input to lint.yml. When provided, the lint
steps and unit tests run with pnpm's --filter=...[<since>] selector, so
only packages changed since the base (and their dependents) are
exercised. Root-level changes (lockfile, .npmrc, workflow files, root
package.json) escape the filter and trigger a full run.

The PR workflow now passes github.base_ref so PRs only check what they
touch. push.yml is unchanged and still runs the full suite on master.

Also adds cancel-in-progress concurrency to the react-native workflow so
new pushes to a branch supersede in-flight iOS/Android builds.
Replace the boolean UNSHARDED list with a per-project shard-count map so
each suite can be sized independently. ui-components moves from 2 to 4
shards; browser and crypto-harness stay at 1 (unsharded); inputs uses
the default of 2.
Going from 2 to 4 shards increased wall-clock CI time — the per-shard
setup and orchestration overhead exceeded the test-runtime savings.
Drop ui-components from the SHARD_COUNTS map so it falls back to the
default of 2.
Three patterns dropped while preserving every assertion:

- cardDetails snapshot tests (4 sites): waitForTimeout(2000) replaced
  with expect(frame.getByLabel("Number")).toBeVisible() — auto-retries
  until the iframe is interactive instead of always paying 2s. Across
  5 browser projects per shard this was ~40s of pure idle per run.

- inputs/events (2 sites): waitForTimeout(800) replaced with
  expect.poll(() => data?.isValid).toBe(true). The tests already assert
  isValid: true so this is the same end-state, just resolved as soon as
  the SDK emits it.

- inputs/magswipe (2 sites): waitForTimeout(500) replaced with
  expect.poll(() => data?.encryptedCard?.swipe).toBe(true). Magswipe
  tests assert isValid: false (cvc missing) but swipe: true, so this is
  the right ready signal.

The downstream assertions on data.encryptedCard.* are unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants