Skip to content

feat(deploy): ship every site through the deployments API, and publish it - #643

Draft
netanelgilad wants to merge 6 commits into
mainfrom
claude/inspiring-edison-55ncqj
Draft

netanelgilad wants to merge 6 commits into
mainfrom
claude/inspiring-edison-55ncqj

Conversation

@netanelgilad

@netanelgilad netanelgilad commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Note

Description

base44 deploy now ships a project's site through the deployments API — the same lane base44 site deploy uses — instead of the legacy tar.gz archive upload, so a full-stack build's worker is no longer silently dropped by the unified deploy. Because deploying and publishing are separate acts server-side, deploy follows its deployment with POST deployments/{git_hash}/publish (what the archive upload did implicitly), while site deploy deliberately does not — the platform's own build step calls it against builder-managed apps, which are published from the builder. The BASE44_DEPLOYMENTS_API env gate is removed: every site deploy takes the lane, and --git-hash / --concurrency are always available.

Related Issue

None

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Other (please describe):

Changes Made

  • publishDeployment() (core/site/api.ts, plus PublishDeploymentResponseSchema in schema.ts): a second call, POST deployments/{git_hash}/publish, addressed by the full commit hash rather than the derived deployment id.
  • base44 deploy ships the site through the deployments lane (core/project/deploy.ts): deployProjectSite() resolves the commit, runs deployToDeployments(), then publishes. New --git-hash <hash> (validated as 7–64 hex chars, defaults to the checkout's HEAD) and --no-publish flags; no --concurrency, since the caller uploading at scale is site deploy. Asset and warning progress is surfaced through a new onSiteProgress callback.
  • Archive upload kept only where a build has no commit: a project with a site.outputDirectory and no git history warns and falls back to deploySite(), which publishes as it always did. A worker build has no archive form, so a missing commit stays fatal there. The only other caller left is base44 create's scaffold deploy.
  • Builder-managed apps no longer fail the deploy: a publish rejected with extra_data.code === "app_publishes_from_builder" is reported as "production was left where it was" and the command still succeeds — its resources and its build did deploy. Any other publish error still fails.
  • hasResourcesToDeploy() is now async and counts a detected full-stack artifact as a site, so a worker build with no site.outputDirectory is no longer reported as "No resources found to deploy".
  • Env gate removed: deploymentsApiEnabled() deleted from core/site/deployment.ts; site deploy always takes the lane, always registers --git-hash / --concurrency, and gains an opt-in --publish that prints the app URL. Its --json document now carries published.
  • Dead legacy path dropped from cli/commands/site/deploy.ts (deployTarball), and the output directory is resolved before the git hash so a defaulted site block is reported before anything else can fail.
  • Tests: new coverage on deploy for publish-by-default, --no-publish, the builder-managed case, a hard publish failure, and the no-commit archive fallback; site deploy tests for not publishing and for --publish; all BASE44_DEPLOYMENTS_API setup removed from the deployment specs. Testkit gains mockDeploymentPublish(), mockDeploymentPublishError(), a publishedCommits recorder, and mockSiteDeployError() renamed to mockDeploymentCreateError().
  • Docs: docs/deployments.md rewritten around "deploying and publishing are separate acts", the per-command publish rules, and what is left of the archive upload; two CHANGELOG entries added.

Testing

  • I have tested these changes locally
  • I have added/updated tests as needed
  • All tests pass (npm test)

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (if applicable)
  • My changes generate no new warnings
  • I have updated docs/ (AGENTS.md) if I made architectural changes

Additional Notes

Worth calling out for automated callers: BASE44_DEPLOYMENTS_API now does nothing (setting it is harmless), and base44 deploy in a git checkout no longer uses deploy-dist — it creates a deployment and publishes it. The platform build sandbox's base44 site deploy -y --json --git-hash <commit> invocation is unchanged and still does not publish.


🤖 Generated by Claude | 2026-10-11 12:24 UTC | d9f6a73

netanelgilad and others added 2 commits September 22, 2026 12:19
base44 dev now serves the whole app on one origin. /api/apps stays with the
local backend; everything else — the app's own /api routes included — is
forwarded to its dev server carrying Base44-App-Id, Base44-Api-Url and a
service-role credential, with the caller's copies of the platform-owned
headers dropped first. Full-stack apps can build a client with
createClientFromRequest locally, the way they do in production, instead of
500ing on every SSR loader and server function.

The dev server's port is read off the URL it announces at startup (the front
door's own port skipped, since the Vite plugin logs it as its proxy target),
and a request that comes back marked as forwarded answers 508 naming the
Vite proxy rather than looping. Websocket upgrades follow the same split, so
HMR reaches the app and the entity-events socket stays local.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tmb4PCrrV2SLRpBjkGAgXJ
…h it

`BASE44_DEPLOYMENTS_API` is gone. The lane it gated is now the only transport
`site deploy` has, and `--git-hash` / `--concurrency` are always registered
rather than appearing only when an env var was set. Setting the variable does
nothing; the sandbox that sets it needs no change.

`base44 deploy` ships its site through the same lane instead of the archive
upload, so a full-stack project's worker is no longer silently dropped, and a
build carries the commit it was made at. Because that lane only builds, the
deploy then publishes what it deployed (`--no-publish` opts out) — the archive
upload it replaces always left the app live, and a deploy that quietly stopped
doing so would be a worse default than a flag.

`site deploy` deliberately does NOT publish, and gains `--publish` instead: the
platform's own build step runs it against builder-managed apps and repoints
production itself, so publishing there would fail exactly those apps. When the
server does refuse a publish for that reason (`app_publishes_from_builder`), the
deploy reports it and still succeeds — its resources and its build did land.

The archive upload keeps the two callers that have no commit to be addressed by:
`base44 create`'s scaffold deploy, and a `base44 deploy` in a project with no git
history, which warns and falls back. A worker build has no archive form, so
there a missing commit is fatal.

Depends on base44-dev/apper#26921 for the publish endpoint.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tmb4PCrrV2SLRpBjkGAgXJ
@netanelgilad netanelgilad self-assigned this Sep 28, 2026
…on-55ncqj

# Conflicts:
#	CHANGELOG.md
#	docs/deployments.md
#	packages/cli/src/cli/dev/serve-command-runner.ts
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/cli@0.1.32-pr.643.d9f6a73

Prefer not to change any import paths? Install using npm alias so your code still imports base44:

npm i "base44@npm:@base44-preview/cli@0.1.32-pr.643.d9f6a73"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "base44": "npm:@base44-preview/cli@0.1.32-pr.643.d9f6a73"
  }
}

Preview published to npm registry — try new features instantly!

claude added 2 commits October 3, 2026 06:35
…ards them too

The compiled binary answered every HMR upgrade with an error: under Bun, bytes
written to the socket a node:http `upgrade` listener receives never reach the
wire, so neither http-proxy's tunnel nor a raw-socket pipe can complete a
handshake from it. `ws` is the one path Bun maps onto its native websockets —
it is how Socket.IO's realtime socket already worked there — so the front door
now accepts the browser's socket with it and relays frames to a `ws` client
connected to the dev server, carrying the same SDK headers the HTTP path does.
The two paths now share one `sdkHeaders()` definition.

The HMR test asserted only that the socket opened, which a relay satisfies on
its own, so it now waits for the dev server's own frame and checks what that
frame says the upgrade arrived with. The fixture also tolerates a reset socket,
as a real dev server does: Bun's client resets rather than closing, and the
unhandled error killed the fixture and with it the dev environment.

Adds `ws` (8.21.0, already locked through miniflare) and `@types/ws` as
devDependencies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tmb4PCrrV2SLRpBjkGAgXJ
Resolves site/deploy.ts against #649's defaulted site block: siteOutputDir()
now always returns a path, so the "No site configuration found" guard this
branch had re-added is unreachable and goes. The output directory is resolved
before the commit, so a defaulted block is reported before anything can fail;
#649's own test passes --git-hash so it still fails on the missing ./dist it
was written for. bun.lock is main's plus this branch's ws / @types/ws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tmb4PCrrV2SLRpBjkGAgXJ
The dev-server front door and its tests now live in #659. This branch
keeps only the deploy routing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tmb4PCrrV2SLRpBjkGAgXJ
@netanelgilad
netanelgilad marked this pull request as draft October 11, 2026 12:23

Copy link
Copy Markdown
Contributor Author

Parking this as a draft.

  • The base44 dev front door is split out to feat(dev): front the app's dev server with the SDK header contract #659. This PR now has only the deploy routing (deployments API as the default lane, env gate removed, deploy publishes).
  • Full-stack deploys look set to go through Yury's base44-dev/apper#29340 (build/deploy pipeline) plus the CLI's base44 publish (versions API, behind BASE44_VERSIONS_API).
  • Once #29340 lands, this PR will probably shrink to having base44 deploy use publish for worker builds.

Generated by Claude Code

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