Skip to content

fix(e2e): refuse to serve a web bundle that was not built for E2E - #6243

Open
shaurya703 wants to merge 1 commit into
tinyhumansai:mainfrom
shaurya703:fix/e2e-web-bundle-guard
Open

shaurya703 wants to merge 1 commit into
tinyhumansai:mainfrom
shaurya703:fix/e2e-web-bundle-guard

Conversation

@shaurya703

@shaurya703 shaurya703 commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • e2e-web-session.sh served whatever was in dist-web, so after a plain pnpm build:web every Playwright spec failed as though the product had regressed. It now refuses a bundle that test:e2e:web:build didn't produce, before starting anything.
  • e2e-web-build.sh marks the bundles it builds with dist-web/.openhuman-e2e-bundle, recording the VITE_* settings compiled in.
  • New scripts/__tests__/e2e-web-bundle-guard.test.mjs runs both real scripts against stubbed node / curl / pnpm / rustc / cargo.
  • The scripts lane now arms on both harness scripts and app/vite.config.*.

Problem

#5920: build:web sets none of the variables e2e-web-build.sh exports (VITE_BACKEND_URL, VITE_OPENHUMAN_E2E_DEFAULT_CORE_MODE, VITE_OPENHUMAN_CORE_RPC_URL, …). It produces a bundle pointed at the wrong backend with the E2E affordances compiled out, and exits 0. The session then served it without complaint.

Solution

  • The marker is written straight after pnpm run build:web inside e2e-web-build.sh, the only script that sets the E2E environment.
  • The session checks for it before launching the mock backend, and gives the same Run pnpm test:e2e:web:build first instruction as the core-binary check a few lines further down.
  • A marker rather than inspecting the bundle: grepping minified output for compiled-in values is brittle.
  • Staleness: the web target builds with emptyOutDir: true, so any later plain build:web removes the marker. One test pins that config, so the guarantee can't silently disappear.
  • CI: both lanes build through test:e2e:web:build. ci-full.yml stages with cp -a app/dist-web/. and restores with cp -a repo/app/dist-web app/, both of which keep the dotfile. Its artifact cache key hashes app/scripts/e2e-web-build.sh, so no bundle from before the marker is restored.
  • Kept to presence. The marker records values, but the session doesn't compare them (e.g. VITE_BACKEND_URL against E2E_MOCK_PORT); that would be a separate decision.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) — 5 cases: an unmarked bundle is refused before the mock backend starts; a marked one proceeds to the next precondition; the build writes the marker with the E2E settings; a later plain build leaves none; the Vite config still empties dist-web. Against main's scripts, the refusal, marker and plain-build cases fail; the other two pass by design.
  • Diff coverage ≥ 80% — N/A: shell and node --test changes only, outside the Vitest / cargo-llvm-cov diff-cover inputs. Both changed paths in the scripts execute in the new tests.
  • Coverage matrix updated — N/A: E2E harness change, no feature row added, removed or renamed
  • All affected feature IDs from the matrix are listed under ## Related — N/A: no feature behaviour changes
  • No new external network dependencies introduced — the tests use local stubs only
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: does not touch a release-cut surface
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

Validation:

  • node --test scripts/__tests__/e2e-web-bundle-guard.test.mjs — 5/5
  • node --test scripts/__tests__/*.test.mjs — the same 7 local failures as unmodified main, none introduced
  • node scripts/generate-test-inventory.mjs — 0 orphans
  • The same stubbed-script test pattern passes in CI's Scripts Self-Tests container on fix(scripts): fail the json_rpc_e2e suite when test enumeration fails #6242

Already red on main@1f58d88c5, so expected here too: Module Pin Gate, Rust Feature-Gate Smoke, and 4 module-pin registry tests in Scripts Self-Tests.

Related

Summary by CodeRabbit

  • Bug Fixes

    • Web end-to-end sessions now refuse bundles that were not produced with the required E2E build process, providing clearer guidance to run the correct command.
    • E2E bundle identification is reset when a standard web build replaces the output.
  • Tests

    • Added coverage for E2E bundle validation, marker creation and removal, build configuration, and startup safeguards.
    • CI now runs the relevant self-tests when E2E scripts or web build configuration changes.

`pnpm build:web` exits 0 with a bundle that points at the wrong backend
and has the E2E affordances compiled out. e2e-web-session.sh served
whatever was in dist-web, so after a plain build:web every Playwright
spec failed as though the product had regressed.

e2e-web-build.sh now writes dist-web/.openhuman-e2e-bundle after its
build, recording the VITE_* settings it compiled in. e2e-web-session.sh
refuses to start without the marker, before launching the mock backend,
and points at `pnpm test:e2e:web:build` — the same instruction the core
binary check a few lines below gives. Vite empties dist-web on every
build (emptyOutDir: true), so a plain build:web after an E2E build
removes the marker.

Both CI lanes build through test:e2e:web:build. ci-full.yml stages the
bundle with `cp -a app/dist-web/.`, which keeps the dotfile, and its
artifact cache key hashes e2e-web-build.sh, so no cached bundle from
before the marker is restored.

scripts/__tests__/e2e-web-bundle-guard.test.mjs runs the real scripts in
a temporary tree with node, curl, pnpm, rustc and cargo stubbed. It
covers an unmarked bundle refused before the mock backend starts, a
marked one proceeding to the next precondition, the build writing the
marker, a later plain build leaving none, and the Vite config still
emptying dist-web. The scripts lane now also arms on both harness
scripts and app/vite.config.*.

Closes tinyhumansai#5920
@shaurya703
shaurya703 requested review from a team and a lite review from Copilot September 13, 2026 07:55
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: f4bceb91-46d1-4d07-8a0f-fc3e892cdb52

📥 Commits

Reviewing files that changed from the base of the PR and between 1f58d88 and 9a7d28c.

📒 Files selected for processing (4)
  • .github/workflows/ci-lite.yml
  • app/scripts/e2e-web-build.sh
  • app/scripts/e2e-web-session.sh
  • scripts/__tests__/e2e-web-bundle-guard.test.mjs

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The web E2E build writes a bundle marker containing diagnostic settings. The session requires this marker before starting processes. New tests cover marker creation, refusal, removal, and Vite output behavior. CI now watches the related paths.

Changes

Web E2E bundle guard

Layer / File(s) Summary
Bundle marker flow
app/scripts/e2e-web-build.sh, app/scripts/e2e-web-session.sh
The build writes .openhuman-e2e-bundle with exported E2E settings. The session exits before starting processes when the marker is missing.
Bundle guard validation
scripts/__tests__/e2e-web-bundle-guard.test.mjs
Tests run the scripts with stubs and verify refusal, acceptance, marker contents, marker removal after a plain build, and the Vite output settings.
CI self-test wiring
.github/workflows/ci-lite.yml
The scripts self-test path filter includes the E2E scripts and Vite configuration.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: senamakel

Merge Risk: ⚪ Minimal · up to 9a7d2

The harness now fails early when a non-E2E bundle is present, with clear rebuild guidance. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preventing the E2E harness from serving web bundles that were not built for E2E.
Linked Issues check ✅ Passed Issue #5920 requires the E2E harness to reject a bundle from plain pnpm build:web and expose the required E2E build command. e2e-web-build.sh exports the required VITE_* settings, runs `build:we…
Out of Scope Changes check ✅ Passed The changes stay within issue #5920. The CI path update activates self-tests for the modified harness scripts and Vite configuration. The stub-based tests verify the guard and stale-marker prevention.…
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

A rabbit marks the bundle bright
Guards the harness day and night
Plain builds clear the sign
Tests check each branching line
CI watches paths in flight

Comment @coderabbitai help to get the list of available commands.

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking. Approving.

             $0.0092 · 130,794 in / 1,449 out · 11,464 cached (9%)  · openrouter/openai/text-embedding-3-small, deepseek/deepseek-v4-flash, z-ai/glm-5.2 · 488 embedded
critique:    $0.0027 · 54,394 in  / 532 out   · 0 cached (0%)       · deepseek/deepseek-v4-flash
security:    $0.0052 · 52,532 in  / 731 out   · 11,464 cached (22%) · deepseek/deepseek-v4-flash, z-ai/glm-5.2
tests:       $0.0008 · 16,222 in  / 112 out   · 0 cached (0%)       · deepseek/deepseek-v4-flash
description: $0.0004 · 7,646 in   / 74 out    · 0 cached (0%)       · deepseek/deepseek-v4-flash

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Sep 13, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a7d28cf05

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


function run(tree, script) {
const env = {
...process.env,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear E2E overrides from the inherited test environment

When the caller has a supported harness variable such as E2E_MOCK_PORT exported, spreading process.env passes that override into the real build script, but the marker test still hardcodes the default port 18473; for example, E2E_MOCK_PORT=29999 node --test scripts/__tests__/e2e-web-bundle-guard.test.mjs fails even though the generated marker is correct. Normalize or remove these E2E variables in the test environment so pnpm test:scripts does not depend on the invoking shell.

Useful? React with 👍 / 👎.

Copilot AI 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.

🔵 Needs a closer look

Three unresolved moderate issues affect marker correctness, rebuild behavior, and test determinism.

Pull request overview

Adds a marker-based guard preventing E2E from serving web bundles not built with E2E settings.

Changes:

  • Marks E2E-built web bundles.
  • Rejects unmarked bundles before session startup.
  • Adds regression tests and expands CI script triggers.
File summaries
File Summary Review findings
scripts/__tests__/e2e-web-bundle-guard.test.mjs Tests marker creation, refusal, and staleness. Moderate (1 vote): isolate inherited environment variables.
app/scripts/e2e-web-session.sh Validates the bundle marker before startup. Moderate (1 vote): use the workspace-qualified rebuild command.
app/scripts/e2e-web-build.sh Writes E2E bundle metadata. Moderate (1 vote): re-apply E2E variables after loading .env or conditionally write the marker.
.github/workflows/ci-lite.yml Expands scripts-lane triggers. No findings.
Review details

Suppressed comments (3)

app/scripts/e2e-web-build.sh:43

  • This marker is written unconditionally after the build, but load-dotenv.sh runs before pnpm run build:web and can override the E2E VITE_* exports from lines 18–23. A local .env containing (for example) VITE_BACKEND_URL can therefore produce a non-E2E bundle that still receives this marker, so the new session guard accepts exactly the class of bundle it is meant to reject. Re-apply the E2E build variables after loading .env and before pnpm run build:web (as app/scripts/e2e-build.sh:44-46 does), or otherwise make the marker conditional on the actual E2E configuration.
cat >"$APP_DIR/dist-web/.openhuman-e2e-bundle" <<MARKER
VITE_BACKEND_URL=${VITE_BACKEND_URL}
VITE_OPENHUMAN_TARGET=${VITE_OPENHUMAN_TARGET}
VITE_OPENHUMAN_E2E_DEFAULT_CORE_MODE=${VITE_OPENHUMAN_E2E_DEFAULT_CORE_MODE}
VITE_OPENHUMAN_E2E_RESTART_APP_AS_RELOAD=${VITE_OPENHUMAN_E2E_RESTART_APP_AS_RELOAD}
VITE_OPENHUMAN_CORE_RPC_URL=${VITE_OPENHUMAN_CORE_RPC_URL}
VITE_CHAT_ATTACHMENTS=${VITE_CHAT_ATTACHMENTS}

app/scripts/e2e-web-session.sh:140

  • When this script is invoked as documented from the repository root (bash app/scripts/e2e-web-session.sh), pnpm test:e2e:web:build resolves against the root package, which does not define that script; it is only in app/package.json. The remediation therefore fails instead of rebuilding the bundle. Please print the workspace-qualified command.
  echo "ERROR: $APP_DIR/dist-web was not built for E2E (no $(basename "$E2E_BUNDLE_MARKER")). Run pnpm test:e2e:web:build first; pnpm build:web alone omits the E2E backend and affordances." >&2

scripts/tests/e2e-web-bundle-guard.test.mjs:96

  • run inherits CARGO_BIN, E2E_MOCK_PORT, and OPENHUMAN_CORE_PORT from the test process. A developer or CI job with CARGO_BIN set can bypass the stub and run a real Cargo build, while E2E_MOCK_PORT can make the hard-coded 127.0.0.1:18473 assertion fail. Set these variables explicitly in the child environment (including CARGO_BIN to the stub path) so this self-test remains isolated and deterministic.
  const env = {
    ...process.env,
    PATH: `${tree.bin}:${process.env.PATH}`,
    RUST_HOST_TRIPLE: "test-triple",
    OPENHUMAN_WORKSPACE: path.join(tree.root, "workspace"),
    E2E_WEB_CORE_TARGET_DIR: path.join(tree.root, "target"),
  };
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pnpm run build:web produces a bundle the e2e harness cannot drive, and exits 0

2 participants