Give a pocs/ app a Cloudflare Workers preview deploy so a PR returns a testable staging URL (auth-working). Use when wiring a POC for previews, or when "build X as a poc" needs to end at a clickable link. For launched apps/ apps use the /deploy skill instead.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add FriendlyInternet/nuxt-crouton --skill poc-deploy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Poc Deploy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/friendlyinternet-poc-deploy)More formats (shields.io, HTML) on the badges page.
---
name: poc-deploy
layer: stack
description: Give a pocs/ app a Cloudflare Workers preview deploy so a PR returns a testable staging URL (auth-working). Use when wiring a POC for previews, or when "build X as a poc" needs to end at a clickable link. For launched apps/ apps use the /deploy skill instead.
allowed-tools: Bash, Read, Edit, Write, Grep, Glob
---
# POC preview deploy
Makes the **endpoint of a POC a live, testable Cloudflare Workers preview URL** — the goal of epic #265. A POC lives in `pocs/<name>` (safe-to-break incubator; see root `CLAUDE.md`). This skill gives it a deploy workflow so **every PR that touches the POC deploys an isolated, auto-provisioned staging env and posts the preview URL on the PR**.
For **launched `apps/` apps** (production counterpart, two-domain deploy) use the **`/deploy`** skill instead — this one is the lighter, staging-only POC path.
## How it works
```
PR touches pocs/<name>/** (POC has a deploy.config.json) → deploy-pocs.yml (generic; detects
the changed/dispatched opted-in POCs) → deploy-app.yml (reusable, workspace: pocs, enable-review: true)
→ build (cloudflare_module, NUXT_PUBLIC_CROUTON_REVIEW=true) → wrangler deploy --env staging
→ auto-provision id-less D1/KV → sync review bridge secrets → sync ids → remote D1 migrate
→ sticky PR comment: 🚀 <name> staging deployed: <url> + overlay usage instructions
```
> **Review overlay is ON by default for all POC staging deploys (#596).** `deploy-pocs.yml` passes
> `enable-review: true` to `deploy-app.yml`, so every POC preview is built with
> `NUXT_PUBLIC_CROUTON_REVIEW=true` (the `@fyit/crouton-devtools` overlay + source stamper + `/api/_feedback`
> bridge). The PR comment includes overlay usage instructions. For the bridge to post `🎯 Preview feedback`
> comments, set the `NUXT_CROUTON_REVIEW_GITHUB_APP_*` repo-level secrets (see
> `writeups/setup/review-bridge-token-setup.md`); the overlay still renders without them.
> **One generic workflow, no per-POC file (#481).** There is a single committed
> `.github/workflows/deploy-pocs.yml`; a POC opts in with `pocs/<name>/deploy.config.json`
> (which the agent pipeline **can** push — it's under `pocs/`, not `.github/workflows/`, which
> needs the `workflows` scope the bot lacks). Do **not** generate a per-POC `deploy-<name>.yml`.
- The reusable `deploy-app.yml` takes a **`workspace`** input (`apps` default, or `pocs`) — that's the only thing that lets a `pocs/` app reuse the same pipeline as `apps/`.
- The preview is stable at **`https://<name>.pmcp.dev`** (the #133 staging domain), so `BETTER_AUTH_URL` is predictable and **auth works on the preview**.
## Wire a POC for previews
1. **Scaffold the POC first** (it must exist at `pocs/<name>` with a `wrangler.jsonc` that has an `env.staging` block: id-less `<name>-staging-db` + route `<name>.pmcp.dev`, and `cf:staging` in its `package.json` — the app scaffold produces these, mirroring `apps/velo`).
> **Add `cf:version` alongside `cf:staging`** (#1836). The `mode: version` dispatch — immutable side-by-side previews — runs the POC's own `cf:version`, and **nothing generates it**: a POC wired for deploy but missing it fails the dispatch. Copy the POC's own `cf:staging` and swap `wrangler deploy` for `wrangler versions upload`, dropping the id-sync and migrate steps (a version upload activates nothing, so there's no DB to migrate). Mirror *that* POC's script, not a template — `loop-station`, for one, prepares data first and skips `inject-wrangler-env`. `deploy-pocs.yml` now fails fast and tells you if it's missing.
2. **Generate + commit the initial D1 migrations.** Collections are **not** migrated by `crouton config`/`crouton init`, so a fresh POC has none — and the deploy's remote-migrate step then fails with *"No migrations present"*. Use the **`db-migrations`** build-first workaround: `NITRO_PRESET=node-server nuxt build` until `.nuxt/hub/db/schema.mjs` appears → `pnpm db:generate` → **commit** `pocs/<name>/server/db/migrations/sqlite/**`. (Don't skip this — it's the step that bit library-catalog, #457.)
3. **Opt the POC in — config only, NO workflow file:**
```bash
pnpm poc:scaffold-deploy <name> # → pocs/<name>/deploy.config.json (NOT a workflow file)
```
It writes `pocs/<name>/deploy.config.json` (`{ stagingUrl, layerPackages }`), read by the shared `deploy-pocs.yml`.
4. **Open a PR touching `pocs/<name>/**`** (e.g. the `deploy.config.json` + migrations). `deploy-pocs.yml` — which must be on the PR's **base** branch (an epic branch must carry it; see #481) — auto-fires → CI deploys the staging Worker and posts the preview URL. First deploy auto-provisions D1/KV. (`workflow_dispatch(app=<name>)` also works if the token has `actions` scope.)
## Auth on a fresh preview (so it's testable)
A freshly deployed Worker has no users. To make the preview testable *with auth*, the POC's **`seed` script provisions a known admin** against the remote D1 (run it post-deploy, or have CI do it), and the admin creds are handed back alongside the URL. (Self-registration on the preview also works if the POC enables it.) See the per-app `seed`/`shots` scripts.
## Requirements / gotchas
- **CI-only:** real Cloudflare deploys run in GitHub Actions — the `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_API_TOKEN` repo secrets must exist (same as the `apps/` deploys), and the token needs account Workers/D1/KV **and** zone Workers-Routes/DNS edit for the `<name>.pmcp.dev` custom domain. There are no CF creds in the dev sandbox; you cannot produce the URL locally — open the PR and let CI do it, then babysit to green.
- **Staging only.** No production block — pocs are previews. Promote `pocs/<name>` → `apps/<name>` and use `/deploy` for production.
- **Worker secrets** (e.g. `BETTER_AUTH_SECRET`) persist across deploys; set them once via `WORKER_SECRETS_JSON` (an Environment secret) or `wrangler secret bulk --env staging`.
- The POC opts in via `pocs/<name>/deploy.config.json` (re-run `pnpm poc:scaffold-deploy <name>` to refresh it). The generic `deploy-pocs.yml` is **shared** — never add a per-POC workflow file. For a `pull_request` deploy to fire, that workflow must be present on the PR's **base** branch (cut/refresh epic branches from current `main` so they carry it — #500/WS3).
- **Migrations must be committed** (`pocs/<name>/server/db/migrations/sqlite/**`) before the deploy, or the remote-migrate step fails — see step 2.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!