Skip to content

perf(e2e): template workspace and scope setup instead of spawning bit - #10672

Merged
davidfirst merged 4 commits into
masterfrom
perf-e2e-template-workspace-setup
Aug 28, 2026
Merged

perf(e2e): template workspace and scope setup instead of spawning bit#10672
davidfirst merged 4 commits into
masterfrom
perf-e2e-template-workspace-setup

Conversation

@davidfirst

@davidfirst davidfirst commented Aug 28, 2026

Copy link
Copy Markdown
Member

bit init, bit init --bare and bit remote add each write only a handful of small files, but every call pays the full bit bootstrap to do it. Across the suite that is ~3,340 calls per run (1,243 workspace inits, 814 bare inits, 1,286 remote-adds) — the largest block of process spin-up that isn't testing anything.

Instead of hardcoding a fixture that would rot the moment bit init changes, the first setup call in each mocha process runs the real command into a template dir; every later call copies that dir and rewrites the only values bit init derives from the target path — the workspace name in workspace.jsonc, and the local scope name <basename>-local-<random>. The bytes always come from the bit init of the version under test. bit remote add has no dir to copy, but it only sets remotes[<remote scope name>] = <url> in scope.json, which is written directly.

Measured on CI (controlled A/B)

Same branch, same test set, same 40-node packing — the control arm was produced by a temporary commit setting BIT_E2E_NO_SETUP_TEMPLATE=1 in the e2e_test job, since comparing across branches has burned us before. Sum of the "Run e2e tests" step across all 40 nodes:

arm machine-min median node
real commands (control) 374.5 9.19m
templated 345.1 8.54m

~29 machine-min / 7.9% per run, median node -7.1%.

Locally, per file: deprecate.e2e.ts 140s -> 128s with bit spawns 162 -> 124, and tag-harmony.e2e.ts 342s -> 305s.

Fidelity

Verified the templated output is byte-identical to the real commands: 12 entries for a workspace, 4 for a bare scope, and scope.json identical after remote add.

These paths keep running the real command: initGit (a real .git moves the scope to .git/bit and suppresses AGENTS.md), interactive/generatePackageJson (different branches in create-consumer), --global remotes, and any case where scope.json isn't where expected — most importantly before bit has auto-created a scope, which git-worktree.e2e.ts exercises deliberately by using addRemoteScope as the first bit command in a worktree.

BIT_E2E_NO_SETUP_TEMPLATE=1 restores the real commands everywhere, for A/B measurement or to rule the templates out when a test misbehaves.

bit init, bit init --bare and bit remote add write a handful of small files but
pay the full bit bootstrap to do it, ~3,300 times per suite run. Run the real
command once per mocha process into a template dir, then copy it and rewrite the
few values init derives from the target path. Output is byte-identical.

BIT_E2E_NO_SETUP_TEMPLATE=1 restores the real commands.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Speed up E2E setup with lazy workspace and scope templates

✨ Enhancement 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Cache real Bit initialization output once per Mocha process for reusable E2E setup templates.
• Rewrite path-derived names and local remotes while preserving byte-identical setup files.
• Fall back to real commands for unsupported scenarios and opt-out debugging.
Diagram

graph TD
  A["Setup request"] --> B{"Fast path eligible?"}
  B -->|Init| C["Lazy real init"] --> D["Template cache"] --> E["Copy and rewrite"] --> F["Test workspace"]
  B -->|Remote| G["Update scope JSON"] --> F
  B -->|Fallback| H["Real Bit CLI"] --> F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Static checked-in fixtures
  • ➕ Avoid even the first real Bit bootstrap per Mocha process.
  • ➕ Simplify runtime template creation and caching.
  • ➖ Can silently drift whenever Bit initialization output changes.
  • ➖ Requires manual fixture maintenance across versions and initialization modes.
2. Call initialization internals directly
  • ➕ Avoid process startup while reusing Bit's implementation.
  • ➕ Eliminate template copying and path-derived rewrites.
  • ➖ Couples E2E helpers to internal APIs and bootstrap assumptions.
  • ➖ May not reproduce CLI wiring, configuration, and filesystem side effects faithfully.
3. Persistent Bit setup daemon
  • ➕ Amortize bootstrap across setup commands without duplicating command semantics.
  • ➕ Could accelerate additional E2E commands beyond initialization.
  • ➖ Introduces substantial lifecycle, isolation, and concurrency complexity.
  • ➖ Creates a broader architectural change for a narrowly scoped bottleneck.

Recommendation: Keep the lazy, real-command-generated templates. They preserve compatibility with the tested Bit version, remove most process startup cost, isolate caches per Mocha process, and retain explicit CLI fallbacks for behaviorally distinct scenarios; static fixtures and internal API calls carry greater drift or coupling risk.

Files changed (2) +185 / -5

Enhancement (1) +47 / -5
e2e-scope-helper.tsRoute common E2E setup through templated fast paths +47/-5

Route common E2E setup through templated fast paths

• Workspace and bare-scope initialization now lazily generate and copy process-local templates instead of repeatedly spawning Bit. Local file remotes are written directly when scope metadata exists, while Git, interactive, package-generation, global, missing-scope, and opt-out cases retain the real commands.

components/legacy/e2e-helper/e2e-scope-helper.ts

Other (1) +138 / -0
e2e-setup-template.tsAdd reusable Bit initialization template utilities +138/-0

Add reusable Bit initialization template utilities

• Introduces process-isolated lazy template creation, copying, and path-derived workspace and scope name rewrites. It also mirrors local file-remote persistence in scope.json and exposes BIT_E2E_NO_SETUP_TEMPLATE as a diagnostic fallback switch.

components/legacy/e2e-helper/e2e-setup-template.ts

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Action required

1. Format SCOPE_JSON_CANDIDATES declaration 📘 Rule violation ⚙ Maintainability ⭐ New
Description
Prettier reformats the newly added single-line array declaration under the repository's 120-column
configuration. Consequently, npm run prettier:check reports this changed file as requiring
formatting.
Code

components/legacy/e2e-helper/e2e-setup-template.ts[34]

+const SCOPE_JSON_CANDIDATES = [path.join('.bit', 'scope.json'), path.join('.git', 'bit', 'scope.json'), 'scope.json'];
Evidence
Compliance rule 4 requires changed files to pass npm run prettier:check. The added declaration at
line 34 exceeds the configured formatting width and is included by the repository's Prettier check.

CLAUDE.md: Code Must Conform to Prettier Formatting
components/legacy/e2e-helper/e2e-setup-template.ts[34-34]
.prettierrc[1-4]
package.json[33-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added `SCOPE_JSON_CANDIDATES` declaration does not match the repository's Prettier output and causes `npm run prettier:check` to fail.

## Issue Context
The repository configures Prettier with a 120-column print width and checks TypeScript files under `components`.

## Fix Focus Areas
- components/legacy/e2e-helper/e2e-setup-template.ts[34-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Format ensureBareScopeTemplate call 📘 Rule violation ⚙ Maintainability ⭐ New
Description
Prettier splits the newly added ensureBareScopeTemplate assignment rather than retaining this
overlong single line. This makes npm run prettier:check fail for the modified helper file.
Code

components/legacy/e2e-helper/e2e-scope-helper.ts[129]

+    const template = ensureBareScopeTemplate(this.scopes.e2eDir, (cwd) => this.command.runCmd('bit init --bare', cwd));
Evidence
Compliance rule 4 requires changed files to pass npm run prettier:check. The added call at line
129 exceeds the configured formatting width and is included by the repository's Prettier check.

CLAUDE.md: Code Must Conform to Prettier Formatting
components/legacy/e2e-helper/e2e-scope-helper.ts[129-129]
.prettierrc[1-4]
package.json[33-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added `ensureBareScopeTemplate` assignment does not match the repository's Prettier output and causes `npm run prettier:check` to fail.

## Issue Context
The repository configures Prettier with a 120-column print width and checks TypeScript files under `components`.

## Fix Focus Areas
- components/legacy/e2e-helper/e2e-scope-helper.ts[129-129]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Optimization disabled in CI 🐞 Bug ➹ Performance
Description
The primary e2e_test job sets BIT_E2E_NO_SETUP_TEMPLATE to a truthy value, so
isSetupTemplateEnabled() always returns false and every setup continues spawning Bit. This defeats
the PR's performance goal for both PR validation and the daily master canary until the temporary
control-arm setting is removed.
Code

.circleci/config.yml[976]

+      BIT_E2E_NO_SETUP_TEMPLATE: "1"
Evidence
The new environment variable is set on the main CircleCI e2e job, while the new helper enables
templating only when that variable is absent. The workflow invokes this same job for PR branches and
the daily master canary.

.circleci/config.yml[960-979]
components/legacy/e2e-helper/e2e-setup-template.ts[24-28]
.circleci/config.yml[1555-1569]
.circleci/config.yml[1626-1630]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CircleCI `e2e_test` job sets `BIT_E2E_NO_SETUP_TEMPLATE=1`, which disables the setup templates and preserves all of the process-spawn overhead this PR is intended to remove.
## Issue Context
`isSetupTemplateEnabled()` returns false whenever this environment variable is truthy. The affected job is used for PR e2e validation and the daily master canary, and the adjacent comment explicitly marks this setting for removal before merge.
## Fix Focus Areas
- .circleci/config.yml[973-976]
- components/legacy/e2e-helper/e2e-setup-template.ts[24-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 608da5c ⚖️ Balanced

Results up to commit 81298bb


🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)


Action required
1. Optimization disabled in CI 🐞 Bug ➹ Performance
Description
The primary e2e_test job sets BIT_E2E_NO_SETUP_TEMPLATE to a truthy value, so
isSetupTemplateEnabled() always returns false and every setup continues spawning Bit. This defeats
the PR's performance goal for both PR validation and the daily master canary until the temporary
control-arm setting is removed.
Code

.circleci/config.yml[976]

+      BIT_E2E_NO_SETUP_TEMPLATE: "1"
Evidence
The new environment variable is set on the main CircleCI e2e job, while the new helper enables
templating only when that variable is absent. The workflow invokes this same job for PR branches and
the daily master canary.

.circleci/config.yml[960-979]
components/legacy/e2e-helper/e2e-setup-template.ts[24-28]
.circleci/config.yml[1555-1569]
.circleci/config.yml[1626-1630]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CircleCI `e2e_test` job sets `BIT_E2E_NO_SETUP_TEMPLATE=1`, which disables the setup templates and preserves all of the process-spawn overhead this PR is intended to remove.

## Issue Context
`isSetupTemplateEnabled()` returns false whenever this environment variable is truthy. The affected job is used for PR e2e validation and the daily master canary, and the adjacent comment explicitly marks this setting for removal before merge.

## Fix Focus Areas
- .circleci/config.yml[973-976]
- components/legacy/e2e-helper/e2e-setup-template.ts[24-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 6aa208a


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Qodo Logo

Comment thread .circleci/config.yml Outdated
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 81298bb

Comment thread components/legacy/e2e-helper/e2e-setup-template.ts
Comment thread components/legacy/e2e-helper/e2e-scope-helper.ts
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 608da5c

@davidfirst
davidfirst enabled auto-merge (squash) August 28, 2026 20:42
@davidfirst
davidfirst merged commit 791e48f into master Aug 28, 2026
14 checks passed
@davidfirst
davidfirst deleted the perf-e2e-template-workspace-setup branch August 28, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants