Skip to content

perf(deploy): build in parallel with test, deploy only assembles and pushes#3812

Merged
cixzhang merged 1 commit into
facebook:mainfrom
Han5991:ci/parallel-deploy-build
Jul 12, 2026
Merged

perf(deploy): build in parallel with test, deploy only assembles and pushes#3812
cixzhang merged 1 commit into
facebook:mainfrom
Han5991:ci/parallel-deploy-build

Conversation

@Han5991

@Han5991 Han5991 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

The deploy pipeline was fully sequential: test (~5–7min, including its own full build for the typecheck gates), then a deploy job that rebuilt everything again from scratch (~4–7min depending on Next.js cache) before pushing to gh-pages. Measured over the last six successful main runs, that put ~9.6–14.2min of execution (avg ~12min) between a merge and the site going live — plus queue time in the pages-deploy concurrency group — and every main push burned two full site builds back to back.

This PR runs the build in parallel with test and turns deploy into a thin assemble-and-push step. Merge-to-live drops to ~7.5min (measured, see below), and since wall time now converges to max(test, build) the per-run variance mostly disappears.

Measured baseline — recent successful main runs (job execution time)

run test deploy (rebuild) sequential total
29137545397 6.8min 7.3min ~14.2min
29137637571 6.9min 4.5min ~11.5min
29139809260 5.4min 4.2min ~9.6min
29140333697 6.5min 7.0min ~13.7min
29140525096 4.5min 7.3min ~11.9min
29140874043 6.6min 4.4min ~11.1min

The deploy job's spread (4.2–7.3min) is the redundant rebuild — the exact work this PR moves into the parallel build job. On top of execution time, run totals include concurrency-group queue wait (e.g. run 29140874043: 11.1min execution but 17.2min created→finished), and 3 of the 10 most recent main deploy runs were cancelled as pending in the pages-deploy group. Shorter runs shrink that churn too.

Changes

  • build (new, parallel with test): full package build + Storybook + Sandbox — identical steps to what deploy used to run, including the pinned no-restore-keys Next.js cache (feat: XDS un-prefix migration — bare names canonical, XDS* compat aliases #2941 rationale unchanged). Uploads three intra-run artifacts (storybook dist, sandbox out, landing-page CSS), retention 1 day.
  • deploy (needs: [test, build]): downloads the artifacts, preserves pr/ + reports/ from gh-pages, assembles the deploy dir, pushes via peaceiris — no checkout of a build tree, no Node setup, no rebuild. test gates the push exactly as before; it just no longer serializes the build.
  • Shorter runs also mean less pending-run churn in the pages-deploy concurrency group on a busy main.

The artifact round-trip for storybook dist/ and sandbox out/ is the same mechanism ci.yml already uses for every PR preview.

Test plan

Validated end-to-end by dispatching this exact workflow on a fork (run, fork Pages disabled so nothing was published):

job started duration
test 10:27:00 6.6min
build 10:27:00 7.2min
deploy 10:34:15 14s
  • test and build started simultaneously and ran in parallel (both 10:27:00)
  • deploy waited for both, then took 14s (download → preserve → assemble → push)
  • Total wall time 7m29s vs ~12min average (up to ~14.2min) for the sequential shape
  • Resulting gh-pages tree verified: storybook/, sandbox/, assets/ (all 3 CSS files), index.html, latest, .nojekyll — expected layout, artifact contents intact
  • YAML parses; no leftover build-tree references in the deploy job (grep-verified)

@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview, Comment Jul 11, 2026 12:31pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 11, 2026
…pushes

The deploy pipeline was sequential: test (~6min, including its own full
build for the typecheck gates), then a deploy job that rebuilt
everything again from scratch (~7min) before pushing. A merged PR took
~13min to reach the live site, and every main push burned two full
builds back to back.

Split the build out of the deploy job and run it in parallel with test:

- build: full package build + Storybook + Sandbox (with the pinned
  Next.js cache, unchanged), uploads the site as three artifacts
  (storybook, sandbox, landing-page CSS), retention 1 day.
- deploy: needs [test, build] — downloads the artifacts, preserves
  pr/ and reports/ from gh-pages, assembles the deploy dir, pushes.
  No Node setup, no rebuild.

test still gates the push exactly as before; it just no longer
serializes the build. Merge-to-live drops to ~max(test, build) + ~1min
of assembly (~8min), and the shorter runs also reduce pending-run
churn in the pages-deploy concurrency group.

The artifact round-trip for storybook dist/ and sandbox out/ is the
same mechanism ci.yml already uses for every PR preview.
@Han5991
Han5991 force-pushed the ci/parallel-deploy-build branch from 57e468d to 7948bbd Compare July 11, 2026 12:28
@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge labels Jul 11, 2026

@cixzhang cixzhang left a comment

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.

Reviewed the full diff. Clean parallelization of the deploy pipeline: test and build now run in parallel and deploy only assembles downloaded artifacts + pushes — the test gate is preserved (needs: [test, build], push still requires test success), artifact round-trip paths are correctly rewired, least-privilege split (build is contents:read), and it mirrors the artifact mechanism ci.yml already uses. Well-evidenced with measured baselines and a fork validation run. Nice improvement.

cixzhang added a commit that referenced this pull request Jul 12, 2026
review-clear never actually cleared: it resolved the PR from workflow_run.head_sha, but for a workflow_run fired by a pull_request_review-triggered workflow that SHA (and the payload branch) point at main, not the PR — and pull_requests is empty for forks. So it always logged 'No PR resolved' and did nothing (e.g. #3812 stayed pending after approval).

The triggering run's own head_branch IS correct even for forks (e.g. ci/parallel-deploy-build). Resolve the open PR by matching that branch (head=OWNER:branch, with a scan-by-ref fallback) instead of the useless head_sha.

@cixzhang cixzhang left a comment

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.

Re-affirming approval (verifying the fixed auto-clear path).

@github-actions github-actions Bot removed the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Jul 12, 2026
@cixzhang
cixzhang merged commit 2aef3d8 into facebook:main Jul 12, 2026
22 checks passed
@Han5991
Han5991 deleted the ci/parallel-deploy-build branch July 12, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants