Skip to content

integration-test-env: add start (brings up the stack only, no tests)#2091

Merged
shrugs merged 5 commits into
mainfrom
fix/integration-test-env-up-down
May 20, 2026
Merged

integration-test-env: add start (brings up the stack only, no tests)#2091
shrugs merged 5 commits into
mainfrom
fix/integration-test-env-up-down

Conversation

@shrugs
Copy link
Copy Markdown
Member

@shrugs shrugs commented May 11, 2026

Summary

  • split the integration-test-env orchestrator into a reusable bring-up phase (lifecycle.ts) shared by two entrypoints
  • new pnpm -F @ensnode/integration-test-env start — bring up the full stack (incl. seed) and block until Ctrl+C, so pnpm test:integration can run from another terminal
  • the previous start script is renamed to start:ci (bring up + run tests + tear down); the root test:integration:ci alias is updated to match so CI behavior is unchanged
  • new --only flag: pnpm start --only devnet,ensrainbow restricts the subset of services brought up, so you can iterate on ensindexer/ensapi locally and have the rest auto-managed + auto-cleaned. valid services: devnet (incl. ensdb + seed), ensrainbow, ensindexer (incl. wait-for-indexing), ensapi
  • ensrainbow now runs at LOG_LEVEL=error so its info/warn chatter doesn't drown out the rest of the stack output
  • Ctrl+C during start exits 0 (user-initiated shutdown is not an error)

Why

Running the integration test env manually (docker compose up devnet ensrainbow + standalone ensapi) skips the orchestrator's seedDevnet phase, so resolver/primary-name records aren't on chain and 6 resolution integration tests fail. This adds a one-shot manual path that runs the same lifecycle CI does (seed included), without coupling it to a test run.

--only exists so when iterating on ensindexer or ensapi (running them yourself in dev mode), the supporting services come up and tear down with one command instead of separate docker compose invocations.

Testing

  • pnpm -F @ensnode/integration-test-env typecheck
  • pnpm lint
  • end-to-end run of pnpm start / Ctrl+C teardown not exercised locally (existing CI flow is unchanged because start:ci is identical to the old start modulo a one-line extracted call). Worth a manual spot-check before merge.

Notes for Reviewer (Optional)

  • lifecycle.ts is a mechanical extraction of phases 1–6 from orchestrator.ts — diff is large only because of the move; the only logic change is one await waitForHealth(...) URL now uses endpoints.ensapi instead of an inline string.
  • SIGINT/SIGTERM handlers are registered at module load in lifecycle.ts so both entrypoints share them automatically.
  • --only gates each phase via a should(service) check inside bringUp. ci.ts passes no options → full stack as before.

Checklist

  • This PR does not change runtime behavior or semantics
  • This PR is low-risk and safe to review quickly

🤖 Generated with Claude Code

@shrugs shrugs requested a review from a team as a code owner May 11, 2026 20:25
Copilot AI review requested due to automatic review settings May 11, 2026 20:25
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 11, 2026

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

Project Deployment Actions Updated (UTC)
enskit-react-example.ensnode.io Ready Ready Preview, Comment May 20, 2026 7:39pm
3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped May 20, 2026 7:39pm
ensnode.io Skipped Skipped May 20, 2026 7:39pm
ensrainbow.io Skipped Skipped May 20, 2026 7:39pm

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 11, 2026

⚠️ No Changeset found

Latest commit: af38882

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

Review Change Stack

Warning

Rate limit exceeded

@shrugs has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 56 minutes and 28 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fde3de59-6805-403f-b04c-658f1adbaaff

📥 Commits

Reviewing files that changed from the base of the PR and between 8f0fd1f and af38882.

📒 Files selected for processing (4)
  • package.json
  • packages/integration-test-env/README.md
  • packages/integration-test-env/package.json
  • packages/integration-test-env/src/lifecycle.ts
📝 Walkthrough

Walkthrough

Refactors the integration-test orchestrator into an exported lifecycle module with bringUp/runIntegrationTests/cleanup APIs, adds CI (start:ci) and local (start) entrypoints, updates package scripts to use the CI entrypoint, and updates README usage to document the lifecycle and entrypoints.

Changes

Lifecycle Refactoring and Entrypoint Split

Layer / File(s) Summary
Lifecycle module exports and foundation
packages/integration-test-env/src/lifecycle.ts
Module docs updated; added exports endpoints, ALL_SERVICES, Service type, parseOnly(); cleanup() promoted to exported; signal handlers/logging adjusted to lifecycle.
Core orchestration and test execution
packages/integration-test-env/src/lifecycle.ts
Added bringUp(options) implementing conditional 6-phase startup (ENSDb/devnet seed, ENSRainbow, ENSIndexer with polling, ENSApi) and runIntegrationTests() which runs pnpm test:integration with ENSNODE_URL=endpoints.ensapi.
CI entrypoint (start:ci)
packages/integration-test-env/src/ci.ts
New CI entrypoint calls bringUp(), triggers runIntegrationTests() (non-blocking), then cleanup(), and exits with non-zero on failure.
Local start entrypoint (start)
packages/integration-test-env/src/start.ts
New CLI parses strict --only filter, calls bringUp({ only }), prints enabled endpoints, and blocks until SIGINT/SIGTERM to trigger cleanup.
Script wiring and package updates
packages/integration-test-env/package.json, package.json
integration-test-env start now runs tsx src/start.ts; root test:integration:ci now invokes @ensnode/integration-test-env start:ci.
README usage and lifecycle docs
packages/integration-test-env/README.md
"How It Works" rewritten into a 6-phase lifecycle; Usage split into "Bring up the stack (manual)" for pnpm start and "Full CI pipeline" for pnpm start:ci.

Sequence Diagram

sequenceDiagram
  participant CI as CI Entrypoint (ci.ts)
  participant Lifecycle as lifecycle.ts
  participant Services as Services (DB/Devnet/ENSRainbow/ENSIndexer/ENSApi)
  participant Tests as pnpm test:integration
  participant Cleanup as cleanup()

  CI->>Lifecycle: bringUp()
  Lifecycle->>Services: start phases (DB/devnet seed, ENSRainbow, ENSIndexer, ENSApi)
  Lifecycle->>Tests: runIntegrationTests() (ENSNODE_URL=endpoints.ensapi)
  Tests->>Cleanup: signal completion
  CI->>Cleanup: cleanup()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • namehash/ensnode#1729: Modifies integration-test CI orchestration and related entrypoints; overlaps with new ci.ts/test:integration:ci wiring.
  • namehash/ensnode#1845: Also refactors integration-test bring-up/orchestration; related to lifecycle/orchestrator changes.

Poem

🐰
I hopped through code to split the start,
CI hums while local dev can cart,
Lifecycle tidy, scripts aligned,
Tests run smooth, endpoints signed —
A carrot for each passing start.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR changes relate to integration-test infrastructure, but the linked issue #39 concerns missing accounts in snapshots and Accounts query ordering—unrelated to the orchestrator refactor. Remove the unrelated linked issue #39 or link the PR to the correct issue describing integration-test-env orchestrator improvements.
Out of Scope Changes check ⚠️ Warning All changes directly support the PR objectives of refactoring the orchestrator and adding start/start:ci entrypoints with --only filtering—no out-of-scope changes detected, but the linked issue mismatch suggests the wrong issue was referenced. Verify the correct GitHub issue number for this integration-test-env orchestrator refactor and update the PR link accordingly.
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a new start command that brings up the stack without running tests.
Description check ✅ Passed The description covers all template sections with clear summaries of changes, reasoning, testing performed, and reviewer notes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/integration-test-env-up-down

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the integration test environment orchestrator into a shared lifecycle module so the stack bring-up (including devnet seeding) can be reused by both CI and a new manual “bring up and wait” workflow.

Changes:

  • Extracts stack bring-up/cleanup/test execution logic into src/lifecycle.ts shared by both entrypoints.
  • Adds a new start entrypoint that brings up the full stack and blocks until Ctrl+C, and renames the prior behavior to start:ci.
  • Updates root test:integration:ci to call the new start:ci script to keep CI behavior consistent.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/integration-test-env/src/start.ts New manual entrypoint to bring up the stack and wait (no tests).
packages/integration-test-env/src/orchestrator.ts Simplified CI entrypoint now delegating to lifecycle.ts.
packages/integration-test-env/src/lifecycle.ts New shared bring-up/cleanup/signal-handling and integration test runner.
packages/integration-test-env/README.md Documents the split between manual start and CI start:ci flows.
packages/integration-test-env/package.json Renames start behavior and adds start:ci script.
package.json Updates test:integration:ci to call start:ci.
Comments suppressed due to low confidence (2)

packages/integration-test-env/src/lifecycle.ts:245

  • The JSDoc for bringUp() says it "runs cleanup() and rethrows" on failure, but bringUp() doesn't wrap its phases in a try/catch/finally and doesn't call cleanup() itself (callers do). Please update the comment to match the actual behavior, or add error-handling inside bringUp() if that's the intended contract.
    packages/integration-test-env/src/lifecycle.ts:117
  • handleShutdown() always exits with code 1 after SIGINT/SIGTERM. For the new manual pnpm start flow (Ctrl+C as a normal teardown), this will report failure to the shell/CI wrappers. Consider exiting 0 for SIGINT (or when CI is not set), and reserve exit code 1 for actual failures/forced termination.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/integration-test-env/README.md Outdated
Comment thread packages/integration-test-env/package.json
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 11, 2026

Greptile Summary

This PR splits the monolithic orchestrator.ts into a shared lifecycle.ts module consumed by two entrypoints: ci.ts (bring-up + tests + teardown, the old CI flow) and start.ts (bring-up + block until Ctrl+C, the new manual developer flow). A --only flag lets users selectively start subsets of the stack.

  • lifecycle.ts extracts phases 1–6 from the old orchestrator, exposing bringUp(), cleanup(), runIntegrationTests(), parseOnly(), and endpoints for shared use.
  • start.ts adds the new pnpm start entrypoint that parks the process until SIGINT/SIGTERM triggers lifecycle cleanup; ci.ts preserves the existing CI flow under the renamed start:ci script.
  • package.json (root) is updated so test:integration:ci calls start:ci instead of the renamed start.

Confidence Score: 5/5

This is a mechanical extraction and renaming with no new runtime logic — the CI path through ci.ts is functionally identical to the old orchestrator.ts main().

The bring-up phases, cleanup ordering, abort-flag pattern, and health-check logic are all unchanged from the original orchestrator. The new start.ts correctly delegates to the same lifecycle module. The only substantive change — the signal handler exit code moving from 1 to 0 — was already flagged in a prior review cycle. No new correctness issues were found.

lifecycle.ts is the highest-leverage file; a regression there would affect both entrypoints. The signal-handler exit-code behaviour already has an open comment from the previous review round.

Important Files Changed

Filename Overview
packages/integration-test-env/src/lifecycle.ts Core lifecycle module extracted from orchestrator.ts; exports bringUp(), cleanup(), runIntegrationTests(), parseOnly(), and endpoints. Signal handlers now unconditionally call process.exit(0), which was already noted by a prior reviewer.
packages/integration-test-env/src/ci.ts New CI entrypoint replacing orchestrator.ts; delegates bring-up and teardown to lifecycle.ts and runs integration tests in between. runIntegrationTests() is called synchronously (correct, uses execaSync) with error propagation through async main().catch().
packages/integration-test-env/src/start.ts New manual-flow entrypoint; parses --only CLI arg, calls bringUp(), logs endpoints, then parks on a never-resolving Promise. Clean, no logic issues.
packages/integration-test-env/package.json Adds start:ci script (CI=1 tsx src/ci.ts) and retargets start to tsx src/start.ts. Straightforward rename, no issues.
package.json Updates test:integration:ci alias from start to start:ci to match the script rename. Correct change, CI behaviour preserved.
packages/integration-test-env/README.md Documentation updated to describe the two entrypoints and the --only flag. Accurate and clear.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([pnpm start]) --> S[start.ts]
    B([pnpm start:ci]) --> C[ci.ts]

    S --> parseArgs[parseCliArgs\n--only flag]
    parseArgs --> bringUp

    C --> bringUp

    subgraph lifecycle.ts
        bringUp{bringUp\nonly?}
        bringUp -->|should devnet| D1[Start ENSDb + Devnet\ndocker-compose]
        D1 --> D2[Seed devnet]
        bringUp -->|should ensrainbow| D3[Start ENSRainbow\npnpm entrypoint]
        D3 --> D4[waitForHealth /ready]
        bringUp -->|should ensindexer| D5[Start ENSIndexer\npnpm start]
        D5 --> D6[waitForHealth /health]
        D6 --> D7[pollIndexingStatus]
        bringUp -->|should ensapi| D8[Start ENSApi\npnpm start]
        D8 --> D9[waitForHealth /health]
    end

    bringUp --> S2[Block on\nnever-resolving Promise]
    bringUp --> C2[runIntegrationTests\nexecaSync pnpm test:integration]
    C2 --> C3[cleanup]
    C3 --> exit0([exit 0])

    SIG([SIGINT / SIGTERM]) --> handler[handleShutdown\nprocess.exit 0]
    handler --> cleanup2[cleanup]

    S2 -->|Ctrl+C| SIG
Loading

Reviews (5): Last reviewed commit: "fix: bot notes (README ports + --only do..." | Re-trigger Greptile

Comment thread packages/integration-test-env/src/lifecycle.ts
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 11, 2026 20:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 11, 2026 20:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 11, 2026 20:44 Inactive
Comment thread packages/integration-test-env/README.md Outdated
Comment thread packages/integration-test-env/src/lifecycle.ts Outdated
shrugs and others added 3 commits May 18, 2026 11:25
Splits the integration-test-env orchestrator into a reusable bring-up
phase (`lifecycle.ts`) shared by two entrypoints:

- `pnpm start` — bring up the full stack (incl. seed) and block until
  Ctrl+C, so `pnpm test:integration` can run from another terminal.
- `pnpm start:ci` — renamed from `start`; bring up + run tests + tear
  down. CI flow is unchanged via the `test:integration:ci` root alias.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The file no longer orchestrates — lifecycle.ts does. ci.ts is now the
CI entrypoint that wires bringUp + runIntegrationTests + cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

packages/integration-test-env/src/lifecycle.ts:140

  • Because lifecycle.ts is shared by start:ci, this handler now exits 0 for SIGTERM/SIGINT during the CI test flow too. A termination before the integration tests finish (for example a timeout or service-manager SIGTERM) can therefore be reported as a successful test:integration:ci run; keep the zero exit behavior scoped to the manual start entrypoint or distinguish SIGINT from CI termination.
    packages/integration-test-env/src/lifecycle.ts:275
  • This exported function's documentation says it runs cleanup on failure, but the implementation does not catch errors or call cleanup; cleanup currently happens only in the entrypoint catch blocks. This mismatch can mislead future callers into leaking started containers/processes if they rely on the documented contract.

Comment thread packages/integration-test-env/package.json
Comment thread packages/integration-test-env/README.md
Comment thread packages/integration-test-env/README.md Outdated
Comment thread packages/integration-test-env/src/start.ts
Comment thread packages/integration-test-env/README.md Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/integration-test-env/src/lifecycle.ts (1)

134-144: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't report every SIGTERM shutdown as success.

SIGTERM is also what CI runners and supervisors use for cancellation/timeouts. Exiting 0 here can make an aborted start:ci run look green. If you want local Ctrl+C to be clean, keep SIGINT at 0 but preserve a non-zero or signal-derived exit for SIGTERM.

Suggested fix
-async function handleShutdown() {
+async function handleShutdown(signal: NodeJS.Signals) {
   if (cleanupInProgress) return;
   cleanupInProgress = true;
   log("Shutting down...");
   await cleanup();
-  // SIGINT/SIGTERM is a user-initiated shutdown, not an error — exit 0.
-  process.exit(0);
+  process.exit(signal === "SIGINT" ? 0 : 128 + 15);
 }
 
-process.on("SIGINT", handleShutdown);
-process.on("SIGTERM", handleShutdown);
+process.on("SIGINT", () => void handleShutdown("SIGINT"));
+process.on("SIGTERM", () => void handleShutdown("SIGTERM"));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/integration-test-env/src/lifecycle.ts` around lines 134 - 144, The
current handleShutdown always calls process.exit(0) which hides CI/supervisor
cancellations; change the shutdown wiring so SIGINT still exits 0 but SIGTERM
yields a non-zero/signal-derived exit code: update handleShutdown to accept an
optional signal name (e.g., function handleShutdown(signal?: string)) and after
await cleanup() call process.exit(0) when signal === "SIGINT" but
process.exit(1) or process.exit(128 + <signalNumber>) for other signals (e.g.,
"SIGTERM"); register handlers with process.on("SIGINT", () =>
handleShutdown("SIGINT")) and process.on("SIGTERM", () =>
handleShutdown("SIGTERM")) while preserving cleanupInProgress and the cleanup()
call.
♻️ Duplicate comments (2)
packages/integration-test-env/README.md (1)

39-39: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the incorrect port list.

This line still lists incorrect ports. Port 8000 does not exist in the stack, and PostgreSQL port 5433 is missing. The correct required ports are: 8545, 3223, 42069, 4334, 5433.

📝 Proposed fix
-Brings up the full stack and blocks until Ctrl+C. The required ports must be available (8545, 8000, 3223, 42069, 4334). Once it's up, run integration tests from another terminal:
+Brings up the full stack and blocks until Ctrl+C. The required ports must be available (8545, 3223, 42069, 4334, 5433). Once it's up, run integration tests from another terminal:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/integration-test-env/README.md` at line 39, Update the port list in
the README line that starts "Brings up the full stack and blocks until Ctrl+C."
to show the correct required ports: 8545, 3223, 42069, 4334, 5433 (remove 8000
and add 5433). Edit that sentence in packages/integration-test-env/README.md so
the parentheses contain the corrected port set.
packages/integration-test-env/src/lifecycle.ts (1)

275-383: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

bringUp() still leaks partial startup on failure.

After phase 1/3/4 acquires resources, any later throw here rejects without tearing them down. That leaves detached processes and compose services running on startup errors, and Line 275 currently promises the opposite. Wrap the phase body in try/catch, call cleanup(), then rethrow so the exported lifecycle contract matches its behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/integration-test-env/src/lifecycle.ts` around lines 275 - 383,
bringUp() can leak started resources if a later phase throws; wrap the main
phase sequence inside a try/catch in the bringUp function, and in the catch call
await cleanup() (which will stop composeEnvironment and spawned services like
those started via spawnService and any started in phases
"devnet"/"ensrainbow"/"ensindexer"/"ensapi"), then rethrow the original error so
the function's contract holds; ensure you reference and use the existing
cleanup() helper and do not swallow the error when rethrowing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/integration-test-env/package.json`:
- Line 10: The package.json "start:ci" script exports CI=1 but that env var is
never used; either remove "CI=1" from the "start:ci" entry in package.json, or
update the code to consume it (e.g., check process.env.CI in src/ci.ts or
src/lifecycle.ts and gate CI-specific behavior such as tighter timeouts, quieter
logging, or alternate resource allocation). Ensure any new behavior is clearly
named and documented in the script and that process.env.CI is parsed as a
boolean where used.

In `@packages/integration-test-env/README.md`:
- Around line 35-43: Add documentation for the new --only flag in the section
that explains how to run the stack with pnpm start: state that you can pass
--only with a comma-separated list of services (valid values: devnet,
ensrainbow, ensindexer, ensapi), show a brief usage example like pnpm start
--only devnet,ensrainbow, and mention that this starts only the listed services
instead of the full stack so ports for the omitted services are not required.

In `@packages/integration-test-env/src/ci.ts`:
- Line 24: runIntegrationTests() is being invoked without awaiting, causing
cleanup() and process.exit(0) to run before tests finish; change the invocation
to await runIntegrationTests() and ensure it's inside an async context (or use
.then/.catch) so the process only calls cleanup() and process.exit(0) after
runIntegrationTests() resolves; refer to runIntegrationTests(), cleanup(), and
process.exit to locate and update the call site and surrounding control flow
(use try/finally or promise chaining to guarantee cleanup runs after the awaited
test run).

In `@packages/integration-test-env/src/lifecycle.ts`:
- Around line 59-77: Add zod to packages/integration-test-env package.json
dependencies, then replace the manual validation in parseOnly with a zod schema:
create a Zod schema that accepts a comma-separated string,
splits/trims/filter(Boolean) and validates each item is one of the allowed
values from ALL_SERVICES, then call zod.parse(...) to validate the incoming
value; use the parsed array to construct and return a Set<Service> (removing the
unchecked "as Service[]" cast) and ensure any validation errors bubble up as zod
errors from parseOnly.

---

Outside diff comments:
In `@packages/integration-test-env/src/lifecycle.ts`:
- Around line 134-144: The current handleShutdown always calls process.exit(0)
which hides CI/supervisor cancellations; change the shutdown wiring so SIGINT
still exits 0 but SIGTERM yields a non-zero/signal-derived exit code: update
handleShutdown to accept an optional signal name (e.g., function
handleShutdown(signal?: string)) and after await cleanup() call process.exit(0)
when signal === "SIGINT" but process.exit(1) or process.exit(128 +
<signalNumber>) for other signals (e.g., "SIGTERM"); register handlers with
process.on("SIGINT", () => handleShutdown("SIGINT")) and process.on("SIGTERM",
() => handleShutdown("SIGTERM")) while preserving cleanupInProgress and the
cleanup() call.

---

Duplicate comments:
In `@packages/integration-test-env/README.md`:
- Line 39: Update the port list in the README line that starts "Brings up the
full stack and blocks until Ctrl+C." to show the correct required ports: 8545,
3223, 42069, 4334, 5433 (remove 8000 and add 5433). Edit that sentence in
packages/integration-test-env/README.md so the parentheses contain the corrected
port set.

In `@packages/integration-test-env/src/lifecycle.ts`:
- Around line 275-383: bringUp() can leak started resources if a later phase
throws; wrap the main phase sequence inside a try/catch in the bringUp function,
and in the catch call await cleanup() (which will stop composeEnvironment and
spawned services like those started via spawnService and any started in phases
"devnet"/"ensrainbow"/"ensindexer"/"ensapi"), then rethrow the original error so
the function's contract holds; ensure you reference and use the existing
cleanup() helper and do not swallow the error when rethrowing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 39dbe864-f7b1-49df-b27d-6acdfbf99110

📥 Commits

Reviewing files that changed from the base of the PR and between 26dc2da and 8f0fd1f.

📒 Files selected for processing (6)
  • package.json
  • packages/integration-test-env/README.md
  • packages/integration-test-env/package.json
  • packages/integration-test-env/src/ci.ts
  • packages/integration-test-env/src/lifecycle.ts
  • packages/integration-test-env/src/start.ts

Comment thread packages/integration-test-env/package.json
Comment thread packages/integration-test-env/README.md
Comment thread packages/integration-test-env/src/ci.ts
Comment thread packages/integration-test-env/src/lifecycle.ts
…env-up-down

# Conflicts:
#	packages/integration-test-env/src/lifecycle.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 19:39
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 20, 2026 19:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 20, 2026 19:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 20, 2026 19:39 Inactive
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented May 20, 2026

@greptile review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

packages/integration-test-env/src/lifecycle.ts:141

  • handleShutdown now exits with code 0 for both SIGINT and SIGTERM. That means the CI entrypoint (start:ci) will also exit 0 on SIGTERM, which can mask unexpected terminations (timeouts, supervisor restarts, etc.) as success. Consider exiting non-zero for SIGTERM (or making the exit code configurable per entrypoint) while keeping SIGINT exit 0 for the interactive start flow.
    packages/integration-test-env/src/lifecycle.ts:284
  • --only currently allows starting services without their required dependencies (e.g. ensapi without ensindexer/devnet, or ensindexer without ensrainbow/devnet). In these cases bringUp() still passes localhost URLs (ENSDb/ENSRainbow) and will typically fail in confusing ways. Consider validating the selected set upfront (enforce dependency closure or throw a clear error explaining what else must be selected / already running).

Copy link
Copy Markdown
Member

@sevenzing sevenzing left a comment

Choose a reason for hiding this comment

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

🚀 🌔

@shrugs shrugs merged commit 0086b7b into main May 20, 2026
20 checks passed
@shrugs shrugs deleted the fix/integration-test-env-up-down branch May 20, 2026 19:48
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.

3 participants