You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(sdk): reject Astro adapter build-tree shipped as site content (gh#411)
A deploy that roots its file source at the build root (`dist/`) instead of
`dist/run402/client/` ships the @run402/astro adapter tree
(`run402/adapter.json`, `run402/server/**`) as static assets and lands every
page under a `run402/client/` path prefix. The static manifest then has no
reachable pages, every URL falls through to the SSR catchall and 404s, and the
SSR bundle becomes publicly downloadable - an apply that "succeeds" but takes
the whole site down (#411).
validateSpec now rejects this locally with `ASTRO_ADAPTER_TREE_IN_SITE` before
any CAS upload or plan - both for literal FileSets (synchronously) and for
`dir()` LocalDirRefs (post-expansion). Not suppressible by RUN402_ALLOW_WARNINGS.
Also: CLI `deploy apply --dir` tolerates the slice omitting `routes`, and
llms-cli.txt documents the anti-pattern + the new guard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CLI dynamically imports `@run402/astro/release-slice` (must be installed in the consuming project, **`@run402/astro >=1.2.1` + `@run402/sdk >=2.18.0`** — older SDKs reject `FunctionSpec.class: 'ssr'` locally in `validateKnownFields` before the spec ever reaches the gateway; the helper preflights this and emits `R402_ASTRO_SDK_VERSION_TOO_OLD` with a precise upgrade command). The helper bundles the SSR server output with esbuild into a single `source` (the gateway rejects multi-file function specs), emits no `/*` catchall route (the gateway routes every unmatched path to the project's `class: 'ssr'` function automatically), defaults `site.public_paths: { mode: "implicit" }` to opt out of inherited explicit-mode paths from the base release, and colocates the `_assets-manifest.json` inside the resolved `build.client` dir (so the slice's site replace dir carries it). On a missing/incompatible manifest the error envelope carries `code: "R402_ASTRO_ADAPTER_MANIFEST_MISSING"` or `R402_ASTRO_ADAPTER_MANIFEST_VERSION_UNSUPPORTED` with `hint` + `docs` fields pointing at run402.com/errors. Direct-SDK callers get the same primitive via `import { buildAstroReleaseSlice } from "@run402/astro/release-slice"`.
315
+
The CLI dynamically imports `@run402/astro/release-slice` (must be installed in the consuming project, **`@run402/astro >=1.2.1` + `@run402/sdk >=2.18.0`** — older SDKs reject `FunctionSpec.class: 'ssr'` locally in `validateKnownFields` before the spec ever reaches the gateway; the helper preflights this and emits `R402_ASTRO_SDK_VERSION_TOO_OLD` with a precise upgrade command). The helper bundles the SSR server output with esbuild into a single `source` (the gateway rejects multi-file function specs), roots the site at the resolved `build.client` dir (`dist/run402/client/`, NOT `dist/`), **omits `routes` entirely from the returned slice** (the gateway routes every unmatched path to the project's `class: 'ssr'` function automatically, so no route table is needed; omitting `routes` — rather than sending an empty `replace` that would CLEAR the table — carries forward any base-release routes such as a separately-declared `/api/*` function and keeps the slice safe to submit from a CI OIDC session without route scopes), defaults `site.public_paths: { mode: "implicit" }` to opt out of inherited explicit-mode paths from the base release, and colocates the `_assets-manifest.json` inside the resolved `build.client` dir (so the slice's site replace dir carries it). On a missing/incompatible manifest the error envelope carries `code: "R402_ASTRO_ADAPTER_MANIFEST_MISSING"` or `R402_ASTRO_ADAPTER_MANIFEST_VERSION_UNSUPPORTED` with `hint` + `docs` fields pointing at run402.com/errors. Direct-SDK callers get the same primitive via `import { buildAstroReleaseSlice } from "@run402/astro/release-slice"`. Do NOT hand-roll `site` / `public_paths`: if a deploy ships the adapter build tree (`run402/adapter.json`, `run402/server/**`) as site content — the symptom of rooting a file source at `dist/` instead of `dist/run402/client/` — the SDK rejects it locally with `ASTRO_ADAPTER_TREE_IN_SITE` before any upload, and the gateway warns `SITE_NO_REACHABLE_HTML` when a release ships HTML that isn't reachable at any public path (kychee-com/run402#411).
316
316
317
317
Recovery from a stuck deploy: when an `apply` ends in `activation_pending` (rare; transient gateway failure between SQL commit and the pointer-swap activation), the gateway auto-resumes on the hourly tick. Static spec/config activation failures are classified promptly and thrown as structured deploy errors instead of polling until timeout. For genuinely resumable operations, call resume explicitly:
0 commit comments