Skip to content

Copy jam filest to dist/, load generated services from dist/#103

Merged
DrEverr merged 5 commits intomainfrom
maso-auto-load-services
Jan 30, 2026
Merged

Copy jam filest to dist/, load generated services from dist/#103
DrEverr merged 5 commits intomainfrom
maso-auto-load-services

Conversation

@DrEverr
Copy link
Member

@DrEverr DrEverr commented Jan 29, 2026

Resolve: #98

  • discover *.jam files and copy them to root/dist/ under name {service.name}.jam
  • added method to retrive all services blobs from dist/folder
  • unified building services between build and deploy command
  • moved generating of genesis.json to dist/ (instead of root)

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

The PR refactors build and deploy workflows to centralize service artifact management: it introduces loadServices() in the SDK to consolidate service build output generation, adds copyJamToDist() to automatically copy generated .jam files to a centralized dist/ folder, extracts Docker invocation into callDockerBuild(), and simplifies CLI commands by removing intermediate JAM file discovery steps.

Changes

Cohort / File(s) Summary
Build Command Refactoring
bin/cli/src/commands/build-command.ts, bin/cli/src/commands/build-command.test.ts
Extracted Docker build logic into dedicated callDockerBuild() function; created new buildService() orchestrator that resolves paths, invokes Docker build, locates generated .jam file, copies it to dist/ via copyJamToDist(), writes build logs, and returns relative path to distribution file. Removed extensive per-service log handling and state mutations. Updated all test imports and invocations to use callDockerBuild().
Deploy Command Simplification
bin/cli/src/commands/deploy-command.ts
Replaced multi-step JAM file discovery and deployment config handling with single loadServices() call that yields service build outputs directly; removed intermediate per-service ID assignment and generateServiceOutput() invocations; updated imports to reflect SDK changes (removed generateServiceOutput, getJamFiles, getServiceConfigs, loadBuildConfig; added generateGenesis, loadServices).
SDK File Utilities
packages/jammin-sdk/utils/file-utils.ts
Changed getJamFiles() return type from Map<string, number> to string[] removing mtime metadata; added error handling for directory scanning; introduced new copyJamToDist() function to copy .jam files to dist/ folder with service-based naming.
SDK Service Output Generation
packages/jammin-sdk/utils/generate-service-output.ts
Added new loadServices() function that loads build config, generates service outputs with ID assignment and collision avoidance; updated ServiceBuildOutput.info type with explicit ServiceAccountInfo import; added imports for loadBuildConfig and path utilities.

Sequence Diagrams

sequenceDiagram
    participant CLI as Build Command
    participant Docker as callDockerBuild
    participant FS as Filesystem
    participant SDK as jammin-sdk
    
    CLI->>+SDK: buildService(service, projectRoot)
    SDK->>+Docker: callDockerBuild(service, projectRoot)
    Docker->>Docker: Execute Docker build
    Docker-->>-SDK: Return build output
    SDK->>+FS: Locate generated .jam file
    FS-->>-SDK: Return .jam file path
    SDK->>+SDK: copyJamToDist(jamPath, serviceName, projectRoot)
    SDK->>+FS: Create dist/ if needed
    FS-->>-SDK: dist/ exists
    SDK->>+FS: Copy .jam to dist/{serviceName}.jam
    FS-->>-SDK: Copy complete
    SDK->>+FS: Write build output log via Bun
    FS-->>-SDK: Log written
    SDK-->>-CLI: Return relative path to dist file
Loading
sequenceDiagram
    participant CLI as Deploy Command
    participant SDK as jammin-sdk
    participant Config as Build Config
    participant FS as Filesystem
    
    CLI->>+SDK: loadServices(projectRoot)
    SDK->>+Config: loadBuildConfig(projectRoot)
    Config-->>-SDK: Return config with services
    SDK->>+FS: Locate .jam files for each service
    FS-->>-SDK: Return .jam file paths
    SDK->>SDK: Assign IDs (reuse configured or auto-increment)
    SDK->>+SDK: generateServiceOutput for each service
    SDK-->>-SDK: Return ServiceBuildOutput array
    SDK-->>-CLI: Return service build outputs
    CLI->>+SDK: generateGenesis(buildOutputs)
    SDK-->>-CLI: Return genesis data
    CLI->>+FS: saveStateFile(genesisData)
    FS-->>-CLI: State file saved
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #54 – Directly related to the refactoring of buildService into callDockerBuild and creation of a new buildService orchestrator, modifying the same build-command functions and test structure.
  • PR #82 – Directly related to the introduction of loadServices(), service deployment config changes, and migration of genesis generation logic to consume SDK-based service outputs.
  • PR #102 – Related to the movement of configuration and utility functions into jammin-sdk and the introduction of service-config utilities that support the new build/deploy flow.

Suggested reviewers

  • tomusdrw
  • skoszuta
  • mateuszsikora
🚥 Pre-merge checks | ✅ 2 | ❌ 3
❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR addresses most requirements from #98: copies .jam files to dist/, adds copyJamToDist utility, and enables loading services from dist/. However, cleanup of stale artifacts and .gitignore updates appear unimplemented. Implement stale .jam file cleanup when services are removed from config, and add dist/ to .gitignore files.
Out of Scope Changes check ⚠️ Warning The PR introduces refactoring of build-command.ts and deploy-command.ts with function renaming and reorganization that extends beyond the stated objective of copying jam files to dist/. Separate function refactoring (buildService/callDockerBuild renaming) from the core jam file copying feature, or clarify these changes as necessary improvements for unifying the build/deploy workflows.
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% 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 mentions copying jam files to dist/ and loading services from dist/, which aligns with the main changes but contains a typo ('filest' instead of 'files').
Description check ✅ Passed The PR description directly relates to the changeset, mentioning jam file discovery, copying to dist/, service loading, and genesis.json generation.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch maso-auto-load-services

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

@DrEverr DrEverr marked this pull request as ready for review January 29, 2026 17:05
@DrEverr DrEverr requested a review from skoszuta January 29, 2026 17:05
Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
bin/cli/src/commands/build-command.ts (1)

1-1: Selecting the first .jam file is nondeterministic; pick the newest (or expected) artifact.

getJamFiles() can return multiple artifacts; array order is filesystem-dependent. This can silently copy a stale .jam when multiple files exist. Consider choosing the most recently modified file (or matching an expected filename).

🛠️ Suggested fix (pick newest by mtime)
-import { mkdir } from "node:fs/promises";
+import { mkdir, stat } from "node:fs/promises";
@@
-  const files = await getJamFiles(servicePath);
-
-  const file = files.length > 0 ? files[0] : undefined;
+  const files = await getJamFiles(servicePath);
+  const filesWithMtime = await Promise.all(
+    files.map(async (filePath) => ({
+      filePath,
+      mtimeMs: (await stat(filePath)).mtimeMs,
+    })),
+  );
+  const file = filesWithMtime.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.filePath;

Also applies to: 52-59

🤖 Fix all issues with AI agents
In `@bin/cli/src/commands/build-command.test.ts`:
- Around line 135-137: The test currently invokes callDockerBuild twice without
awaiting, causing race/false-positive issues; fix it by calling callDockerBuild
once (e.g., const p = callDockerBuild(service, "/test/project")) and use await
expect(p).rejects.toThrow("Build failed for service 'failing-service'") (or
await expect(p).rejects.toThrow() then with message) so the rejection assertion
is awaited and the promise is not executed twice; reference callDockerBuild and
the failing-service assertion in the test.

In `@bin/cli/src/commands/deploy-command.ts`:
- Line 48: Fix the typo in the user-facing log call: update the p.log.message
invocation that currently prints "🎁 Genereted file: genesis.json" to use the
correct spelling "Generated" (i.e., "🎁 Generated file: genesis.json") so the
CLI shows a correct message; locate the call to p.log.message in
deploy-command.ts and change the string accordingly.
- Line 41: loadServices is currently called without context and loads artifacts
for every configured service, causing single-service deploys to fail; modify the
call site in deploy-command.ts to pass the list of services you actually built
(the selected service names), update loadServices' signature (and any callers)
to accept an optional whitelist of service names, and change its implementation
(in generate-service-output.ts / the utils that produce service outputs) to
filter artifacts by that whitelist so loadServices only validates/returns
outputs for the built services.

In `@packages/jammin-sdk/utils/generate-service-output.ts`:
- Around line 16-18: Update the top docstring that currently reads "Load a
service from the dist/ directory by name" to reflect that the module/function
loads multiple services (plural); edit the comment in
packages/jammin-sdk/utils/generate-service-output.ts to something like "Load
services from the dist/ directory by name (supports loading multiple services)"
so it accurately documents the behavior of the module/function that enumerates
and imports multiple service outputs.
- Around line 19-23: loadServices accepts a projectRoot but still calls
loadBuildConfig() which uses process.cwd(), so the build config may be read from
the wrong directory; update loadServices to resolve the config relative to the
provided projectRoot by calling loadBuildConfig with the projectRoot (or first
resolve a config path with projectRoot and pass that into loadBuildConfig), and
ensure any subsequent artifact resolution (e.g., serviceDeployConfigs and
usedIds logic) uses paths derived from projectRoot rather than the current
working directory; refer to the loadServices function and the loadBuildConfig
call to locate where to pass/derive the projectRoot.
🧹 Nitpick comments (1)
bin/cli/src/commands/build-command.ts (1)

20-43: Add JSDoc for the exported build helpers.

📝 Suggested additions
+/**
+ * Run the Docker build for a single service and return combined output.
+ */
 export async function callDockerBuild(service: ServiceConfig, projectRoot: string): Promise<string> {
@@
 }
 
+/**
+ * Build a service, copy the resulting .jam into dist/, and return the dist-relative path.
+ */
 export async function buildService(service: ServiceConfig, projectRoot: string): Promise<string> {
As per coding guidelines Use JSDoc comments for public APIs (functions, classes, exported types).

@DrEverr DrEverr requested a review from tomusdrw January 30, 2026 07:20
@DrEverr DrEverr merged commit b1c27fd into main Jan 30, 2026
8 checks passed
@DrEverr DrEverr deleted the maso-auto-load-services branch January 30, 2026 13:05
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.

Auto-copy service.jam artifacts to dist folder during build

2 participants