Skip to content

chore: update Dockerfile and CI configuration for Node 20, enhance pa…#112

Merged
miguelangaranocurrents merged 7 commits intomainfrom
feat/esm-cjs-imports
May 7, 2026
Merged

chore: update Dockerfile and CI configuration for Node 20, enhance pa…#112
miguelangaranocurrents merged 7 commits intomainfrom
feat/esm-cjs-imports

Conversation

@agoldis
Copy link
Copy Markdown
Contributor

@agoldis agoldis commented Mar 25, 2026

…ckage structure

  • Updated Dockerfile to use Node 20 for both build and runtime stages.
  • Modified GitHub Actions workflow to support testing across Node versions 20.x, 22.x, and 24.x.
  • Enhanced package.json to include new module exports and updated dependencies.
  • Introduced tsconfig.cjs.json for CommonJS builds and adjusted TypeScript configurations.
  • Added new scripts for CJS package JSON generation and updated test scripts for improved coverage.
  • Refactored source code structure, including the introduction of an API entry point and integration tests for ESM and CJS compatibility.

Summary by cubic

Move to a dual ESM/CJS build with a clean programmatic API, keep the CLI stdio entrypoint, and adopt Node 20 across Docker and CI. Adds clear failure handling when CURRENTS_API_KEY is missing.

  • New Features

    • Ship dual ESM/CJS builds with an exports map and a new startMcpServer entry point; CLI stdio stays in src/index.ts, server/tool registration moves to src/server.ts; src/api.ts exposes programmatic exports; tools now use direct zod schemas.
    • Integration tests for ESM import, CJS require and dynamic import, CLI bin/npx via npm pack, and published tarball resolution via import "@currents/mcp"; tests build first, increase CLI test timeout, and mock CURRENTS_API_KEY for startup.
    • Error handling: throw on missing CURRENTS_API_KEY (MISSING_CURRENTS_API_KEY_MESSAGE); CLI logs a short guidance message without a stack trace.
    • Platform/deps: Docker and CI on Node 20; CI matrix 20.x/22.x/24.x; upgrade @modelcontextprotocol/sdk to ^1.28.0.
  • Migration

    • Requires Node >=20 (engines updated).
    • Programmatic usage:
      • ESM: import { startMcpServer } from @currents/mcp
      • CJS: const { startMcpServer } = require(@currents/mcp) or import(@currents/mcp)

Written for commit da86eed. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Added multi-version Node.js testing (versions 20.x, 22.x, 24.x).
    • Enabled dual ESM/CJS package builds with proper export maps.
  • Tests

    • Added integration tests for CLI tarball packaging and npx execution.
    • Added tests for module resolution across ESM/CJS import scenarios.
  • Chores

    • Updated Docker base image to Node 20 Alpine.
    • Enhanced TypeScript configuration for modern module resolution.

agoldis added 2 commits March 25, 2026 11:41
…ckage structure

- Updated Dockerfile to use Node 20 for both build and runtime stages.
- Modified GitHub Actions workflow to support testing across Node versions 20.x, 22.x, and 24.x.
- Enhanced package.json to include new module exports and updated dependencies.
- Introduced tsconfig.cjs.json for CommonJS builds and adjusted TypeScript configurations.
- Added new scripts for CJS package JSON generation and updated test scripts for improved coverage.
- Refactored source code structure, including the introduction of an API entry point and integration tests for ESM and CJS compatibility.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 14 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="mcp-server/src/server.ts">

<violation number="1" location="mcp-server/src/server.ts:44">
P2: Fail fast when the API key is missing; logging and continuing starts a server that can’t successfully call the Currents API.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread mcp-server/src/server.ts Outdated
agoldis and others added 5 commits March 25, 2026 12:14
- Updated integration test to always run for package consumers, removing the dual build check.
- Reformatted action descriptions in the server registration to improve readability and maintain consistency across tools.
…ion test timeout

- Changed action tools to directly use the zodSchema instead of its shape for schema definition.
- Enhanced the integration test timeout for the packaged CLI to ensure reliability during execution.
…SM test

- Updated the GitHub Actions workflow to clarify test coverage for workspace ESM/CJS and added a new test for npm pack and import behavior.
- Introduced new integration tests for packaged CLI functionality, ensuring proper execution of the `bin` field and `npx` behavior.
- Added a test for resolving the package name `@currents/mcp` using `package.json` exports after installation from a tarball.
- Included a fixture to validate the ESM entry point and its functionality in a consumer project context.
…ntegration tests

- Enhanced error logging in the main entry point to provide clearer guidance when the CURRENTS_API_KEY is not set.
- Updated the server startup logic to throw an error if the CURRENTS_API_KEY is missing, improving robustness.
- Added a default value for CURRENTS_API_KEY in the environment module to prevent empty strings.
- Modified integration tests to include a mock environment variable for CURRENTS_API_KEY, ensuring proper test execution.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR refactors the MCP server package to support dual ESM/CommonJS builds with a separate entry point, extracts server initialization into a reusable startMcpServer() function, normalizes all tool schema exports, and adds comprehensive integration tests for package distribution and module interoperability.

Changes

Dual ESM/CJS Package Refactor with Server Extraction

Layer / File(s) Summary
Build Configuration
mcp-server/tsconfig.json, mcp-server/tsconfig.cjs.json
TypeScript target updated to ES2023 with NodeNext module resolution; new CommonJS build config outputs to build/cjs with CommonJS target and Node10 resolution.
Package Entry Points & Build Scripts
mcp-server/package.json
Package exports updated with main/module/types pointing to built artifacts; new exports map for import/require/types; build script now runs CJS TypeScript compilation and writes CJS package.json.
Build Helper Scripts
mcp-server/scripts/write-cjs-package-json.mjs
New ESM script creates build/cjs/package.json with {"type":"commonjs"} to mark CJS output directory.
Infrastructure Configuration
Dockerfile, .github/workflows/test.yml
Dockerfile pinned to node:20-alpine and updated to copy tsconfig.cjs.json and scripts/; GitHub Actions test job configured with Node version matrix (20.x, 22.x, 24.x).
Environment & API
mcp-server/src/lib/env.ts, mcp-server/src/api.ts
CURRENTS_API_KEY uses nullish coalescing and trim; new MISSING_CURRENTS_API_KEY_MESSAGE constant; api.ts re-exports startMcpServer as public entry point.
Server Initialization
mcp-server/src/server.ts
New file creates McpServer instance, registers ~30 tool handlers across Actions, Projects, Runs, Specs, Tests, Errors, and Webhooks categories; exports startMcpServer() function validating API key, connecting stdio transport, and keeping process alive.
CLI Entry Refactoring
mcp-server/src/index.ts
Simplified to call startMcpServer() instead of inline initialization; centralized error handling detects missing-key error and logs specific remediation message; ~278 lines of inline setup removed.
Tool Schema Normalization
mcp-server/src/tools/*/\*.ts
All ~30 tool definitions across Actions, Projects, Runs, Specs, Tests, Errors, and Webhooks updated to export full zodSchema instead of zodSchema.shape.
Test Fixtures
mcp-server/test/fixtures/consumer-*.{cjs,mjs}
New fixture scripts for ESM (consumer-esm.mjs), CommonJS require (consumer-cjs.cjs), dynamic import in CJS (consumer-cjs-dynamic-import.cjs), and published package ESM (consumer-published-esm.mjs).
Integration Tests
mcp-server/src/cli-bin.integration.test.ts, mcp-server/src/package-environments.integration.test.ts, mcp-server/src/package-published-esm.integration.test.ts
Three integration test suites: CLI tarball verification via npm pack and npx; ESM/CJS interop validation via real Node child processes; published package testing via npm pack + npm install + fixture execution.
Webhook Schema Tests
mcp-server/src/tools/webhooks/webhooks.test.ts
Schema assertions updated to access Zod properties via shape.* instead of top-level, reflecting change from zodSchema.shape to zodSchema exports.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The PR title is partially related to the changeset—it mentions Dockerfile and CI configuration updates (which are present), but uses an ellipsis ('enhance pa…') that obscures the main objectives and leaves the description incomplete, making it unclear what the primary focus or enhancement is. Complete the title to clearly state the primary objective, such as 'chore: update Dockerfile and CI for Node 20, add ESM/CJS dual packaging and integration tests' to fully convey the scope of changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/esm-cjs-imports

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

Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (4)
mcp-server/src/tools/actions/create-action.ts (1)

93-99: 💤 Low value

action and matcher can use Zod-inferred types instead of any.

The Zod schemas already precisely define these shapes; the loose types in CreateActionRequest only weaken compile-time safety.

♻️ Proposed refactor
-interface CreateActionRequest {
-  name: string;
-  description?: string | null;
-  action: any[];
-  matcher: any;
-  expiresAfter?: string | null;
-}
+type CreateActionRequest = Omit<z.infer<typeof zodSchema>, 'projectId'>;

Or, if keeping the explicit interface:

 interface CreateActionRequest {
   name: string;
   description?: string | null;
-  action: any[];
-  matcher: any;
+  action: z.infer<typeof RuleAction>[];
+  matcher: z.infer<typeof RuleMatcher>;
   expiresAfter?: string | null;
 }
🤖 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 `@mcp-server/src/tools/actions/create-action.ts` around lines 93 - 99, The
CreateActionRequest interface uses any for action and matcher which weakens type
safety; replace those any types with Zod-inferred types derived from the
existing Zod schemas (e.g., use z.infer<typeof ActionSchema> and z.infer<typeof
MatcherSchema> or the actual schema variable names present in this file) so that
CreateActionRequest.action and CreateActionRequest.matcher reflect the precise
shapes validated by the schemas; update imports/usage accordingly and run
TypeScript checks to ensure no further type errors.
mcp-server/src/package-published-esm.integration.test.ts (1)

59-86: 💤 Low value

Temp directories are not cleaned up after test.

The test creates packDir and installDir via mkdtempSync but never removes them. While the OS eventually cleans tmpdir, repeated test runs accumulate stale directories. Consider adding cleanup in an afterAll or afterEach hook.

Additionally, packTarball is duplicated between this file and cli-bin.integration.test.ts. A shared test utility would reduce maintenance burden.

🤖 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 `@mcp-server/src/package-published-esm.integration.test.ts` around lines 59 -
86, This test leaks temporary directories created by mkdtempSync into packDir
and installDir; add cleanup by tracking those paths and removing them in an
afterEach or afterAll hook (use fs.rmSync or fs.rmdirSync with recursive/force
options) so each test run deletes packDir and installDir, and refactor the
duplicated packTarball implementation into a shared test utility module and
update both this test and cli-bin.integration.test.ts to import and use that
single packTarball helper.
mcp-server/src/package-environments.integration.test.ts (1)

33-60: 💤 Low value

Consider adding skipIf guard for consistency with other integration tests.

The CLI and published-tarball integration tests use describe.skipIf(!existsSync(buildIndex)) to skip gracefully when build/ is missing. This suite relies solely on the assumption that test:run builds first, but running vitest directly (e.g., during development) will produce confusing errors instead of a skip.

Proposed fix
+const buildIndex = path.join(root, "build", "index.js");
+
-describe("package consumers (Node ESM, CJS require, CJS dynamic import)", () => {
+describe.skipIf(!existsSync(buildIndex))("package consumers (Node ESM, CJS require, CJS dynamic import)", () => {

Also add existsSync to the import from node:fs.

🤖 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 `@mcp-server/src/package-environments.integration.test.ts` around lines 33 -
60, This test suite should skip when the build output is missing to match other
integration tests: add an existsSync import from "node:fs" and wrap the existing
describe("package consumers ...") with describe.skipIf(!existsSync(buildIndex))
(using the existing buildIndex variable), so the tests gracefully skip when
build/ is not present instead of erroring when running vitest directly.
mcp-server/package.json (1)

29-29: 💤 Low value

chmod in build script won't work on Windows.

The chmod 755 build/index.js command will fail on Windows systems without a Unix compatibility layer. This is acceptable if Windows developers use WSL or if CI handles the primary build, but it could cause issues for Windows-native development.

Consider wrapping in a cross-platform solution or documenting the requirement.

🤖 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 `@mcp-server/package.json` at line 29, The build script currently runs "chmod
755 build/index.js" which fails on Windows; modify the "build" npm script
(and/or update scripts/write-cjs-package-json.mjs) to set executable bits in a
cross-platform way—either remove the chmod and set permissions inside the Node
script using fs.chmod when supported, or use a cross-platform tool (e.g.,
chmod-cli or shelljs) and call that from the "build" script so Windows builds
won't error; ensure the change still runs tsc && tsc -p tsconfig.cjs.json &&
node ./scripts/write-cjs-package-json.mjs as before.
🤖 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 `@Dockerfile`:
- Line 5: Update the Dockerfile base image to a supported Node LTS version:
replace the FROM node:20-alpine AS build reference with FROM node:22-alpine AS
build (or FROM node:24-alpine AS build for a longer-lived choice); ensure any
other Dockerfiles referencing node:20-alpine or node:21-alpine (the "21-21"
mention) are updated consistently, and run the build/CI to confirm no runtime or
dependency issues require minor tweaks after the Node upgrade.

---

Nitpick comments:
In `@mcp-server/package.json`:
- Line 29: The build script currently runs "chmod 755 build/index.js" which
fails on Windows; modify the "build" npm script (and/or update
scripts/write-cjs-package-json.mjs) to set executable bits in a cross-platform
way—either remove the chmod and set permissions inside the Node script using
fs.chmod when supported, or use a cross-platform tool (e.g., chmod-cli or
shelljs) and call that from the "build" script so Windows builds won't error;
ensure the change still runs tsc && tsc -p tsconfig.cjs.json && node
./scripts/write-cjs-package-json.mjs as before.

In `@mcp-server/src/package-environments.integration.test.ts`:
- Around line 33-60: This test suite should skip when the build output is
missing to match other integration tests: add an existsSync import from
"node:fs" and wrap the existing describe("package consumers ...") with
describe.skipIf(!existsSync(buildIndex)) (using the existing buildIndex
variable), so the tests gracefully skip when build/ is not present instead of
erroring when running vitest directly.

In `@mcp-server/src/package-published-esm.integration.test.ts`:
- Around line 59-86: This test leaks temporary directories created by
mkdtempSync into packDir and installDir; add cleanup by tracking those paths and
removing them in an afterEach or afterAll hook (use fs.rmSync or fs.rmdirSync
with recursive/force options) so each test run deletes packDir and installDir,
and refactor the duplicated packTarball implementation into a shared test
utility module and update both this test and cli-bin.integration.test.ts to
import and use that single packTarball helper.

In `@mcp-server/src/tools/actions/create-action.ts`:
- Around line 93-99: The CreateActionRequest interface uses any for action and
matcher which weakens type safety; replace those any types with Zod-inferred
types derived from the existing Zod schemas (e.g., use z.infer<typeof
ActionSchema> and z.infer<typeof MatcherSchema> or the actual schema variable
names present in this file) so that CreateActionRequest.action and
CreateActionRequest.matcher reflect the precise shapes validated by the schemas;
update imports/usage accordingly and run TypeScript checks to ensure no further
type errors.
🪄 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: CHILL

Plan: Pro

Run ID: 3fb21cc5-8922-4dca-b1b2-45a553c37c57

📥 Commits

Reviewing files that changed from the base of the PR and between c6a529f and b124391.

⛔ Files ignored due to path filters (1)
  • mcp-server/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (49)
  • .github/workflows/test.yml
  • Dockerfile
  • mcp-server/package.json
  • mcp-server/scripts/write-cjs-package-json.mjs
  • mcp-server/src/api.ts
  • mcp-server/src/cli-bin.integration.test.ts
  • mcp-server/src/index.ts
  • mcp-server/src/lib/env.ts
  • mcp-server/src/package-environments.integration.test.ts
  • mcp-server/src/package-published-esm.integration.test.ts
  • mcp-server/src/server.ts
  • mcp-server/src/tools/actions/create-action.ts
  • mcp-server/src/tools/actions/delete-action.ts
  • mcp-server/src/tools/actions/disable-action.ts
  • mcp-server/src/tools/actions/enable-action.ts
  • mcp-server/src/tools/actions/get-action.ts
  • mcp-server/src/tools/actions/get-affected-test-executions-by-action.ts
  • mcp-server/src/tools/actions/get-affected-test-executions.ts
  • mcp-server/src/tools/actions/list-actions.ts
  • mcp-server/src/tools/actions/list-affected-tests.ts
  • mcp-server/src/tools/actions/update-action.ts
  • mcp-server/src/tools/errors/get-errors-explorer.ts
  • mcp-server/src/tools/projects/get-project-insights.ts
  • mcp-server/src/tools/projects/get-project.ts
  • mcp-server/src/tools/projects/get-projects.ts
  • mcp-server/src/tools/runs/cancel-run-github-ci.ts
  • mcp-server/src/tools/runs/cancel-run.ts
  • mcp-server/src/tools/runs/delete-run.ts
  • mcp-server/src/tools/runs/find-run.ts
  • mcp-server/src/tools/runs/get-run.ts
  • mcp-server/src/tools/runs/get-runs.ts
  • mcp-server/src/tools/runs/reset-run.ts
  • mcp-server/src/tools/specs/get-spec-files-performance.ts
  • mcp-server/src/tools/specs/get-spec-instances.ts
  • mcp-server/src/tools/tests/get-test-results.ts
  • mcp-server/src/tools/tests/get-tests-performance.ts
  • mcp-server/src/tools/tests/get-tests-signature.ts
  • mcp-server/src/tools/webhooks/create-webhook.ts
  • mcp-server/src/tools/webhooks/delete-webhook.ts
  • mcp-server/src/tools/webhooks/get-webhook.ts
  • mcp-server/src/tools/webhooks/list-webhooks.ts
  • mcp-server/src/tools/webhooks/update-webhook.ts
  • mcp-server/src/tools/webhooks/webhooks.test.ts
  • mcp-server/test/fixtures/consumer-cjs-dynamic-import.cjs
  • mcp-server/test/fixtures/consumer-cjs.cjs
  • mcp-server/test/fixtures/consumer-esm.mjs
  • mcp-server/test/fixtures/consumer-published-esm.mjs
  • mcp-server/tsconfig.cjs.json
  • mcp-server/tsconfig.json

Comment thread Dockerfile
@miguelangaranocurrents miguelangaranocurrents merged commit d95d3b9 into main May 7, 2026
5 checks passed
@miguelangaranocurrents miguelangaranocurrents deleted the feat/esm-cjs-imports branch May 7, 2026 16: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.

3 participants