Skip to content

Add new deployment flow (direct)#55

Merged
Fermionic-Lyu merged 3 commits into
masterfrom
new-deployment-flow
Apr 16, 2026
Merged

Add new deployment flow (direct)#55
Fermionic-Lyu merged 3 commits into
masterfrom
new-deployment-flow

Conversation

@Fermionic-Lyu

@Fermionic-Lyu Fermionic-Lyu commented Apr 15, 2026

Copy link
Copy Markdown
Member

Note

Add direct file-based deployment flow to replace zip uploads

  • Adds a deployDirect flow in deployment.ts that collects files, hashes them (SHA-1), creates a session via POST /api/deployments/direct, and uploads files concurrently before calling start.
  • Falls back to the legacy zip-based flow when the backend returns 404 (via DirectDeploymentUnsupportedError) or the backend version is below 2.0.6.
  • Adds shouldExcludeDeploymentPath to consistently exclude .env*, node_modules, .git, .next, dist, build, .insforge, .DS_Store, and *.log files from both direct and legacy flows.
  • Remote mode now returns executable bash/Node instructions for direct upload instead of zip instructions on supported backends.
  • Upload concurrency defaults to 8 and is capped at 32, configurable via INSFORGE_DEPLOY_UPLOAD_CONCURRENCY.
  • Behavioral Change: parseCreateDeploymentResponse now uses strict zod validation and throws on invalid response shapes instead of silently accepting them.

Macroscope summarized 6387e7e.

Summary by CodeRabbit

  • New Features

    • Direct deployment to compatible backends with parallel file uploads, automatic fallback to legacy zip when unsupported, and a generated CLI/script to perform local direct uploads and start deployments.
    • Deployment status output now adapts based on backend capability and cloud vs self-hosted endpoints.
  • Chores

    • Package bumped to 1.2.10; shared-schemas dependency updated.
    • Expanded deployment exclusions to include .insforge and .env; upload concurrency configurable (env var, default 8).

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

Walkthrough

Adds a backend-version–gated direct-deployment flow (min backend 2.0.6) with per-file SHA1+size computation, expanded exclusions, parallel bounded-concurrency direct uploads (with zip fallback on 404), centralizes exclusions, extends tool registration context with backendVersion, and bumps package version and a shared-schemas dependency.

Changes

Cohort / File(s) Summary
Package metadata
package.json
Package version bumped 1.2.91.2.10. Dependency @insforge/shared-schemas bumped 1.1.471.1.49.
Deployment module
src/shared/tools/deployment.ts
Replaced custom type-guard with schema parsing; added direct-deployment capability detection (min 2.0.6); compute per-file SHA1+sizes, centralized exclusions (adds .insforge and *.env*), create direct session, upload files via parallel bounded-concurrency PUT /api/deployments/:id/files/:fileId/content (env INSFORGE_DEPLOY_UPLOAD_CONCURRENCY, default 8, cap 32), validate backend file entries, POST /start, and fallback to legacy zip flow on 404; adjusted start messaging.
Tool registration & types
src/shared/tools/index.ts, src/shared/tools/types.ts
RegisterContext now includes backendVersion: string; minor formatting/refactors in fetchBackendVersion and error construction in registration logic.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

  • feat: fetch-sdk-docs tool #25: Modifies shared tools/registration machinery and backend version gating—closely related to RegisterContext and registration logic changes.
  • Add create-deployment tool #22: Alters deployment tooling and create-deployment flow—directly related to the new direct-deployment implementation.

Suggested reviewers

  • tonychang04

Poem

🐇 I counted hashes in the night,

small files gleaming, queued just right,
with bounded hops and a clever tune,
uploads dance beneath the moon,
a rabbit cheers: deploys take flight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% 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 'Add new deployment flow (direct)' accurately captures the main change: introduction of a direct file upload deployment flow as an alternative to the legacy zip-based approach.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 new-deployment-flow

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

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package.json`:
- Line 3: Update the "version" field in package.json (the version key currently
set to "1.2.10-dev.3") to the next minor prerelease line for this new feature —
e.g., "1.3.0-dev.1" (or increment N if you already have prior 1.3.0-dev
releases) so the package uses the correct X.Y.Z-dev.N prerelease track for a
minor release.

In `@src/shared/tools/deployment.ts`:
- Around line 235-240: The code is erroneously passing successful upload
responses (e.g., 204 No Content) into handleApiResponse(), which always calls
response.json() and will throw on empty bodies; update the Direct Deployment
path around the response handling in deployment.ts so that after you check for
response.status === 404 and throw DirectDeploymentUnsupportedError(), you
short-circuit for successful statuses (e.g., if response.ok or specifically
response.status === 204) and return/continue without calling
handleApiResponse(); only call handleApiResponse(response) for non-success
responses that require JSON error parsing.
- Around line 610-613: The zip command uses root-only -x patterns and will
include nested files like apps/*/.env and packages/*/node_modules; update the
zipping step in the block that builds the command using escapedDir/tmpZip so it
excludes nested paths by either switching to recursive exclude patterns (e.g.
use "**/.env*" or "*/node_modules/*"/"**/dist/**") or, preferably, reuse the
existing JS filter shouldExcludeDeploymentPath() to produce the exact exclude
list or to pre-filter files before zipping (i.e., build the archive from a
filtered file list rather than relying on root-level -x patterns); locate the
zip invocation that references escapedDir and tmpZip and replace the patterns or
wiring to shouldExcludeDeploymentPath() accordingly.

In `@src/shared/tools/index.ts`:
- Around line 175-177: The catch block that throws new Error("Cannot initialize
tools: backend at ... unreachable") should stop treating all failures as
"unreachable"—inspect the original error from
fetchBackendVersion()/health-check: if it's an HTTP response with status >=500
include a message like "backend returned HTTP 5xx (status ...)" and attach the
status/code; if it's a parse/validation error for the health payload use
"malformed health payload" and include the parsing/validation error; if it's a
network/fetch failure keep "unreachable" or "network error" and include the
underlying error; preserve the cause property when rethrowing and update the
thrown message in the throw new Error(...) in src/shared/tools/index.ts to
reflect these cases and include the original error details.
🪄 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: ecc179f2-137a-4919-9430-5d6e801a4209

📥 Commits

Reviewing files that changed from the base of the PR and between 635343e and 6860d03.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • package.json
  • src/shared/tools/deployment.ts
  • src/shared/tools/index.ts
  • src/shared/tools/types.ts

Comment thread package.json Outdated
Comment on lines +235 to +240
if (response.status === 404) {
throw new DirectDeploymentUnsupportedError();
}

await handleApiResponse(response);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t run successful file uploads through handleApiResponse().

handleApiResponse() always calls response.json() (src/shared/response-handler.ts:27-46). If the upload endpoint returns a valid empty success body like 204 No Content, the local direct-deploy path will throw after the file was already uploaded.

Possible fix
   if (response.status === 404) {
     throw new DirectDeploymentUnsupportedError();
   }
 
-  await handleApiResponse(response);
+  if (!response.ok) {
+    await handleApiResponse(response);
+  }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (response.status === 404) {
throw new DirectDeploymentUnsupportedError();
}
await handleApiResponse(response);
}
if (response.status === 404) {
throw new DirectDeploymentUnsupportedError();
}
if (!response.ok) {
await handleApiResponse(response);
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/tools/deployment.ts` around lines 235 - 240, The code is
erroneously passing successful upload responses (e.g., 204 No Content) into
handleApiResponse(), which always calls response.json() and will throw on empty
bodies; update the Direct Deployment path around the response handling in
deployment.ts so that after you check for response.status === 404 and throw
DirectDeploymentUnsupportedError(), you short-circuit for successful statuses
(e.g., if response.ok or specifically response.status === 204) and
return/continue without calling handleApiResponse(); only call
handleApiResponse(response) for non-success responses that require JSON error
parsing.

Comment on lines 610 to +613
## Step 1: Zip the source directory
\`\`\`bash
cd ${escapedDir} && zip -r ${tmpZip} . \
-x "node_modules/*" ".git/*" ".next/*" ".env" ".env.local" "dist/*" "build/*" ".DS_Store" "*.log"
-x "node_modules/*" ".git/*" ".next/*" ".env*" "dist/*" "build/*" ".insforge/*" ".DS_Store" "*.log"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

On common Info-ZIP builds, does zip -r archive.zip . -x ".env*" "node_modules/" "dist/" "build/" ".insforge/"exclude nested paths likeapps/web/.env.local, packages/foo/node_modules/react/index.js, and services/api/dist/server.js?

💡 Result:

No, on common Info-ZIP builds, the command zip -r archive.zip . -x ".env*" "node_modules/" "dist/" "build/" ".insforge/" does NOT exclude nested paths like apps/web/.env.local, packages/foo/node_modules/react/index.js, and services/api/dist/server.js. The -x patterns are matched against the full relative paths of files as they would appear in the archive (e.g., "apps/web/.env.local"). Patterns like ".env*" match only files whose full path starts with ".env*" (root-level only), not those ending with it or matching anywhere. "node_modules/" matches only direct contents of a root-level "node_modules/" directory (e.g., "node_modules/foo"), not nested ones like "packages/foo/node_modules/react/index.js", because the pattern lacks path prefix to match the nested location and the wildcard doesn't recurse across multiple directory levels by default in Info-ZIP matching. To exclude nested occurrences, use patterns like "node_modules" or "/.env" (though exact syntax for recursive basename matching varies; common practice is "name" or find alternatives), or "/node_modules/" if supported, but the given patterns fail for nested paths per man page behavior and community examples where "node_modules/" excludes only top-level.

Citations:


Use recursive patterns or JS-side filters instead of root-level-only zip exclusions.

The -x patterns in the zip command only match files at the root level. Nested paths like apps/web/.env.local, packages/foo/node_modules/**, and services/api/dist/** will still be archived, leaking secrets and bloating the payload. Replace with recursive patterns like "*/.env*", "*/node_modules", "*/dist", "*/build", or better yet, reuse the JS-side shouldExcludeDeploymentPath() filter logic to maintain consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/tools/deployment.ts` around lines 610 - 613, The zip command uses
root-only -x patterns and will include nested files like apps/*/.env and
packages/*/node_modules; update the zipping step in the block that builds the
command using escapedDir/tmpZip so it excludes nested paths by either switching
to recursive exclude patterns (e.g. use "**/.env*" or
"*/node_modules/*"/"**/dist/**") or, preferably, reuse the existing JS filter
shouldExcludeDeploymentPath() to produce the exact exclude list or to pre-filter
files before zipping (i.e., build the archive from a filtered file list rather
than relying on root-level -x patterns); locate the zip invocation that
references escapedDir and tmpZip and replace the patterns or wiring to
shouldExcludeDeploymentPath() accordingly.

Comment thread src/shared/tools/index.ts

@tonychang04 tonychang04 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

didn't really check mcp as prioritized cli + skills. but if anyone have problems we can ping and fix

@Fermionic-Lyu
Fermionic-Lyu merged commit 0ae2fa4 into master Apr 16, 2026
3 checks passed
@Fermionic-Lyu
Fermionic-Lyu deleted the new-deployment-flow branch April 16, 2026 07:07
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