Files
supabase/apps/studio/components/interfaces/Workers/DeployWorkerDialog.tsx
Jordi Enric 509d80c9eb feat(studio): CLI deploy instructions for workers (FE-4191) (#49194)
## What

The surface that shows you how to deploy a worker from the CLI, plus the
product rename and the alpha framing.

- **Compute → Workers.** `PRODUCT_NAME` and `CLI_NAME` now say `Workers`
/ `workers`, so the sidebar, page title, command menu, and every
generated snippet match the CLI. One name, not two.
- **`DeployWorkerDialog`** — scaffold / configure / push, with copyable
`supabase workers` and `config.toml` snippets
- **`WorkersEmptyState`** — an `EmptyStatePresentational` with a
permission-gated deploy action
- **`AlphaNotice`** on the list page, and a **New** badge on the sidebar
entry (`Route.isNew`)
- **`WorkerSnippetTabs`** — CLI, `config.toml`, and curl/JS/Python calls
built from one worker shape. Reused by #49195.

Snippet URLs resolve from the project's `app_config.endpoint`
(`https://<project>/workers/v1/<name>`, the same shape as
`/functions/v1/`), and fall back to `[YOUR WORKER URL]` before settings
load rather than printing a wrong host.

## How to test

Only on the **Mockamaster** project in staging — it is the one project
in the alpha allow-list.

1. Staging dashboard → Mockamaster → **Workers** (the sidebar entry
carries a **New** badge)
2. **Deploy a worker** → step through the tabs; every snippet should
name the real worker URL, not a placeholder
3. Copy the cURL snippet and run it: expect `401`. Reaching a deployed
worker needs a second allow-list (`WORKERS_ALLOWED_PROJECTS` in
api-gateway `customer-router/wrangler.toml`), separate from the flag
that unlocks the dashboard.
4. Open a project with no workers to see the empty state

## Tests

`workerSnippets.test.ts` covers the generated output users copy: worker
URL in all three call snippets, the `[YOUR WORKER URL]` fallback, anon
vs service-role placeholder, empty-name fallback and trimming, runtime
default, and every `config.toml` field.

## Unverified copy

The dialog steps and the `supabase workers <sub>` subcommands come from
the original POC spec, not from the shipped CLI. Same for "Dockerfile,
Node.js and Deno supported" in the empty state — only Deno is confirmed
end to end. Worth a check by someone who knows the CLI surface.

Closes FE-4191

---------

Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com>
2026-08-25 15:38:57 +02:00

68 lines
2.0 KiB
TypeScript

import {
Dialog,
DialogContent,
DialogHeader,
DialogSection,
DialogSectionSeparator,
DialogTitle,
} from 'ui'
import { EXAMPLE_WORKER } from './workerSnippets'
import { WorkerSnippetTabs } from './WorkerSnippetTabs'
interface DeployWorkerDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
}
const STEPS = [
{
title: 'Scaffold the worker',
description: 'Creates supabase/workers/<name>/ with an entrypoint for the runtime you pick.',
},
{
title: 'Configure it',
description: 'Runtime, size, access, and instance count live in supabase/config.toml.',
},
{
title: 'Push it',
description: 'Builds the image and schedules it on a microVM in US West.',
},
]
export const DeployWorkerDialog = ({ open, onOpenChange }: DeployWorkerDialogProps) => (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent size="large">
<DialogHeader>
<DialogTitle>Deploy a worker</DialogTitle>
</DialogHeader>
<DialogSection className="space-y-4">
<p className="text-sm text-foreground-light">
Workers are deployed with the Supabase CLI. This dashboard is read-only during the private
alpha.
</p>
<ol className="space-y-4">
{STEPS.map((step, index) => (
<li key={step.title} className="flex gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-strong text-xs text-foreground-light">
{index + 1}
</span>
<div className="space-y-0.5">
<p className="text-sm text-foreground">{step.title}</p>
<p className="text-sm text-foreground-lighter">{step.description}</p>
</div>
</li>
))}
</ol>
</DialogSection>
<DialogSectionSeparator />
<DialogSection>
<WorkerSnippetTabs input={EXAMPLE_WORKER} tabs={['cli', 'config']} />
</DialogSection>
</DialogContent>
</Dialog>
)