Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/compute-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: compute preview

on:
pull_request:
types:
- opened
- reopened
- synchronize
delete:

permissions:
contents: read
issues: write
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.event.ref }}
cancel-in-progress: true

jobs:
deploy-preview:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0

- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: .node-version
cache: pnpm

- name: Install Bun
env:
BUN_VERSION: 1.3.12
run: |
curl -fsSL https://bun.sh/install | bash -s -- bun-v${BUN_VERSION}
echo "$HOME/.bun/bin" >> "$GITHUB_PATH"
"$HOME/.bun/bin/bun" --version

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build Compute artifact
run: pnpm build:deploy

- name: Deploy preview
id: deploy
env:
PRISMA_API_TOKEN: ${{ secrets.STUDIO_PREVIEW_COMPUTE_TOKEN }}
PREVIEW_BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
run: node scripts/compute-preview/compute-preview-deploy.mjs

- name: Comment preview URL on PR
env:
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_TOKEN: ${{ github.token }}
PREVIEW_BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
PREVIEW_PR_NUMBER: ${{ github.event.pull_request.number }}
PREVIEW_SERVICE_NAME: ${{ steps.deploy.outputs.preview_service_name }}
PREVIEW_SERVICE_URL: ${{ steps.deploy.outputs.preview_service_url }}
PREVIEW_VERSION_URL: ${{ steps.deploy.outputs.preview_version_url }}
run: node scripts/compute-preview/compute-preview-comment.mjs

destroy-preview:
if: github.event_name == 'delete' && github.event.ref_type == 'branch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.repository.default_branch }}

- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: .node-version

- name: Install Bun
env:
BUN_VERSION: 1.3.12
run: |
curl -fsSL https://bun.sh/install | bash -s -- bun-v${BUN_VERSION}
echo "$HOME/.bun/bin" >> "$GITHUB_PATH"
"$HOME/.bun/bin/bun" --version

- name: Destroy preview service for deleted branch
env:
PRISMA_API_TOKEN: ${{ secrets.STUDIO_PREVIEW_COMPUTE_TOKEN }}
PREVIEW_BRANCH_NAME: ${{ github.event.ref }}
run: node scripts/compute-preview/compute-preview-destroy.mjs
57 changes: 57 additions & 0 deletions Architecture/compute-preview-deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Compute Preview Deploys

This document is normative for branch-scoped Compute preview deployments.

## Purpose

Pull requests need a live Studio preview without manually creating and cleaning up
Compute services for every branch.

The preview deployment path uses the existing `pnpm build:deploy` artifact and
publishes it into the dedicated Compute project named `studio-preview`.

## Triggering

- A preview deploy MUST run when a pull request is opened, reopened, or updated
with new commits.
- Preview deploys MUST only run for branches inside this repository. Forked pull
requests MUST NOT receive the Compute token.
- A preview service MUST be destroyed when the corresponding Git branch is
deleted.
- Because the GitHub `delete` event is evaluated from the default branch
workflow set, this workflow MUST be merged to `main` before branch-deletion
cleanup becomes automatic for later branches.

## Service Naming

- Preview services MUST be keyed by the pull request branch name.
- Because Compute service names need a filesystem- and URL-safe shape, the raw
branch name MUST be normalized to a lowercase slug containing only
alphanumeric segments separated by `-`.
- If the normalized branch slug exceeds the Compute name budget, it MUST be
truncated and keep a stable hash suffix so repeated deploys resolve to the
same service.
- The same normalization MUST be used for deploy and destroy flows.

## Deploy Flow

- The workflow MUST build the preview artifact with `pnpm build:deploy`.
- The workflow MUST authenticate with Compute through the GitHub Actions secret
`STUDIO_PREVIEW_COMPUTE_TOKEN`, exposed to the CLI as `PRISMA_API_TOKEN`.
- The deploy helper MUST resolve the `studio-preview` Compute project by name at
runtime instead of hardcoding an opaque service id.
- If the branch preview service does not exist, the helper MUST create it in the
project's default region.
- If the service already exists, the helper MUST deploy a new version to that
same service.
- Deployments MUST use the published CLI entrypoint:
`bunx @prisma/compute-cli@latest deploy --skip-build --path deploy --entrypoint bundle/server.bundle.js --http-port 8080 --env STUDIO_DEMO_PORT=8080`.

## PR Feedback

- Successful preview deploys MUST post the live service URL back to the pull
request.
- The PR comment MUST be sticky: later deploys for the same PR update the
existing preview comment instead of creating duplicates.
- The comment MUST include the original branch name plus the resolved Compute
service name so any slug normalization stays visible.
39 changes: 24 additions & 15 deletions Architecture/demo-compute-bundling.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,43 @@ It is responsible for:
1. building the browser JS from `demo/ppg-dev/client.tsx`
2. processing `ui/index.css` through the repo PostCSS pipeline
3. injecting those prebuilt assets into the bundled server through `virtual:prebuilt-assets`
4. writing a self-contained output directory whose entrypoint is `bundle/server.bundle.js`

It is not responsible for manually collecting Prisma Postgres dev runtime assets anymore, but it does need to carry Prisma Streams worker runtime files that Bun does not discover automatically.
4. copying Prisma Dev runtime assets into `bundle/` with their stable filenames
5. bundling Prisma Streams local's worker into `touch/processor_worker.js`
6. copying the worker's vendored `hash_vendor/` files into `touch/`
7. writing a self-contained output directory whose entrypoint is `bundle/server.bundle.js`

## Prisma Dev Runtime Assets

`@prisma/dev@0.23.1` exposes a Bun runtime-asset manifest for PGlite.
`@prisma/dev@0.24.6` exposes a Bun runtime-asset manifest for PGlite and also
exports `copyPrismaDevRuntimeAssets()`.

That means when `build-compute.ts` bundles `demo/ppg-dev/server.ts` with Bun:

- Bun sees `@prisma/dev`'s literal Bun manifest import
- Bun emits the required `pglite.wasm`, `pglite.data`, and extension `*.tar.gz` files automatically
- those files land next to the server bundle in `deploy/bundle/`

Studio no longer scans `node_modules/@electric-sql/pglite/dist` or copies those files by hand.
- Bun emits hashed PGlite `.wasm`, `.data`, and extension archives next to the bundled server entrypoint
- `build-compute.ts` then copies the same runtime assets into `deploy/bundle/` with their canonical names like `pglite.wasm` and `pglite-seed.tar.gz`

## Prisma Streams Runtime Assets
That extra copy is a Studio-side workaround for the current Compute boot path:
the deployed `@prisma/dev` runtime still resolves stable filenames relative to
the server bundle in some startup paths, so the Compute artifact needs both the
hashed Bun-emitted assets and the canonical names.

Prisma Dev can also start a local Prisma Streams server. That runtime spawns a touch interpreter worker from `@prisma/streams-local`.
## Prisma Streams Worker Assets

`build-compute.ts` MUST therefore copy:
`@prisma/dev` also starts Prisma Streams local and spawns a worker from
`../touch/processor_worker.js` relative to the bundled server entrypoint.

- `@prisma/streams-local/dist/touch`
- the worker's bare runtime dependency package, `better-result`
For the Compute artifact that means:

into the output directory.
- the server entrypoint stays at `deploy/bundle/server.bundle.js`
- stable PGlite assets live in `deploy/bundle/`
- the Streams worker must live at `deploy/touch/processor_worker.js`
- the worker's vendored hashing modules must live at `deploy/touch/hash_vendor/`

This is an explicit exception to the "no manual runtime asset copying" rule above: Bun handles the main PGlite runtime assets automatically, but the spawned Streams worker is resolved at runtime from the packaged filesystem and must remain self-contained after deployment.
The worker cannot be copied verbatim from `node_modules` because it still
imports package dependencies such as `better-result` and `ajv`. `build-compute.ts`
therefore Bun-bundles that worker into a standalone file before copying the
vendored hash modules alongside it.

## Runtime Detection

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- Add optional Prisma Streams setup support, wire the `ppg-dev` demo to Prisma Dev's Streams server, and show live stream names in a new sidebar `Streams` section.
- Add a dedicated stream event view with infinite scrolling, expandable rows, and summary columns for time, key, indexed fields, preview text, and payload size.
- Keep stream event counts live while a stream is open, and reveal newly arrived events in 50-row batches without snapping the current list.
- Work around the current `@prisma/dev` Compute asset-resolution gap by copying stable PGlite runtime filenames into the deploy bundle and bundling the Prisma Streams local worker, so the packaged demo can boot correctly on Compute with WAL syncing still enabled.
- Add automatic Compute preview deploys for pull requests, so branch builds land in the `studio-preview` project, comment their live URL on the PR, and clean themselves up when the branch is deleted.

## 0.27.3

Expand Down
11 changes: 9 additions & 2 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ This gives users an accurate live model of the database and keeps table navigati
## Deployable Prisma Postgres Demo

The local `ppg-dev` demo can be packaged into a Compute-ready artifact instead of requiring the repo checkout at runtime.
The deploy builder precompiles the browser JS/CSS, injects those assets into the bundled server, and relies on `@prisma/dev`'s Bun runtime-asset manifest so PGlite's WASM, data, and extension archives are emitted automatically beside the server bundle.
When that bundled demo also starts its embedded local Prisma Streams runtime, Studio now relies on the published `@prisma/streams-local` package to carry its own runtime tuning defaults instead of layering a second demo-specific memory policy on top.
The deploy builder precompiles the browser JS/CSS, injects those assets into the bundled server, copies Prisma Dev's PGlite runtime assets into the bundle with stable filenames, and bundles the Prisma Streams worker into `touch/` so the Compute artifact can boot and keep WAL-to-stream syncing alive outside the repo checkout.
The same demo entrypoint can also run against external development infrastructure through `pnpm demo:ppg -- --database-url <postgres-url> --streams-server-url <streams-url>`, or in streams-only mode through `pnpm demo:ppg -- --streams-server-url <streams-url>`. In those modes, Studio keeps serving the local shell and `/api/streams` proxy, but skips local Prisma Dev startup, local Streams startup, WAL wiring, and local seeding so you can point the demo at an already-running backend stack.

## Streams-Only Studio Shell
Expand All @@ -27,6 +26,14 @@ In that mode the shell hides schema selection, table navigation, and database-on
Studio's local development workflow can temporarily replace the published npm `@prisma/dev` package with the sibling source package from `../team-expansion/dev/server`, while also swapping its `@prisma/streams-local` dependency over to a built local Streams checkout.
That override stays opt-in, rebuilds from the sibling repos by default, and can be reverted without rewriting the tracked lockfile, so experimental Prisma Dev and Durable Streams work can stay local to one Studio checkout.

## Compute PR Preview Deploys

Pull requests can publish the current branch into the dedicated `studio-preview`
Compute project without hand-creating services for each branch.
The preview workflow derives a stable Compute-safe service name from the branch,
reuses that service across later pushes, posts the live URL back to the PR, and
destroys the preview service when the branch is deleted.

## Introspection Recovery and Retry

Startup introspection failures show retryable diagnostics in both the sidebar and the main table panel instead of pretending the database has no tables.
Expand Down
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,46 @@ Revert to the published npm packages with `pnpm streams:use-npm`.
`@prisma/dev` now emits its own PGlite runtime assets during Bun bundling, so
plain `bun build` no longer needs `--packages external` just to keep Prisma
Postgres dev working. For a source-free Compute artifact, use `pnpm build:deploy`:
that path still prebuilds the browser JS/CSS and injects those assets into the
server bundle so the deployed demo does not need the repo checkout at runtime.
that path prebuilds the browser JS/CSS, injects those assets into the server
bundle, and copies Prisma Dev's runtime assets into `deploy/bundle/` with
stable filenames so the deployed demo does not need the repo checkout at
runtime. It also Bun-bundles the Prisma Streams local worker into `deploy/touch/`
so Compute can keep Prisma Dev's WAL-to-stream sidecar alive in the source-free artifact.

Deploy that artifact with:

```sh
bunx @prisma/compute-cli deploy --skip-build \
--path deploy \
--entrypoint bundle/server.bundle.js \
--http-port 8080 \
--env STUDIO_DEMO_PORT=8080 \
--service <service-id>
```

## Compute Preview Deploys

This repo also maintains branch-scoped Compute previews for pull requests.

- `.github/workflows/compute-preview.yml` deploys the current PR branch into the
dedicated `studio-preview` Compute project whenever a PR is opened,
reopened, or updated with new commits.
- The preview service name is derived from the branch name through a stable
Compute-safe slug, so later pushes reuse the same service instead of creating
duplicates.
- The workflow updates one sticky PR comment with the live preview URL after a
successful deploy.
- When a Git branch is deleted, the same workflow destroys the matching preview
service.

The workflow expects the GitHub Actions secret
`STUDIO_PREVIEW_COMPUTE_TOKEN`, which should contain a Compute API token for the
`studio-preview` project.

For branch-deletion cleanup to happen automatically, the workflow must be
present on the default branch. In practice that means merging the preview
workflow to `main` once, after which later PR branches will get full automatic
create/update/delete behavior.

## Development Workflow

Expand Down
Loading